@vtxmacro/cli 2026.8.22 → 2026.8.23

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.
Files changed (2) hide show
  1. package/bin/vtx.js +143 -9
  2. 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.22",
41
+ package_version: "2026.8.23",
42
42
  codex_package_name: "@openai/codex",
43
43
  codex_version: "0.147.0",
44
44
  platforms: {
@@ -20047,11 +20047,27 @@ child.once('close', async () => {
20047
20047
  });
20048
20048
  }
20049
20049
  }
20050
- async requireModel(modelName, reasoningEffort, deadlineAtMs, signal) {
20050
+ async readModelCapabilities(deadlineAtMs, signal) {
20051
20051
  let cursor = null;
20052
20052
  const seen = /* @__PURE__ */ new Set();
20053
- let match = null;
20053
+ const capabilities = [];
20054
20054
  do {
20055
+ if (signal?.aborted) {
20056
+ throw new CodexAppServerError({
20057
+ message: "Codex model catalog request was cancelled before dispatch.",
20058
+ category: "cancelled",
20059
+ code: "cancelled",
20060
+ retryable: false
20061
+ });
20062
+ }
20063
+ if (Date.now() >= deadlineAtMs) {
20064
+ throw new CodexAppServerError({
20065
+ message: "Codex model catalog request exceeded the immutable deadline before dispatch.",
20066
+ category: "timeout",
20067
+ code: "deadline_exceeded",
20068
+ retryable: false
20069
+ });
20070
+ }
20055
20071
  const result2 = await this.request("model/list", {
20056
20072
  includeHidden: true,
20057
20073
  ...cursor ? { cursor } : {}
@@ -20062,7 +20078,19 @@ child.once('close', async () => {
20062
20078
  const data = Array.isArray(result2.data) ? result2.data : [];
20063
20079
  for (const raw of data) {
20064
20080
  const candidate = objectOrNull(raw);
20065
- if (candidate && (candidate.model === modelName || candidate.id === modelName)) match = candidate;
20081
+ if (!candidate) continue;
20082
+ const id2 = typeof candidate.id === "string" && candidate.id.trim() ? candidate.id.trim() : null;
20083
+ const model = typeof candidate.model === "string" && candidate.model.trim() ? candidate.model.trim() : null;
20084
+ if (!id2 && !model) continue;
20085
+ const supportedReasoningEfforts = Array.isArray(candidate.supportedReasoningEfforts) ? candidate.supportedReasoningEfforts.flatMap((item) => {
20086
+ const reasoningEffort = objectOrNull(item)?.reasoningEffort;
20087
+ return typeof reasoningEffort === "string" && reasoningEffort.trim() ? [reasoningEffort.trim()] : [];
20088
+ }) : [];
20089
+ capabilities.push(Object.freeze({
20090
+ id: id2,
20091
+ model,
20092
+ supportedReasoningEfforts: Object.freeze(supportedReasoningEfforts)
20093
+ }));
20066
20094
  }
20067
20095
  cursor = typeof result2.nextCursor === "string" && result2.nextCursor ? result2.nextCursor : null;
20068
20096
  if (cursor && seen.has(cursor)) {
@@ -20075,6 +20103,10 @@ child.once('close', async () => {
20075
20103
  }
20076
20104
  if (cursor) seen.add(cursor);
20077
20105
  } while (cursor);
20106
+ return Object.freeze(capabilities);
20107
+ }
20108
+ requireModelCapability(capabilities, modelName, reasoningEffort) {
20109
+ const match = capabilities.find((candidate) => candidate.model === modelName || candidate.id === modelName);
20078
20110
  if (!match) {
20079
20111
  throw new CodexAppServerError({
20080
20112
  message: "The requested Codex model is unavailable.",
@@ -20083,8 +20115,7 @@ child.once('close', async () => {
20083
20115
  retryable: false
20084
20116
  });
20085
20117
  }
20086
- const efforts = Array.isArray(match.supportedReasoningEfforts) ? match.supportedReasoningEfforts.map((item) => objectOrNull(item)?.reasoningEffort) : [];
20087
- if (!efforts.includes(reasoningEffort)) {
20118
+ if (!match.supportedReasoningEfforts.includes(reasoningEffort)) {
20088
20119
  throw new CodexAppServerError({
20089
20120
  message: "The requested Codex reasoning effort is unavailable.",
20090
20121
  category: "model",
@@ -20093,7 +20124,30 @@ child.once('close', async () => {
20093
20124
  });
20094
20125
  }
20095
20126
  }
20127
+ async requireModel(modelName, reasoningEffort, deadlineAtMs, signal) {
20128
+ this.requireModelCapability(
20129
+ await this.readModelCapabilities(deadlineAtMs, signal),
20130
+ modelName,
20131
+ reasoningEffort
20132
+ );
20133
+ }
20096
20134
  async startThread(options) {
20135
+ if (options.signal?.aborted) {
20136
+ throw new CodexAppServerError({
20137
+ message: "Codex thread request was cancelled before dispatch.",
20138
+ category: "cancelled",
20139
+ code: "cancelled",
20140
+ retryable: false
20141
+ });
20142
+ }
20143
+ if (Date.now() >= options.deadlineAtMs) {
20144
+ throw new CodexAppServerError({
20145
+ message: "Codex thread request exceeded the immutable deadline before dispatch.",
20146
+ category: "timeout",
20147
+ code: "deadline_exceeded",
20148
+ retryable: false
20149
+ });
20150
+ }
20097
20151
  const result2 = await this.request("thread/start", {
20098
20152
  model: options.requestedModel,
20099
20153
  modelProvider: "openai",
@@ -20823,7 +20877,7 @@ import {
20823
20877
  import { randomBytes as randomBytes3 } from "node:crypto";
20824
20878
  import { tmpdir as tmpdir2 } from "node:os";
20825
20879
  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;
20880
+ 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
20881
  var init_codex_adapter = __esm({
20828
20882
  "lib/inference-host/codex-adapter.ts"() {
20829
20883
  "use strict";
@@ -20971,6 +21025,24 @@ var init_codex_adapter = __esm({
20971
21025
  }
20972
21026
  };
20973
21027
  utf8Bytes = (value) => Buffer.byteLength(value, "utf8");
21028
+ assertAttemptActive = (deadlineAtMs, signal) => {
21029
+ if (signal?.aborted) {
21030
+ throw new CodexAppServerError({
21031
+ message: "Codex attempt was cancelled before dispatch.",
21032
+ category: "cancelled",
21033
+ code: "cancelled",
21034
+ retryable: false
21035
+ });
21036
+ }
21037
+ if (Date.now() >= deadlineAtMs) {
21038
+ throw new CodexAppServerError({
21039
+ message: "Codex attempt exceeded the immutable deadline before dispatch.",
21040
+ category: "timeout",
21041
+ code: "deadline_exceeded",
21042
+ retryable: false
21043
+ });
21044
+ }
21045
+ };
20974
21046
  tomlString = (value) => JSON.stringify(value);
20975
21047
  permissionConfig = (codexHome) => [
20976
21048
  'forced_login_method = "chatgpt"',
@@ -21335,6 +21407,7 @@ var init_codex_adapter = __esm({
21335
21407
  return {
21336
21408
  session,
21337
21409
  codexHome,
21410
+ capabilityPreflight: null,
21338
21411
  processToken,
21339
21412
  processReceiptPath,
21340
21413
  bootIdentity,
@@ -21417,6 +21490,65 @@ var init_codex_adapter = __esm({
21417
21490
  }
21418
21491
  await session.closePromise;
21419
21492
  }
21493
+ async requireDurableSessionCapability(durableSession, modelName, reasoningEffort, deadlineAtMs, signal) {
21494
+ assertAttemptActive(deadlineAtMs, signal);
21495
+ if (!durableSession.capabilityPreflight) {
21496
+ durableSession.capabilityPreflight = (async () => {
21497
+ try {
21498
+ await durableSession.session.requireManagedChatGptAuth(deadlineAtMs, signal);
21499
+ assertAttemptActive(deadlineAtMs, signal);
21500
+ return await durableSession.session.readModelCapabilities(deadlineAtMs, signal);
21501
+ } catch (error48) {
21502
+ try {
21503
+ await this.invalidateDurableSession(durableSession);
21504
+ } catch (invalidationError) {
21505
+ throw new CodexAppServerError({
21506
+ message: "Codex capability preflight failed and session shutdown was not confirmed.",
21507
+ category: "adapter",
21508
+ code: "capability_preflight_invalidation_unconfirmed",
21509
+ retryable: false,
21510
+ cause: new AggregateError([error48, invalidationError])
21511
+ });
21512
+ }
21513
+ throw error48;
21514
+ }
21515
+ })();
21516
+ }
21517
+ const preflight = durableSession.capabilityPreflight;
21518
+ const capabilities = await new Promise((resolve6, reject) => {
21519
+ let settled = false;
21520
+ const finish = (callback) => {
21521
+ if (settled) return;
21522
+ settled = true;
21523
+ clearTimeout(timer);
21524
+ signal?.removeEventListener("abort", onAbort);
21525
+ callback();
21526
+ };
21527
+ const onAbort = () => finish(() => reject(new CodexAppServerError({
21528
+ message: "Codex capability preflight wait was cancelled.",
21529
+ category: "cancelled",
21530
+ code: "cancelled",
21531
+ retryable: false
21532
+ })));
21533
+ const timer = setTimeout(() => finish(() => reject(new CodexAppServerError({
21534
+ message: "Codex capability preflight wait exceeded the immutable deadline.",
21535
+ category: "timeout",
21536
+ code: "deadline_exceeded",
21537
+ retryable: false
21538
+ }))), Math.max(1, deadlineAtMs - Date.now()));
21539
+ signal?.addEventListener("abort", onAbort, { once: true });
21540
+ if (signal?.aborted) {
21541
+ onAbort();
21542
+ return;
21543
+ }
21544
+ void preflight.then(
21545
+ (value) => finish(() => resolve6(value)),
21546
+ (error48) => finish(() => reject(error48))
21547
+ );
21548
+ });
21549
+ assertAttemptActive(deadlineAtMs, signal);
21550
+ durableSession.session.requireModelCapability(capabilities, modelName, reasoningEffort);
21551
+ }
21420
21552
  runAttempt(input) {
21421
21553
  const active = this.inFlightAttempts.get(input.attemptId);
21422
21554
  if (active) {
@@ -21647,13 +21779,14 @@ var init_codex_adapter = __esm({
21647
21779
  };
21648
21780
  latestCheckpoint = baseCheckpoint;
21649
21781
  await recoveryHooks?.save(baseCheckpoint);
21650
- await session.requireManagedChatGptAuth(input.deadlineAtMs, input.signal);
21651
- await session.requireModel(
21782
+ await this.requireDurableSessionCapability(
21783
+ sessionLease,
21652
21784
  input.requestedModel,
21653
21785
  input.requestedReasoningEffort,
21654
21786
  input.deadlineAtMs,
21655
21787
  input.signal
21656
21788
  );
21789
+ assertAttemptActive(input.deadlineAtMs, input.signal);
21657
21790
  const thread = await session.startThread({
21658
21791
  workspacePath: resources.workspacePath,
21659
21792
  systemPrompt: input.systemPrompt,
@@ -21708,6 +21841,7 @@ var init_codex_adapter = __esm({
21708
21841
  "rpc_rejected",
21709
21842
  "invalid_rpc_result",
21710
21843
  "rpc_timeout",
21844
+ "capability_preflight_invalidation_unconfirmed",
21711
21845
  "invalid_thread_provenance",
21712
21846
  "thread_cleanup_identity_missing",
21713
21847
  "thread_delete_unconfirmed"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vtxmacro/cli",
3
- "version": "2026.8.22",
3
+ "version": "2026.8.23",
4
4
  "description": "VTX Macro CLI, MCP server, and durable subscription inference host.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",