@vtxmacro/cli 2026.8.22 → 2026.8.24
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 +235 -26
- 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.24",
|
|
42
42
|
codex_package_name: "@openai/codex",
|
|
43
43
|
codex_version: "0.147.0",
|
|
44
44
|
platforms: {
|
|
@@ -16132,7 +16132,10 @@ function assertLocalState(value) {
|
|
|
16132
16132
|
}
|
|
16133
16133
|
return record2;
|
|
16134
16134
|
}
|
|
16135
|
-
async function ensureInferencePrivateDirectory(path) {
|
|
16135
|
+
async function ensureInferencePrivateDirectory(path, dependencies = {}) {
|
|
16136
|
+
const platform = dependencies.platform ?? process.platform;
|
|
16137
|
+
const runner = dependencies.runner ?? runWindowsPrivateAcl;
|
|
16138
|
+
const defaultRoot = dependencies.defaultRoot ?? resolve(homedir(), ".vtx", "inference-host");
|
|
16136
16139
|
let created = false;
|
|
16137
16140
|
try {
|
|
16138
16141
|
const before = await lstat(path);
|
|
@@ -16148,9 +16151,18 @@ async function ensureInferencePrivateDirectory(path) {
|
|
|
16148
16151
|
if (after.isSymbolicLink() || !after.isDirectory()) {
|
|
16149
16152
|
throw new Error("Inference host state directory is unsafe.");
|
|
16150
16153
|
}
|
|
16151
|
-
if (
|
|
16152
|
-
if (created)
|
|
16153
|
-
|
|
16154
|
+
if (platform === "win32") {
|
|
16155
|
+
if (created) {
|
|
16156
|
+
await secureWindowsPrivatePath(path, "directory", "harden", platform, runner);
|
|
16157
|
+
} else {
|
|
16158
|
+
await secureExistingWindowsPath(
|
|
16159
|
+
path,
|
|
16160
|
+
"directory",
|
|
16161
|
+
platform,
|
|
16162
|
+
runner,
|
|
16163
|
+
defaultRoot
|
|
16164
|
+
);
|
|
16165
|
+
}
|
|
16154
16166
|
return;
|
|
16155
16167
|
}
|
|
16156
16168
|
if ((after.mode & 63) !== 0) {
|
|
@@ -16173,9 +16185,16 @@ async function syncInferenceDirectory(path, platform = process.platform) {
|
|
|
16173
16185
|
await handle.close();
|
|
16174
16186
|
}
|
|
16175
16187
|
}
|
|
16176
|
-
async function writeAtomicInferencePrivateFile(path, contents) {
|
|
16188
|
+
async function writeAtomicInferencePrivateFile(path, contents, dependencies = {}) {
|
|
16189
|
+
const platform = dependencies.platform ?? process.platform;
|
|
16190
|
+
const runner = dependencies.runner ?? runWindowsPrivateAcl;
|
|
16191
|
+
const defaultRoot = dependencies.defaultRoot ?? resolve(homedir(), ".vtx", "inference-host");
|
|
16177
16192
|
const directory = dirname(path);
|
|
16178
|
-
await ensureInferencePrivateDirectory(directory);
|
|
16193
|
+
await ensureInferencePrivateDirectory(directory, dependencies);
|
|
16194
|
+
const hardenedDirectoryIdentity = platform === "win32" && isDefaultWindowsPrivatePath(directory, defaultRoot) ? windowsAclCache.get(aclCacheKey(directory, "directory", "harden")) : void 0;
|
|
16195
|
+
if (platform === "win32" && isDefaultWindowsPrivatePath(directory, defaultRoot) && !hardenedDirectoryIdentity) {
|
|
16196
|
+
throw new Error("Windows private directory ACL hardening was not durably verified.");
|
|
16197
|
+
}
|
|
16179
16198
|
const temporary = join(
|
|
16180
16199
|
directory,
|
|
16181
16200
|
`.${process.pid}.${randomBytes(12).toString("hex")}.tmp`
|
|
@@ -16194,19 +16213,42 @@ async function writeAtomicInferencePrivateFile(path, contents) {
|
|
|
16194
16213
|
throw error48;
|
|
16195
16214
|
}
|
|
16196
16215
|
await handle.close();
|
|
16197
|
-
await secureWindowsPrivatePath(temporary, "file", "harden");
|
|
16216
|
+
await secureWindowsPrivatePath(temporary, "file", "harden", platform, runner);
|
|
16217
|
+
const hardenedIdentity = platform === "win32" ? windowsAclCache.get(aclCacheKey(temporary, "file", "harden")) : void 0;
|
|
16218
|
+
if (platform === "win32" && !hardenedIdentity) {
|
|
16219
|
+
await rm(temporary, { force: true }).catch(() => void 0);
|
|
16220
|
+
throw new Error("Windows private ACL hardening was not durably verified.");
|
|
16221
|
+
}
|
|
16198
16222
|
try {
|
|
16199
16223
|
invalidateWindowsAclCache(path);
|
|
16200
16224
|
await rename(temporary, path);
|
|
16201
|
-
|
|
16202
|
-
|
|
16203
|
-
|
|
16225
|
+
if (platform === "win32" && hardenedIdentity) {
|
|
16226
|
+
await rebindHardenedWindowsAclAfterRename(
|
|
16227
|
+
temporary,
|
|
16228
|
+
path,
|
|
16229
|
+
"file",
|
|
16230
|
+
hardenedIdentity
|
|
16231
|
+
);
|
|
16232
|
+
} else {
|
|
16233
|
+
invalidateWindowsAclCache(temporary);
|
|
16234
|
+
}
|
|
16235
|
+
await syncInferenceDirectory(directory, platform);
|
|
16236
|
+
if (platform === "win32" && hardenedDirectoryIdentity) {
|
|
16237
|
+
await rebindHardenedWindowsDirectoryAfterOwnedMutation(
|
|
16238
|
+
directory,
|
|
16239
|
+
hardenedDirectoryIdentity
|
|
16240
|
+
);
|
|
16241
|
+
}
|
|
16204
16242
|
} catch (error48) {
|
|
16205
16243
|
await rm(temporary, { force: true }).catch(() => void 0);
|
|
16244
|
+
invalidateWindowsAclCache(temporary);
|
|
16206
16245
|
throw error48;
|
|
16207
16246
|
}
|
|
16208
16247
|
}
|
|
16209
|
-
async function readInferencePrivateFile(path, label) {
|
|
16248
|
+
async function readInferencePrivateFile(path, label, dependencies = {}) {
|
|
16249
|
+
const platform = dependencies.platform ?? process.platform;
|
|
16250
|
+
const runner = dependencies.runner ?? runWindowsPrivateAcl;
|
|
16251
|
+
const defaultRoot = dependencies.defaultRoot ?? resolve(homedir(), ".vtx", "inference-host");
|
|
16210
16252
|
let before;
|
|
16211
16253
|
try {
|
|
16212
16254
|
before = await lstat(path);
|
|
@@ -16217,15 +16259,21 @@ async function readInferencePrivateFile(path, label) {
|
|
|
16217
16259
|
if (before.isSymbolicLink() || !before.isFile()) {
|
|
16218
16260
|
throw new Error(`${label} is unsafe.`);
|
|
16219
16261
|
}
|
|
16220
|
-
await secureExistingWindowsPath(
|
|
16221
|
-
|
|
16262
|
+
await secureExistingWindowsPath(
|
|
16263
|
+
dirname(path),
|
|
16264
|
+
"directory",
|
|
16265
|
+
platform,
|
|
16266
|
+
runner,
|
|
16267
|
+
defaultRoot
|
|
16268
|
+
);
|
|
16269
|
+
await secureExistingWindowsPath(path, "file", platform, runner, defaultRoot);
|
|
16222
16270
|
const handle = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
16223
16271
|
try {
|
|
16224
16272
|
const opened = await handle.stat();
|
|
16225
16273
|
if (!opened.isFile() || opened.dev !== before.dev || opened.ino !== before.ino || opened.size > MAX_INFERENCE_PRIVATE_FILE_BYTES || typeof process.getuid === "function" && opened.uid !== process.getuid()) {
|
|
16226
16274
|
throw new Error(`${label} changed while it was opened.`);
|
|
16227
16275
|
}
|
|
16228
|
-
if (
|
|
16276
|
+
if (platform !== "win32" && (opened.mode & 63) !== 0) {
|
|
16229
16277
|
throw new Error(`${label} must have mode 0600.`);
|
|
16230
16278
|
}
|
|
16231
16279
|
return await handle.readFile("utf8");
|
|
@@ -16440,7 +16488,7 @@ async function acquireInferenceHostProcessLock(path, dependencies = {}) {
|
|
|
16440
16488
|
}
|
|
16441
16489
|
};
|
|
16442
16490
|
}
|
|
16443
|
-
var INFERENCE_CREDENTIAL_NAMESPACE, MAX_INFERENCE_PRIVATE_FILE_BYTES, WINDOWS_PRIVATE_ACL_SCRIPT, windowsPrivateAclInvocation, runWindowsPrivateAcl, windowsAclCache, windowsAclIdentity, aclCacheKey, secureWindowsPrivatePath, invalidateWindowsAclCache, isDefaultWindowsPrivatePath, secureExistingWindowsPath, linuxProcessIdentity, windowsProcessIdentity, darwinProcessIdentity, runSmallIdentityCommand, cachedSystemBootIdentity, readInferenceSystemBootIdentity, defaultProcessIdentity, defaultCurrentProcessIdentity, processLockObservationCache, inferenceProcessIdentitiesMatch, credentialStoreIdentity;
|
|
16491
|
+
var INFERENCE_CREDENTIAL_NAMESPACE, MAX_INFERENCE_PRIVATE_FILE_BYTES, WINDOWS_PRIVATE_ACL_SCRIPT, windowsPrivateAclInvocation, runWindowsPrivateAcl, windowsAclCache, windowsAclIdentity, aclCacheKey, secureWindowsPrivatePath, invalidateWindowsAclCache, rebindHardenedWindowsAclAfterRename, rebindHardenedWindowsDirectoryAfterOwnedMutation, isDefaultWindowsPrivatePath, secureExistingWindowsPath, linuxProcessIdentity, windowsProcessIdentity, darwinProcessIdentity, runSmallIdentityCommand, cachedSystemBootIdentity, readInferenceSystemBootIdentity, defaultProcessIdentity, defaultCurrentProcessIdentity, processLockObservationCache, inferenceProcessIdentitiesMatch, credentialStoreIdentity;
|
|
16444
16492
|
var init_config = __esm({
|
|
16445
16493
|
"lib/inference-host/config.ts"() {
|
|
16446
16494
|
"use strict";
|
|
@@ -16581,6 +16629,35 @@ if(-not $userFull) { throw 'private ACL does not grant the current user full con
|
|
|
16581
16629
|
}
|
|
16582
16630
|
}
|
|
16583
16631
|
};
|
|
16632
|
+
rebindHardenedWindowsAclAfterRename = async (source, destination, kind, expected) => {
|
|
16633
|
+
const resolvedSource = resolve(source);
|
|
16634
|
+
const resolvedDestination = resolve(destination);
|
|
16635
|
+
if (resolvedSource === resolvedDestination || dirname(resolvedSource) !== dirname(resolvedDestination)) {
|
|
16636
|
+
throw new Error("Windows private ACL cache rename boundary is invalid.");
|
|
16637
|
+
}
|
|
16638
|
+
const published = await windowsAclIdentity(destination);
|
|
16639
|
+
if (published.dev !== expected.dev || published.ino !== expected.ino || published.mode !== expected.mode || published.mtimeNs !== expected.mtimeNs || published.size !== expected.size) {
|
|
16640
|
+
invalidateWindowsAclCache(source);
|
|
16641
|
+
invalidateWindowsAclCache(destination);
|
|
16642
|
+
throw new Error("Windows private file identity changed during atomic publication.");
|
|
16643
|
+
}
|
|
16644
|
+
invalidateWindowsAclCache(source);
|
|
16645
|
+
invalidateWindowsAclCache(destination);
|
|
16646
|
+
for (const mode of ["harden", "verify", "verify-owner"]) {
|
|
16647
|
+
windowsAclCache.set(aclCacheKey(destination, kind, mode), published);
|
|
16648
|
+
}
|
|
16649
|
+
};
|
|
16650
|
+
rebindHardenedWindowsDirectoryAfterOwnedMutation = async (path, expected) => {
|
|
16651
|
+
const current = await windowsAclIdentity(path);
|
|
16652
|
+
if (current.dev !== expected.dev || current.ino !== expected.ino || current.mode !== expected.mode) {
|
|
16653
|
+
invalidateWindowsAclCache(path);
|
|
16654
|
+
throw new Error("Windows private directory identity changed during atomic publication.");
|
|
16655
|
+
}
|
|
16656
|
+
invalidateWindowsAclCache(path);
|
|
16657
|
+
for (const mode of ["harden", "verify", "verify-owner"]) {
|
|
16658
|
+
windowsAclCache.set(aclCacheKey(path, "directory", mode), current);
|
|
16659
|
+
}
|
|
16660
|
+
};
|
|
16584
16661
|
isDefaultWindowsPrivatePath = (path, root = resolve(homedir(), ".vtx", "inference-host")) => {
|
|
16585
16662
|
const child = relative(root, resolve(path));
|
|
16586
16663
|
return child === "" || !child.startsWith("..") && !child.includes(":");
|
|
@@ -16591,8 +16668,6 @@ if(-not $userFull) { throw 'private ACL does not grant the current user full con
|
|
|
16591
16668
|
await secureWindowsPrivatePath(path, kind, "verify", platform, runner);
|
|
16592
16669
|
return;
|
|
16593
16670
|
}
|
|
16594
|
-
await secureWindowsPrivatePath(path, kind, "verify-owner", platform, runner);
|
|
16595
|
-
invalidateWindowsAclCache(path);
|
|
16596
16671
|
await secureWindowsPrivatePath(path, kind, "harden", platform, runner);
|
|
16597
16672
|
};
|
|
16598
16673
|
linuxProcessIdentity = async (pid) => {
|
|
@@ -20047,11 +20122,27 @@ child.once('close', async () => {
|
|
|
20047
20122
|
});
|
|
20048
20123
|
}
|
|
20049
20124
|
}
|
|
20050
|
-
async
|
|
20125
|
+
async readModelCapabilities(deadlineAtMs, signal) {
|
|
20051
20126
|
let cursor = null;
|
|
20052
20127
|
const seen = /* @__PURE__ */ new Set();
|
|
20053
|
-
|
|
20128
|
+
const capabilities = [];
|
|
20054
20129
|
do {
|
|
20130
|
+
if (signal?.aborted) {
|
|
20131
|
+
throw new CodexAppServerError({
|
|
20132
|
+
message: "Codex model catalog request was cancelled before dispatch.",
|
|
20133
|
+
category: "cancelled",
|
|
20134
|
+
code: "cancelled",
|
|
20135
|
+
retryable: false
|
|
20136
|
+
});
|
|
20137
|
+
}
|
|
20138
|
+
if (Date.now() >= deadlineAtMs) {
|
|
20139
|
+
throw new CodexAppServerError({
|
|
20140
|
+
message: "Codex model catalog request exceeded the immutable deadline before dispatch.",
|
|
20141
|
+
category: "timeout",
|
|
20142
|
+
code: "deadline_exceeded",
|
|
20143
|
+
retryable: false
|
|
20144
|
+
});
|
|
20145
|
+
}
|
|
20055
20146
|
const result2 = await this.request("model/list", {
|
|
20056
20147
|
includeHidden: true,
|
|
20057
20148
|
...cursor ? { cursor } : {}
|
|
@@ -20062,7 +20153,19 @@ child.once('close', async () => {
|
|
|
20062
20153
|
const data = Array.isArray(result2.data) ? result2.data : [];
|
|
20063
20154
|
for (const raw of data) {
|
|
20064
20155
|
const candidate = objectOrNull(raw);
|
|
20065
|
-
if (candidate
|
|
20156
|
+
if (!candidate) continue;
|
|
20157
|
+
const id2 = typeof candidate.id === "string" && candidate.id.trim() ? candidate.id.trim() : null;
|
|
20158
|
+
const model = typeof candidate.model === "string" && candidate.model.trim() ? candidate.model.trim() : null;
|
|
20159
|
+
if (!id2 && !model) continue;
|
|
20160
|
+
const supportedReasoningEfforts = Array.isArray(candidate.supportedReasoningEfforts) ? candidate.supportedReasoningEfforts.flatMap((item) => {
|
|
20161
|
+
const reasoningEffort = objectOrNull(item)?.reasoningEffort;
|
|
20162
|
+
return typeof reasoningEffort === "string" && reasoningEffort.trim() ? [reasoningEffort.trim()] : [];
|
|
20163
|
+
}) : [];
|
|
20164
|
+
capabilities.push(Object.freeze({
|
|
20165
|
+
id: id2,
|
|
20166
|
+
model,
|
|
20167
|
+
supportedReasoningEfforts: Object.freeze(supportedReasoningEfforts)
|
|
20168
|
+
}));
|
|
20066
20169
|
}
|
|
20067
20170
|
cursor = typeof result2.nextCursor === "string" && result2.nextCursor ? result2.nextCursor : null;
|
|
20068
20171
|
if (cursor && seen.has(cursor)) {
|
|
@@ -20075,6 +20178,10 @@ child.once('close', async () => {
|
|
|
20075
20178
|
}
|
|
20076
20179
|
if (cursor) seen.add(cursor);
|
|
20077
20180
|
} while (cursor);
|
|
20181
|
+
return Object.freeze(capabilities);
|
|
20182
|
+
}
|
|
20183
|
+
requireModelCapability(capabilities, modelName, reasoningEffort) {
|
|
20184
|
+
const match = capabilities.find((candidate) => candidate.model === modelName || candidate.id === modelName);
|
|
20078
20185
|
if (!match) {
|
|
20079
20186
|
throw new CodexAppServerError({
|
|
20080
20187
|
message: "The requested Codex model is unavailable.",
|
|
@@ -20083,8 +20190,7 @@ child.once('close', async () => {
|
|
|
20083
20190
|
retryable: false
|
|
20084
20191
|
});
|
|
20085
20192
|
}
|
|
20086
|
-
|
|
20087
|
-
if (!efforts.includes(reasoningEffort)) {
|
|
20193
|
+
if (!match.supportedReasoningEfforts.includes(reasoningEffort)) {
|
|
20088
20194
|
throw new CodexAppServerError({
|
|
20089
20195
|
message: "The requested Codex reasoning effort is unavailable.",
|
|
20090
20196
|
category: "model",
|
|
@@ -20093,7 +20199,30 @@ child.once('close', async () => {
|
|
|
20093
20199
|
});
|
|
20094
20200
|
}
|
|
20095
20201
|
}
|
|
20202
|
+
async requireModel(modelName, reasoningEffort, deadlineAtMs, signal) {
|
|
20203
|
+
this.requireModelCapability(
|
|
20204
|
+
await this.readModelCapabilities(deadlineAtMs, signal),
|
|
20205
|
+
modelName,
|
|
20206
|
+
reasoningEffort
|
|
20207
|
+
);
|
|
20208
|
+
}
|
|
20096
20209
|
async startThread(options) {
|
|
20210
|
+
if (options.signal?.aborted) {
|
|
20211
|
+
throw new CodexAppServerError({
|
|
20212
|
+
message: "Codex thread request was cancelled before dispatch.",
|
|
20213
|
+
category: "cancelled",
|
|
20214
|
+
code: "cancelled",
|
|
20215
|
+
retryable: false
|
|
20216
|
+
});
|
|
20217
|
+
}
|
|
20218
|
+
if (Date.now() >= options.deadlineAtMs) {
|
|
20219
|
+
throw new CodexAppServerError({
|
|
20220
|
+
message: "Codex thread request exceeded the immutable deadline before dispatch.",
|
|
20221
|
+
category: "timeout",
|
|
20222
|
+
code: "deadline_exceeded",
|
|
20223
|
+
retryable: false
|
|
20224
|
+
});
|
|
20225
|
+
}
|
|
20097
20226
|
const result2 = await this.request("thread/start", {
|
|
20098
20227
|
model: options.requestedModel,
|
|
20099
20228
|
modelProvider: "openai",
|
|
@@ -20823,7 +20952,7 @@ import {
|
|
|
20823
20952
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
20824
20953
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
20825
20954
|
import { isAbsolute as isAbsolute2, join as join4, relative as relative2, resolve as resolve3, sep as sep2 } from "node:path";
|
|
20826
|
-
var INITIAL_CODEX_INFERENCE_MODEL, SUPPORTED_CODEX_REASONING_EFFORTS, MAX_PROMPT_BYTES2, tokenUsageReceiptSchema, turnResultReceiptSchema, terminalReceiptSchema, recoveryCheckpointSchema, recoveryFileSchema, FileCodexAttemptRecoveryStore, utf8Bytes, tomlString, permissionConfig, ensureDedicatedCodexHome, createIsolatedCodexAttemptResources, createIsolatedCodexHostResources, validateAttemptInput, isStrictDescendant, assertRecoveryResourceScope, removeRecoveredThread, confirmGuardianTerminatedForRecovery, reconcileCodexAttemptRecovery, CodexSubscriptionAdapter;
|
|
20955
|
+
var INITIAL_CODEX_INFERENCE_MODEL, SUPPORTED_CODEX_REASONING_EFFORTS, MAX_PROMPT_BYTES2, tokenUsageReceiptSchema, turnResultReceiptSchema, terminalReceiptSchema, recoveryCheckpointSchema, recoveryFileSchema, FileCodexAttemptRecoveryStore, utf8Bytes, assertAttemptActive, tomlString, permissionConfig, ensureDedicatedCodexHome, createIsolatedCodexAttemptResources, createIsolatedCodexHostResources, validateAttemptInput, isStrictDescendant, assertRecoveryResourceScope, removeRecoveredThread, confirmGuardianTerminatedForRecovery, reconcileCodexAttemptRecovery, CodexSubscriptionAdapter;
|
|
20827
20956
|
var init_codex_adapter = __esm({
|
|
20828
20957
|
"lib/inference-host/codex-adapter.ts"() {
|
|
20829
20958
|
"use strict";
|
|
@@ -20971,6 +21100,24 @@ var init_codex_adapter = __esm({
|
|
|
20971
21100
|
}
|
|
20972
21101
|
};
|
|
20973
21102
|
utf8Bytes = (value) => Buffer.byteLength(value, "utf8");
|
|
21103
|
+
assertAttemptActive = (deadlineAtMs, signal) => {
|
|
21104
|
+
if (signal?.aborted) {
|
|
21105
|
+
throw new CodexAppServerError({
|
|
21106
|
+
message: "Codex attempt was cancelled before dispatch.",
|
|
21107
|
+
category: "cancelled",
|
|
21108
|
+
code: "cancelled",
|
|
21109
|
+
retryable: false
|
|
21110
|
+
});
|
|
21111
|
+
}
|
|
21112
|
+
if (Date.now() >= deadlineAtMs) {
|
|
21113
|
+
throw new CodexAppServerError({
|
|
21114
|
+
message: "Codex attempt exceeded the immutable deadline before dispatch.",
|
|
21115
|
+
category: "timeout",
|
|
21116
|
+
code: "deadline_exceeded",
|
|
21117
|
+
retryable: false
|
|
21118
|
+
});
|
|
21119
|
+
}
|
|
21120
|
+
};
|
|
20974
21121
|
tomlString = (value) => JSON.stringify(value);
|
|
20975
21122
|
permissionConfig = (codexHome) => [
|
|
20976
21123
|
'forced_login_method = "chatgpt"',
|
|
@@ -21335,6 +21482,7 @@ var init_codex_adapter = __esm({
|
|
|
21335
21482
|
return {
|
|
21336
21483
|
session,
|
|
21337
21484
|
codexHome,
|
|
21485
|
+
capabilityPreflight: null,
|
|
21338
21486
|
processToken,
|
|
21339
21487
|
processReceiptPath,
|
|
21340
21488
|
bootIdentity,
|
|
@@ -21417,6 +21565,65 @@ var init_codex_adapter = __esm({
|
|
|
21417
21565
|
}
|
|
21418
21566
|
await session.closePromise;
|
|
21419
21567
|
}
|
|
21568
|
+
async requireDurableSessionCapability(durableSession, modelName, reasoningEffort, deadlineAtMs, signal) {
|
|
21569
|
+
assertAttemptActive(deadlineAtMs, signal);
|
|
21570
|
+
if (!durableSession.capabilityPreflight) {
|
|
21571
|
+
durableSession.capabilityPreflight = (async () => {
|
|
21572
|
+
try {
|
|
21573
|
+
await durableSession.session.requireManagedChatGptAuth(deadlineAtMs, signal);
|
|
21574
|
+
assertAttemptActive(deadlineAtMs, signal);
|
|
21575
|
+
return await durableSession.session.readModelCapabilities(deadlineAtMs, signal);
|
|
21576
|
+
} catch (error48) {
|
|
21577
|
+
try {
|
|
21578
|
+
await this.invalidateDurableSession(durableSession);
|
|
21579
|
+
} catch (invalidationError) {
|
|
21580
|
+
throw new CodexAppServerError({
|
|
21581
|
+
message: "Codex capability preflight failed and session shutdown was not confirmed.",
|
|
21582
|
+
category: "adapter",
|
|
21583
|
+
code: "capability_preflight_invalidation_unconfirmed",
|
|
21584
|
+
retryable: false,
|
|
21585
|
+
cause: new AggregateError([error48, invalidationError])
|
|
21586
|
+
});
|
|
21587
|
+
}
|
|
21588
|
+
throw error48;
|
|
21589
|
+
}
|
|
21590
|
+
})();
|
|
21591
|
+
}
|
|
21592
|
+
const preflight = durableSession.capabilityPreflight;
|
|
21593
|
+
const capabilities = await new Promise((resolve6, reject) => {
|
|
21594
|
+
let settled = false;
|
|
21595
|
+
const finish = (callback) => {
|
|
21596
|
+
if (settled) return;
|
|
21597
|
+
settled = true;
|
|
21598
|
+
clearTimeout(timer);
|
|
21599
|
+
signal?.removeEventListener("abort", onAbort);
|
|
21600
|
+
callback();
|
|
21601
|
+
};
|
|
21602
|
+
const onAbort = () => finish(() => reject(new CodexAppServerError({
|
|
21603
|
+
message: "Codex capability preflight wait was cancelled.",
|
|
21604
|
+
category: "cancelled",
|
|
21605
|
+
code: "cancelled",
|
|
21606
|
+
retryable: false
|
|
21607
|
+
})));
|
|
21608
|
+
const timer = setTimeout(() => finish(() => reject(new CodexAppServerError({
|
|
21609
|
+
message: "Codex capability preflight wait exceeded the immutable deadline.",
|
|
21610
|
+
category: "timeout",
|
|
21611
|
+
code: "deadline_exceeded",
|
|
21612
|
+
retryable: false
|
|
21613
|
+
}))), Math.max(1, deadlineAtMs - Date.now()));
|
|
21614
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
21615
|
+
if (signal?.aborted) {
|
|
21616
|
+
onAbort();
|
|
21617
|
+
return;
|
|
21618
|
+
}
|
|
21619
|
+
void preflight.then(
|
|
21620
|
+
(value) => finish(() => resolve6(value)),
|
|
21621
|
+
(error48) => finish(() => reject(error48))
|
|
21622
|
+
);
|
|
21623
|
+
});
|
|
21624
|
+
assertAttemptActive(deadlineAtMs, signal);
|
|
21625
|
+
durableSession.session.requireModelCapability(capabilities, modelName, reasoningEffort);
|
|
21626
|
+
}
|
|
21420
21627
|
runAttempt(input) {
|
|
21421
21628
|
const active = this.inFlightAttempts.get(input.attemptId);
|
|
21422
21629
|
if (active) {
|
|
@@ -21647,13 +21854,14 @@ var init_codex_adapter = __esm({
|
|
|
21647
21854
|
};
|
|
21648
21855
|
latestCheckpoint = baseCheckpoint;
|
|
21649
21856
|
await recoveryHooks?.save(baseCheckpoint);
|
|
21650
|
-
await
|
|
21651
|
-
|
|
21857
|
+
await this.requireDurableSessionCapability(
|
|
21858
|
+
sessionLease,
|
|
21652
21859
|
input.requestedModel,
|
|
21653
21860
|
input.requestedReasoningEffort,
|
|
21654
21861
|
input.deadlineAtMs,
|
|
21655
21862
|
input.signal
|
|
21656
21863
|
);
|
|
21864
|
+
assertAttemptActive(input.deadlineAtMs, input.signal);
|
|
21657
21865
|
const thread = await session.startThread({
|
|
21658
21866
|
workspacePath: resources.workspacePath,
|
|
21659
21867
|
systemPrompt: input.systemPrompt,
|
|
@@ -21708,6 +21916,7 @@ var init_codex_adapter = __esm({
|
|
|
21708
21916
|
"rpc_rejected",
|
|
21709
21917
|
"invalid_rpc_result",
|
|
21710
21918
|
"rpc_timeout",
|
|
21919
|
+
"capability_preflight_invalidation_unconfirmed",
|
|
21711
21920
|
"invalid_thread_provenance",
|
|
21712
21921
|
"thread_cleanup_identity_missing",
|
|
21713
21922
|
"thread_delete_unconfirmed"
|