@okxweb3/a2a-node 0.2.1-beta-8ae7a0d300-260807161635 → 0.2.1
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 +744 -44
- package/dist/index.js +733 -40
- 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.1
|
|
9436
|
+
version: "0.2.1",
|
|
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.1
|
|
9447
|
+
userAgent: `okx-a2a-node/${"0.2.1"}`,
|
|
9448
9448
|
auth: {
|
|
9449
9449
|
...config.token ? { token: config.token } : {},
|
|
9450
9450
|
...config.password ? { password: config.password } : {}
|
|
@@ -25478,6 +25478,8 @@ var init_events = __esm({
|
|
|
25478
25478
|
XMTP_DEBUG_SYNC_REQUESTED: "XMTP debug sync requested",
|
|
25479
25479
|
XMTP_DEBUG_SYNC_COMPLETED: "XMTP debug sync completed",
|
|
25480
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",
|
|
25481
25483
|
ADDRESS_SYNC_COMPLETED: "Address sync completed",
|
|
25482
25484
|
AGENT_REFRESH_SESSION_EXPIRED: "Agent refresh aborted: onchainos session expired, local clients taken offline",
|
|
25483
25485
|
OFFLINE_REPLAY_MESSAGE_REPLAYED: "Offline replay message replayed",
|
|
@@ -25512,6 +25514,8 @@ var init_events = __esm({
|
|
|
25512
25514
|
CONVERSATIONS_STREAM_FAILED: "conversations.stream failed",
|
|
25513
25515
|
AGENT_START_FAILED: "agent.start failed",
|
|
25514
25516
|
AGENT_STREAM_ERROR: "agent stream error",
|
|
25517
|
+
AGENT_UNHANDLED_ERROR: "Agent unhandled error",
|
|
25518
|
+
AGENT_STREAM_RECOVERY_TIMEOUT: "Agent stream recovery timeout",
|
|
25515
25519
|
BOOTSTRAP_FAILED: "Bootstrap failed",
|
|
25516
25520
|
ONCHAINOS_SESSION_EXPIRED: "Onchainos session expired",
|
|
25517
25521
|
ONCHAINOS_CLI_ERROR: "Onchainos CLI error",
|
|
@@ -25521,6 +25525,7 @@ var init_events = __esm({
|
|
|
25521
25525
|
MESSAGE_PARSE_FAILED: "Message parse failed",
|
|
25522
25526
|
MESSAGE_HANDLER_ERROR: "Message handler error",
|
|
25523
25527
|
INBOUND_DISPATCH_FAILED: "Inbound dispatch failed",
|
|
25528
|
+
INBOUND_REPLAY_GATE_DRAIN_FAILED: "Inbound replay gate drain failed",
|
|
25524
25529
|
// Default name stamped on events that reach Sentry without going through this
|
|
25525
25530
|
// logger — uncaught exceptions and unhandled rejections. Without it those
|
|
25526
25531
|
// events carry no eventName and cannot be classified.
|
|
@@ -25818,7 +25823,10 @@ var init_xmtp_test_metrics = __esm({
|
|
|
25818
25823
|
"Address sync completed",
|
|
25819
25824
|
"Agent client created",
|
|
25820
25825
|
"Agent client removed",
|
|
25821
|
-
"
|
|
25826
|
+
"agent stream error",
|
|
25827
|
+
"Agent stream recovered",
|
|
25828
|
+
"Agent stream recovery replay completed",
|
|
25829
|
+
"Agent stream recovery timeout",
|
|
25822
25830
|
"conversations.stream failed",
|
|
25823
25831
|
"Inbound delivered to session",
|
|
25824
25832
|
"Inbound dispatch failed",
|
|
@@ -25837,6 +25845,190 @@ var init_xmtp_test_metrics = __esm({
|
|
|
25837
25845
|
}
|
|
25838
25846
|
});
|
|
25839
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
|
+
|
|
25840
26032
|
// ../core/src/sentry-logger/index.ts
|
|
25841
26033
|
function applyFatalEventDefaults(event) {
|
|
25842
26034
|
try {
|
|
@@ -25882,6 +26074,7 @@ var init_sentry_logger = __esm({
|
|
|
25882
26074
|
init_events();
|
|
25883
26075
|
init_log_fields();
|
|
25884
26076
|
init_xmtp_test_metrics();
|
|
26077
|
+
init_error_diagnostics();
|
|
25885
26078
|
init_events();
|
|
25886
26079
|
init_log_fields();
|
|
25887
26080
|
FLOW_ID = (0, import_node_crypto5.randomUUID)();
|
|
@@ -25969,14 +26162,23 @@ var init_sentry_logger = __esm({
|
|
|
25969
26162
|
"agentId",
|
|
25970
26163
|
"agentPlatform",
|
|
25971
26164
|
"cacheName",
|
|
26165
|
+
"causeCode",
|
|
26166
|
+
"causeType",
|
|
26167
|
+
"causeVariant",
|
|
25972
26168
|
"checkpoint",
|
|
25973
26169
|
"code",
|
|
25974
26170
|
"communicationClass",
|
|
25975
26171
|
"component",
|
|
25976
26172
|
"eventFamily",
|
|
25977
26173
|
"eventName",
|
|
26174
|
+
"endpoint",
|
|
26175
|
+
"errorCategory",
|
|
26176
|
+
"errorCode",
|
|
26177
|
+
"errorRetryability",
|
|
26178
|
+
"errorSyscall",
|
|
25978
26179
|
"exitCode",
|
|
25979
26180
|
"fromAgentId",
|
|
26181
|
+
"grpcMethod",
|
|
25980
26182
|
"jobId",
|
|
25981
26183
|
"kind",
|
|
25982
26184
|
"method",
|
|
@@ -26000,17 +26202,24 @@ var init_sentry_logger = __esm({
|
|
|
26000
26202
|
"source",
|
|
26001
26203
|
"stage",
|
|
26002
26204
|
"status",
|
|
26205
|
+
"streamErrorCode",
|
|
26206
|
+
"streamType",
|
|
26003
26207
|
"subcommand",
|
|
26004
26208
|
"systemEvent",
|
|
26005
26209
|
"taskId",
|
|
26006
26210
|
"taskMode",
|
|
26007
26211
|
"toAgentId",
|
|
26008
26212
|
"transport",
|
|
26213
|
+
"transportFailure",
|
|
26214
|
+
"transportProtocol",
|
|
26009
26215
|
"type",
|
|
26010
26216
|
"workloadClass"
|
|
26011
26217
|
]);
|
|
26012
26218
|
SENTRY_FINGERPRINT_KEYS = [
|
|
26013
26219
|
"eventName",
|
|
26220
|
+
"errorCategory",
|
|
26221
|
+
"errorCode",
|
|
26222
|
+
"errorSyscall",
|
|
26014
26223
|
"cacheName",
|
|
26015
26224
|
"component",
|
|
26016
26225
|
"method",
|
|
@@ -26074,6 +26283,9 @@ var init_sentry_logger = __esm({
|
|
|
26074
26283
|
LogEvent.MESSAGE_SENT,
|
|
26075
26284
|
LogEvent.AGENT_CLIENT_CREATED,
|
|
26076
26285
|
LogEvent.AGENT_CLIENT_REMOVED,
|
|
26286
|
+
LogEvent.AGENT_STREAM_ERROR,
|
|
26287
|
+
LogEvent.AGENT_STREAM_RECOVERED,
|
|
26288
|
+
LogEvent.AGENT_STREAM_RECOVERY_REPLAY_COMPLETED,
|
|
26077
26289
|
LogEvent.ADDRESS_SYNC_COMPLETED,
|
|
26078
26290
|
LogEvent.AGENTS_REFRESHED,
|
|
26079
26291
|
LogEvent.AGENTS_WAKEUP_NOTIFIED,
|
|
@@ -26205,19 +26417,24 @@ var init_sentry_logger = __esm({
|
|
|
26205
26417
|
}
|
|
26206
26418
|
captureError(message, error, extraWithFlow) {
|
|
26207
26419
|
try {
|
|
26420
|
+
const errorDiagnostics = buildErrorDiagnostics(
|
|
26421
|
+
message,
|
|
26422
|
+
error,
|
|
26423
|
+
extraWithFlow
|
|
26424
|
+
);
|
|
26425
|
+
const diagnosticExtra = {
|
|
26426
|
+
...extraWithFlow,
|
|
26427
|
+
...errorDiagnostics
|
|
26428
|
+
};
|
|
26208
26429
|
Sentry.withScope((scope) => {
|
|
26209
26430
|
scope.setLevel("error");
|
|
26210
|
-
_SentryLogger.applyDiagnostics(scope, message,
|
|
26431
|
+
_SentryLogger.applyDiagnostics(scope, message, diagnosticExtra);
|
|
26211
26432
|
Sentry.captureException(_SentryLogger.createSentryEvent(message), {
|
|
26212
26433
|
// eventName is unconditional: callers that pass no Error object are
|
|
26213
26434
|
// still classified events, and without it they reach SLS anonymous.
|
|
26214
26435
|
extra: {
|
|
26215
|
-
...
|
|
26216
|
-
eventName: message
|
|
26217
|
-
...error ? {
|
|
26218
|
-
errorName: error.name,
|
|
26219
|
-
errorMessageLength: String(error.message.length)
|
|
26220
|
-
} : {}
|
|
26436
|
+
...diagnosticExtra,
|
|
26437
|
+
eventName: message
|
|
26221
26438
|
}
|
|
26222
26439
|
});
|
|
26223
26440
|
});
|
|
@@ -27416,7 +27633,7 @@ var init_sentry_config = __esm({
|
|
|
27416
27633
|
environment = process.env.SENTRY_ENV === "dev" ? "dev" : "prod";
|
|
27417
27634
|
SENTRY_CONFIG = {
|
|
27418
27635
|
projectName: "okx/openclaw-okx-a2a-extension",
|
|
27419
|
-
release: "0.2.1
|
|
27636
|
+
release: "0.2.1",
|
|
27420
27637
|
environment,
|
|
27421
27638
|
runtimeContainer: normalizeRuntimeContainer(process.env.OKX_A2A_RUNTIME_CONTAINER)
|
|
27422
27639
|
};
|
|
@@ -38586,7 +38803,7 @@ async function exportDiagnosticLogs(options) {
|
|
|
38586
38803
|
node: process.version,
|
|
38587
38804
|
platform: process.platform,
|
|
38588
38805
|
arch: process.arch,
|
|
38589
|
-
packageVersion: true ? "0.2.1
|
|
38806
|
+
packageVersion: true ? "0.2.1" : "unknown",
|
|
38590
38807
|
sensitiveContentIncluded: options.includeSensitiveContent,
|
|
38591
38808
|
listenerAndLlmContentIncluded: true,
|
|
38592
38809
|
credentialsAlwaysRedacted: true,
|
|
@@ -39731,7 +39948,7 @@ async function exec(args) {
|
|
|
39731
39948
|
);
|
|
39732
39949
|
logger.error(
|
|
39733
39950
|
LogEvent.ONCHAINOS_CLI_ERROR,
|
|
39734
|
-
new Error("onchainos command failed"),
|
|
39951
|
+
err2 instanceof Error ? err2 : new Error("onchainos command failed"),
|
|
39735
39952
|
{
|
|
39736
39953
|
component: "onchainos_cli",
|
|
39737
39954
|
source: "onchainos",
|
|
@@ -54459,6 +54676,171 @@ var init_dist4 = __esm({
|
|
|
54459
54676
|
}
|
|
54460
54677
|
});
|
|
54461
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
|
+
|
|
54462
54844
|
// ../core/src/xmtp-sdk/extract-job-id.ts
|
|
54463
54845
|
function extractJobIdFromContent(content2) {
|
|
54464
54846
|
const raw = typeof content2 === "string" ? content2 : stringifyJsonForEnvelope(content2);
|
|
@@ -55262,6 +55644,12 @@ function parseGroupPayload(content2) {
|
|
|
55262
55644
|
function isOfflineReplayForTrigger(trigger) {
|
|
55263
55645
|
return trigger === "startup";
|
|
55264
55646
|
}
|
|
55647
|
+
function replaySingleFlightDiscriminator(trigger, clientGeneration, recoveryIdentity) {
|
|
55648
|
+
if (trigger === "stream_recovery") {
|
|
55649
|
+
return `stream_recovery:${clientGeneration}:${recoveryIdentity ?? "unknown"}`;
|
|
55650
|
+
}
|
|
55651
|
+
return isOfflineReplayForTrigger(trigger) ? `startup_offline:${clientGeneration}` : `online_repair:${clientGeneration}`;
|
|
55652
|
+
}
|
|
55265
55653
|
function createOfflineReplayAddressSummary(address) {
|
|
55266
55654
|
return {
|
|
55267
55655
|
address,
|
|
@@ -55279,7 +55667,7 @@ function createOfflineReplayAddressSummary(address) {
|
|
|
55279
55667
|
durationMs: 0
|
|
55280
55668
|
};
|
|
55281
55669
|
}
|
|
55282
|
-
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;
|
|
55670
|
+
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;
|
|
55283
55671
|
var init_xmtp_sdk = __esm({
|
|
55284
55672
|
"../core/src/xmtp-sdk/index.ts"() {
|
|
55285
55673
|
"use strict";
|
|
@@ -55289,6 +55677,7 @@ var init_xmtp_sdk = __esm({
|
|
|
55289
55677
|
init_dist4();
|
|
55290
55678
|
init_dist2();
|
|
55291
55679
|
init_sentry_logger();
|
|
55680
|
+
init_stream_recovery_telemetry();
|
|
55292
55681
|
init_extract_job_id();
|
|
55293
55682
|
init_self_filter();
|
|
55294
55683
|
init_logging();
|
|
@@ -55306,10 +55695,11 @@ var init_xmtp_sdk = __esm({
|
|
|
55306
55695
|
this.inbound = inbound;
|
|
55307
55696
|
}
|
|
55308
55697
|
inbound;
|
|
55309
|
-
|
|
55698
|
+
holds = 1;
|
|
55310
55699
|
queue = [];
|
|
55700
|
+
drainInFlight;
|
|
55311
55701
|
middleware = async (ctx, next) => {
|
|
55312
|
-
if (!this.
|
|
55702
|
+
if (this.holds === 0 && !this.drainInFlight) {
|
|
55313
55703
|
await this.inbound(ctx, next);
|
|
55314
55704
|
return;
|
|
55315
55705
|
}
|
|
@@ -55318,19 +55708,55 @@ var init_xmtp_sdk = __esm({
|
|
|
55318
55708
|
get bufferedCount() {
|
|
55319
55709
|
return this.queue.length;
|
|
55320
55710
|
}
|
|
55711
|
+
abandonFailedAndRelease() {
|
|
55712
|
+
const abandoned = this.queue.length > 0 ? 1 : 0;
|
|
55713
|
+
if (abandoned > 0) {
|
|
55714
|
+
this.queue.shift();
|
|
55715
|
+
}
|
|
55716
|
+
if (this.holds > 0) {
|
|
55717
|
+
this.holds--;
|
|
55718
|
+
}
|
|
55719
|
+
return abandoned;
|
|
55720
|
+
}
|
|
55721
|
+
hold() {
|
|
55722
|
+
this.holds++;
|
|
55723
|
+
}
|
|
55321
55724
|
async drain() {
|
|
55725
|
+
if (this.holds > 0) {
|
|
55726
|
+
this.holds--;
|
|
55727
|
+
}
|
|
55728
|
+
return this.drainReleased();
|
|
55729
|
+
}
|
|
55730
|
+
async drainReleased() {
|
|
55731
|
+
if (this.holds > 0) {
|
|
55732
|
+
return 0;
|
|
55733
|
+
}
|
|
55734
|
+
if (this.drainInFlight) {
|
|
55735
|
+
return this.drainInFlight;
|
|
55736
|
+
}
|
|
55737
|
+
const drain = Promise.resolve().then(() => this.drainQueue());
|
|
55738
|
+
this.drainInFlight = drain;
|
|
55739
|
+
try {
|
|
55740
|
+
return await drain;
|
|
55741
|
+
} finally {
|
|
55742
|
+
if (this.drainInFlight === drain) {
|
|
55743
|
+
this.drainInFlight = void 0;
|
|
55744
|
+
}
|
|
55745
|
+
}
|
|
55746
|
+
}
|
|
55747
|
+
async drainQueue() {
|
|
55322
55748
|
let drained = 0;
|
|
55323
|
-
while (this.queue.length > 0) {
|
|
55749
|
+
while (this.holds === 0 && this.queue.length > 0) {
|
|
55324
55750
|
const item = this.queue.shift();
|
|
55325
55751
|
try {
|
|
55326
55752
|
await this.inbound(item.ctx, item.next);
|
|
55327
55753
|
} catch (err2) {
|
|
55328
55754
|
this.queue.unshift(item);
|
|
55755
|
+
this.holds++;
|
|
55329
55756
|
throw err2;
|
|
55330
55757
|
}
|
|
55331
55758
|
drained++;
|
|
55332
55759
|
}
|
|
55333
|
-
this.buffering = false;
|
|
55334
55760
|
return drained;
|
|
55335
55761
|
}
|
|
55336
55762
|
};
|
|
@@ -55346,6 +55772,9 @@ var init_xmtp_sdk = __esm({
|
|
|
55346
55772
|
}
|
|
55347
55773
|
}
|
|
55348
55774
|
};
|
|
55775
|
+
STREAM_RECOVERY_ALERT_THRESHOLD_MS = 3e4;
|
|
55776
|
+
REPLAY_GATE_DRAIN_MAX_ATTEMPTS = 3;
|
|
55777
|
+
REPLAY_GATE_DRAIN_RETRY_DELAY_MS = 100;
|
|
55349
55778
|
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-]+)*)?$/;
|
|
55350
55779
|
isRecord5 = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
55351
55780
|
isPositiveNumber = (value) => typeof value === "number" && Number.isFinite(value) && value > 0;
|
|
@@ -55390,7 +55819,15 @@ var init_xmtp_sdk = __esm({
|
|
|
55390
55819
|
};
|
|
55391
55820
|
dataDir = DEFAULT_DATA_DIR;
|
|
55392
55821
|
syncByAddress = /* @__PURE__ */ new Map();
|
|
55822
|
+
offlineReplaySingleFlight = new KeyedSingleFlight();
|
|
55393
55823
|
inboundReplayGates = /* @__PURE__ */ new Map();
|
|
55824
|
+
streamRecoveryCleanupByAddress = /* @__PURE__ */ new Map();
|
|
55825
|
+
nextClientGeneration = 1;
|
|
55826
|
+
clientGenerationByClient = /* @__PURE__ */ new WeakMap();
|
|
55827
|
+
resolveStartupReplayCompletion;
|
|
55828
|
+
startupReplayCompletion = new Promise((resolve14) => {
|
|
55829
|
+
this.resolveStartupReplayCompletion = resolve14;
|
|
55830
|
+
});
|
|
55394
55831
|
agentListFingerprint;
|
|
55395
55832
|
// Only one refreshAgents can be in flight at a time; concurrent calls
|
|
55396
55833
|
// coalesce onto the same promise. This avoids duplicate Agent.create()
|
|
@@ -55845,6 +56282,7 @@ var init_xmtp_sdk = __esm({
|
|
|
55845
56282
|
const client = this.clients.get(address);
|
|
55846
56283
|
if (client) {
|
|
55847
56284
|
try {
|
|
56285
|
+
this.cancelStreamRecoveryForAddress(address);
|
|
55848
56286
|
this.stoppedAddresses.add(address.toLowerCase());
|
|
55849
56287
|
client.stop();
|
|
55850
56288
|
logWithTimestamp(
|
|
@@ -56018,7 +56456,16 @@ var init_xmtp_sdk = __esm({
|
|
|
56018
56456
|
logWithTimestamp(
|
|
56019
56457
|
`[xmtp-sdk] refresh: ${address} has a prior sync timestamp, triggering offline replay`
|
|
56020
56458
|
);
|
|
56021
|
-
|
|
56459
|
+
const expectedClient = this.clients.get(address) ?? null;
|
|
56460
|
+
const expectedGate = this.inboundReplayGates.get(
|
|
56461
|
+
address.toLowerCase()
|
|
56462
|
+
);
|
|
56463
|
+
void this.replayOfflineMessagesForAddressSingleFlight(
|
|
56464
|
+
address,
|
|
56465
|
+
"agent_refresh",
|
|
56466
|
+
void 0,
|
|
56467
|
+
expectedClient
|
|
56468
|
+
).catch((err2) => {
|
|
56022
56469
|
logWithTimestamp(`[xmtp-sdk] refresh: ${address} offline replay failed:`, err2);
|
|
56023
56470
|
logger.error(
|
|
56024
56471
|
LogEvent.OFFLINE_REPLAY_FAILED,
|
|
@@ -56028,7 +56475,7 @@ var init_xmtp_sdk = __esm({
|
|
|
56028
56475
|
stage: "refreshAgents/replay"
|
|
56029
56476
|
}
|
|
56030
56477
|
);
|
|
56031
|
-
}).then(() => this.drainInboundReplayGate(address)).catch((err2) => {
|
|
56478
|
+
}).then(() => this.drainInboundReplayGate(address, expectedGate)).catch((err2) => {
|
|
56032
56479
|
logWithTimestamp(`[xmtp-sdk] refresh: ${address} replay gate drain failed:`, err2);
|
|
56033
56480
|
});
|
|
56034
56481
|
}
|
|
@@ -56060,6 +56507,7 @@ var init_xmtp_sdk = __esm({
|
|
|
56060
56507
|
}
|
|
56061
56508
|
const addressKey = address.toLowerCase();
|
|
56062
56509
|
try {
|
|
56510
|
+
this.cancelStreamRecoveryForAddress(address);
|
|
56063
56511
|
this.stoppedAddresses.add(addressKey);
|
|
56064
56512
|
await Promise.resolve(oldClient.stop());
|
|
56065
56513
|
this.clients.delete(address);
|
|
@@ -56116,11 +56564,17 @@ var init_xmtp_sdk = __esm({
|
|
|
56116
56564
|
phase: "recycle"
|
|
56117
56565
|
});
|
|
56118
56566
|
await this.startListeningForAddresses([address]);
|
|
56567
|
+
const replayGate = this.inboundReplayGates.get(addressKey);
|
|
56119
56568
|
let replaySummary;
|
|
56120
56569
|
try {
|
|
56121
|
-
replaySummary = await this.
|
|
56570
|
+
replaySummary = await this.replayOfflineMessagesForAddressSingleFlight(
|
|
56571
|
+
address,
|
|
56572
|
+
"client_recycle",
|
|
56573
|
+
void 0,
|
|
56574
|
+
agent
|
|
56575
|
+
);
|
|
56122
56576
|
} finally {
|
|
56123
|
-
await this.drainInboundReplayGate(address);
|
|
56577
|
+
await this.drainInboundReplayGate(address, replayGate);
|
|
56124
56578
|
}
|
|
56125
56579
|
addresses.push(replaySummary);
|
|
56126
56580
|
replayed += replaySummary.replayed;
|
|
@@ -56128,6 +56582,7 @@ var init_xmtp_sdk = __esm({
|
|
|
56128
56582
|
recycled++;
|
|
56129
56583
|
} catch (err2) {
|
|
56130
56584
|
failed++;
|
|
56585
|
+
this.cancelStreamRecoveryForAddress(address);
|
|
56131
56586
|
this.clients.delete(address);
|
|
56132
56587
|
logWithTimestamp(`[xmtp-sdk] recycle: failed to recreate client: ${address}`, err2);
|
|
56133
56588
|
logger.error(
|
|
@@ -56528,16 +56983,83 @@ var init_xmtp_sdk = __esm({
|
|
|
56528
56983
|
async startListening() {
|
|
56529
56984
|
await this.startListeningForAddresses([...this.clients.keys()]);
|
|
56530
56985
|
}
|
|
56531
|
-
async drainInboundReplayGate(address) {
|
|
56986
|
+
async drainInboundReplayGate(address, expectedGate) {
|
|
56987
|
+
if (!expectedGate) {
|
|
56988
|
+
return 0;
|
|
56989
|
+
}
|
|
56532
56990
|
const gate = this.inboundReplayGates.get(address.toLowerCase());
|
|
56533
|
-
if (!gate) {
|
|
56991
|
+
if (!gate || gate !== expectedGate) {
|
|
56534
56992
|
return 0;
|
|
56535
56993
|
}
|
|
56536
|
-
|
|
56994
|
+
let attempt = 0;
|
|
56995
|
+
let totalDrained = 0;
|
|
56996
|
+
let releaseHold = true;
|
|
56997
|
+
while (true) {
|
|
56998
|
+
try {
|
|
56999
|
+
const drained = releaseHold ? await gate.drain() : await gate.drainReleased();
|
|
57000
|
+
totalDrained += drained;
|
|
57001
|
+
logWithTimestamp(
|
|
57002
|
+
`[xmtp-sdk:${address}] replay barrier released, buffered=${totalDrained} attempt=${attempt + 1}`
|
|
57003
|
+
);
|
|
57004
|
+
return totalDrained;
|
|
57005
|
+
} catch (err2) {
|
|
57006
|
+
attempt++;
|
|
57007
|
+
logWithTimestamp(
|
|
57008
|
+
`[xmtp-sdk:${address}] replay barrier drain failed attempt=${attempt}/${REPLAY_GATE_DRAIN_MAX_ATTEMPTS}:`,
|
|
57009
|
+
err2
|
|
57010
|
+
);
|
|
57011
|
+
if (attempt < REPLAY_GATE_DRAIN_MAX_ATTEMPTS) {
|
|
57012
|
+
releaseHold = true;
|
|
57013
|
+
await new Promise(
|
|
57014
|
+
(resolve14) => setTimeout(resolve14, REPLAY_GATE_DRAIN_RETRY_DELAY_MS * attempt)
|
|
57015
|
+
);
|
|
57016
|
+
continue;
|
|
57017
|
+
}
|
|
57018
|
+
const abandoned = gate.abandonFailedAndRelease();
|
|
57019
|
+
logger.error(
|
|
57020
|
+
LogEvent.INBOUND_REPLAY_GATE_DRAIN_FAILED,
|
|
57021
|
+
err2 instanceof Error ? err2 : void 0,
|
|
57022
|
+
{
|
|
57023
|
+
walletAddress: address,
|
|
57024
|
+
attemptCount: String(REPLAY_GATE_DRAIN_MAX_ATTEMPTS),
|
|
57025
|
+
abandonedCount: String(abandoned),
|
|
57026
|
+
stage: "inboundReplayGate/fail-open",
|
|
57027
|
+
reason: "drain_retry_exhausted"
|
|
57028
|
+
}
|
|
57029
|
+
);
|
|
57030
|
+
logWithTimestamp(
|
|
57031
|
+
`[xmtp-sdk:${address}] replay barrier fail-open after ${REPLAY_GATE_DRAIN_MAX_ATTEMPTS} failed attempts, abandoned=${abandoned}`
|
|
57032
|
+
);
|
|
57033
|
+
attempt = 0;
|
|
57034
|
+
releaseHold = false;
|
|
57035
|
+
}
|
|
57036
|
+
}
|
|
57037
|
+
}
|
|
57038
|
+
holdInboundReplayGate(address) {
|
|
57039
|
+
const gate = this.inboundReplayGates.get(address.toLowerCase());
|
|
57040
|
+
if (!gate) {
|
|
57041
|
+
return void 0;
|
|
57042
|
+
}
|
|
57043
|
+
gate.hold();
|
|
56537
57044
|
logWithTimestamp(
|
|
56538
|
-
`[xmtp-sdk:${address}]
|
|
57045
|
+
`[xmtp-sdk:${address}] replay barrier held, buffered=${gate.bufferedCount}`
|
|
56539
57046
|
);
|
|
56540
|
-
return
|
|
57047
|
+
return gate;
|
|
57048
|
+
}
|
|
57049
|
+
cancelStreamRecoveryForAddress(address) {
|
|
57050
|
+
const addressKey = address.toLowerCase();
|
|
57051
|
+
const cleanup = this.streamRecoveryCleanupByAddress.get(addressKey);
|
|
57052
|
+
this.streamRecoveryCleanupByAddress.delete(addressKey);
|
|
57053
|
+
cleanup?.();
|
|
57054
|
+
}
|
|
57055
|
+
getClientGeneration(client) {
|
|
57056
|
+
const existing = this.clientGenerationByClient.get(client);
|
|
57057
|
+
if (existing !== void 0) {
|
|
57058
|
+
return existing;
|
|
57059
|
+
}
|
|
57060
|
+
const generation = this.nextClientGeneration++;
|
|
57061
|
+
this.clientGenerationByClient.set(client, generation);
|
|
57062
|
+
return generation;
|
|
56541
57063
|
}
|
|
56542
57064
|
notifyAgentsWakeupAfterReplay() {
|
|
56543
57065
|
const notifyAgentsWakeup2 = this.tools.notifyAgentsWakeup;
|
|
@@ -56571,10 +57093,18 @@ var init_xmtp_sdk = __esm({
|
|
|
56571
57093
|
* cannot overtake the stored backlog.
|
|
56572
57094
|
*/
|
|
56573
57095
|
async completeStartupReplay() {
|
|
57096
|
+
const startupGates = new Map(
|
|
57097
|
+
[...this.clients.keys()].map((address) => [
|
|
57098
|
+
address,
|
|
57099
|
+
this.inboundReplayGates.get(address.toLowerCase())
|
|
57100
|
+
])
|
|
57101
|
+
);
|
|
56574
57102
|
const summary = await this.replayOfflineMessages("startup");
|
|
56575
|
-
for (const address of
|
|
56576
|
-
await this.drainInboundReplayGate(address);
|
|
57103
|
+
for (const [address, expectedGate] of startupGates) {
|
|
57104
|
+
await this.drainInboundReplayGate(address, expectedGate);
|
|
56577
57105
|
}
|
|
57106
|
+
this.resolveStartupReplayCompletion?.();
|
|
57107
|
+
this.resolveStartupReplayCompletion = void 0;
|
|
56578
57108
|
this.notifyAgentsWakeupAfterReplay();
|
|
56579
57109
|
return summary;
|
|
56580
57110
|
}
|
|
@@ -56582,6 +57112,8 @@ var init_xmtp_sdk = __esm({
|
|
|
56582
57112
|
const valid = addresses.filter((addr) => this.clients.has(addr));
|
|
56583
57113
|
await parallelMap(valid, async (address) => {
|
|
56584
57114
|
const agent = this.clients.get(address);
|
|
57115
|
+
const clientGeneration = this.getClientGeneration(agent);
|
|
57116
|
+
const addressKey = address.toLowerCase();
|
|
56585
57117
|
const tag = `[xmtp-sdk:${address}]`;
|
|
56586
57118
|
const onchainosAgent = this.getAgentByAddress(address);
|
|
56587
57119
|
const identity = {
|
|
@@ -56684,14 +57216,131 @@ var init_xmtp_sdk = __esm({
|
|
|
56684
57216
|
logWithTimestamp(`${tag} reconnecting in ${delay}ms (attempt=${attempt + 1})`);
|
|
56685
57217
|
setTimeout(() => void startWithRetry(attempt + 1), delay);
|
|
56686
57218
|
};
|
|
57219
|
+
const streamRecovery = new StreamRecoveryTelemetry();
|
|
57220
|
+
let recoveryTimeout;
|
|
57221
|
+
let pendingRecoveryGate;
|
|
57222
|
+
let recoveryDisposed = false;
|
|
57223
|
+
this.cancelStreamRecoveryForAddress(address);
|
|
57224
|
+
const cleanupStreamRecovery = () => {
|
|
57225
|
+
recoveryDisposed = true;
|
|
57226
|
+
streamRecovery.cancel();
|
|
57227
|
+
if (recoveryTimeout) {
|
|
57228
|
+
clearTimeout(recoveryTimeout);
|
|
57229
|
+
recoveryTimeout = void 0;
|
|
57230
|
+
}
|
|
57231
|
+
};
|
|
57232
|
+
this.streamRecoveryCleanupByAddress.set(
|
|
57233
|
+
addressKey,
|
|
57234
|
+
cleanupStreamRecovery
|
|
57235
|
+
);
|
|
56687
57236
|
agent.on("unhandledError", (err2) => {
|
|
57237
|
+
if (recoveryDisposed || this.clients.get(address) !== agent || this.stoppedAddresses.has(addressKey)) {
|
|
57238
|
+
return;
|
|
57239
|
+
}
|
|
57240
|
+
if (!isAgentStreamRecoveryError(err2)) {
|
|
57241
|
+
logWithTimestamp(`${tag} agent unhandled error:`, err2);
|
|
57242
|
+
logger.error(LogEvent.AGENT_UNHANDLED_ERROR, err2, agentExtras(identity));
|
|
57243
|
+
return;
|
|
57244
|
+
}
|
|
57245
|
+
const recovery = streamRecovery.markError();
|
|
57246
|
+
const errorTelemetry = extractStreamErrorTelemetry(err2);
|
|
57247
|
+
if (!recovery.alreadyRecovering) {
|
|
57248
|
+
pendingRecoveryGate = this.holdInboundReplayGate(address);
|
|
57249
|
+
}
|
|
56688
57250
|
logWithTimestamp(`${tag} agent stream error:`, err2);
|
|
56689
|
-
logger.
|
|
57251
|
+
logger.info(LogEvent.AGENT_STREAM_ERROR, {
|
|
57252
|
+
...agentExtras(identity),
|
|
57253
|
+
...errorTelemetry,
|
|
57254
|
+
clientGeneration: String(clientGeneration),
|
|
57255
|
+
recoverySequence: String(recovery.recoverySequence),
|
|
57256
|
+
recoveryAlreadyActive: String(recovery.alreadyRecovering)
|
|
57257
|
+
});
|
|
57258
|
+
if (!recovery.alreadyRecovering) {
|
|
57259
|
+
recoveryTimeout = setTimeout(() => {
|
|
57260
|
+
if (recoveryDisposed || this.clients.get(address) !== agent || this.stoppedAddresses.has(addressKey) || streamRecovery.activeSequence !== recovery.recoverySequence) {
|
|
57261
|
+
return;
|
|
57262
|
+
}
|
|
57263
|
+
logger.error(LogEvent.AGENT_STREAM_RECOVERY_TIMEOUT, void 0, {
|
|
57264
|
+
...agentExtras(identity),
|
|
57265
|
+
...errorTelemetry,
|
|
57266
|
+
clientGeneration: String(clientGeneration),
|
|
57267
|
+
recoverySequence: String(recovery.recoverySequence),
|
|
57268
|
+
recoveryDurationMs: String(STREAM_RECOVERY_ALERT_THRESHOLD_MS),
|
|
57269
|
+
thresholdMs: String(STREAM_RECOVERY_ALERT_THRESHOLD_MS)
|
|
57270
|
+
});
|
|
57271
|
+
}, STREAM_RECOVERY_ALERT_THRESHOLD_MS);
|
|
57272
|
+
}
|
|
56690
57273
|
});
|
|
56691
57274
|
agent.on("start", () => {
|
|
57275
|
+
if (recoveryDisposed || this.clients.get(address) !== agent || this.stoppedAddresses.has(addressKey)) {
|
|
57276
|
+
return;
|
|
57277
|
+
}
|
|
57278
|
+
const recovery = streamRecovery.markStarted();
|
|
57279
|
+
if (recoveryTimeout) {
|
|
57280
|
+
clearTimeout(recoveryTimeout);
|
|
57281
|
+
recoveryTimeout = void 0;
|
|
57282
|
+
}
|
|
56692
57283
|
logWithTimestamp(
|
|
56693
57284
|
`${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))}`
|
|
56694
57285
|
);
|
|
57286
|
+
if (recovery) {
|
|
57287
|
+
const recoveryGate = pendingRecoveryGate;
|
|
57288
|
+
pendingRecoveryGate = void 0;
|
|
57289
|
+
logger.info(LogEvent.AGENT_STREAM_RECOVERED, {
|
|
57290
|
+
...agentExtras(identity),
|
|
57291
|
+
clientGeneration: String(clientGeneration),
|
|
57292
|
+
recoverySequence: String(recovery.recoverySequence),
|
|
57293
|
+
recoveryDurationMs: String(recovery.recoveryDurationMs)
|
|
57294
|
+
});
|
|
57295
|
+
void (async () => {
|
|
57296
|
+
try {
|
|
57297
|
+
const summary = await this.replayOfflineMessagesForStreamRecovery(
|
|
57298
|
+
address,
|
|
57299
|
+
String(recovery.recoverySequence),
|
|
57300
|
+
agent
|
|
57301
|
+
);
|
|
57302
|
+
if (!recoveryDisposed && this.clients.get(address) === agent) {
|
|
57303
|
+
logger.info(LogEvent.AGENT_STREAM_RECOVERY_REPLAY_COMPLETED, {
|
|
57304
|
+
...agentExtras(identity),
|
|
57305
|
+
clientGeneration: String(clientGeneration),
|
|
57306
|
+
recoverySequence: String(recovery.recoverySequence),
|
|
57307
|
+
replayed: String(summary.replayed),
|
|
57308
|
+
skipped: String(summary.skipped),
|
|
57309
|
+
conversationCount: String(summary.conversations),
|
|
57310
|
+
replayDurationMs: String(summary.durationMs)
|
|
57311
|
+
});
|
|
57312
|
+
}
|
|
57313
|
+
} catch (err2) {
|
|
57314
|
+
logWithTimestamp(`${tag} recovery offline replay failed:`, err2);
|
|
57315
|
+
logger.error(
|
|
57316
|
+
LogEvent.OFFLINE_REPLAY_FAILED,
|
|
57317
|
+
err2 instanceof Error ? err2 : new Error(String(err2)),
|
|
57318
|
+
{
|
|
57319
|
+
...agentExtras(identity),
|
|
57320
|
+
clientGeneration: String(clientGeneration),
|
|
57321
|
+
recoverySequence: String(recovery.recoverySequence),
|
|
57322
|
+
stage: "streamRecovery/replay"
|
|
57323
|
+
}
|
|
57324
|
+
);
|
|
57325
|
+
} finally {
|
|
57326
|
+
try {
|
|
57327
|
+
await this.drainInboundReplayGate(address, recoveryGate);
|
|
57328
|
+
} catch (err2) {
|
|
57329
|
+
logWithTimestamp(`${tag} recovery replay gate drain failed:`, err2);
|
|
57330
|
+
logger.error(
|
|
57331
|
+
LogEvent.OFFLINE_REPLAY_FAILED,
|
|
57332
|
+
err2 instanceof Error ? err2 : new Error(String(err2)),
|
|
57333
|
+
{
|
|
57334
|
+
...agentExtras(identity),
|
|
57335
|
+
clientGeneration: String(clientGeneration),
|
|
57336
|
+
recoverySequence: String(recovery.recoverySequence),
|
|
57337
|
+
stage: "streamRecovery/drain-gate"
|
|
57338
|
+
}
|
|
57339
|
+
);
|
|
57340
|
+
}
|
|
57341
|
+
}
|
|
57342
|
+
})();
|
|
57343
|
+
}
|
|
56695
57344
|
if (process.env.XMTP_FORCE_DEBUG === "true") {
|
|
56696
57345
|
void logDetails(agent).catch((err2) => {
|
|
56697
57346
|
logWithTimestamp(`${tag} agent debug details failed:`, err2);
|
|
@@ -56709,12 +57358,12 @@ var init_xmtp_sdk = __esm({
|
|
|
56709
57358
|
logWithTimestamp(`${tag} message listener started`);
|
|
56710
57359
|
});
|
|
56711
57360
|
}
|
|
56712
|
-
async replayOfflineMessagesForAddress(address, trigger = "periodic_repair") {
|
|
57361
|
+
async replayOfflineMessagesForAddress(address, expectedClient, trigger = "periodic_repair") {
|
|
56713
57362
|
const addressReplayStartedAt = Date.now();
|
|
56714
57363
|
const summary = createOfflineReplayAddressSummary(address);
|
|
56715
57364
|
const isOfflineReplay = isOfflineReplayForTrigger(trigger);
|
|
56716
57365
|
const agent = this.clients.get(address);
|
|
56717
|
-
if (!agent) {
|
|
57366
|
+
if (!agent || agent !== expectedClient) {
|
|
56718
57367
|
summary.durationMs = Date.now() - addressReplayStartedAt;
|
|
56719
57368
|
return summary;
|
|
56720
57369
|
}
|
|
@@ -56919,6 +57568,35 @@ var init_xmtp_sdk = __esm({
|
|
|
56919
57568
|
);
|
|
56920
57569
|
return summary;
|
|
56921
57570
|
}
|
|
57571
|
+
replayOfflineMessagesForAddressSingleFlight(address, trigger = "periodic_repair", recoveryIdentity, expectedClient = this.clients.get(address) ?? null) {
|
|
57572
|
+
const clientGeneration = expectedClient ? this.getClientGeneration(expectedClient) : "missing";
|
|
57573
|
+
const eligibilityClass = replaySingleFlightDiscriminator(
|
|
57574
|
+
trigger,
|
|
57575
|
+
clientGeneration,
|
|
57576
|
+
recoveryIdentity
|
|
57577
|
+
);
|
|
57578
|
+
return this.offlineReplaySingleFlight.run(
|
|
57579
|
+
address,
|
|
57580
|
+
eligibilityClass,
|
|
57581
|
+
async () => {
|
|
57582
|
+
await this._backupReady;
|
|
57583
|
+
return this.replayOfflineMessagesForAddress(
|
|
57584
|
+
address,
|
|
57585
|
+
expectedClient,
|
|
57586
|
+
trigger
|
|
57587
|
+
);
|
|
57588
|
+
}
|
|
57589
|
+
);
|
|
57590
|
+
}
|
|
57591
|
+
async replayOfflineMessagesForStreamRecovery(address, recoveryIdentity, expectedClient) {
|
|
57592
|
+
await this.startupReplayCompletion;
|
|
57593
|
+
return this.replayOfflineMessagesForAddressSingleFlight(
|
|
57594
|
+
address,
|
|
57595
|
+
"stream_recovery",
|
|
57596
|
+
recoveryIdentity,
|
|
57597
|
+
expectedClient
|
|
57598
|
+
);
|
|
57599
|
+
}
|
|
56922
57600
|
async replayOfflineMessages(trigger = "periodic_repair") {
|
|
56923
57601
|
await this._backupReady;
|
|
56924
57602
|
const replayStartedAt = Date.now();
|
|
@@ -56926,7 +57604,10 @@ var init_xmtp_sdk = __esm({
|
|
|
56926
57604
|
let totalSkipped = 0;
|
|
56927
57605
|
const addresses = [];
|
|
56928
57606
|
for (const address of this.clients.keys()) {
|
|
56929
|
-
const summary2 = await this.
|
|
57607
|
+
const summary2 = await this.replayOfflineMessagesForAddressSingleFlight(
|
|
57608
|
+
address,
|
|
57609
|
+
trigger
|
|
57610
|
+
);
|
|
56930
57611
|
addresses.push(summary2);
|
|
56931
57612
|
const { replayed, skipped: skipped2 } = summary2;
|
|
56932
57613
|
totalReplayed += replayed;
|
|
@@ -65447,12 +66128,12 @@ async function runListenerWithLock(options, paths) {
|
|
|
65447
66128
|
});
|
|
65448
66129
|
}
|
|
65449
66130
|
});
|
|
65450
|
-
service.setPluginVersion("0.2.1
|
|
66131
|
+
service.setPluginVersion("0.2.1");
|
|
65451
66132
|
await service.init();
|
|
65452
66133
|
const pluginVersionStatus = service.pluginVersionStatus;
|
|
65453
66134
|
if (pluginVersionStatus.unavailable) {
|
|
65454
66135
|
throw new Error(
|
|
65455
|
-
`@okxweb3/a2a-node v${"0.2.1
|
|
66136
|
+
`@okxweb3/a2a-node v${"0.2.1"} is below the required minimum v${pluginVersionStatus.minVersion}`
|
|
65456
66137
|
);
|
|
65457
66138
|
}
|
|
65458
66139
|
const systemConfig = service.getSystemConfig();
|
|
@@ -65470,7 +66151,7 @@ async function runListenerWithLock(options, paths) {
|
|
|
65470
66151
|
onchainosAgentId: "*",
|
|
65471
66152
|
reason: "system-config missing sentryDsn",
|
|
65472
66153
|
pluginId: "@okxweb3/a2a-node",
|
|
65473
|
-
pluginVersion: "0.2.1
|
|
66154
|
+
pluginVersion: "0.2.1"
|
|
65474
66155
|
});
|
|
65475
66156
|
}
|
|
65476
66157
|
logWithTimestamp(
|
|
@@ -66138,6 +66819,7 @@ function summarizeXmtpTestEvents(runId, events) {
|
|
|
66138
66819
|
const nodeDurations = /* @__PURE__ */ new Map();
|
|
66139
66820
|
const replayLags = /* @__PURE__ */ new Map();
|
|
66140
66821
|
const replayHandles = /* @__PURE__ */ new Map();
|
|
66822
|
+
const streamRecoveries = /* @__PURE__ */ new Map();
|
|
66141
66823
|
const agentMap = /* @__PURE__ */ new Map();
|
|
66142
66824
|
for (const event of events) {
|
|
66143
66825
|
const key = deliveryKey(event);
|
|
@@ -66170,6 +66852,18 @@ function summarizeXmtpTestEvents(runId, events) {
|
|
|
66170
66852
|
event.handlerTotalMs
|
|
66171
66853
|
);
|
|
66172
66854
|
}
|
|
66855
|
+
if (event.eventName === "Agent stream recovered") {
|
|
66856
|
+
setDuration(
|
|
66857
|
+
streamRecoveries,
|
|
66858
|
+
[
|
|
66859
|
+
eventAgentId(event),
|
|
66860
|
+
stringValue(event.clientGeneration) || "unknown-client",
|
|
66861
|
+
stringValue(event.recoverySequence) || "unknown-recovery",
|
|
66862
|
+
event.timestamp
|
|
66863
|
+
].join(":"),
|
|
66864
|
+
event.recoveryDurationMs
|
|
66865
|
+
);
|
|
66866
|
+
}
|
|
66173
66867
|
}
|
|
66174
66868
|
const agents = [...agentMap.entries()].filter(([, value]) => value.live.size > 0 || value.replay.size > 0).map(([agentId, value]) => {
|
|
66175
66869
|
const total = (/* @__PURE__ */ new Set([...value.live, ...value.replay])).size;
|
|
@@ -66191,7 +66885,9 @@ function summarizeXmtpTestEvents(runId, events) {
|
|
|
66191
66885
|
duplicateEvents: countEvent(events, "Inbound ignored: duplicate message"),
|
|
66192
66886
|
replayMessageFailures: countEvent(events, "Offline replay message failed"),
|
|
66193
66887
|
replayScanFailures: countEvent(events, "Offline replay failed"),
|
|
66194
|
-
streamFailures: countEvent(events, "conversations.stream failed") + countEvent(events, "
|
|
66888
|
+
streamFailures: countEvent(events, "conversations.stream failed") + countEvent(events, "agent stream error"),
|
|
66889
|
+
streamRecoveries: countEvent(events, "Agent stream recovered"),
|
|
66890
|
+
streamRecoveryTimeouts: countEvent(events, "Agent stream recovery timeout"),
|
|
66195
66891
|
connectionFailures: countEvent(events, "XMTP connection failed"),
|
|
66196
66892
|
successfulReplayScans: countEvent(events, "Address sync completed"),
|
|
66197
66893
|
replayScansWithMessages: events.filter((event) => event.eventName === "Address sync completed" && numericValue(event.replayed) > 0).length,
|
|
@@ -66199,6 +66895,7 @@ function summarizeXmtpTestEvents(runId, events) {
|
|
|
66199
66895
|
nodeHandlerMs: summarizeDurations([...nodeDurations.values()]),
|
|
66200
66896
|
replayLagMs: summarizeDurations([...replayLags.values()]),
|
|
66201
66897
|
replayHandleMs: summarizeDurations([...replayHandles.values()]),
|
|
66898
|
+
streamRecoveryMs: summarizeDurations([...streamRecoveries.values()]),
|
|
66202
66899
|
agents
|
|
66203
66900
|
};
|
|
66204
66901
|
}
|
|
@@ -66213,6 +66910,8 @@ Reliability
|
|
|
66213
66910
|
Replay message failures ${summary.replayMessageFailures}
|
|
66214
66911
|
Replay scan failures ${summary.replayScanFailures}
|
|
66215
66912
|
Stream failures ${summary.streamFailures}
|
|
66913
|
+
Stream recoveries ${summary.streamRecoveries}
|
|
66914
|
+
Recovery timeouts (>30s) ${summary.streamRecoveryTimeouts}
|
|
66216
66915
|
XMTP connection failures ${summary.connectionFailures}
|
|
66217
66916
|
Replay scans ${summary.successfulReplayScans}
|
|
66218
66917
|
Scans with replay ${summary.replayScansWithMessages}
|
|
@@ -66221,7 +66920,8 @@ Timing
|
|
|
66221
66920
|
XMTP delivery p50/p95/max ${formatDurationSummary(summary.xmtpDeliveryMs)}
|
|
66222
66921
|
Node handler p50/p95/max ${formatDurationSummary(summary.nodeHandlerMs)}
|
|
66223
66922
|
Replay lag p50/p95/max ${formatDurationSummary(summary.replayLagMs)}
|
|
66224
|
-
Replay handler p50/p95/max ${formatDurationSummary(summary.replayHandleMs)}
|
|
66923
|
+
Replay handler p50/p95/max ${formatDurationSummary(summary.replayHandleMs)}
|
|
66924
|
+
Stream recovery p50/p95/max ${formatDurationSummary(summary.streamRecoveryMs)}`);
|
|
66225
66925
|
if (summary.agents.length > 0) {
|
|
66226
66926
|
console.log("\nAgents");
|
|
66227
66927
|
for (const agent of summary.agents) {
|
|
@@ -113550,7 +114250,7 @@ async function getCurrentNodeCliVersion() {
|
|
|
113550
114250
|
return await getGlobalNpmPackageVersion(UPDATE_PACKAGES.node) ?? getBundledNodeCliVersion();
|
|
113551
114251
|
}
|
|
113552
114252
|
function getBundledNodeCliVersion() {
|
|
113553
|
-
return true ? "0.2.1
|
|
114253
|
+
return true ? "0.2.1" : null;
|
|
113554
114254
|
}
|
|
113555
114255
|
function readConfiguredAiProvider() {
|
|
113556
114256
|
const explicit = process.env.OKX_A2A_AI_PROVIDER || process.env.OKX_AGENT_TASK_AI_CLI;
|
|
@@ -113760,7 +114460,7 @@ async function updateHermes(release, options) {
|
|
|
113760
114460
|
}
|
|
113761
114461
|
}
|
|
113762
114462
|
async function installGatewayPluginForDoctor(target) {
|
|
113763
|
-
const release = isPrereleaseVersion("0.2.1
|
|
114463
|
+
const release = isPrereleaseVersion("0.2.1") ? "beta" : "latest";
|
|
113764
114464
|
const insideTargetGateway = detectGatewayInvocation() === target;
|
|
113765
114465
|
const options = {
|
|
113766
114466
|
restart: !insideTargetGateway,
|
|
@@ -114748,7 +115448,7 @@ async function runDoctor(options = {}) {
|
|
|
114748
115448
|
platform: options.platform ?? process.platform,
|
|
114749
115449
|
env: options.env ?? process.env,
|
|
114750
115450
|
target: options.target ?? resolveDoctorTarget(options.env ?? process.env),
|
|
114751
|
-
cliVersion: options.cliVersion ?? (true ? "0.2.1
|
|
115451
|
+
cliVersion: options.cliVersion ?? (true ? "0.2.1" : "0.0.0"),
|
|
114752
115452
|
fixMode: options.fix === true,
|
|
114753
115453
|
nonInteractive: options.nonInteractive === true,
|
|
114754
115454
|
packageChanged: false,
|
|
@@ -115716,7 +116416,7 @@ init_sentry_logger();
|
|
|
115716
116416
|
init_sentry_config();
|
|
115717
116417
|
var CURRENT_GATEWAY_SESSION_KEYS_ENV4 = "OKX_A2A_CURRENT_GATEWAY_SESSION_KEYS";
|
|
115718
116418
|
function printUsage3() {
|
|
115719
|
-
console.log(`okx-a2a ${"0.2.1
|
|
116419
|
+
console.log(`okx-a2a ${"0.2.1"}
|
|
115720
116420
|
|
|
115721
116421
|
Usage:
|
|
115722
116422
|
okx-a2a <command> [options]
|
|
@@ -115756,7 +116456,7 @@ Run \`okx-a2a <command> -h\` for command-specific help.
|
|
|
115756
116456
|
`);
|
|
115757
116457
|
}
|
|
115758
116458
|
function printVersion() {
|
|
115759
|
-
console.log("0.2.1
|
|
116459
|
+
console.log("0.2.1");
|
|
115760
116460
|
}
|
|
115761
116461
|
function printDaemonUsage() {
|
|
115762
116462
|
console.log(`Usage: okx-a2a daemon <start|restart|stop|status|autostart> [options]
|
|
@@ -117167,7 +117867,7 @@ async function main() {
|
|
|
117167
117867
|
if (command === "xmtp-test") {
|
|
117168
117868
|
const { handleXmtpTestCommand: handleXmtpTestCommand2 } = await Promise.resolve().then(() => (init_xmtp_test_cli(), xmtp_test_cli_exports));
|
|
117169
117869
|
await handleXmtpTestCommand2(process.argv.slice(3), {
|
|
117170
|
-
packageVersion: "0.2.1
|
|
117870
|
+
packageVersion: "0.2.1",
|
|
117171
117871
|
agentSdkVersion: "2.3.0",
|
|
117172
117872
|
nodeSdkVersion: "6.1.0",
|
|
117173
117873
|
nodeBindingsVersion: "1.11.0"
|