@vtxmacro/cli 2026.8.20 → 2026.8.22
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/bin/vtx.js +341 -103
- package/package.json +1 -1
package/bin/vtx.js
CHANGED
|
@@ -38,7 +38,7 @@ var init_agent_cli_release = __esm({
|
|
|
38
38
|
"agent-cli-release.json"() {
|
|
39
39
|
agent_cli_release_default = {
|
|
40
40
|
package_name: "@vtxmacro/cli",
|
|
41
|
-
package_version: "2026.8.
|
|
41
|
+
package_version: "2026.8.22",
|
|
42
42
|
codex_package_name: "@openai/codex",
|
|
43
43
|
codex_version: "0.147.0",
|
|
44
44
|
platforms: {
|
|
@@ -19837,6 +19837,9 @@ child.once('close', async () => {
|
|
|
19837
19837
|
this.fatalListeners.add(listener);
|
|
19838
19838
|
return () => this.fatalListeners.delete(listener);
|
|
19839
19839
|
}
|
|
19840
|
+
isUsable() {
|
|
19841
|
+
return !this.closed && this.fatalError === null && this.process.exitCode === null;
|
|
19842
|
+
}
|
|
19840
19843
|
async readAccountSnapshot(deadlineAtMs, signal, refreshToken = false) {
|
|
19841
19844
|
const result2 = await this.request("account/read", { refreshToken }, {
|
|
19842
19845
|
timeoutMs: Math.max(1, deadlineAtMs - Date.now()),
|
|
@@ -20196,6 +20199,30 @@ child.once('close', async () => {
|
|
|
20196
20199
|
});
|
|
20197
20200
|
const startedAt = Date.now();
|
|
20198
20201
|
const unsubscribe = this.subscribe(({ method, params }) => {
|
|
20202
|
+
const eventThreadId = String(params.threadId || "");
|
|
20203
|
+
const scopedMethod = method.startsWith("thread/") || method.startsWith("turn/") || method.startsWith("item/") || method.startsWith("rawResponse") || method === "model/rerouted";
|
|
20204
|
+
if (scopedMethod && !eventThreadId) {
|
|
20205
|
+
terminalReject(new CodexAppServerError({
|
|
20206
|
+
message: "Codex notification omitted its thread scope.",
|
|
20207
|
+
category: "adapter",
|
|
20208
|
+
code: "missing_thread_notification_scope",
|
|
20209
|
+
retryable: false,
|
|
20210
|
+
dispatchOutcome: requestWritten ? turnId ? "confirmed_dispatched" : "outcome_unknown" : "not_dispatched"
|
|
20211
|
+
}));
|
|
20212
|
+
return;
|
|
20213
|
+
}
|
|
20214
|
+
if (scopedMethod && eventThreadId !== request.thread.threadId) {
|
|
20215
|
+
if (!this.threads.has(eventThreadId)) {
|
|
20216
|
+
terminalReject(new CodexAppServerError({
|
|
20217
|
+
message: "Codex notification crossed thread scope.",
|
|
20218
|
+
category: "adapter",
|
|
20219
|
+
code: "cross_thread_notification",
|
|
20220
|
+
retryable: false,
|
|
20221
|
+
dispatchOutcome: turnId ? "confirmed_dispatched" : "outcome_unknown"
|
|
20222
|
+
}));
|
|
20223
|
+
}
|
|
20224
|
+
return;
|
|
20225
|
+
}
|
|
20199
20226
|
if (forbiddenMethod(method)) {
|
|
20200
20227
|
terminalReject(new CodexAppServerError({
|
|
20201
20228
|
message: "Codex attempted to use forbidden child authority.",
|
|
@@ -20231,18 +20258,6 @@ child.once('close', async () => {
|
|
|
20231
20258
|
return;
|
|
20232
20259
|
}
|
|
20233
20260
|
}
|
|
20234
|
-
const eventThreadId = String(params.threadId || "");
|
|
20235
|
-
const scopedMethod = method.startsWith("thread/") || method.startsWith("turn/") || method.startsWith("item/") || method.startsWith("rawResponse") || method === "model/rerouted";
|
|
20236
|
-
if (scopedMethod && eventThreadId !== request.thread.threadId) {
|
|
20237
|
-
terminalReject(new CodexAppServerError({
|
|
20238
|
-
message: "Codex notification crossed thread scope.",
|
|
20239
|
-
category: "adapter",
|
|
20240
|
-
code: "cross_thread_notification",
|
|
20241
|
-
retryable: false,
|
|
20242
|
-
dispatchOutcome: turnId ? "confirmed_dispatched" : "outcome_unknown"
|
|
20243
|
-
}));
|
|
20244
|
-
return;
|
|
20245
|
-
}
|
|
20246
20261
|
const eventTurn = objectOrNull(params.turn);
|
|
20247
20262
|
const eventTurnId = String(params.turnId || eventTurn?.id || "");
|
|
20248
20263
|
const turnScopedMethod = method.startsWith("turn/") || method.startsWith("item/") || method.startsWith("rawResponse") || method === "model/rerouted";
|
|
@@ -20884,7 +20899,7 @@ var init_codex_adapter = __esm({
|
|
|
20884
20899
|
context.addIssue({ code: "custom", message: "Codex recovery thread identity is incomplete." });
|
|
20885
20900
|
}
|
|
20886
20901
|
const guardianManaged = value.processToken !== null || value.processReceiptPath !== null;
|
|
20887
|
-
if (value.processToken === null !== (value.processReceiptPath === null) || value.processState === "unmanaged" === guardianManaged || value.cleanupConfirmed &&
|
|
20902
|
+
if (value.processToken === null !== (value.processReceiptPath === null) || value.processState === "unmanaged" === guardianManaged || value.cleanupConfirmed && value.processState === "spawn_intent") {
|
|
20888
20903
|
context.addIssue({ code: "custom", message: "Codex recovery process identity is invalid." });
|
|
20889
20904
|
}
|
|
20890
20905
|
});
|
|
@@ -21293,8 +21308,115 @@ var init_codex_adapter = __esm({
|
|
|
21293
21308
|
CodexSubscriptionAdapter = class {
|
|
21294
21309
|
constructor(dependencies = {}) {
|
|
21295
21310
|
this.inFlightAttempts = /* @__PURE__ */ new Map();
|
|
21311
|
+
this.attemptCleanups = /* @__PURE__ */ new Map();
|
|
21312
|
+
this.durableSession = null;
|
|
21313
|
+
this.durableSessionStart = null;
|
|
21314
|
+
this.closing = false;
|
|
21315
|
+
this.adapterClosePromise = null;
|
|
21296
21316
|
this.dependencies = dependencies;
|
|
21297
21317
|
}
|
|
21318
|
+
async startDurableSession(codexHome, deadlineAtMs) {
|
|
21319
|
+
const binary = await (this.dependencies.resolveBinary ?? resolvePinnedCodexBinary)();
|
|
21320
|
+
const guardianManaged = Boolean(
|
|
21321
|
+
this.dependencies.recoveryHooks && !this.dependencies.spawnProcess
|
|
21322
|
+
);
|
|
21323
|
+
const bootIdentity = guardianManaged ? await (this.dependencies.readBootIdentity ?? readInferenceSystemBootIdentity)() : null;
|
|
21324
|
+
const processToken = guardianManaged ? randomBytes3(32).toString("hex") : null;
|
|
21325
|
+
const guardianReceiptRoot = guardianManaged ? this.dependencies.guardianReceiptRoot ?? join4(tmpdir2(), "vtx-codex-guardian-receipts") : null;
|
|
21326
|
+
if (guardianReceiptRoot) await ensureInferencePrivateDirectory(guardianReceiptRoot);
|
|
21327
|
+
const processReceiptPath = guardianReceiptRoot && processToken ? join4(guardianReceiptRoot, `${processToken}.json`) : null;
|
|
21328
|
+
const session = await CodexAppServerSession.start({
|
|
21329
|
+
binary,
|
|
21330
|
+
codexHome,
|
|
21331
|
+
deadlineAtMs,
|
|
21332
|
+
spawnProcess: this.dependencies.spawnProcess,
|
|
21333
|
+
guardian: processToken && processReceiptPath ? { processToken, receiptPath: processReceiptPath, bootIdentity: bootIdentity ?? void 0 } : void 0
|
|
21334
|
+
});
|
|
21335
|
+
return {
|
|
21336
|
+
session,
|
|
21337
|
+
codexHome,
|
|
21338
|
+
processToken,
|
|
21339
|
+
processReceiptPath,
|
|
21340
|
+
bootIdentity,
|
|
21341
|
+
terminated: false,
|
|
21342
|
+
closePromise: null
|
|
21343
|
+
};
|
|
21344
|
+
}
|
|
21345
|
+
async acquireDurableSession(codexHome, deadlineAtMs, signal) {
|
|
21346
|
+
if (this.closing) {
|
|
21347
|
+
throw new CodexAppServerError({
|
|
21348
|
+
message: "Codex adapter is closing.",
|
|
21349
|
+
category: "transport",
|
|
21350
|
+
code: "transport_closed",
|
|
21351
|
+
retryable: true
|
|
21352
|
+
});
|
|
21353
|
+
}
|
|
21354
|
+
if (this.durableSession && this.durableSession.codexHome === codexHome && this.durableSession.session.isUsable()) return this.durableSession;
|
|
21355
|
+
if (this.durableSession && this.durableSession.codexHome !== codexHome) {
|
|
21356
|
+
await this.invalidateDurableSession(this.durableSession);
|
|
21357
|
+
}
|
|
21358
|
+
if (this.durableSession && !this.durableSession.session.isUsable()) {
|
|
21359
|
+
await this.invalidateDurableSession(this.durableSession);
|
|
21360
|
+
}
|
|
21361
|
+
if (!this.durableSessionStart) {
|
|
21362
|
+
const start2 = this.startDurableSession(codexHome, deadlineAtMs);
|
|
21363
|
+
this.durableSessionStart = start2;
|
|
21364
|
+
void start2.then((session) => {
|
|
21365
|
+
if (this.durableSessionStart === start2) this.durableSession = session;
|
|
21366
|
+
}).finally(() => {
|
|
21367
|
+
if (this.durableSessionStart === start2) this.durableSessionStart = null;
|
|
21368
|
+
}).catch(() => void 0);
|
|
21369
|
+
}
|
|
21370
|
+
const start = this.durableSessionStart;
|
|
21371
|
+
return await new Promise((resolveSession, reject) => {
|
|
21372
|
+
let settled = false;
|
|
21373
|
+
const finish = (callback) => {
|
|
21374
|
+
if (settled) return;
|
|
21375
|
+
settled = true;
|
|
21376
|
+
clearTimeout(timer);
|
|
21377
|
+
signal?.removeEventListener("abort", onAbort);
|
|
21378
|
+
callback();
|
|
21379
|
+
};
|
|
21380
|
+
const onAbort = () => finish(() => reject(new CodexAppServerError({
|
|
21381
|
+
message: "Codex session acquisition was cancelled.",
|
|
21382
|
+
category: "cancelled",
|
|
21383
|
+
code: "cancelled",
|
|
21384
|
+
retryable: false
|
|
21385
|
+
})));
|
|
21386
|
+
const timer = setTimeout(() => finish(() => reject(new CodexAppServerError({
|
|
21387
|
+
message: "Codex session acquisition exceeded the immutable deadline.",
|
|
21388
|
+
category: "timeout",
|
|
21389
|
+
code: "deadline_exceeded",
|
|
21390
|
+
retryable: false
|
|
21391
|
+
}))), Math.max(1, deadlineAtMs - Date.now()));
|
|
21392
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
21393
|
+
if (signal?.aborted) {
|
|
21394
|
+
onAbort();
|
|
21395
|
+
return;
|
|
21396
|
+
}
|
|
21397
|
+
void start.then(
|
|
21398
|
+
(session) => finish(() => resolveSession(session)),
|
|
21399
|
+
(error48) => finish(() => reject(error48))
|
|
21400
|
+
);
|
|
21401
|
+
});
|
|
21402
|
+
}
|
|
21403
|
+
async invalidateDurableSession(session) {
|
|
21404
|
+
if (this.durableSession === session) this.durableSession = null;
|
|
21405
|
+
if (!session.closePromise) {
|
|
21406
|
+
session.closePromise = (async () => {
|
|
21407
|
+
await session.session.close();
|
|
21408
|
+
if (session.processToken && session.processReceiptPath) {
|
|
21409
|
+
await waitForCodexGuardianState(
|
|
21410
|
+
{ processToken: session.processToken, receiptPath: session.processReceiptPath },
|
|
21411
|
+
"terminated",
|
|
21412
|
+
Date.now() + 5e3
|
|
21413
|
+
);
|
|
21414
|
+
}
|
|
21415
|
+
session.terminated = true;
|
|
21416
|
+
})();
|
|
21417
|
+
}
|
|
21418
|
+
await session.closePromise;
|
|
21419
|
+
}
|
|
21298
21420
|
runAttempt(input) {
|
|
21299
21421
|
const active = this.inFlightAttempts.get(input.attemptId);
|
|
21300
21422
|
if (active) {
|
|
@@ -21309,15 +21431,21 @@ var init_codex_adapter = __esm({
|
|
|
21309
21431
|
}
|
|
21310
21432
|
return active.promise;
|
|
21311
21433
|
}
|
|
21312
|
-
const promise2 = this.executeAttempt(input)
|
|
21313
|
-
if (this.inFlightAttempts.get(input.attemptId)?.promise === promise2) {
|
|
21314
|
-
this.inFlightAttempts.delete(input.attemptId);
|
|
21315
|
-
}
|
|
21316
|
-
});
|
|
21434
|
+
const promise2 = this.executeAttempt(input);
|
|
21317
21435
|
this.inFlightAttempts.set(input.attemptId, {
|
|
21318
21436
|
inputSha256: input.inputSha256,
|
|
21319
21437
|
promise: promise2
|
|
21320
21438
|
});
|
|
21439
|
+
void promise2.then(async () => {
|
|
21440
|
+
await this.attemptCleanups.get(input.attemptId)?.catch(() => void 0);
|
|
21441
|
+
if (this.inFlightAttempts.get(input.attemptId)?.promise === promise2) {
|
|
21442
|
+
this.inFlightAttempts.delete(input.attemptId);
|
|
21443
|
+
}
|
|
21444
|
+
}, () => {
|
|
21445
|
+
if (this.inFlightAttempts.get(input.attemptId)?.promise === promise2) {
|
|
21446
|
+
this.inFlightAttempts.delete(input.attemptId);
|
|
21447
|
+
}
|
|
21448
|
+
}).catch(() => void 0);
|
|
21321
21449
|
return promise2;
|
|
21322
21450
|
}
|
|
21323
21451
|
async acknowledgeAttempt(attemptId) {
|
|
@@ -21329,8 +21457,27 @@ var init_codex_adapter = __esm({
|
|
|
21329
21457
|
retryable: false
|
|
21330
21458
|
});
|
|
21331
21459
|
}
|
|
21460
|
+
const activeCleanup = this.attemptCleanups.get(attemptId);
|
|
21461
|
+
if (activeCleanup) {
|
|
21462
|
+
try {
|
|
21463
|
+
await activeCleanup;
|
|
21464
|
+
} catch (error48) {
|
|
21465
|
+
throw new CodexAppServerError({
|
|
21466
|
+
message: "Codex attempt cleanup could not be confirmed.",
|
|
21467
|
+
category: "adapter",
|
|
21468
|
+
code: "attempt_cleanup_unconfirmed",
|
|
21469
|
+
retryable: false,
|
|
21470
|
+
cause: error48
|
|
21471
|
+
});
|
|
21472
|
+
}
|
|
21473
|
+
}
|
|
21332
21474
|
const recoveryHooks = this.dependencies.recoveryHooks;
|
|
21333
|
-
if (!recoveryHooks)
|
|
21475
|
+
if (!recoveryHooks) {
|
|
21476
|
+
if (activeCleanup && this.attemptCleanups.get(attemptId) === activeCleanup) {
|
|
21477
|
+
this.attemptCleanups.delete(attemptId);
|
|
21478
|
+
}
|
|
21479
|
+
return;
|
|
21480
|
+
}
|
|
21334
21481
|
const checkpoint = await recoveryHooks.load(attemptId);
|
|
21335
21482
|
if (checkpoint && !checkpoint.cleanupConfirmed) {
|
|
21336
21483
|
throw new CodexAppServerError({
|
|
@@ -21352,9 +21499,60 @@ var init_codex_adapter = __esm({
|
|
|
21352
21499
|
dispatchOutcome: checkpoint.dispatchOutcome
|
|
21353
21500
|
});
|
|
21354
21501
|
}
|
|
21355
|
-
await
|
|
21502
|
+
const receipt = await readCodexGuardianReceipt(checkpoint.processReceiptPath);
|
|
21503
|
+
if (checkpoint.processState === "terminated" || receipt === null || receipt.state === "terminated") {
|
|
21504
|
+
await rm3(checkpoint.processReceiptPath, { force: true });
|
|
21505
|
+
}
|
|
21356
21506
|
}
|
|
21357
21507
|
await recoveryHooks.clear(attemptId);
|
|
21508
|
+
if (activeCleanup && this.attemptCleanups.get(attemptId) === activeCleanup) {
|
|
21509
|
+
this.attemptCleanups.delete(attemptId);
|
|
21510
|
+
}
|
|
21511
|
+
}
|
|
21512
|
+
async close() {
|
|
21513
|
+
if (!this.adapterClosePromise) {
|
|
21514
|
+
this.closing = true;
|
|
21515
|
+
this.adapterClosePromise = (async () => {
|
|
21516
|
+
const sessions = /* @__PURE__ */ new Set();
|
|
21517
|
+
if (this.durableSession) sessions.add(this.durableSession);
|
|
21518
|
+
const starting = this.durableSessionStart;
|
|
21519
|
+
if (starting) {
|
|
21520
|
+
const started = await starting.catch(() => null);
|
|
21521
|
+
if (started) sessions.add(started);
|
|
21522
|
+
}
|
|
21523
|
+
await Promise.all(
|
|
21524
|
+
[...sessions].map((session) => this.invalidateDurableSession(session))
|
|
21525
|
+
);
|
|
21526
|
+
await Promise.allSettled(
|
|
21527
|
+
[...this.inFlightAttempts.values()].map((attempt) => attempt.promise)
|
|
21528
|
+
);
|
|
21529
|
+
await Promise.allSettled(
|
|
21530
|
+
[...this.attemptCleanups.values()]
|
|
21531
|
+
);
|
|
21532
|
+
let unconfirmedReceiptPaths = /* @__PURE__ */ new Set();
|
|
21533
|
+
const recoveryHooks = this.dependencies.recoveryHooks;
|
|
21534
|
+
if (recoveryHooks) {
|
|
21535
|
+
if (!recoveryHooks.loadAll) {
|
|
21536
|
+
unconfirmedReceiptPaths = null;
|
|
21537
|
+
} else {
|
|
21538
|
+
try {
|
|
21539
|
+
const checkpoints = await recoveryHooks.loadAll();
|
|
21540
|
+
unconfirmedReceiptPaths = new Set(
|
|
21541
|
+
Object.values(checkpoints).filter((checkpoint) => !checkpoint.cleanupConfirmed && checkpoint.processReceiptPath !== null).map((checkpoint) => resolve3(checkpoint.processReceiptPath))
|
|
21542
|
+
);
|
|
21543
|
+
} catch {
|
|
21544
|
+
unconfirmedReceiptPaths = null;
|
|
21545
|
+
}
|
|
21546
|
+
}
|
|
21547
|
+
}
|
|
21548
|
+
for (const session of sessions) {
|
|
21549
|
+
if (session.processReceiptPath && unconfirmedReceiptPaths !== null && !unconfirmedReceiptPaths.has(resolve3(session.processReceiptPath))) {
|
|
21550
|
+
await rm3(session.processReceiptPath, { force: true });
|
|
21551
|
+
}
|
|
21552
|
+
}
|
|
21553
|
+
})();
|
|
21554
|
+
}
|
|
21555
|
+
await this.adapterClosePromise;
|
|
21358
21556
|
}
|
|
21359
21557
|
async executeAttempt(input) {
|
|
21360
21558
|
const validatedInput = validateAttemptInput(input);
|
|
@@ -21406,6 +21604,7 @@ var init_codex_adapter = __esm({
|
|
|
21406
21604
|
});
|
|
21407
21605
|
}
|
|
21408
21606
|
let resources = null;
|
|
21607
|
+
let sessionLease = null;
|
|
21409
21608
|
let session = null;
|
|
21410
21609
|
let threadId = null;
|
|
21411
21610
|
let baseCheckpoint = null;
|
|
@@ -21413,22 +21612,20 @@ var init_codex_adapter = __esm({
|
|
|
21413
21612
|
let currentDispatchOutcome = "not_dispatched";
|
|
21414
21613
|
let completedResult = null;
|
|
21415
21614
|
let caughtError = null;
|
|
21615
|
+
let sessionInvalidationError = null;
|
|
21416
21616
|
try {
|
|
21417
|
-
const binary = await (this.dependencies.resolveBinary ?? resolvePinnedCodexBinary)();
|
|
21418
21617
|
resources = await (this.dependencies.createAttemptResources ?? ((attemptId) => createIsolatedCodexAttemptResources(
|
|
21419
21618
|
attemptId,
|
|
21420
21619
|
this.dependencies.codexHome
|
|
21421
21620
|
)))(input.attemptId);
|
|
21422
21621
|
await access2(resources.codexHome, fsConstants2.R_OK | fsConstants2.W_OK);
|
|
21423
21622
|
await access2(resources.workspacePath, fsConstants2.R_OK);
|
|
21424
|
-
|
|
21425
|
-
|
|
21426
|
-
|
|
21427
|
-
|
|
21428
|
-
|
|
21429
|
-
|
|
21430
|
-
}
|
|
21431
|
-
const processReceiptPath = guardianReceiptRoot && processToken ? join4(guardianReceiptRoot, `${processToken}.json`) : null;
|
|
21623
|
+
sessionLease = await this.acquireDurableSession(
|
|
21624
|
+
resources.codexHome,
|
|
21625
|
+
input.deadlineAtMs,
|
|
21626
|
+
input.signal
|
|
21627
|
+
);
|
|
21628
|
+
session = sessionLease.session;
|
|
21432
21629
|
baseCheckpoint = {
|
|
21433
21630
|
schemaVersion: "vtx_codex_attempt_recovery_v1",
|
|
21434
21631
|
attemptId: input.attemptId,
|
|
@@ -21438,10 +21635,10 @@ var init_codex_adapter = __esm({
|
|
|
21438
21635
|
workspacePath: resources.workspacePath,
|
|
21439
21636
|
threadId: null,
|
|
21440
21637
|
threadPath: null,
|
|
21441
|
-
processToken,
|
|
21442
|
-
processReceiptPath,
|
|
21443
|
-
processState:
|
|
21444
|
-
bootIdentity,
|
|
21638
|
+
processToken: sessionLease.processToken,
|
|
21639
|
+
processReceiptPath: sessionLease.processReceiptPath,
|
|
21640
|
+
processState: sessionLease.processToken ? "running" : "unmanaged",
|
|
21641
|
+
bootIdentity: sessionLease.bootIdentity,
|
|
21445
21642
|
cleanupConfirmed: false,
|
|
21446
21643
|
adapterRequestId: null,
|
|
21447
21644
|
adapterResponseId: null,
|
|
@@ -21450,19 +21647,6 @@ var init_codex_adapter = __esm({
|
|
|
21450
21647
|
};
|
|
21451
21648
|
latestCheckpoint = baseCheckpoint;
|
|
21452
21649
|
await recoveryHooks?.save(baseCheckpoint);
|
|
21453
|
-
session = await CodexAppServerSession.start({
|
|
21454
|
-
binary,
|
|
21455
|
-
codexHome: resources.codexHome,
|
|
21456
|
-
deadlineAtMs: input.deadlineAtMs,
|
|
21457
|
-
signal: input.signal,
|
|
21458
|
-
spawnProcess: this.dependencies.spawnProcess,
|
|
21459
|
-
guardian: processToken && processReceiptPath ? { processToken, receiptPath: processReceiptPath, bootIdentity: bootIdentity ?? void 0 } : void 0
|
|
21460
|
-
});
|
|
21461
|
-
if (guardianManaged) {
|
|
21462
|
-
baseCheckpoint = { ...baseCheckpoint, processState: "running" };
|
|
21463
|
-
latestCheckpoint = baseCheckpoint;
|
|
21464
|
-
await recoveryHooks?.save(baseCheckpoint);
|
|
21465
|
-
}
|
|
21466
21650
|
await session.requireManagedChatGptAuth(input.deadlineAtMs, input.signal);
|
|
21467
21651
|
await session.requireModel(
|
|
21468
21652
|
input.requestedModel,
|
|
@@ -21517,11 +21701,23 @@ var init_codex_adapter = __esm({
|
|
|
21517
21701
|
terminal: { kind: "completed", result: result2 }
|
|
21518
21702
|
};
|
|
21519
21703
|
await recoveryHooks?.save(latestCheckpoint);
|
|
21520
|
-
await session.deleteThread(thread.threadId);
|
|
21521
|
-
threadId = null;
|
|
21522
21704
|
return result2;
|
|
21523
21705
|
} catch (error48) {
|
|
21524
21706
|
caughtError = error48;
|
|
21707
|
+
if (sessionLease && (!sessionLease.session.isUsable() || error48 instanceof CodexAppServerError && (error48.category === "transport" || [
|
|
21708
|
+
"rpc_rejected",
|
|
21709
|
+
"invalid_rpc_result",
|
|
21710
|
+
"rpc_timeout",
|
|
21711
|
+
"invalid_thread_provenance",
|
|
21712
|
+
"thread_cleanup_identity_missing",
|
|
21713
|
+
"thread_delete_unconfirmed"
|
|
21714
|
+
].includes(error48.code)))) {
|
|
21715
|
+
try {
|
|
21716
|
+
await this.invalidateDurableSession(sessionLease);
|
|
21717
|
+
} catch (invalidationError) {
|
|
21718
|
+
sessionInvalidationError = invalidationError;
|
|
21719
|
+
}
|
|
21720
|
+
}
|
|
21525
21721
|
if (error48 instanceof CodexAppServerError) {
|
|
21526
21722
|
const dispatchOutcome = error48.dispatchOutcome === "not_dispatched" ? currentDispatchOutcome : error48.dispatchOutcome;
|
|
21527
21723
|
if (baseCheckpoint && !completedResult) {
|
|
@@ -21584,64 +21780,63 @@ var init_codex_adapter = __esm({
|
|
|
21584
21780
|
}
|
|
21585
21781
|
throw classified;
|
|
21586
21782
|
} finally {
|
|
21587
|
-
|
|
21588
|
-
|
|
21589
|
-
|
|
21590
|
-
|
|
21591
|
-
|
|
21592
|
-
|
|
21783
|
+
const cleanup = async () => {
|
|
21784
|
+
let cleanupError = sessionInvalidationError;
|
|
21785
|
+
if (session && threadId) {
|
|
21786
|
+
try {
|
|
21787
|
+
await session.deleteThread(threadId);
|
|
21788
|
+
} catch (error48) {
|
|
21789
|
+
cleanupError = error48;
|
|
21790
|
+
}
|
|
21593
21791
|
}
|
|
21594
|
-
|
|
21595
|
-
|
|
21596
|
-
|
|
21597
|
-
|
|
21598
|
-
|
|
21599
|
-
}
|
|
21600
|
-
if (latestCheckpoint && recoveryHooks) {
|
|
21601
|
-
try {
|
|
21602
|
-
if (latestCheckpoint.processToken && latestCheckpoint.processReceiptPath) {
|
|
21603
|
-
await waitForCodexGuardianState(
|
|
21604
|
-
{
|
|
21605
|
-
processToken: latestCheckpoint.processToken,
|
|
21606
|
-
receiptPath: latestCheckpoint.processReceiptPath
|
|
21607
|
-
},
|
|
21608
|
-
"terminated",
|
|
21609
|
-
Date.now() + 5e3
|
|
21610
|
-
);
|
|
21792
|
+
if (sessionLease && cleanupError) {
|
|
21793
|
+
try {
|
|
21794
|
+
await this.invalidateDurableSession(sessionLease);
|
|
21795
|
+
} catch (error48) {
|
|
21796
|
+
cleanupError ??= error48;
|
|
21611
21797
|
}
|
|
21612
|
-
} catch (error48) {
|
|
21613
|
-
cleanupError ??= error48;
|
|
21614
21798
|
}
|
|
21615
|
-
|
|
21616
|
-
|
|
21617
|
-
|
|
21618
|
-
|
|
21619
|
-
|
|
21620
|
-
|
|
21799
|
+
if (resources && cleanupError === null) {
|
|
21800
|
+
try {
|
|
21801
|
+
await resources.cleanup();
|
|
21802
|
+
} catch (error48) {
|
|
21803
|
+
cleanupError = error48;
|
|
21804
|
+
}
|
|
21621
21805
|
}
|
|
21622
|
-
|
|
21623
|
-
|
|
21624
|
-
|
|
21625
|
-
|
|
21626
|
-
|
|
21627
|
-
|
|
21628
|
-
|
|
21806
|
+
if (latestCheckpoint && recoveryHooks && cleanupError === null) {
|
|
21807
|
+
latestCheckpoint = {
|
|
21808
|
+
...latestCheckpoint,
|
|
21809
|
+
processState: latestCheckpoint.processToken ? sessionLease?.terminated ? "terminated" : "running" : "unmanaged",
|
|
21810
|
+
cleanupConfirmed: true
|
|
21811
|
+
};
|
|
21812
|
+
try {
|
|
21813
|
+
await recoveryHooks.save(latestCheckpoint);
|
|
21814
|
+
} catch (error48) {
|
|
21815
|
+
cleanupError = error48;
|
|
21816
|
+
}
|
|
21817
|
+
}
|
|
21818
|
+
if (cleanupError) {
|
|
21819
|
+
throw new CodexAppServerError({
|
|
21820
|
+
message: "Codex attempt cleanup could not be confirmed.",
|
|
21821
|
+
category: "adapter",
|
|
21822
|
+
code: "attempt_cleanup_unconfirmed",
|
|
21823
|
+
retryable: false,
|
|
21824
|
+
dispatchOutcome: currentDispatchOutcome,
|
|
21825
|
+
cause: cleanupError
|
|
21826
|
+
});
|
|
21827
|
+
}
|
|
21828
|
+
};
|
|
21829
|
+
if (completedResult && caughtError === null) {
|
|
21830
|
+
const cleanupPromise = cleanup();
|
|
21831
|
+
void cleanupPromise.catch(() => void 0);
|
|
21832
|
+
this.attemptCleanups.set(input.attemptId, cleanupPromise);
|
|
21833
|
+
} else {
|
|
21629
21834
|
try {
|
|
21630
|
-
await
|
|
21835
|
+
await cleanup();
|
|
21631
21836
|
} catch (error48) {
|
|
21632
|
-
|
|
21837
|
+
if (caughtError === null) throw error48;
|
|
21633
21838
|
}
|
|
21634
21839
|
}
|
|
21635
|
-
if (cleanupError && caughtError === null) {
|
|
21636
|
-
throw new CodexAppServerError({
|
|
21637
|
-
message: "Codex attempt cleanup could not be confirmed.",
|
|
21638
|
-
category: "adapter",
|
|
21639
|
-
code: "attempt_cleanup_unconfirmed",
|
|
21640
|
-
retryable: false,
|
|
21641
|
-
dispatchOutcome: currentDispatchOutcome,
|
|
21642
|
-
cause: cleanupError
|
|
21643
|
-
});
|
|
21644
|
-
}
|
|
21645
21840
|
}
|
|
21646
21841
|
}
|
|
21647
21842
|
};
|
|
@@ -29377,7 +29572,11 @@ var init_runner = __esm({
|
|
|
29377
29572
|
} finally {
|
|
29378
29573
|
removeAbortListener();
|
|
29379
29574
|
unregisterSignals();
|
|
29380
|
-
|
|
29575
|
+
try {
|
|
29576
|
+
await this.dependencies.codexAdapter.close?.();
|
|
29577
|
+
} finally {
|
|
29578
|
+
await lock2.release();
|
|
29579
|
+
}
|
|
29381
29580
|
}
|
|
29382
29581
|
}
|
|
29383
29582
|
async persistReceipt(receipt, now) {
|
|
@@ -30382,11 +30581,18 @@ ${result2.stderr}`)) {
|
|
|
30382
30581
|
const startedAt = Date.now();
|
|
30383
30582
|
const log = createWriteStream(manifest.log_path, { flags: "a", mode: 384 });
|
|
30384
30583
|
return await new Promise((resolvePromise, reject) => {
|
|
30584
|
+
let stdout = "";
|
|
30385
30585
|
const child = spawn5(manifest.executable, args, {
|
|
30386
30586
|
env: { ...process.env, ...manifest.runtime_environment },
|
|
30387
30587
|
windowsHide: true,
|
|
30388
|
-
stdio: ["ignore",
|
|
30588
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
30389
30589
|
});
|
|
30590
|
+
child.stdout.on("data", (chunk) => {
|
|
30591
|
+
const text = chunk.toString("utf8");
|
|
30592
|
+
log.write(text);
|
|
30593
|
+
stdout = `${stdout}${text}`.slice(-65536);
|
|
30594
|
+
});
|
|
30595
|
+
child.stderr.on("data", (chunk) => log.write(chunk));
|
|
30390
30596
|
const onAbort = () => child.kill("SIGTERM");
|
|
30391
30597
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
30392
30598
|
child.once("error", (error48) => {
|
|
@@ -30397,7 +30603,24 @@ ${result2.stderr}`)) {
|
|
|
30397
30603
|
child.once("exit", (code) => {
|
|
30398
30604
|
signal.removeEventListener("abort", onAbort);
|
|
30399
30605
|
log.end();
|
|
30400
|
-
|
|
30606
|
+
let drainReason = null;
|
|
30607
|
+
for (const line of stdout.trim().split("\n").reverse()) {
|
|
30608
|
+
try {
|
|
30609
|
+
const parsed = JSON.parse(line);
|
|
30610
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed) && typeof parsed.drain_reason === "string" && /^[a-z0-9_]{1,96}$/u.test(
|
|
30611
|
+
parsed.drain_reason
|
|
30612
|
+
)) {
|
|
30613
|
+
drainReason = parsed.drain_reason;
|
|
30614
|
+
break;
|
|
30615
|
+
}
|
|
30616
|
+
} catch {
|
|
30617
|
+
}
|
|
30618
|
+
}
|
|
30619
|
+
resolvePromise({
|
|
30620
|
+
exitCode: code ?? 1,
|
|
30621
|
+
uptimeMs: Date.now() - startedAt,
|
|
30622
|
+
drainReason
|
|
30623
|
+
});
|
|
30401
30624
|
});
|
|
30402
30625
|
});
|
|
30403
30626
|
};
|
|
@@ -30447,6 +30670,7 @@ ${result2.stderr}`)) {
|
|
|
30447
30670
|
await appendServiceLog(manifest.log_path, "worker_exited", {
|
|
30448
30671
|
exit_code: result2.exitCode,
|
|
30449
30672
|
uptime_ms: result2.uptimeMs,
|
|
30673
|
+
drain_reason: result2.drainReason ?? null,
|
|
30450
30674
|
retry_after_ms: retryAfterMs
|
|
30451
30675
|
});
|
|
30452
30676
|
await sleep4(retryAfterMs);
|
|
@@ -31932,7 +32156,21 @@ Waiting for approval...
|
|
|
31932
32156
|
...dependencies,
|
|
31933
32157
|
registerLifecycleSignalHandlers: unregister
|
|
31934
32158
|
}, warnings);
|
|
31935
|
-
|
|
32159
|
+
let drainReason = null;
|
|
32160
|
+
try {
|
|
32161
|
+
const summary = JSON.parse(result2.stdout);
|
|
32162
|
+
if (summary && typeof summary === "object" && !Array.isArray(summary) && typeof summary.drain_reason === "string" && /^[a-z0-9_]{1,96}$/u.test(
|
|
32163
|
+
summary.drain_reason
|
|
32164
|
+
)) {
|
|
32165
|
+
drainReason = summary.drain_reason;
|
|
32166
|
+
}
|
|
32167
|
+
} catch {
|
|
32168
|
+
}
|
|
32169
|
+
return {
|
|
32170
|
+
exitCode: result2.exitCode,
|
|
32171
|
+
uptimeMs: Date.now() - startedAt,
|
|
32172
|
+
drainReason
|
|
32173
|
+
};
|
|
31936
32174
|
}
|
|
31937
32175
|
}
|
|
31938
32176
|
);
|