lody 0.44.2-next.1 → 0.44.3-next.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/index.js +53 -39
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -36820,7 +36820,7 @@ Mongoose Error Code: ${error2.code}` : ""}`
|
|
|
36820
36820
|
return client;
|
|
36821
36821
|
}
|
|
36822
36822
|
const name = "lody";
|
|
36823
|
-
const version$4 = "0.44.
|
|
36823
|
+
const version$4 = "0.44.3-next.1";
|
|
36824
36824
|
const description = "Lody Agent CLI tool for managing remote command execution";
|
|
36825
36825
|
const type = "module";
|
|
36826
36826
|
const main$3 = "dist/index.js";
|
|
@@ -112230,6 +112230,9 @@ ${this.stack.split("\n").slice(1).join("\n")}` : this.toString();
|
|
|
112230
112230
|
isTransportConnected() {
|
|
112231
112231
|
return this.transportStatus === "connected";
|
|
112232
112232
|
}
|
|
112233
|
+
isRecovering() {
|
|
112234
|
+
return !this.isCleanedUp && !this.isStreamsHealthy();
|
|
112235
|
+
}
|
|
112233
112236
|
setTransportStatus(status) {
|
|
112234
112237
|
this.transportStatus = status;
|
|
112235
112238
|
if (status === "disconnected") {
|
|
@@ -113429,6 +113432,9 @@ ${this.stack.split("\n").slice(1).join("\n")}` : this.toString();
|
|
|
113429
113432
|
isTransportConnected() {
|
|
113430
113433
|
return this.connectionRecovery.isTransportConnected();
|
|
113431
113434
|
}
|
|
113435
|
+
isTransportRecovering() {
|
|
113436
|
+
return this.connectionRecovery.isRecovering();
|
|
113437
|
+
}
|
|
113432
113438
|
getConnectedRoomCount() {
|
|
113433
113439
|
return this.sessions.size + this.codeSessions.size;
|
|
113434
113440
|
}
|
|
@@ -122333,23 +122339,20 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
122333
122339
|
}
|
|
122334
122340
|
return Boolean(meta.latestUserMsgId && meta.latestUserMsgId !== meta.lastHandledUserMsgId);
|
|
122335
122341
|
}
|
|
122336
|
-
async setHistorySyncWaitStatus(sessionId, sessionDoc, detail) {
|
|
122337
|
-
try {
|
|
122338
|
-
await sessionDoc.setStatus(SessionStatusFactory.initializing(void 0, detail));
|
|
122339
|
-
} catch (error2) {
|
|
122340
|
-
this.deps.logger.debug(`[${sessionId}] Failed to set history sync wait status (${detail}): ${formatErrorMessage(error2)}`);
|
|
122341
|
-
}
|
|
122342
|
-
}
|
|
122343
122342
|
async waitForPendingUserTurnHistorySync(sessionId, sessionDoc, meta) {
|
|
122344
122343
|
this.deps.logger.debug(`[${sessionId}] Pending user turn metadata is visible but history is missing it; waiting up to ${SessionDispatchWatcher.HISTORY_SYNC_WAIT_TIMEOUT_MS / 1e3}s for history CRDT sync`);
|
|
122345
|
-
let currentWaitDetail = "joining-history";
|
|
122346
|
-
await this.setHistorySyncWaitStatus(sessionId, sessionDoc, currentWaitDetail);
|
|
122347
122344
|
try {
|
|
122348
122345
|
await sessionDoc.ensureDocRoomJoined();
|
|
122349
122346
|
} catch (error2) {
|
|
122350
122347
|
this.deps.logger.debug(`[${sessionId}] Failed to ensure session history room is joined before waiting: ${formatErrorMessage(error2)}`);
|
|
122351
122348
|
}
|
|
122352
|
-
|
|
122349
|
+
await sessionDoc.waitUntilSynced();
|
|
122350
|
+
const freshMeta = await sessionDoc.getMetaState() ?? meta;
|
|
122351
|
+
if (!this.hasPendingUserTurnSignal(freshMeta)) {
|
|
122352
|
+
this.deps.logger.debug(`[${sessionId}] Pending user turn pointer cleared during pre-wait sync; exiting wait`);
|
|
122353
|
+
return null;
|
|
122354
|
+
}
|
|
122355
|
+
const turnAfterJoin = await this.checkHistoryAndQueue(sessionDoc, freshMeta);
|
|
122353
122356
|
if (turnAfterJoin) {
|
|
122354
122357
|
return turnAfterJoin;
|
|
122355
122358
|
}
|
|
@@ -122367,18 +122370,11 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
122367
122370
|
unsubscribeMirror?.();
|
|
122368
122371
|
unsubscribeStatus?.();
|
|
122369
122372
|
};
|
|
122370
|
-
const updateWaitStatus = (detail) => {
|
|
122371
|
-
if (currentWaitDetail === detail) {
|
|
122372
|
-
return;
|
|
122373
|
-
}
|
|
122374
|
-
currentWaitDetail = detail;
|
|
122375
|
-
void this.setHistorySyncWaitStatus(sessionId, sessionDoc, detail);
|
|
122376
|
-
};
|
|
122377
122373
|
const checkForTurn = () => {
|
|
122378
122374
|
if (settled) {
|
|
122379
122375
|
return;
|
|
122380
122376
|
}
|
|
122381
|
-
void this.checkHistoryAndQueue(sessionDoc,
|
|
122377
|
+
void this.checkHistoryAndQueue(sessionDoc, freshMeta).then((turn) => {
|
|
122382
122378
|
if (settled || !turn) {
|
|
122383
122379
|
return;
|
|
122384
122380
|
}
|
|
@@ -122398,7 +122394,6 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
122398
122394
|
}
|
|
122399
122395
|
reconnectAttempted = true;
|
|
122400
122396
|
void (async () => {
|
|
122401
|
-
updateWaitStatus("reconnecting-history");
|
|
122402
122397
|
const jitterMs = SessionDispatchWatcher.getReconnectJitterMs();
|
|
122403
122398
|
this.deps.logger.debug(`[${sessionId}] Session history room ${reason}; attempting one rejoin in ${jitterMs}ms`);
|
|
122404
122399
|
await SessionDispatchWatcher.sleep(jitterMs);
|
|
@@ -122417,14 +122412,6 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
122417
122412
|
if (settled || !status) {
|
|
122418
122413
|
return;
|
|
122419
122414
|
}
|
|
122420
|
-
if (status === "connecting" || status === "joined") {
|
|
122421
|
-
updateWaitStatus("joining-history");
|
|
122422
|
-
return;
|
|
122423
|
-
}
|
|
122424
|
-
if (status === "reconnecting") {
|
|
122425
|
-
updateWaitStatus("reconnecting-history");
|
|
122426
|
-
return;
|
|
122427
|
-
}
|
|
122428
122415
|
if (status === "disconnected" || status === "error") {
|
|
122429
122416
|
attemptReconnectOnce(status);
|
|
122430
122417
|
}
|
|
@@ -122461,16 +122448,20 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
122461
122448
|
if (meta.machineId !== this.deps.machineId || meta.isArchived || !this.hasPendingUserTurnSignal(meta)) {
|
|
122462
122449
|
return;
|
|
122463
122450
|
}
|
|
122464
|
-
|
|
122451
|
+
const pendingUserMsgId = meta.processingUserMsgId ?? meta.latestUserMsgId ?? meta.lastHandledUserMsgId;
|
|
122452
|
+
const recoveryPatch = {
|
|
122465
122453
|
status: SessionStatusFactory.idle(),
|
|
122466
|
-
latestUserMsgId: void 0,
|
|
122467
|
-
processingUserMsgId: void 0,
|
|
122468
122454
|
dispatchError: {
|
|
122469
122455
|
code: SessionDispatchWatcher.DISPATCH_HISTORY_SYNC_TIMEOUT_CODE,
|
|
122470
122456
|
message: "Dispatch recovery could not reconnect to this session after 5 minutes. Send a new message to retry.",
|
|
122471
122457
|
at: getServerNow()
|
|
122472
122458
|
}
|
|
122473
|
-
}
|
|
122459
|
+
};
|
|
122460
|
+
if (pendingUserMsgId) {
|
|
122461
|
+
recoveryPatch.lastHandledUserMsgId = pendingUserMsgId;
|
|
122462
|
+
recoveryPatch.latestUserMsgId = pendingUserMsgId;
|
|
122463
|
+
}
|
|
122464
|
+
await this.deps.workspaceDocument.repo.upsertDocMeta?.(roomId, recoveryPatch);
|
|
122474
122465
|
const watched = this.watchedSessions.get(sessionId);
|
|
122475
122466
|
watched?.unsubscribe();
|
|
122476
122467
|
this.watchedSessions.delete(sessionId);
|
|
@@ -133184,6 +133175,9 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
|
|
|
133184
133175
|
isControlPlaneReady() {
|
|
133185
133176
|
return this.documentManager.isTransportConnected();
|
|
133186
133177
|
}
|
|
133178
|
+
isControlPlaneRecovering() {
|
|
133179
|
+
return this.documentManager.isTransportRecovering();
|
|
133180
|
+
}
|
|
133187
133181
|
getActiveSessionCount() {
|
|
133188
133182
|
return this.runtime.getActiveSessionCount();
|
|
133189
133183
|
}
|
|
@@ -135013,23 +135007,26 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
|
|
|
135013
135007
|
refreshRuntimeState() {
|
|
135014
135008
|
const desiredCount = this.desiredWorkspaces.size;
|
|
135015
135009
|
let connectedCount = 0;
|
|
135010
|
+
let reconnectingCount = 0;
|
|
135016
135011
|
let totalActiveSessions = 0;
|
|
135017
135012
|
let totalConnectedRooms = 0;
|
|
135018
135013
|
for (const runtime of this.runtimes.values()) {
|
|
135019
135014
|
if (runtime.lody.isControlPlaneReady()) {
|
|
135020
135015
|
connectedCount += 1;
|
|
135016
|
+
} else if (runtime.lody.isControlPlaneRecovering()) {
|
|
135017
|
+
reconnectingCount += 1;
|
|
135021
135018
|
}
|
|
135022
135019
|
totalActiveSessions += runtime.lody.getActiveSessionCount();
|
|
135023
135020
|
totalConnectedRooms += runtime.lody.getConnectedRoomCount();
|
|
135024
135021
|
}
|
|
135025
135022
|
this.runtimeStateReporter.setActiveSessionCount(totalActiveSessions);
|
|
135026
135023
|
this.runtimeStateReporter.setConnectedRoomCount(totalConnectedRooms);
|
|
135027
|
-
const
|
|
135024
|
+
const hasWorkspaceRetry = this.retryTimers.size > 0 || this.startInFlight.size > 0;
|
|
135025
|
+
const nextConnectivity = desiredCount === 0 ? "online" : connectedCount === desiredCount ? "online" : reconnectingCount > 0 || hasWorkspaceRetry ? "reconnecting" : "offline";
|
|
135028
135026
|
if (this.lastConnectivity !== nextConnectivity) {
|
|
135029
135027
|
this.lastConnectivity = nextConnectivity;
|
|
135030
135028
|
this.runtimeStateReporter.setConnectivity(nextConnectivity);
|
|
135031
135029
|
}
|
|
135032
|
-
const hasWorkspaceRetry = this.retryTimers.size > 0 || this.startInFlight.size > 0;
|
|
135033
135030
|
if (hasWorkspaceRetry && !this.hasWorkspaceRetryIssue) {
|
|
135034
135031
|
this.hasWorkspaceRetryIssue = true;
|
|
135035
135032
|
this.runtimeStateReporter.upsertIssue({
|
|
@@ -167312,10 +167309,18 @@ ${entry2.text}`).join("\n\n");
|
|
|
167312
167309
|
}
|
|
167313
167310
|
const DEFAULT_MIN_RETRY_MS$1 = 1e3;
|
|
167314
167311
|
const DEFAULT_MAX_RETRY_MS$1 = 3e4;
|
|
167315
|
-
|
|
167312
|
+
const DEFAULT_JITTER_FRACTION = 0.2;
|
|
167313
|
+
function buildRetryDelay(attempt, minMs = DEFAULT_MIN_RETRY_MS$1, maxMs = DEFAULT_MAX_RETRY_MS$1, options = {}) {
|
|
167316
167314
|
const exponent = Math.max(0, attempt);
|
|
167317
|
-
const
|
|
167318
|
-
|
|
167315
|
+
const baseDelay = Math.min(minMs * 2 ** exponent, maxMs);
|
|
167316
|
+
const jitterFraction = Math.max(0, options.jitterFraction ?? DEFAULT_JITTER_FRACTION);
|
|
167317
|
+
if (jitterFraction === 0) {
|
|
167318
|
+
return baseDelay;
|
|
167319
|
+
}
|
|
167320
|
+
const random2 = options.random ?? Math.random;
|
|
167321
|
+
const randomValue = Math.min(1, Math.max(0, random2()));
|
|
167322
|
+
const jitterMultiplier = 1 + (randomValue * 2 - 1) * jitterFraction;
|
|
167323
|
+
return Math.min(Math.max(0, Math.round(baseDelay * jitterMultiplier)), maxMs);
|
|
167319
167324
|
}
|
|
167320
167325
|
class FailureWindow {
|
|
167321
167326
|
historyMs = [];
|
|
@@ -167376,6 +167381,7 @@ ${result.stderr}`;
|
|
|
167376
167381
|
probeFailureThreshold;
|
|
167377
167382
|
minRetryMs;
|
|
167378
167383
|
maxRetryMs;
|
|
167384
|
+
retryRandom;
|
|
167379
167385
|
failureWindow;
|
|
167380
167386
|
triggered = false;
|
|
167381
167387
|
inFlight = false;
|
|
@@ -167407,6 +167413,7 @@ ${result.stderr}`;
|
|
|
167407
167413
|
this.probeFailureThreshold = options.probeFailureThreshold ?? DEFAULT_PROBE_FAILURE_THRESHOLD;
|
|
167408
167414
|
this.minRetryMs = options.minRetryMs ?? DEFAULT_MIN_RETRY_MS;
|
|
167409
167415
|
this.maxRetryMs = options.maxRetryMs ?? DEFAULT_MAX_RETRY_MS;
|
|
167416
|
+
this.retryRandom = options.retryRandom ?? Math.random;
|
|
167410
167417
|
this.failureWindow = new FailureWindow(options.fatalFailureWindowMs ?? DEFAULT_FATAL_FAILURE_WINDOW_MS, options.fatalFailureThreshold ?? DEFAULT_FATAL_FAILURE_THRESHOLD);
|
|
167411
167418
|
}
|
|
167412
167419
|
getState() {
|
|
@@ -167486,6 +167493,9 @@ ${result.stderr}`;
|
|
|
167486
167493
|
this.latestRuntimeState = runtimeState;
|
|
167487
167494
|
this.probeFailureCount = 0;
|
|
167488
167495
|
this.probeUnavailable = false;
|
|
167496
|
+
this.clearRetryTimer();
|
|
167497
|
+
this.attempt = 0;
|
|
167498
|
+
this.failureWindow.reset();
|
|
167489
167499
|
this.lastStateMessage = void 0;
|
|
167490
167500
|
} else {
|
|
167491
167501
|
this.probeFailureCount += 1;
|
|
@@ -167506,7 +167516,9 @@ ${result.stderr}`;
|
|
|
167506
167516
|
} else if (this.fatalReason) {
|
|
167507
167517
|
phase = "fatal";
|
|
167508
167518
|
} else if (runtime) {
|
|
167509
|
-
phase = runtime.phase === "fatal" ? "fatal" : runtime.phase;
|
|
167519
|
+
phase = runtime.phase === "fatal" ? "fatal" : runtime.connectivity === "reconnecting" ? "reconnecting" : runtime.phase;
|
|
167520
|
+
} else if (this.retryTimer) {
|
|
167521
|
+
phase = "reconnecting";
|
|
167510
167522
|
} else if (childRunning) {
|
|
167511
167523
|
phase = this.probeUnavailable ? "offline" : "starting";
|
|
167512
167524
|
} else if (this.probeUnavailable && !this.inFlight && !this.retryTimer) {
|
|
@@ -167563,7 +167575,9 @@ ${result.stderr}`;
|
|
|
167563
167575
|
scheduleRetry(reason, recordFailure = true) {
|
|
167564
167576
|
if (this.fatalReason) return;
|
|
167565
167577
|
if (recordFailure && this.recordFailure(reason)) return;
|
|
167566
|
-
const delay2 = buildRetryDelay(this.attempt, this.minRetryMs, this.maxRetryMs
|
|
167578
|
+
const delay2 = buildRetryDelay(this.attempt, this.minRetryMs, this.maxRetryMs, {
|
|
167579
|
+
random: this.retryRandom
|
|
167580
|
+
});
|
|
167567
167581
|
this.attempt += 1;
|
|
167568
167582
|
this.clearRetryTimer();
|
|
167569
167583
|
this.pendingRetryInMs = delay2;
|