lody 0.44.2-next.1 → 0.44.4-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 +474 -219
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -45,13 +45,13 @@ import require$$1$6 from "string_decoder";
|
|
|
45
45
|
import * as http$2 from "http";
|
|
46
46
|
import http__default from "http";
|
|
47
47
|
import require$$1$7 from "https";
|
|
48
|
-
import require$$0$a, { execSync, exec, execFile as execFile$1 } from "child_process";
|
|
48
|
+
import require$$0$a, { execSync, exec, execFileSync, execFile as execFile$1 } from "child_process";
|
|
49
49
|
import { randomFillSync, randomUUID as randomUUID$1, createHash as createHash$1 } from "node:crypto";
|
|
50
50
|
import require$$0$b from "net";
|
|
51
51
|
import require$$4$3 from "tls";
|
|
52
52
|
import { i as imports, _ as __wbg_set_wasm$1, r as rawWasm, L as LoroDoc, E as EphemeralStoreWasm, U as UndoManager, c as callPendingEvents$3, a as LoroTree, b as LoroText, d as LoroMovableList, e as LoroList, f as LoroMap, g as __vite__initWasm, V as VersionVector, h as decodeImportBlobMeta, __tla as __tla_0 } from "./chunks/loro_wasm_bg-DgxHrrrp.js";
|
|
53
53
|
import * as fs$5 from "fs/promises";
|
|
54
|
-
import fs__default$1, { stat as stat$1, readFile as readFile$1 } from "fs/promises";
|
|
54
|
+
import fs__default$1, { stat as stat$1, readFile as readFile$1, statfs } from "fs/promises";
|
|
55
55
|
import fsPromises, { stat, open } from "node:fs/promises";
|
|
56
56
|
import { fileURLToPath } from "node:url";
|
|
57
57
|
import require$$2$7 from "assert";
|
|
@@ -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.4-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";
|
|
@@ -78436,6 +78436,7 @@ Task description:
|
|
|
78436
78436
|
"session_init_failed",
|
|
78437
78437
|
"session_restore_failed",
|
|
78438
78438
|
"session_not_found",
|
|
78439
|
+
"memory_pressure",
|
|
78439
78440
|
"acp_not_ready",
|
|
78440
78441
|
"agent_disconnected",
|
|
78441
78442
|
"turn_pre_prompt_failed",
|
|
@@ -112230,6 +112231,9 @@ ${this.stack.split("\n").slice(1).join("\n")}` : this.toString();
|
|
|
112230
112231
|
isTransportConnected() {
|
|
112231
112232
|
return this.transportStatus === "connected";
|
|
112232
112233
|
}
|
|
112234
|
+
isRecovering() {
|
|
112235
|
+
return !this.isCleanedUp && !this.isStreamsHealthy();
|
|
112236
|
+
}
|
|
112233
112237
|
setTransportStatus(status) {
|
|
112234
112238
|
this.transportStatus = status;
|
|
112235
112239
|
if (status === "disconnected") {
|
|
@@ -113429,6 +113433,9 @@ ${this.stack.split("\n").slice(1).join("\n")}` : this.toString();
|
|
|
113429
113433
|
isTransportConnected() {
|
|
113430
113434
|
return this.connectionRecovery.isTransportConnected();
|
|
113431
113435
|
}
|
|
113436
|
+
isTransportRecovering() {
|
|
113437
|
+
return this.connectionRecovery.isRecovering();
|
|
113438
|
+
}
|
|
113432
113439
|
getConnectedRoomCount() {
|
|
113433
113440
|
return this.sessions.size + this.codeSessions.size;
|
|
113434
113441
|
}
|
|
@@ -120210,6 +120217,221 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
120210
120217
|
}
|
|
120211
120218
|
return resolveAgentConfigEnvForSessionResume(repo, options.agentConfigId);
|
|
120212
120219
|
};
|
|
120220
|
+
function getMemoryPressureSnapshot() {
|
|
120221
|
+
const windowsStatus = getWindowsMemoryStatus();
|
|
120222
|
+
const systemAvailable = getSystemAvailableMemoryBytes(windowsStatus);
|
|
120223
|
+
const cgroupAvailable = getCgroupAvailableMemoryBytes();
|
|
120224
|
+
const availableMemoryBytes = cgroupAvailable !== null ? Math.min(systemAvailable, cgroupAvailable) : systemAvailable;
|
|
120225
|
+
const effectiveMemoryLimitBytes = getEffectiveMemoryLimitBytes();
|
|
120226
|
+
return {
|
|
120227
|
+
availableMemoryBytes,
|
|
120228
|
+
effectiveMemoryLimitBytes,
|
|
120229
|
+
...windowsStatus ? {
|
|
120230
|
+
availableCommitBytes: windowsStatus.availableCommitBytes,
|
|
120231
|
+
commitLimitBytes: windowsStatus.commitLimitBytes,
|
|
120232
|
+
committedBytes: windowsStatus.committedBytes
|
|
120233
|
+
} : {}
|
|
120234
|
+
};
|
|
120235
|
+
}
|
|
120236
|
+
function getEffectiveMemoryLimitBytes() {
|
|
120237
|
+
const totalMem = os__default.totalmem();
|
|
120238
|
+
const cgroupMax = getCgroupMemoryMaxBytes();
|
|
120239
|
+
if (cgroupMax !== null) {
|
|
120240
|
+
return Math.min(totalMem, cgroupMax);
|
|
120241
|
+
}
|
|
120242
|
+
return totalMem;
|
|
120243
|
+
}
|
|
120244
|
+
function getSystemAvailableMemoryBytes(windowsStatus) {
|
|
120245
|
+
if (windowsStatus) {
|
|
120246
|
+
return Math.max(windowsStatus.availableBytes, os__default.freemem());
|
|
120247
|
+
}
|
|
120248
|
+
const darwinAvailable = getDarwinAvailableMemoryBytes();
|
|
120249
|
+
if (darwinAvailable !== null) {
|
|
120250
|
+
return darwinAvailable;
|
|
120251
|
+
}
|
|
120252
|
+
try {
|
|
120253
|
+
const meminfo = readFileSync("/proc/meminfo", "utf8");
|
|
120254
|
+
const match5 = meminfo.match(/MemAvailable:\s+(\d+)/);
|
|
120255
|
+
if (match5?.[1]) {
|
|
120256
|
+
return parseInt(match5[1], 10) * 1024;
|
|
120257
|
+
}
|
|
120258
|
+
} catch {
|
|
120259
|
+
}
|
|
120260
|
+
return os__default.freemem();
|
|
120261
|
+
}
|
|
120262
|
+
function getWindowsMemoryStatus() {
|
|
120263
|
+
if (process.platform !== "win32") {
|
|
120264
|
+
return null;
|
|
120265
|
+
}
|
|
120266
|
+
try {
|
|
120267
|
+
const script = `
|
|
120268
|
+
$mem = Get-CimInstance -ClassName Win32_PerfFormattedData_PerfOS_Memory |
|
|
120269
|
+
Select-Object AvailableBytes, CommitLimit, CommittedBytes
|
|
120270
|
+
$mem | ConvertTo-Json -Compress
|
|
120271
|
+
`;
|
|
120272
|
+
const output = execFileSync("powershell.exe", [
|
|
120273
|
+
"-NoProfile",
|
|
120274
|
+
"-NonInteractive",
|
|
120275
|
+
"-ExecutionPolicy",
|
|
120276
|
+
"Bypass",
|
|
120277
|
+
"-Command",
|
|
120278
|
+
script
|
|
120279
|
+
], {
|
|
120280
|
+
encoding: "utf8"
|
|
120281
|
+
});
|
|
120282
|
+
return parseWindowsMemoryStatus(output);
|
|
120283
|
+
} catch {
|
|
120284
|
+
return null;
|
|
120285
|
+
}
|
|
120286
|
+
}
|
|
120287
|
+
function parseWindowsMemoryStatus(rawJson) {
|
|
120288
|
+
try {
|
|
120289
|
+
const parsed = JSON.parse(rawJson);
|
|
120290
|
+
const availableBytes = Number(parsed.AvailableBytes);
|
|
120291
|
+
const commitLimitBytes = Number(parsed.CommitLimit);
|
|
120292
|
+
const committedBytes = Number(parsed.CommittedBytes);
|
|
120293
|
+
if (!Number.isFinite(availableBytes) || availableBytes < 0 || !Number.isFinite(commitLimitBytes) || commitLimitBytes <= 0 || !Number.isFinite(committedBytes) || committedBytes < 0) {
|
|
120294
|
+
return null;
|
|
120295
|
+
}
|
|
120296
|
+
return {
|
|
120297
|
+
availableBytes,
|
|
120298
|
+
commitLimitBytes,
|
|
120299
|
+
committedBytes,
|
|
120300
|
+
availableCommitBytes: Math.max(0, commitLimitBytes - committedBytes)
|
|
120301
|
+
};
|
|
120302
|
+
} catch {
|
|
120303
|
+
return null;
|
|
120304
|
+
}
|
|
120305
|
+
}
|
|
120306
|
+
function getDarwinAvailableMemoryBytes() {
|
|
120307
|
+
if (process.platform !== "darwin") {
|
|
120308
|
+
return null;
|
|
120309
|
+
}
|
|
120310
|
+
try {
|
|
120311
|
+
const vmStatOutput = execFileSync("vm_stat", {
|
|
120312
|
+
encoding: "utf8"
|
|
120313
|
+
});
|
|
120314
|
+
const parsed = parseDarwinAvailableMemoryBytes(vmStatOutput);
|
|
120315
|
+
if (parsed !== null) {
|
|
120316
|
+
return Math.max(parsed, os__default.freemem());
|
|
120317
|
+
}
|
|
120318
|
+
} catch {
|
|
120319
|
+
}
|
|
120320
|
+
return null;
|
|
120321
|
+
}
|
|
120322
|
+
function parseDarwinAvailableMemoryBytes(vmStatOutput) {
|
|
120323
|
+
const pageSizeMatch = vmStatOutput.match(/page size of\s+(\d+)\s+bytes/i);
|
|
120324
|
+
if (!pageSizeMatch?.[1]) {
|
|
120325
|
+
return null;
|
|
120326
|
+
}
|
|
120327
|
+
const pageSize = parseInt(pageSizeMatch[1], 10);
|
|
120328
|
+
if (!Number.isFinite(pageSize) || pageSize <= 0) {
|
|
120329
|
+
return null;
|
|
120330
|
+
}
|
|
120331
|
+
const counters = /* @__PURE__ */ new Map();
|
|
120332
|
+
for (const rawLine of vmStatOutput.split("\n")) {
|
|
120333
|
+
const line3 = rawLine.trim();
|
|
120334
|
+
const match5 = line3.match(/^"?([^":]+?)"?:\s+(\d+)\.?$/);
|
|
120335
|
+
if (!match5?.[1] || !match5[2]) {
|
|
120336
|
+
continue;
|
|
120337
|
+
}
|
|
120338
|
+
counters.set(match5[1].toLowerCase(), parseInt(match5[2], 10));
|
|
120339
|
+
}
|
|
120340
|
+
const freePages = counters.get("pages free") ?? 0;
|
|
120341
|
+
const speculativePages = counters.get("pages speculative") ?? 0;
|
|
120342
|
+
const purgeablePages = counters.get("pages purgeable") ?? 0;
|
|
120343
|
+
const inactivePages = counters.get("pages inactive") ?? 0;
|
|
120344
|
+
const fileBackedPages = counters.get("file-backed pages");
|
|
120345
|
+
if (freePages === 0 && speculativePages === 0 && purgeablePages === 0 && inactivePages === 0) {
|
|
120346
|
+
return null;
|
|
120347
|
+
}
|
|
120348
|
+
const reclaimableCachedPages = fileBackedPages !== void 0 ? Math.min(fileBackedPages, inactivePages) : inactivePages;
|
|
120349
|
+
const availablePages = freePages + speculativePages + purgeablePages + reclaimableCachedPages;
|
|
120350
|
+
return availablePages * pageSize;
|
|
120351
|
+
}
|
|
120352
|
+
function getCgroupMemoryMaxBytes() {
|
|
120353
|
+
try {
|
|
120354
|
+
const cgroupPath = readSelfCgroupPath();
|
|
120355
|
+
if (cgroupPath === null) return null;
|
|
120356
|
+
let tightest = null;
|
|
120357
|
+
let current2 = cgroupPath;
|
|
120358
|
+
for (let depth = 0; depth < 20; depth++) {
|
|
120359
|
+
const memMaxPath = `/sys/fs/cgroup${current2 === "/" ? "" : current2}/memory.max`;
|
|
120360
|
+
const raw = readFileSafe(memMaxPath);
|
|
120361
|
+
if (raw !== null) {
|
|
120362
|
+
const trimmed = raw.trim();
|
|
120363
|
+
if (trimmed !== "max") {
|
|
120364
|
+
const value = parseInt(trimmed, 10);
|
|
120365
|
+
if (Number.isFinite(value) && value > 0) {
|
|
120366
|
+
tightest = tightest === null ? value : Math.min(tightest, value);
|
|
120367
|
+
}
|
|
120368
|
+
}
|
|
120369
|
+
}
|
|
120370
|
+
if (current2 === "/" || current2 === "") break;
|
|
120371
|
+
const parent = current2.substring(0, current2.lastIndexOf("/")) || "/";
|
|
120372
|
+
if (parent === current2) break;
|
|
120373
|
+
current2 = parent;
|
|
120374
|
+
}
|
|
120375
|
+
return tightest;
|
|
120376
|
+
} catch {
|
|
120377
|
+
return null;
|
|
120378
|
+
}
|
|
120379
|
+
}
|
|
120380
|
+
function getCgroupAvailableMemoryBytes() {
|
|
120381
|
+
try {
|
|
120382
|
+
const cgroupPath = readSelfCgroupPath();
|
|
120383
|
+
if (cgroupPath === null) return null;
|
|
120384
|
+
let tightestMax = null;
|
|
120385
|
+
let tightestPath = null;
|
|
120386
|
+
let current2 = cgroupPath;
|
|
120387
|
+
for (let depth = 0; depth < 20; depth++) {
|
|
120388
|
+
const prefix = `/sys/fs/cgroup${current2 === "/" ? "" : current2}`;
|
|
120389
|
+
const raw = readFileSafe(`${prefix}/memory.max`);
|
|
120390
|
+
if (raw !== null) {
|
|
120391
|
+
const trimmed = raw.trim();
|
|
120392
|
+
if (trimmed !== "max") {
|
|
120393
|
+
const value = parseInt(trimmed, 10);
|
|
120394
|
+
if (Number.isFinite(value) && value > 0) {
|
|
120395
|
+
if (tightestMax === null || value < tightestMax) {
|
|
120396
|
+
tightestMax = value;
|
|
120397
|
+
tightestPath = prefix;
|
|
120398
|
+
}
|
|
120399
|
+
}
|
|
120400
|
+
}
|
|
120401
|
+
}
|
|
120402
|
+
if (current2 === "/" || current2 === "") break;
|
|
120403
|
+
const parent = current2.substring(0, current2.lastIndexOf("/")) || "/";
|
|
120404
|
+
if (parent === current2) break;
|
|
120405
|
+
current2 = parent;
|
|
120406
|
+
}
|
|
120407
|
+
if (tightestMax === null || tightestPath === null) return null;
|
|
120408
|
+
const currentRaw = readFileSafe(`${tightestPath}/memory.current`);
|
|
120409
|
+
if (currentRaw === null) return null;
|
|
120410
|
+
const currentUsage = parseInt(currentRaw.trim(), 10);
|
|
120411
|
+
if (!Number.isFinite(currentUsage)) return null;
|
|
120412
|
+
return Math.max(0, tightestMax - currentUsage);
|
|
120413
|
+
} catch {
|
|
120414
|
+
return null;
|
|
120415
|
+
}
|
|
120416
|
+
}
|
|
120417
|
+
function readSelfCgroupPath() {
|
|
120418
|
+
try {
|
|
120419
|
+
const content = readFileSync("/proc/self/cgroup", "utf8");
|
|
120420
|
+
const line3 = content.split("\n").map((l) => l.trim()).find((l) => l.startsWith("0::"));
|
|
120421
|
+
if (!line3) return null;
|
|
120422
|
+
const cgroupPath = line3.slice(3).trim();
|
|
120423
|
+
return cgroupPath || "/";
|
|
120424
|
+
} catch {
|
|
120425
|
+
return null;
|
|
120426
|
+
}
|
|
120427
|
+
}
|
|
120428
|
+
function readFileSafe(filePath) {
|
|
120429
|
+
try {
|
|
120430
|
+
return readFileSync(filePath, "utf8");
|
|
120431
|
+
} catch {
|
|
120432
|
+
return null;
|
|
120433
|
+
}
|
|
120434
|
+
}
|
|
120213
120435
|
class SessionTurnCancelled extends TaggedError("SessionTurnCancelled") {
|
|
120214
120436
|
}
|
|
120215
120437
|
class SessionTurnHalted extends TaggedError("SessionTurnHalted") {
|
|
@@ -120230,6 +120452,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
120230
120452
|
AUTH_REQUIRED: -32e3,
|
|
120231
120453
|
RESOURCE_NOT_FOUND: -32002
|
|
120232
120454
|
};
|
|
120455
|
+
const BYTES_PER_GIB = 1024 * 1024 * 1024;
|
|
120233
120456
|
const shouldRedactEnvKey = (key2) => /token|secret|password|passwd|key/i.test(key2);
|
|
120234
120457
|
const redactEnvForLog = (env2) => {
|
|
120235
120458
|
if (!env2) {
|
|
@@ -120265,6 +120488,46 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
120265
120488
|
canceledTurnBySession = /* @__PURE__ */ new Map();
|
|
120266
120489
|
currentTurnBySession = /* @__PURE__ */ new Map();
|
|
120267
120490
|
turnRuntimeBySession = /* @__PURE__ */ new Map();
|
|
120491
|
+
formatGiB(bytes) {
|
|
120492
|
+
if (bytes === null || !Number.isFinite(bytes) || bytes < 0) {
|
|
120493
|
+
return "unavailable";
|
|
120494
|
+
}
|
|
120495
|
+
return `${(bytes / BYTES_PER_GIB).toFixed(1)}GB`;
|
|
120496
|
+
}
|
|
120497
|
+
formatPercent(value) {
|
|
120498
|
+
if (value === null || !Number.isFinite(value) || value < 0) {
|
|
120499
|
+
return "unavailable";
|
|
120500
|
+
}
|
|
120501
|
+
return `${value.toFixed(1)}%`;
|
|
120502
|
+
}
|
|
120503
|
+
async getFreeDiskBytes() {
|
|
120504
|
+
try {
|
|
120505
|
+
const stats = await statfs(os__default.homedir());
|
|
120506
|
+
const bsize = typeof stats.bsize === "bigint" ? Number(stats.bsize) : stats.bsize;
|
|
120507
|
+
const bavail = typeof stats.bavail === "bigint" ? Number(stats.bavail) : stats.bavail;
|
|
120508
|
+
if (!Number.isFinite(bsize) || !Number.isFinite(bavail) || bsize <= 0 || bavail < 0) {
|
|
120509
|
+
return null;
|
|
120510
|
+
}
|
|
120511
|
+
return bsize * bavail;
|
|
120512
|
+
} catch {
|
|
120513
|
+
return null;
|
|
120514
|
+
}
|
|
120515
|
+
}
|
|
120516
|
+
async logTurnStartResources(sessionId, mode2) {
|
|
120517
|
+
try {
|
|
120518
|
+
const memorySnapshot = getMemoryPressureSnapshot();
|
|
120519
|
+
const availableMemoryBytes = memorySnapshot.availableMemoryBytes;
|
|
120520
|
+
const memoryFreePercent = memorySnapshot.effectiveMemoryLimitBytes > 0 ? availableMemoryBytes / memorySnapshot.effectiveMemoryLimitBytes * 100 : null;
|
|
120521
|
+
const [resources, freeDiskBytes] = await Promise.all([
|
|
120522
|
+
this.deps.collectMachineResources().catch(() => null),
|
|
120523
|
+
this.getFreeDiskBytes()
|
|
120524
|
+
]);
|
|
120525
|
+
const cpuUsagePercent = resources?.cpuUsagePercent ?? null;
|
|
120526
|
+
this.deps.logger.info(`[${sessionId}] Turn start resources (mode=${mode2}): memoryAvailable=${this.formatGiB(availableMemoryBytes)} memoryAvailablePercent=${this.formatPercent(memoryFreePercent)} cpuUsage=${this.formatPercent(cpuUsagePercent)} diskFree=${this.formatGiB(freeDiskBytes)}`);
|
|
120527
|
+
} catch (error2) {
|
|
120528
|
+
this.deps.logger.debug(`[${sessionId}] Failed to log turn start resources: ${formatErrorMessage(error2)}`);
|
|
120529
|
+
}
|
|
120530
|
+
}
|
|
120268
120531
|
createTurnRuntime(sessionId, turnId, userTurnId, session) {
|
|
120269
120532
|
return {
|
|
120270
120533
|
sessionId,
|
|
@@ -120447,10 +120710,19 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
120447
120710
|
async recordKnownChatFailure(options) {
|
|
120448
120711
|
await this.deps.recordChatFailure(options.sessionDoc, options.reason, options.message);
|
|
120449
120712
|
if (options.userTurnId) {
|
|
120450
|
-
await this.
|
|
120713
|
+
await this.markTurnFailed(options.sessionId, options.sessionDoc, options.userTurnId);
|
|
120451
120714
|
}
|
|
120452
120715
|
await options.sessionDoc.setStatus(SessionStatusFactory.idle());
|
|
120453
120716
|
}
|
|
120717
|
+
formatMemoryPressureWarningMessage(result) {
|
|
120718
|
+
const availableMb = Math.round(result.availableMemoryBytes / 1024 / 1024);
|
|
120719
|
+
const thresholdMb = Math.round(result.thresholdBytes / 1024 / 1024);
|
|
120720
|
+
const commitText = result.availableCommitBytes !== void 0 && (result.pressureReason === "commit" || result.pressureReason === "physical_and_commit") && result.commitThresholdBytes !== void 0 ? ` Commit headroom is ${Math.round(result.availableCommitBytes / 1024 / 1024)}MB (threshold: ${Math.round(result.commitThresholdBytes / 1024 / 1024)}MB).` : "";
|
|
120721
|
+
return `The machine is under memory pressure (${availableMb}MB available, ${thresholdMb}MB required to start a turn). Proceeding anyway because the new turn may be used to free resources.${commitText}`;
|
|
120722
|
+
}
|
|
120723
|
+
warnOnMemoryPressure(sessionId, result) {
|
|
120724
|
+
this.deps.logger.warn(`[${sessionId}] ${this.formatMemoryPressureWarningMessage(result)}`);
|
|
120725
|
+
}
|
|
120454
120726
|
recordKnownChatFailureAndHaltEffect(options) {
|
|
120455
120727
|
return this.tryPromise(() => this.recordKnownChatFailure(options)).pipe(flatMap$1(() => fail(new SessionTurnHalted({
|
|
120456
120728
|
sessionId: options.sessionId,
|
|
@@ -120474,7 +120746,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
120474
120746
|
}
|
|
120475
120747
|
this.deps.logger.error(options.describe(options.error), options.error);
|
|
120476
120748
|
if (options.userTurnId) {
|
|
120477
|
-
await this.
|
|
120749
|
+
await this.markTurnFailed(options.sessionId, options.sessionDoc, options.userTurnId);
|
|
120478
120750
|
}
|
|
120479
120751
|
await this.handleTurnError(options.sessionId, options.sessionDoc, options.error);
|
|
120480
120752
|
await options.onUnhandledError?.(options.error);
|
|
@@ -120810,8 +121082,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
120810
121082
|
await this.setUserTurnStatus(sessionDoc, userTurnId, "processing");
|
|
120811
121083
|
await this.upsertSessionMeta(sessionId, {
|
|
120812
121084
|
latestUserMsgId: userTurnId,
|
|
120813
|
-
processingUserMsgId: userTurnId
|
|
120814
|
-
dispatchError: void 0
|
|
121085
|
+
processingUserMsgId: userTurnId
|
|
120815
121086
|
});
|
|
120816
121087
|
}
|
|
120817
121088
|
async clearDispatchProcessing(sessionId) {
|
|
@@ -120860,34 +121131,31 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
120860
121131
|
await this.upsertSessionMeta(sessionId, {
|
|
120861
121132
|
latestUserMsgId: existingMeta?.latestUserMsgId ?? cancelledUserMsgId,
|
|
120862
121133
|
lastHandledUserMsgId: cancelledUserMsgId,
|
|
120863
|
-
processingUserMsgId: void 0
|
|
120864
|
-
dispatchError: void 0
|
|
121134
|
+
processingUserMsgId: void 0
|
|
120865
121135
|
});
|
|
120866
121136
|
return;
|
|
120867
121137
|
}
|
|
120868
121138
|
await this.clearDispatchProcessing(sessionId);
|
|
120869
121139
|
}
|
|
121140
|
+
resolveLatestUserMsgIdForTerminalTurn(meta, terminalUserTurnId) {
|
|
121141
|
+
return meta?.latestUserMsgId && meta.latestUserMsgId !== terminalUserTurnId ? meta.latestUserMsgId : terminalUserTurnId;
|
|
121142
|
+
}
|
|
120870
121143
|
async setDispatchHandled(sessionId, sessionDoc, userTurnId) {
|
|
121144
|
+
const existingMeta = await this.getSessionMeta(sessionId);
|
|
120871
121145
|
await this.setUserTurnStatus(sessionDoc, userTurnId, "handled");
|
|
120872
121146
|
await this.upsertSessionMeta(sessionId, {
|
|
120873
|
-
latestUserMsgId: userTurnId,
|
|
121147
|
+
latestUserMsgId: this.resolveLatestUserMsgIdForTerminalTurn(existingMeta, userTurnId),
|
|
120874
121148
|
lastHandledUserMsgId: userTurnId,
|
|
120875
|
-
processingUserMsgId: void 0
|
|
120876
|
-
dispatchError: void 0
|
|
121149
|
+
processingUserMsgId: void 0
|
|
120877
121150
|
});
|
|
120878
121151
|
}
|
|
120879
|
-
async
|
|
121152
|
+
async markTurnFailed(sessionId, sessionDoc, userTurnId) {
|
|
121153
|
+
const existingMeta = await this.getSessionMeta(sessionId);
|
|
120880
121154
|
await this.setUserTurnStatus(sessionDoc, userTurnId, "failed");
|
|
120881
121155
|
await this.upsertSessionMeta(sessionId, {
|
|
120882
|
-
latestUserMsgId: userTurnId,
|
|
120883
|
-
|
|
120884
|
-
|
|
120885
|
-
code: code2,
|
|
120886
|
-
...message ? {
|
|
120887
|
-
message
|
|
120888
|
-
} : {},
|
|
120889
|
-
at: getServerNow()
|
|
120890
|
-
}
|
|
121156
|
+
latestUserMsgId: this.resolveLatestUserMsgIdForTerminalTurn(existingMeta, userTurnId),
|
|
121157
|
+
lastHandledUserMsgId: userTurnId,
|
|
121158
|
+
processingUserMsgId: void 0
|
|
120891
121159
|
});
|
|
120892
121160
|
}
|
|
120893
121161
|
resolveGitHubProjectBranch(meta, preferredBranch) {
|
|
@@ -120981,15 +121249,18 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
120981
121249
|
}
|
|
120982
121250
|
async continueSession(message) {
|
|
120983
121251
|
const { sessionId, acpSessionConfig, userId, userName, userEmail, userTurnId } = message;
|
|
120984
|
-
await this.deps.evictForMemoryPressure(sessionId);
|
|
121252
|
+
const memoryPressureResult = await this.deps.evictForMemoryPressure(sessionId);
|
|
121253
|
+
if (memoryPressureResult.stillUnderPressure) {
|
|
121254
|
+
this.warnOnMemoryPressure(sessionId, memoryPressureResult);
|
|
121255
|
+
}
|
|
121256
|
+
await this.logTurnStartResources(sessionId, "continue");
|
|
121257
|
+
const sessionDoc = await this.deps.workspaceDocument.getOrCreateSessionDoc(sessionId);
|
|
120985
121258
|
this.deps.touchSession(sessionId);
|
|
120986
121259
|
this.deps.logger.info(`Session chat received: ${sessionId}`);
|
|
120987
121260
|
this.deps.logger.debug(`[${sessionId}] Received chat request (userTurnId=${userTurnId})`);
|
|
120988
121261
|
await this.upsertSessionMeta(sessionId, {
|
|
120989
|
-
latestUserMsgId: userTurnId
|
|
120990
|
-
dispatchError: void 0
|
|
121262
|
+
latestUserMsgId: userTurnId
|
|
120991
121263
|
});
|
|
120992
|
-
const sessionDoc = await this.deps.workspaceDocument.getOrCreateSessionDoc(sessionId);
|
|
120993
121264
|
const incomingProjectBranch = message.project?.branch?.trim();
|
|
120994
121265
|
if (incomingProjectBranch) {
|
|
120995
121266
|
await sessionDoc.setBaseBranch(incomingProjectBranch);
|
|
@@ -121326,7 +121597,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
121326
121597
|
}));
|
|
121327
121598
|
}
|
|
121328
121599
|
async startSession(message) {
|
|
121329
|
-
await this.deps.evictForMemoryPressure(message.sessionId);
|
|
121600
|
+
const memoryPressureResult = await this.deps.evictForMemoryPressure(message.sessionId);
|
|
121330
121601
|
const { sessionId, acpSessionConfig, workspaceId, env: env2 } = message;
|
|
121331
121602
|
const userTurnId = typeof message.userTurnId === "string" && message.userTurnId.trim() ? message.userTurnId.trim() : void 0;
|
|
121332
121603
|
const project = message.project;
|
|
@@ -121339,6 +121610,10 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
121339
121610
|
const promptText = agentConfig.prompt ?? "";
|
|
121340
121611
|
const promptBytes = Buffer.byteLength(promptText, "utf8");
|
|
121341
121612
|
const promptPreview = promptText.length > 200 ? `${promptText.slice(0, 200)}\u2026` : promptText;
|
|
121613
|
+
if (memoryPressureResult.stillUnderPressure) {
|
|
121614
|
+
this.warnOnMemoryPressure(sessionId, memoryPressureResult);
|
|
121615
|
+
}
|
|
121616
|
+
await this.logTurnStartResources(sessionId, "start");
|
|
121342
121617
|
const sessionDoc = await this.deps.workspaceDocument.getOrCreateSessionDoc(sessionId);
|
|
121343
121618
|
const existingMeta = await sessionDoc.getMetaState();
|
|
121344
121619
|
const fromFeedbackPostId = message.meta?.fromFeedbackPostId?.trim() || existingMeta?.fromFeedbackPostId?.trim() || void 0;
|
|
@@ -121362,12 +121637,6 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
121362
121637
|
fromFeedbackPostId
|
|
121363
121638
|
};
|
|
121364
121639
|
this.deps.logger.debug(`[${sessionId}] session/create summary`, configForLog);
|
|
121365
|
-
if (userTurnId) {
|
|
121366
|
-
await this.upsertSessionMeta(sessionId, {
|
|
121367
|
-
latestUserMsgId: userTurnId,
|
|
121368
|
-
dispatchError: void 0
|
|
121369
|
-
});
|
|
121370
|
-
}
|
|
121371
121640
|
const sessionConfig = {
|
|
121372
121641
|
sessionId,
|
|
121373
121642
|
workspaceId,
|
|
@@ -121388,6 +121657,11 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
121388
121657
|
if (project) {
|
|
121389
121658
|
await sessionDoc.setProject(project);
|
|
121390
121659
|
}
|
|
121660
|
+
if (userTurnId) {
|
|
121661
|
+
await this.upsertSessionMeta(sessionId, {
|
|
121662
|
+
latestUserMsgId: userTurnId
|
|
121663
|
+
});
|
|
121664
|
+
}
|
|
121391
121665
|
if (branch) {
|
|
121392
121666
|
await sessionDoc.setBaseBranch(branch);
|
|
121393
121667
|
}
|
|
@@ -122051,9 +122325,6 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
122051
122325
|
if (meta.lastCanceledTurn && meta.lastCanceledTurn !== this.cancelSeenTurn.get(meta.id)) {
|
|
122052
122326
|
return true;
|
|
122053
122327
|
}
|
|
122054
|
-
if (meta.dispatchError?.code === SessionDispatchWatcher.DISPATCH_HISTORY_SYNC_TIMEOUT_CODE) {
|
|
122055
|
-
return false;
|
|
122056
|
-
}
|
|
122057
122328
|
if (!meta.lastHandledUserMsgId) {
|
|
122058
122329
|
return true;
|
|
122059
122330
|
}
|
|
@@ -122149,12 +122420,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
122149
122420
|
await this.deps.workspaceDocument.repo.upsertDocMeta?.(getSessionRoomId(sessionId), {
|
|
122150
122421
|
latestUserMsgId: userTurnId,
|
|
122151
122422
|
lastHandledUserMsgId: userTurnId,
|
|
122152
|
-
processingUserMsgId: void 0
|
|
122153
|
-
dispatchError: {
|
|
122154
|
-
code: reason === "cli_token_invalid" ? "cli_token_invalid" : "machine_access_denied",
|
|
122155
|
-
message,
|
|
122156
|
-
at: getServerNow()
|
|
122157
|
-
}
|
|
122423
|
+
processingUserMsgId: void 0
|
|
122158
122424
|
});
|
|
122159
122425
|
await sessionDoc.setStatus(SessionStatusFactory.idle());
|
|
122160
122426
|
}
|
|
@@ -122284,7 +122550,6 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
122284
122550
|
static HISTORY_SYNC_WAIT_TIMEOUT_MS = 5 * 6e4;
|
|
122285
122551
|
static HISTORY_RECONNECT_JITTER_MIN_MS = 500;
|
|
122286
122552
|
static HISTORY_RECONNECT_JITTER_MAX_MS = 1500;
|
|
122287
|
-
static DISPATCH_HISTORY_SYNC_TIMEOUT_CODE = "dispatch_recovery_unhealthy";
|
|
122288
122553
|
static setUnrefTimeout(callback, delayMs) {
|
|
122289
122554
|
const timer2 = setTimeout(callback, delayMs);
|
|
122290
122555
|
if (typeof timer2 === "object" && "unref" in timer2) {
|
|
@@ -122333,23 +122598,20 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
122333
122598
|
}
|
|
122334
122599
|
return Boolean(meta.latestUserMsgId && meta.latestUserMsgId !== meta.lastHandledUserMsgId);
|
|
122335
122600
|
}
|
|
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
122601
|
async waitForPendingUserTurnHistorySync(sessionId, sessionDoc, meta) {
|
|
122344
122602
|
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
122603
|
try {
|
|
122348
122604
|
await sessionDoc.ensureDocRoomJoined();
|
|
122349
122605
|
} catch (error2) {
|
|
122350
122606
|
this.deps.logger.debug(`[${sessionId}] Failed to ensure session history room is joined before waiting: ${formatErrorMessage(error2)}`);
|
|
122351
122607
|
}
|
|
122352
|
-
|
|
122608
|
+
await sessionDoc.waitUntilSynced();
|
|
122609
|
+
const freshMeta = await sessionDoc.getMetaState() ?? meta;
|
|
122610
|
+
if (!this.hasPendingUserTurnSignal(freshMeta)) {
|
|
122611
|
+
this.deps.logger.debug(`[${sessionId}] Pending user turn pointer cleared during pre-wait sync; exiting wait`);
|
|
122612
|
+
return null;
|
|
122613
|
+
}
|
|
122614
|
+
const turnAfterJoin = await this.checkHistoryAndQueue(sessionDoc, freshMeta);
|
|
122353
122615
|
if (turnAfterJoin) {
|
|
122354
122616
|
return turnAfterJoin;
|
|
122355
122617
|
}
|
|
@@ -122367,18 +122629,11 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
122367
122629
|
unsubscribeMirror?.();
|
|
122368
122630
|
unsubscribeStatus?.();
|
|
122369
122631
|
};
|
|
122370
|
-
const updateWaitStatus = (detail) => {
|
|
122371
|
-
if (currentWaitDetail === detail) {
|
|
122372
|
-
return;
|
|
122373
|
-
}
|
|
122374
|
-
currentWaitDetail = detail;
|
|
122375
|
-
void this.setHistorySyncWaitStatus(sessionId, sessionDoc, detail);
|
|
122376
|
-
};
|
|
122377
122632
|
const checkForTurn = () => {
|
|
122378
122633
|
if (settled) {
|
|
122379
122634
|
return;
|
|
122380
122635
|
}
|
|
122381
|
-
void this.checkHistoryAndQueue(sessionDoc,
|
|
122636
|
+
void this.checkHistoryAndQueue(sessionDoc, freshMeta).then((turn) => {
|
|
122382
122637
|
if (settled || !turn) {
|
|
122383
122638
|
return;
|
|
122384
122639
|
}
|
|
@@ -122398,7 +122653,6 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
122398
122653
|
}
|
|
122399
122654
|
reconnectAttempted = true;
|
|
122400
122655
|
void (async () => {
|
|
122401
|
-
updateWaitStatus("reconnecting-history");
|
|
122402
122656
|
const jitterMs = SessionDispatchWatcher.getReconnectJitterMs();
|
|
122403
122657
|
this.deps.logger.debug(`[${sessionId}] Session history room ${reason}; attempting one rejoin in ${jitterMs}ms`);
|
|
122404
122658
|
await SessionDispatchWatcher.sleep(jitterMs);
|
|
@@ -122417,14 +122671,6 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
122417
122671
|
if (settled || !status) {
|
|
122418
122672
|
return;
|
|
122419
122673
|
}
|
|
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
122674
|
if (status === "disconnected" || status === "error") {
|
|
122429
122675
|
attemptReconnectOnce(status);
|
|
122430
122676
|
}
|
|
@@ -122461,16 +122707,15 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
122461
122707
|
if (meta.machineId !== this.deps.machineId || meta.isArchived || !this.hasPendingUserTurnSignal(meta)) {
|
|
122462
122708
|
return;
|
|
122463
122709
|
}
|
|
122464
|
-
|
|
122465
|
-
|
|
122466
|
-
|
|
122467
|
-
|
|
122468
|
-
|
|
122469
|
-
|
|
122470
|
-
|
|
122471
|
-
|
|
122472
|
-
|
|
122473
|
-
});
|
|
122710
|
+
const pendingUserMsgId = meta.processingUserMsgId ?? meta.latestUserMsgId ?? meta.lastHandledUserMsgId;
|
|
122711
|
+
const recoveryPatch = {
|
|
122712
|
+
status: SessionStatusFactory.idle()
|
|
122713
|
+
};
|
|
122714
|
+
if (pendingUserMsgId) {
|
|
122715
|
+
recoveryPatch.lastHandledUserMsgId = pendingUserMsgId;
|
|
122716
|
+
recoveryPatch.latestUserMsgId = pendingUserMsgId;
|
|
122717
|
+
}
|
|
122718
|
+
await this.deps.workspaceDocument.repo.upsertDocMeta?.(roomId, recoveryPatch);
|
|
122474
122719
|
const watched = this.watchedSessions.get(sessionId);
|
|
122475
122720
|
watched?.unsubscribe();
|
|
122476
122721
|
this.watchedSessions.delete(sessionId);
|
|
@@ -123217,8 +123462,14 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
123217
123462
|
permissionRequestStartTimes = /* @__PURE__ */ new Map();
|
|
123218
123463
|
machineHeartbeatTimer = null;
|
|
123219
123464
|
static MACHINE_HEARTBEAT_INTERVAL_MS = 2e4;
|
|
123220
|
-
evictForMemoryPressureFn = async () => {
|
|
123221
|
-
|
|
123465
|
+
evictForMemoryPressureFn = async () => ({
|
|
123466
|
+
availableMemoryBytes: 0,
|
|
123467
|
+
thresholdBytes: 0,
|
|
123468
|
+
hadMemoryPressure: false,
|
|
123469
|
+
stillUnderPressure: false,
|
|
123470
|
+
evictedSessionIds: [],
|
|
123471
|
+
pressureReason: null
|
|
123472
|
+
});
|
|
123222
123473
|
executionService;
|
|
123223
123474
|
sessionDispatchWatcher;
|
|
123224
123475
|
autoPromptRunner;
|
|
@@ -125230,6 +125481,16 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
125230
125481
|
hasPendingUpdates(sessionId) {
|
|
125231
125482
|
return this.store.has(sessionId) && this.store.get(sessionId).acpUpdateBuffer.length > 0;
|
|
125232
125483
|
}
|
|
125484
|
+
async hasPendingUserWork(sessionId) {
|
|
125485
|
+
const meta = (await this.workspaceDocument.repo.getDocMeta(getSessionRoomId(sessionId)))?.meta;
|
|
125486
|
+
if (!meta) {
|
|
125487
|
+
return false;
|
|
125488
|
+
}
|
|
125489
|
+
if (meta.processingUserMsgId) {
|
|
125490
|
+
return true;
|
|
125491
|
+
}
|
|
125492
|
+
return Boolean(meta.latestUserMsgId && meta.latestUserMsgId !== meta.lastHandledUserMsgId);
|
|
125493
|
+
}
|
|
125233
125494
|
isArchiveInFlight(sessionId) {
|
|
125234
125495
|
return this.archiveInFlight.has(sessionId);
|
|
125235
125496
|
}
|
|
@@ -125586,116 +125847,6 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
125586
125847
|
}
|
|
125587
125848
|
}
|
|
125588
125849
|
}
|
|
125589
|
-
function getAvailableMemoryBytes() {
|
|
125590
|
-
const systemAvailable = getSystemAvailableMemoryBytes();
|
|
125591
|
-
const cgroupAvailable = getCgroupAvailableMemoryBytes();
|
|
125592
|
-
if (cgroupAvailable !== null) {
|
|
125593
|
-
return Math.min(systemAvailable, cgroupAvailable);
|
|
125594
|
-
}
|
|
125595
|
-
return systemAvailable;
|
|
125596
|
-
}
|
|
125597
|
-
function getEffectiveMemoryLimitBytes() {
|
|
125598
|
-
const totalMem = os__default.totalmem();
|
|
125599
|
-
const cgroupMax = getCgroupMemoryMaxBytes();
|
|
125600
|
-
if (cgroupMax !== null) {
|
|
125601
|
-
return Math.min(totalMem, cgroupMax);
|
|
125602
|
-
}
|
|
125603
|
-
return totalMem;
|
|
125604
|
-
}
|
|
125605
|
-
function getSystemAvailableMemoryBytes() {
|
|
125606
|
-
try {
|
|
125607
|
-
const meminfo = readFileSync("/proc/meminfo", "utf8");
|
|
125608
|
-
const match5 = meminfo.match(/MemAvailable:\s+(\d+)/);
|
|
125609
|
-
if (match5?.[1]) {
|
|
125610
|
-
return parseInt(match5[1], 10) * 1024;
|
|
125611
|
-
}
|
|
125612
|
-
} catch {
|
|
125613
|
-
}
|
|
125614
|
-
return os__default.freemem();
|
|
125615
|
-
}
|
|
125616
|
-
function getCgroupMemoryMaxBytes() {
|
|
125617
|
-
try {
|
|
125618
|
-
const cgroupPath = readSelfCgroupPath();
|
|
125619
|
-
if (cgroupPath === null) return null;
|
|
125620
|
-
let tightest = null;
|
|
125621
|
-
let current2 = cgroupPath;
|
|
125622
|
-
for (let depth = 0; depth < 20; depth++) {
|
|
125623
|
-
const memMaxPath = `/sys/fs/cgroup${current2 === "/" ? "" : current2}/memory.max`;
|
|
125624
|
-
const raw = readFileSafe(memMaxPath);
|
|
125625
|
-
if (raw !== null) {
|
|
125626
|
-
const trimmed = raw.trim();
|
|
125627
|
-
if (trimmed !== "max") {
|
|
125628
|
-
const value = parseInt(trimmed, 10);
|
|
125629
|
-
if (Number.isFinite(value) && value > 0) {
|
|
125630
|
-
tightest = tightest === null ? value : Math.min(tightest, value);
|
|
125631
|
-
}
|
|
125632
|
-
}
|
|
125633
|
-
}
|
|
125634
|
-
if (current2 === "/" || current2 === "") break;
|
|
125635
|
-
const parent = current2.substring(0, current2.lastIndexOf("/")) || "/";
|
|
125636
|
-
if (parent === current2) break;
|
|
125637
|
-
current2 = parent;
|
|
125638
|
-
}
|
|
125639
|
-
return tightest;
|
|
125640
|
-
} catch {
|
|
125641
|
-
return null;
|
|
125642
|
-
}
|
|
125643
|
-
}
|
|
125644
|
-
function getCgroupAvailableMemoryBytes() {
|
|
125645
|
-
try {
|
|
125646
|
-
const cgroupPath = readSelfCgroupPath();
|
|
125647
|
-
if (cgroupPath === null) return null;
|
|
125648
|
-
let tightestMax = null;
|
|
125649
|
-
let tightestPath = null;
|
|
125650
|
-
let current2 = cgroupPath;
|
|
125651
|
-
for (let depth = 0; depth < 20; depth++) {
|
|
125652
|
-
const prefix = `/sys/fs/cgroup${current2 === "/" ? "" : current2}`;
|
|
125653
|
-
const raw = readFileSafe(`${prefix}/memory.max`);
|
|
125654
|
-
if (raw !== null) {
|
|
125655
|
-
const trimmed = raw.trim();
|
|
125656
|
-
if (trimmed !== "max") {
|
|
125657
|
-
const value = parseInt(trimmed, 10);
|
|
125658
|
-
if (Number.isFinite(value) && value > 0) {
|
|
125659
|
-
if (tightestMax === null || value < tightestMax) {
|
|
125660
|
-
tightestMax = value;
|
|
125661
|
-
tightestPath = prefix;
|
|
125662
|
-
}
|
|
125663
|
-
}
|
|
125664
|
-
}
|
|
125665
|
-
}
|
|
125666
|
-
if (current2 === "/" || current2 === "") break;
|
|
125667
|
-
const parent = current2.substring(0, current2.lastIndexOf("/")) || "/";
|
|
125668
|
-
if (parent === current2) break;
|
|
125669
|
-
current2 = parent;
|
|
125670
|
-
}
|
|
125671
|
-
if (tightestMax === null || tightestPath === null) return null;
|
|
125672
|
-
const currentRaw = readFileSafe(`${tightestPath}/memory.current`);
|
|
125673
|
-
if (currentRaw === null) return null;
|
|
125674
|
-
const currentUsage = parseInt(currentRaw.trim(), 10);
|
|
125675
|
-
if (!Number.isFinite(currentUsage)) return null;
|
|
125676
|
-
return Math.max(0, tightestMax - currentUsage);
|
|
125677
|
-
} catch {
|
|
125678
|
-
return null;
|
|
125679
|
-
}
|
|
125680
|
-
}
|
|
125681
|
-
function readSelfCgroupPath() {
|
|
125682
|
-
try {
|
|
125683
|
-
const content = readFileSync("/proc/self/cgroup", "utf8");
|
|
125684
|
-
const line3 = content.split("\n").map((l) => l.trim()).find((l) => l.startsWith("0::"));
|
|
125685
|
-
if (!line3) return null;
|
|
125686
|
-
const cgroupPath = line3.slice(3).trim();
|
|
125687
|
-
return cgroupPath || "/";
|
|
125688
|
-
} catch {
|
|
125689
|
-
return null;
|
|
125690
|
-
}
|
|
125691
|
-
}
|
|
125692
|
-
function readFileSafe(filePath) {
|
|
125693
|
-
try {
|
|
125694
|
-
return readFileSync(filePath, "utf8");
|
|
125695
|
-
} catch {
|
|
125696
|
-
return null;
|
|
125697
|
-
}
|
|
125698
|
-
}
|
|
125699
125850
|
function readEnvNumber(key2, fallback2) {
|
|
125700
125851
|
const raw = process.env[key2];
|
|
125701
125852
|
if (!raw) return fallback2;
|
|
@@ -125703,6 +125854,8 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
125703
125854
|
return Number.isFinite(parsed) ? parsed : fallback2;
|
|
125704
125855
|
}
|
|
125705
125856
|
const GIB = 1024 * 1024 * 1024;
|
|
125857
|
+
const WINDOWS_COMMIT_THRESHOLD_FLOOR_BYTES = 512 * 1024 * 1024;
|
|
125858
|
+
const WINDOWS_COMMIT_THRESHOLD_CEILING_BYTES = 2 * GIB;
|
|
125706
125859
|
function defaultMemoryThresholdBytes() {
|
|
125707
125860
|
const tenPercent = Math.floor(getEffectiveMemoryLimitBytes() * 0.1);
|
|
125708
125861
|
return Math.max(GIB, Math.min(4 * GIB, tenPercent));
|
|
@@ -125715,6 +125868,9 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
125715
125868
|
memoryThresholdBytes: readEnvNumber("LODY_SESSION_GC_MEMORY_THRESHOLD_BYTES", defaultMemoryThresholdBytes())
|
|
125716
125869
|
};
|
|
125717
125870
|
}
|
|
125871
|
+
function getWindowsCommitThresholdBytes(memoryThresholdBytes) {
|
|
125872
|
+
return Math.max(WINDOWS_COMMIT_THRESHOLD_FLOOR_BYTES, Math.min(WINDOWS_COMMIT_THRESHOLD_CEILING_BYTES, memoryThresholdBytes));
|
|
125873
|
+
}
|
|
125718
125874
|
class SessionGCManager {
|
|
125719
125875
|
constructor(config2, deps) {
|
|
125720
125876
|
this.config = config2;
|
|
@@ -125738,7 +125894,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
125738
125894
|
}
|
|
125739
125895
|
async sweep() {
|
|
125740
125896
|
const sweepStart = Date.now();
|
|
125741
|
-
const candidates = this.getIdleCandidates();
|
|
125897
|
+
const candidates = await this.getIdleCandidates();
|
|
125742
125898
|
if (candidates.length === 0) {
|
|
125743
125899
|
return;
|
|
125744
125900
|
}
|
|
@@ -125746,7 +125902,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
125746
125902
|
let cleaned = 0;
|
|
125747
125903
|
let skipped = 0;
|
|
125748
125904
|
for (const { sessionId } of candidates) {
|
|
125749
|
-
if (!this.isStillEligibleForGC(sessionId)) {
|
|
125905
|
+
if (!await this.isStillEligibleForGC(sessionId)) {
|
|
125750
125906
|
skipped++;
|
|
125751
125907
|
continue;
|
|
125752
125908
|
}
|
|
@@ -125764,19 +125920,50 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
125764
125920
|
this.deps.logger.debug(`[GC] Sweep completed: cleaned ${cleaned}/${candidates.length} sessions in ${sweepDuration}ms`);
|
|
125765
125921
|
}
|
|
125766
125922
|
async evictForMemoryPressure(excludeSessionId) {
|
|
125923
|
+
const thresholdBytes = this.config.memoryThresholdBytes;
|
|
125924
|
+
const commitThresholdBytes = getWindowsCommitThresholdBytes(thresholdBytes);
|
|
125925
|
+
let memorySnapshot = getMemoryPressureSnapshot();
|
|
125926
|
+
let availableMemory = memorySnapshot.availableMemoryBytes;
|
|
125927
|
+
let pressureReason = this.getPressureReason(memorySnapshot, thresholdBytes, commitThresholdBytes);
|
|
125767
125928
|
if (!this.config.enabled) {
|
|
125768
|
-
return
|
|
125929
|
+
return {
|
|
125930
|
+
availableMemoryBytes: availableMemory,
|
|
125931
|
+
thresholdBytes,
|
|
125932
|
+
hadMemoryPressure: false,
|
|
125933
|
+
stillUnderPressure: false,
|
|
125934
|
+
evictedSessionIds: [],
|
|
125935
|
+
pressureReason: null,
|
|
125936
|
+
...memorySnapshot.availableCommitBytes !== void 0 ? {
|
|
125937
|
+
availableCommitBytes: memorySnapshot.availableCommitBytes,
|
|
125938
|
+
commitThresholdBytes,
|
|
125939
|
+
commitLimitBytes: memorySnapshot.commitLimitBytes,
|
|
125940
|
+
committedBytes: memorySnapshot.committedBytes
|
|
125941
|
+
} : {}
|
|
125942
|
+
};
|
|
125769
125943
|
}
|
|
125770
|
-
|
|
125771
|
-
|
|
125772
|
-
|
|
125944
|
+
if (pressureReason === null) {
|
|
125945
|
+
return {
|
|
125946
|
+
availableMemoryBytes: availableMemory,
|
|
125947
|
+
thresholdBytes,
|
|
125948
|
+
hadMemoryPressure: false,
|
|
125949
|
+
stillUnderPressure: false,
|
|
125950
|
+
evictedSessionIds: [],
|
|
125951
|
+
pressureReason: null,
|
|
125952
|
+
...memorySnapshot.availableCommitBytes !== void 0 ? {
|
|
125953
|
+
availableCommitBytes: memorySnapshot.availableCommitBytes,
|
|
125954
|
+
commitThresholdBytes,
|
|
125955
|
+
commitLimitBytes: memorySnapshot.commitLimitBytes,
|
|
125956
|
+
committedBytes: memorySnapshot.committedBytes
|
|
125957
|
+
} : {}
|
|
125958
|
+
};
|
|
125773
125959
|
}
|
|
125774
|
-
|
|
125960
|
+
const commitText = memorySnapshot.availableCommitBytes !== void 0 ? `, commit headroom ${Math.round(memorySnapshot.availableCommitBytes / 1024 / 1024)}MB (threshold: ${Math.round(commitThresholdBytes / 1024 / 1024)}MB)` : "";
|
|
125961
|
+
this.deps.logger.debug(`[GC] Memory pressure detected: ${Math.round(availableMemory / 1024 / 1024)}MB available (threshold: ${Math.round(thresholdBytes / 1024 / 1024)}MB)${commitText}`);
|
|
125775
125962
|
const sessions = this.getSessionsWithIdleTime();
|
|
125776
125963
|
sessions.sort((a, b) => b.idleMs - a.idleMs);
|
|
125777
|
-
|
|
125964
|
+
const evictedSessionIds = [];
|
|
125778
125965
|
for (const { sessionId, idleMs } of sessions) {
|
|
125779
|
-
if (
|
|
125966
|
+
if (pressureReason === null) {
|
|
125780
125967
|
break;
|
|
125781
125968
|
}
|
|
125782
125969
|
if (excludeSessionId && sessionId === excludeSessionId) {
|
|
@@ -125785,30 +125972,63 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
125785
125972
|
if (idleMs === 0) {
|
|
125786
125973
|
continue;
|
|
125787
125974
|
}
|
|
125788
|
-
if (!this.isEligibleForCleanup(sessionId)) {
|
|
125975
|
+
if (!await this.isEligibleForCleanup(sessionId)) {
|
|
125789
125976
|
continue;
|
|
125790
125977
|
}
|
|
125791
125978
|
try {
|
|
125792
125979
|
this.deps.logger.debug(`[GC] Evicting session ${sessionId} (idle ${Math.round(idleMs / 1e3)}s) due to memory pressure`);
|
|
125793
125980
|
await this.deps.cleanSession(sessionId);
|
|
125794
|
-
|
|
125795
|
-
|
|
125981
|
+
evictedSessionIds.push(sessionId);
|
|
125982
|
+
memorySnapshot = getMemoryPressureSnapshot();
|
|
125983
|
+
availableMemory = memorySnapshot.availableMemoryBytes;
|
|
125984
|
+
pressureReason = this.getPressureReason(memorySnapshot, thresholdBytes, commitThresholdBytes);
|
|
125796
125985
|
} catch (error2) {
|
|
125797
125986
|
this.deps.logger.error(`[GC] Failed to evict session ${sessionId}: ${formatErrorMessage(error2)}`);
|
|
125798
125987
|
}
|
|
125799
125988
|
}
|
|
125800
|
-
|
|
125801
|
-
|
|
125989
|
+
const stillUnderPressure = pressureReason !== null;
|
|
125990
|
+
if (evictedSessionIds.length > 0) {
|
|
125991
|
+
this.deps.logger.debug(`[GC] Memory pressure eviction complete: evicted ${evictedSessionIds.length} sessions, available memory now ${Math.round(availableMemory / 1024 / 1024)}MB`);
|
|
125992
|
+
} else if (stillUnderPressure) {
|
|
125993
|
+
this.deps.logger.debug("[GC] Memory pressure persists but no idle sessions were eligible for eviction");
|
|
125994
|
+
}
|
|
125995
|
+
return {
|
|
125996
|
+
availableMemoryBytes: availableMemory,
|
|
125997
|
+
thresholdBytes,
|
|
125998
|
+
hadMemoryPressure: true,
|
|
125999
|
+
stillUnderPressure,
|
|
126000
|
+
evictedSessionIds,
|
|
126001
|
+
pressureReason,
|
|
126002
|
+
...memorySnapshot.availableCommitBytes !== void 0 ? {
|
|
126003
|
+
availableCommitBytes: memorySnapshot.availableCommitBytes,
|
|
126004
|
+
commitThresholdBytes,
|
|
126005
|
+
commitLimitBytes: memorySnapshot.commitLimitBytes,
|
|
126006
|
+
committedBytes: memorySnapshot.committedBytes
|
|
126007
|
+
} : {}
|
|
126008
|
+
};
|
|
126009
|
+
}
|
|
126010
|
+
getPressureReason(snapshot, thresholdBytes, commitThresholdBytes) {
|
|
126011
|
+
const physicalPressure = snapshot.availableMemoryBytes < thresholdBytes;
|
|
126012
|
+
const commitPressure = snapshot.availableCommitBytes !== void 0 && snapshot.availableCommitBytes < commitThresholdBytes;
|
|
126013
|
+
if (physicalPressure && commitPressure) {
|
|
126014
|
+
return "physical_and_commit";
|
|
126015
|
+
}
|
|
126016
|
+
if (physicalPressure) {
|
|
126017
|
+
return "physical";
|
|
125802
126018
|
}
|
|
126019
|
+
if (commitPressure) {
|
|
126020
|
+
return "commit";
|
|
126021
|
+
}
|
|
126022
|
+
return null;
|
|
125803
126023
|
}
|
|
125804
|
-
getIdleCandidates() {
|
|
126024
|
+
async getIdleCandidates() {
|
|
125805
126025
|
const sessions = this.getSessionsWithIdleTime();
|
|
125806
126026
|
const candidates = [];
|
|
125807
126027
|
for (const session of sessions) {
|
|
125808
126028
|
if (session.idleMs < this.config.idleTimeoutMs) {
|
|
125809
126029
|
continue;
|
|
125810
126030
|
}
|
|
125811
|
-
if (!this.isEligibleForCleanup(session.sessionId)) {
|
|
126031
|
+
if (!await this.isEligibleForCleanup(session.sessionId)) {
|
|
125812
126032
|
continue;
|
|
125813
126033
|
}
|
|
125814
126034
|
candidates.push(session);
|
|
@@ -125836,20 +126056,23 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
125836
126056
|
}
|
|
125837
126057
|
return result;
|
|
125838
126058
|
}
|
|
125839
|
-
isEligibleForCleanup(sessionId) {
|
|
126059
|
+
async isEligibleForCleanup(sessionId) {
|
|
125840
126060
|
if (this.deps.hasActiveTurn(sessionId)) {
|
|
125841
126061
|
return false;
|
|
125842
126062
|
}
|
|
125843
126063
|
if (this.deps.hasPendingUpdates(sessionId)) {
|
|
125844
126064
|
return false;
|
|
125845
126065
|
}
|
|
126066
|
+
if (await this.deps.hasPendingUserWork(sessionId)) {
|
|
126067
|
+
return false;
|
|
126068
|
+
}
|
|
125846
126069
|
if (this.deps.isArchiveInFlight(sessionId)) {
|
|
125847
126070
|
return false;
|
|
125848
126071
|
}
|
|
125849
126072
|
return true;
|
|
125850
126073
|
}
|
|
125851
|
-
isStillEligibleForGC(sessionId) {
|
|
125852
|
-
if (!this.isEligibleForCleanup(sessionId)) {
|
|
126074
|
+
async isStillEligibleForGC(sessionId) {
|
|
126075
|
+
if (!await this.isEligibleForCleanup(sessionId)) {
|
|
125853
126076
|
return false;
|
|
125854
126077
|
}
|
|
125855
126078
|
const lastActivity = this.deps.getSessionLastActivity(sessionId);
|
|
@@ -125977,6 +126200,7 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
125977
126200
|
getSessionLastActivity: (sessionId) => handler.getLastActivity(sessionId),
|
|
125978
126201
|
hasActiveTurn: (sessionId) => handler.hasActiveTurn(sessionId),
|
|
125979
126202
|
hasPendingUpdates: (sessionId) => handler.hasPendingUpdates(sessionId),
|
|
126203
|
+
hasPendingUserWork: async (sessionId) => await handler.hasPendingUserWork(sessionId),
|
|
125980
126204
|
isArchiveInFlight: (sessionId) => handler.isArchiveInFlight(sessionId),
|
|
125981
126205
|
cleanSession: (sessionId) => handler.cleanSessionForGC(sessionId),
|
|
125982
126206
|
getSessionIds: () => handler.getTrackedSessionIds(),
|
|
@@ -125985,8 +126209,16 @@ The postId is ${normalizedFeedbackPostId}. Use the feedback-progress-reporter sk
|
|
|
125985
126209
|
this.gcManager.start();
|
|
125986
126210
|
handler.setEvictForMemoryPressure(async (excludeSessionId) => {
|
|
125987
126211
|
if (this.gcManager) {
|
|
125988
|
-
await this.gcManager.evictForMemoryPressure(excludeSessionId);
|
|
126212
|
+
return await this.gcManager.evictForMemoryPressure(excludeSessionId);
|
|
125989
126213
|
}
|
|
126214
|
+
return {
|
|
126215
|
+
availableMemoryBytes: 0,
|
|
126216
|
+
thresholdBytes: 0,
|
|
126217
|
+
hadMemoryPressure: false,
|
|
126218
|
+
stillUnderPressure: false,
|
|
126219
|
+
evictedSessionIds: [],
|
|
126220
|
+
pressureReason: null
|
|
126221
|
+
};
|
|
125990
126222
|
});
|
|
125991
126223
|
}
|
|
125992
126224
|
requireSessionManager() {
|
|
@@ -133184,6 +133416,9 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
|
|
|
133184
133416
|
isControlPlaneReady() {
|
|
133185
133417
|
return this.documentManager.isTransportConnected();
|
|
133186
133418
|
}
|
|
133419
|
+
isControlPlaneRecovering() {
|
|
133420
|
+
return this.documentManager.isTransportRecovering();
|
|
133421
|
+
}
|
|
133187
133422
|
getActiveSessionCount() {
|
|
133188
133423
|
return this.runtime.getActiveSessionCount();
|
|
133189
133424
|
}
|
|
@@ -135013,23 +135248,26 @@ export PATH=${toSingleQuotedShellString(ghShimBinDir)}:"$PATH"
|
|
|
135013
135248
|
refreshRuntimeState() {
|
|
135014
135249
|
const desiredCount = this.desiredWorkspaces.size;
|
|
135015
135250
|
let connectedCount = 0;
|
|
135251
|
+
let reconnectingCount = 0;
|
|
135016
135252
|
let totalActiveSessions = 0;
|
|
135017
135253
|
let totalConnectedRooms = 0;
|
|
135018
135254
|
for (const runtime of this.runtimes.values()) {
|
|
135019
135255
|
if (runtime.lody.isControlPlaneReady()) {
|
|
135020
135256
|
connectedCount += 1;
|
|
135257
|
+
} else if (runtime.lody.isControlPlaneRecovering()) {
|
|
135258
|
+
reconnectingCount += 1;
|
|
135021
135259
|
}
|
|
135022
135260
|
totalActiveSessions += runtime.lody.getActiveSessionCount();
|
|
135023
135261
|
totalConnectedRooms += runtime.lody.getConnectedRoomCount();
|
|
135024
135262
|
}
|
|
135025
135263
|
this.runtimeStateReporter.setActiveSessionCount(totalActiveSessions);
|
|
135026
135264
|
this.runtimeStateReporter.setConnectedRoomCount(totalConnectedRooms);
|
|
135027
|
-
const
|
|
135265
|
+
const hasWorkspaceRetry = this.retryTimers.size > 0 || this.startInFlight.size > 0;
|
|
135266
|
+
const nextConnectivity = desiredCount === 0 ? "online" : connectedCount === desiredCount ? "online" : reconnectingCount > 0 || hasWorkspaceRetry ? "reconnecting" : "offline";
|
|
135028
135267
|
if (this.lastConnectivity !== nextConnectivity) {
|
|
135029
135268
|
this.lastConnectivity = nextConnectivity;
|
|
135030
135269
|
this.runtimeStateReporter.setConnectivity(nextConnectivity);
|
|
135031
135270
|
}
|
|
135032
|
-
const hasWorkspaceRetry = this.retryTimers.size > 0 || this.startInFlight.size > 0;
|
|
135033
135271
|
if (hasWorkspaceRetry && !this.hasWorkspaceRetryIssue) {
|
|
135034
135272
|
this.hasWorkspaceRetryIssue = true;
|
|
135035
135273
|
this.runtimeStateReporter.upsertIssue({
|
|
@@ -167312,10 +167550,18 @@ ${entry2.text}`).join("\n\n");
|
|
|
167312
167550
|
}
|
|
167313
167551
|
const DEFAULT_MIN_RETRY_MS$1 = 1e3;
|
|
167314
167552
|
const DEFAULT_MAX_RETRY_MS$1 = 3e4;
|
|
167315
|
-
|
|
167553
|
+
const DEFAULT_JITTER_FRACTION = 0.2;
|
|
167554
|
+
function buildRetryDelay(attempt, minMs = DEFAULT_MIN_RETRY_MS$1, maxMs = DEFAULT_MAX_RETRY_MS$1, options = {}) {
|
|
167316
167555
|
const exponent = Math.max(0, attempt);
|
|
167317
|
-
const
|
|
167318
|
-
|
|
167556
|
+
const baseDelay = Math.min(minMs * 2 ** exponent, maxMs);
|
|
167557
|
+
const jitterFraction = Math.max(0, options.jitterFraction ?? DEFAULT_JITTER_FRACTION);
|
|
167558
|
+
if (jitterFraction === 0) {
|
|
167559
|
+
return baseDelay;
|
|
167560
|
+
}
|
|
167561
|
+
const random2 = options.random ?? Math.random;
|
|
167562
|
+
const randomValue = Math.min(1, Math.max(0, random2()));
|
|
167563
|
+
const jitterMultiplier = 1 + (randomValue * 2 - 1) * jitterFraction;
|
|
167564
|
+
return Math.min(Math.max(0, Math.round(baseDelay * jitterMultiplier)), maxMs);
|
|
167319
167565
|
}
|
|
167320
167566
|
class FailureWindow {
|
|
167321
167567
|
historyMs = [];
|
|
@@ -167376,6 +167622,7 @@ ${result.stderr}`;
|
|
|
167376
167622
|
probeFailureThreshold;
|
|
167377
167623
|
minRetryMs;
|
|
167378
167624
|
maxRetryMs;
|
|
167625
|
+
retryRandom;
|
|
167379
167626
|
failureWindow;
|
|
167380
167627
|
triggered = false;
|
|
167381
167628
|
inFlight = false;
|
|
@@ -167407,6 +167654,7 @@ ${result.stderr}`;
|
|
|
167407
167654
|
this.probeFailureThreshold = options.probeFailureThreshold ?? DEFAULT_PROBE_FAILURE_THRESHOLD;
|
|
167408
167655
|
this.minRetryMs = options.minRetryMs ?? DEFAULT_MIN_RETRY_MS;
|
|
167409
167656
|
this.maxRetryMs = options.maxRetryMs ?? DEFAULT_MAX_RETRY_MS;
|
|
167657
|
+
this.retryRandom = options.retryRandom ?? Math.random;
|
|
167410
167658
|
this.failureWindow = new FailureWindow(options.fatalFailureWindowMs ?? DEFAULT_FATAL_FAILURE_WINDOW_MS, options.fatalFailureThreshold ?? DEFAULT_FATAL_FAILURE_THRESHOLD);
|
|
167411
167659
|
}
|
|
167412
167660
|
getState() {
|
|
@@ -167486,6 +167734,9 @@ ${result.stderr}`;
|
|
|
167486
167734
|
this.latestRuntimeState = runtimeState;
|
|
167487
167735
|
this.probeFailureCount = 0;
|
|
167488
167736
|
this.probeUnavailable = false;
|
|
167737
|
+
this.clearRetryTimer();
|
|
167738
|
+
this.attempt = 0;
|
|
167739
|
+
this.failureWindow.reset();
|
|
167489
167740
|
this.lastStateMessage = void 0;
|
|
167490
167741
|
} else {
|
|
167491
167742
|
this.probeFailureCount += 1;
|
|
@@ -167506,7 +167757,9 @@ ${result.stderr}`;
|
|
|
167506
167757
|
} else if (this.fatalReason) {
|
|
167507
167758
|
phase = "fatal";
|
|
167508
167759
|
} else if (runtime) {
|
|
167509
|
-
phase = runtime.phase === "fatal" ? "fatal" : runtime.phase;
|
|
167760
|
+
phase = runtime.phase === "fatal" ? "fatal" : runtime.connectivity === "reconnecting" ? "reconnecting" : runtime.phase;
|
|
167761
|
+
} else if (this.retryTimer) {
|
|
167762
|
+
phase = "reconnecting";
|
|
167510
167763
|
} else if (childRunning) {
|
|
167511
167764
|
phase = this.probeUnavailable ? "offline" : "starting";
|
|
167512
167765
|
} else if (this.probeUnavailable && !this.inFlight && !this.retryTimer) {
|
|
@@ -167563,7 +167816,9 @@ ${result.stderr}`;
|
|
|
167563
167816
|
scheduleRetry(reason, recordFailure = true) {
|
|
167564
167817
|
if (this.fatalReason) return;
|
|
167565
167818
|
if (recordFailure && this.recordFailure(reason)) return;
|
|
167566
|
-
const delay2 = buildRetryDelay(this.attempt, this.minRetryMs, this.maxRetryMs
|
|
167819
|
+
const delay2 = buildRetryDelay(this.attempt, this.minRetryMs, this.maxRetryMs, {
|
|
167820
|
+
random: this.retryRandom
|
|
167821
|
+
});
|
|
167567
167822
|
this.attempt += 1;
|
|
167568
167823
|
this.clearRetryTimer();
|
|
167569
167824
|
this.pendingRetryInMs = delay2;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lody",
|
|
3
|
-
"version": "0.44.
|
|
3
|
+
"version": "0.44.4-next.1",
|
|
4
4
|
"description": "Lody Agent CLI tool for managing remote command execution",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -72,11 +72,11 @@
|
|
|
72
72
|
"winston-transport": "^4.7.1",
|
|
73
73
|
"ws": "^8.18.3",
|
|
74
74
|
"zod": "^4.1.5",
|
|
75
|
-
"@lody/cli-supervisor": "0.0.1",
|
|
76
75
|
"@lody/convex": "0.0.1",
|
|
77
|
-
"@lody/loro-streams-rpc": "0.0.1",
|
|
78
76
|
"@lody/shared": "0.0.1",
|
|
79
|
-
"loro-code": "0.0.1"
|
|
77
|
+
"loro-code": "0.0.1",
|
|
78
|
+
"@lody/cli-supervisor": "0.0.1",
|
|
79
|
+
"@lody/loro-streams-rpc": "0.0.1"
|
|
80
80
|
},
|
|
81
81
|
"files": [
|
|
82
82
|
"dist",
|