@vtxmacro/cli 2026.8.50 → 2026.8.51

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 +191 -65
  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.50",
41
+ package_version: "2026.8.51",
42
42
  codex_package_name: "@openai/codex",
43
43
  codex_version: "0.147.0",
44
44
  copilot_sdk_package_name: "@github/copilot-sdk",
@@ -18058,7 +18058,7 @@ ${body}`;
18058
18058
  });
18059
18059
 
18060
18060
  // lib/inference-host/mcp-client.ts
18061
- var EXTERNAL_INFERENCE_MCP_PROTOCOL_VERSION, EXTERNAL_INFERENCE_AUTOMATED_HOST_TOOLS, EXTERNAL_INFERENCE_OPERATIONAL_TOOLS, ExternalInferenceMcpError, DEFAULT_REQUEST_TIMEOUT_MS, MAX_RETRY_AFTER_MS, parseRetryAfterMs, identifierSchema2, safeCodeSchema2, hostMutationResultSchema, attemptStartResultSchema, agentConnectResultSchema, agentHeartbeatResultSchema, timestampSchema2, positiveGenerationSchema, jsonObjectSchema, agentAssignmentNextArgumentsSchema, agentAssignmentNextResultSchema, agentAssignmentHeartbeatArgumentsSchema, agentAssignmentHeartbeatResultSchema, agentDataCallArgumentsSchema, agentDataCallResultSchema, agentDecisionSubmitArgumentsSchema, agentDecisionSubmitResultSchema, agentDecisionStatusArgumentsSchema, agentDecisionStatusResultSchema, agentAssignmentReleaseArgumentsSchema, agentAssignmentReleaseResultSchema, jobCompletionResultSchema, jobFailureResultSchema, toolContracts, discoveryResultSchema, toolListResultSchema, inlineStructuredContentSchema, protocolMeta, parseJsonDocument, parseSseDocuments, parseResponseDocuments, exactOperationalInventory, exactJson, invalidBoundResult, verifyToolResult, ExternalInferenceMcpClient;
18061
+ var EXTERNAL_INFERENCE_MCP_PROTOCOL_VERSION, EXTERNAL_INFERENCE_AUTOMATED_HOST_TOOLS, EXTERNAL_INFERENCE_OPERATIONAL_TOOLS, ExternalInferenceMcpError, DEFAULT_REQUEST_TIMEOUT_MS, MAX_RETRY_AFTER_MS, parseRetryAfterMs, identifierSchema2, safeCodeSchema2, hostMutationResultSchema, attemptStartResultSchema, agentConnectResultSchema, agentHeartbeatResultSchema, timestampSchema2, positiveGenerationSchema, jsonObjectSchema, agentAssignmentNextArgumentsSchema, agentDataCapabilityDescriptorSchema, agentAssignmentNextResultSchema, agentAssignmentHeartbeatArgumentsSchema, agentAssignmentHeartbeatResultSchema, agentDataCallArgumentsSchema, agentDataCallResultSchema, agentDecisionSubmitArgumentsSchema, agentDecisionSubmitResultSchema, agentDecisionStatusArgumentsSchema, agentDecisionStatusResultSchema, agentAssignmentReleaseArgumentsSchema, agentAssignmentReleaseResultSchema, jobCompletionResultSchema, jobFailureResultSchema, toolContracts, discoveryResultSchema, toolListResultSchema, inlineStructuredContentSchema, protocolMeta, parseJsonDocument, parseSseDocuments, parseResponseDocuments, exactOperationalInventory, exactJson, invalidBoundResult, verifyToolResult, ExternalInferenceMcpClient;
18062
18062
  var init_mcp_client = __esm({
18063
18063
  "lib/inference-host/mcp-client.ts"() {
18064
18064
  "use strict";
@@ -18156,7 +18156,25 @@ var init_mcp_client = __esm({
18156
18156
  agentAssignmentNextArgumentsSchema = external_exports.strictObject({
18157
18157
  operation_id: identifierSchema2,
18158
18158
  host_id: identifierSchema2,
18159
- requested_at: timestampSchema2
18159
+ requested_at: timestampSchema2,
18160
+ contract_version: external_exports.literal("agent_assignment_v2"),
18161
+ assignment_id: identifierSchema2.optional(),
18162
+ assignment_generation: positiveGenerationSchema.optional()
18163
+ }).superRefine((value, context) => {
18164
+ if (value.assignment_id === void 0 !== (value.assignment_generation === void 0)) {
18165
+ context.addIssue({
18166
+ code: "custom",
18167
+ message: "Agent recovery assignment identity is incomplete.",
18168
+ path: ["assignment_id"]
18169
+ });
18170
+ }
18171
+ });
18172
+ agentDataCapabilityDescriptorSchema = external_exports.strictObject({
18173
+ id: external_exports.string().min(1).max(128),
18174
+ title: external_exports.string().min(1),
18175
+ description: external_exports.string().min(1),
18176
+ input_schema: jsonObjectSchema,
18177
+ input_schema_sha256: external_exports.string().regex(/^[0-9a-f]{64}$/u)
18160
18178
  });
18161
18179
  agentAssignmentNextResultSchema = external_exports.discriminatedUnion("claim_state", [
18162
18180
  external_exports.strictObject({
@@ -18172,6 +18190,11 @@ var init_mcp_client = __esm({
18172
18190
  model_id: identifierSchema2,
18173
18191
  reasoning_effort: safeCodeSchema2,
18174
18192
  allowed_symbols: external_exports.array(external_exports.string().min(1)).min(1),
18193
+ contract_version: external_exports.literal("agent_assignment_v2"),
18194
+ data_contract: external_exports.array(agentDataCapabilityDescriptorSchema).min(1).refine(
18195
+ (value) => new Set(value.map((descriptor) => descriptor.id)).size === value.length,
18196
+ { message: "Agent data capability descriptors must be unique." }
18197
+ ),
18175
18198
  output_schema_version: external_exports.string().min(1),
18176
18199
  output_schema: jsonObjectSchema,
18177
18200
  minimum_wake_seconds: external_exports.number().int().positive().max(Number.MAX_SAFE_INTEGER),
@@ -19743,19 +19766,42 @@ var init_agent_state = __esm({
19743
19766
  "updated_at"
19744
19767
  ])) throw new Error(message);
19745
19768
  const assignment = assertPlainObject(state.assignment, message);
19746
- if (state.schema_version !== "vtx_codex_agent_runtime_v1" || typeof state.host_id !== "string" || !state.host_id || !isIsoTimestamp(state.next_wake_at) || !isIsoTimestamp(state.updated_at) || !hasExactKeys(assignment, [
19747
- "assignment_id",
19748
- "assignment_generation",
19749
- "model_id",
19750
- "reasoning_effort",
19751
- "bot_mode",
19752
- "execution_mode",
19753
- "allowed_symbols",
19754
- "output_schema",
19755
- "minimum_wake_seconds",
19756
- "maximum_wake_seconds",
19757
- "lease_expires_at"
19758
- ]) || typeof assignment.assignment_id !== "string" || !assignment.assignment_id || !Number.isSafeInteger(assignment.assignment_generation) || Number(assignment.assignment_generation) < 1 || typeof assignment.model_id !== "string" || !assignment.model_id || typeof assignment.reasoning_effort !== "string" || !assignment.reasoning_effort || !["trader", "assistant"].includes(String(assignment.bot_mode)) || !["server", "client"].includes(String(assignment.execution_mode)) || !Array.isArray(assignment.allowed_symbols) || assignment.allowed_symbols.some((symbol2) => typeof symbol2 !== "string" || !symbol2) || !assignment.output_schema || typeof assignment.output_schema !== "object" || Array.isArray(assignment.output_schema) || !Number.isSafeInteger(assignment.minimum_wake_seconds) || Number(assignment.minimum_wake_seconds) < 1 || !Number.isSafeInteger(assignment.maximum_wake_seconds) || Number(assignment.maximum_wake_seconds) < Number(assignment.minimum_wake_seconds) || !isIsoTimestamp(assignment.lease_expires_at)) throw new Error(message);
19769
+ if (!["vtx_codex_agent_runtime_v1", "vtx_codex_agent_runtime_v2"].includes(
19770
+ String(state.schema_version)
19771
+ ) || typeof state.host_id !== "string" || !state.host_id || !isIsoTimestamp(state.next_wake_at) || !isIsoTimestamp(state.updated_at) || !hasExactKeys(
19772
+ assignment,
19773
+ [
19774
+ "assignment_id",
19775
+ "assignment_generation",
19776
+ "model_id",
19777
+ "reasoning_effort",
19778
+ "bot_mode",
19779
+ "execution_mode",
19780
+ "allowed_symbols",
19781
+ "output_schema",
19782
+ "minimum_wake_seconds",
19783
+ "maximum_wake_seconds",
19784
+ "lease_expires_at",
19785
+ ...state.schema_version === "vtx_codex_agent_runtime_v2" ? ["data_contract"] : []
19786
+ ]
19787
+ ) || typeof assignment.assignment_id !== "string" || !assignment.assignment_id || !Number.isSafeInteger(assignment.assignment_generation) || Number(assignment.assignment_generation) < 1 || typeof assignment.model_id !== "string" || !assignment.model_id || typeof assignment.reasoning_effort !== "string" || !assignment.reasoning_effort || !["trader", "assistant"].includes(String(assignment.bot_mode)) || !["server", "client"].includes(String(assignment.execution_mode)) || !Array.isArray(assignment.allowed_symbols) || assignment.allowed_symbols.some((symbol2) => typeof symbol2 !== "string" || !symbol2) || !assignment.output_schema || typeof assignment.output_schema !== "object" || Array.isArray(assignment.output_schema) || !Number.isSafeInteger(assignment.minimum_wake_seconds) || Number(assignment.minimum_wake_seconds) < 1 || !Number.isSafeInteger(assignment.maximum_wake_seconds) || Number(assignment.maximum_wake_seconds) < Number(assignment.minimum_wake_seconds) || !isIsoTimestamp(assignment.lease_expires_at)) throw new Error(message);
19788
+ if (state.schema_version === "vtx_codex_agent_runtime_v2") {
19789
+ if (!Array.isArray(assignment.data_contract) || assignment.data_contract.length === 0) {
19790
+ throw new Error(message);
19791
+ }
19792
+ const capabilityIds = assignment.data_contract.map((value2) => {
19793
+ const descriptor = assertPlainObject(value2, message);
19794
+ if (!hasExactKeys(descriptor, [
19795
+ "id",
19796
+ "title",
19797
+ "description",
19798
+ "input_schema",
19799
+ "input_schema_sha256"
19800
+ ]) || typeof descriptor.id !== "string" || !descriptor.id || typeof descriptor.title !== "string" || !descriptor.title || typeof descriptor.description !== "string" || !descriptor.description || !descriptor.input_schema || typeof descriptor.input_schema !== "object" || Array.isArray(descriptor.input_schema) || typeof descriptor.input_schema_sha256 !== "string" || !/^[0-9a-f]{64}$/u.test(descriptor.input_schema_sha256)) throw new Error(message);
19801
+ return descriptor.id;
19802
+ });
19803
+ if (new Set(capabilityIds).size !== capabilityIds.length) throw new Error(message);
19804
+ }
19759
19805
  if (state.thread !== null) {
19760
19806
  const thread = assertPlainObject(state.thread, message);
19761
19807
  if (!hasExactKeys(thread, [
@@ -19909,7 +19955,7 @@ async function logoutCodexSubscription(options) {
19909
19955
  await session.close();
19910
19956
  }
19911
19957
  }
19912
- var CODEX_INFERENCE_PERMISSION_PROFILE, CODEX_AGENT_PERMISSION_PROFILE, CODEX_REASONING_CONTENT_MAX_UTF8_BYTES, CODEX_REASONING_SUMMARY_MAX_UTF8_BYTES, CODEX_ACCOUNT_PLAN_TYPES, CODEX_AGENT_DYNAMIC_TOOLS, CodexAppServerError, objectOrNull, finiteToken, tokenUsageFromBreakdown, usageFromNotification, validPlanType, nonnegativeSafeIntegerOrNull, nonnegativeFiniteNumberOrNull, parseRateLimitWindow, RATE_LIMIT_REACHED_TYPES, DEFAULT_CODEX_QUOTA_COOLDOWN_MS, MAX_CODEX_QUOTA_COOLDOWN_MS, CODEX_TRANSIENT_RATE_LIMIT_COOLDOWN_MS, parseRateLimitSnapshot, codexRateLimitRetryAtMs, codexAccountRateLimitReached, forbiddenMethod, forbiddenTerminalItem, forbiddenAgentMethod, forbiddenAgentTerminalItem, CODEX_AGENT_TOOL_SPECS, classifyCodexTurnFailure, scrubbedCodexEnvironment, killWindowsProcessTree, appServerArgs, GUARDIAN_SCRIPT, WINDOWS_RECEIPT_REPLACE_ERROR_CODES, MAX_RETIRED_RESPONSE_IDS, LATE_RESPONSE_SAFE_METHODS, replaceCodexGuardianReceiptFile, writeCodexGuardianSpawnIntent, parseGuardianReceipt, readCodexGuardianReceipt, waitForCodexGuardianState, defaultSpawn, CodexAppServerSession;
19958
+ var CODEX_INFERENCE_PERMISSION_PROFILE, CODEX_AGENT_PERMISSION_PROFILE, CODEX_REASONING_CONTENT_MAX_UTF8_BYTES, CODEX_REASONING_SUMMARY_MAX_UTF8_BYTES, CODEX_ACCOUNT_PLAN_TYPES, CODEX_AGENT_DYNAMIC_TOOLS, CodexAppServerError, objectOrNull, finiteToken, tokenUsageFromBreakdown, usageFromNotification, validPlanType, nonnegativeSafeIntegerOrNull, nonnegativeFiniteNumberOrNull, parseRateLimitWindow, RATE_LIMIT_REACHED_TYPES, DEFAULT_CODEX_QUOTA_COOLDOWN_MS, MAX_CODEX_QUOTA_COOLDOWN_MS, CODEX_TRANSIENT_RATE_LIMIT_COOLDOWN_MS, parseRateLimitSnapshot, codexRateLimitRetryAtMs, codexAccountRateLimitReached, forbiddenMethod, forbiddenTerminalItem, forbiddenAgentMethod, forbiddenAgentTerminalItem, createCodexAgentToolSpecs, classifyCodexTurnFailure, scrubbedCodexEnvironment, killWindowsProcessTree, appServerArgs, GUARDIAN_SCRIPT, WINDOWS_RECEIPT_REPLACE_ERROR_CODES, MAX_RETIRED_RESPONSE_IDS, LATE_RESPONSE_SAFE_METHODS, replaceCodexGuardianReceiptFile, writeCodexGuardianSpawnIntent, parseGuardianReceipt, readCodexGuardianReceipt, waitForCodexGuardianState, defaultSpawn, CodexAppServerSession;
19913
19959
  var init_codex_app_server = __esm({
19914
19960
  "lib/inference-host/codex-app-server.ts"() {
19915
19961
  "use strict";
@@ -20074,41 +20120,62 @@ var init_codex_app_server = __esm({
20074
20120
  "webSearch",
20075
20121
  "contextCompaction"
20076
20122
  ].includes(String(item.type || ""));
20077
- CODEX_AGENT_TOOL_SPECS = [
20078
- {
20079
- name: "vtx_get_data",
20080
- description: "Request assignment-scoped VTX data. Choose the capability and only the arguments needed for this decision.",
20081
- inputSchema: {
20082
- type: "object",
20083
- additionalProperties: false,
20084
- required: ["capability", "arguments"],
20085
- properties: {
20086
- capability: { type: "string", minLength: 1 },
20087
- arguments: { type: "object" }
20088
- }
20089
- }
20090
- },
20091
- {
20092
- name: "vtx_submit_decision",
20093
- description: "Submit one VTX structured trading decision candidate using the assignment decision schema.",
20094
- inputSchema: {
20095
- type: "object",
20096
- additionalProperties: false,
20097
- required: ["candidate"],
20098
- properties: { candidate: { type: "object" } }
20123
+ createCodexAgentToolSpecs = (dataContract, decisionSchema) => {
20124
+ if (dataContract.length === 0 || Object.keys(decisionSchema).length === 0) {
20125
+ throw new CodexAppServerError({
20126
+ message: "Codex Agent data contract is unavailable.",
20127
+ category: "schema",
20128
+ code: "invalid_agent_data_contract",
20129
+ retryable: false
20130
+ });
20131
+ }
20132
+ const dataRequestBranches = dataContract.map((descriptor) => ({
20133
+ type: "object",
20134
+ additionalProperties: false,
20135
+ required: ["capability", "arguments"],
20136
+ description: descriptor.description,
20137
+ properties: {
20138
+ capability: {
20139
+ type: "string",
20140
+ const: descriptor.id,
20141
+ title: descriptor.title
20142
+ },
20143
+ arguments: descriptor.input_schema
20099
20144
  }
20100
- },
20101
- {
20102
- name: "vtx_decision_status",
20103
- description: "Resolve the durable status of a previously attempted decision operation.",
20104
- inputSchema: {
20105
- type: "object",
20106
- additionalProperties: false,
20107
- required: ["operation_id"],
20108
- properties: { operation_id: { type: "string", minLength: 1 } }
20145
+ }));
20146
+ return [
20147
+ {
20148
+ type: "function",
20149
+ name: "vtx_get_data",
20150
+ description: "Request assignment-scoped VTX data using one exact canonical capability schema.",
20151
+ inputSchema: {
20152
+ oneOf: dataRequestBranches
20153
+ }
20154
+ },
20155
+ {
20156
+ type: "function",
20157
+ name: "vtx_submit_decision",
20158
+ description: "Submit one VTX structured trading decision candidate using the assignment decision schema.",
20159
+ inputSchema: {
20160
+ type: "object",
20161
+ additionalProperties: false,
20162
+ required: ["candidate"],
20163
+ properties: { candidate: decisionSchema }
20164
+ }
20165
+ },
20166
+ {
20167
+ type: "function",
20168
+ name: "vtx_decision_status",
20169
+ description: "Resolve the durable status of a previously attempted decision operation.",
20170
+ inputSchema: {
20171
+ type: "object",
20172
+ additionalProperties: false,
20173
+ required: ["operation_id"],
20174
+ properties: { operation_id: { type: "string", minLength: 1 } }
20175
+ }
20109
20176
  }
20110
- }
20111
- ];
20177
+ ];
20178
+ };
20112
20179
  classifyCodexTurnFailure = (codexErrorInfo, terminalStatus) => {
20113
20180
  if (terminalStatus === "interrupted") {
20114
20181
  return { code: "cancelled", category: "cancelled", retryable: false, httpStatusCode: null };
@@ -20272,7 +20339,7 @@ var init_codex_app_server = __esm({
20272
20339
  });
20273
20340
  });
20274
20341
  };
20275
- appServerArgs = () => {
20342
+ appServerArgs = (enableAgentCodeModeHost = false) => {
20276
20343
  const args = [
20277
20344
  "app-server",
20278
20345
  "--stdio",
@@ -20295,8 +20362,9 @@ var init_codex_app_server = __esm({
20295
20362
  "memories",
20296
20363
  "image_generation",
20297
20364
  "multi_agent",
20298
- "code_mode_host"
20365
+ ...enableAgentCodeModeHost ? [] : ["code_mode_host"]
20299
20366
  ]) args.push("--disable", feature);
20367
+ if (enableAgentCodeModeHost) args.push("--enable", "code_mode_host");
20300
20368
  return args;
20301
20369
  };
20302
20370
  GUARDIAN_SCRIPT = String.raw`
@@ -20641,7 +20709,9 @@ child.once('close', async (code, signal) => {
20641
20709
  });
20642
20710
  }
20643
20711
  }
20644
- const child = spawnProcess(options.binary.path, appServerArgs(), {
20712
+ const child = spawnProcess(options.binary.path, appServerArgs(
20713
+ options.enableAgentCodeModeHost === true
20714
+ ), {
20645
20715
  env: scrubbedCodexEnvironment(options.codexHome),
20646
20716
  stdio: ["pipe", "pipe", "pipe"],
20647
20717
  windowsHide: true,
@@ -21445,7 +21515,7 @@ child.once('close', async (code, signal) => {
21445
21515
  ephemeral: false,
21446
21516
  historyMode: "legacy",
21447
21517
  environments: [],
21448
- dynamicTools: CODEX_AGENT_TOOL_SPECS,
21518
+ dynamicTools: createCodexAgentToolSpecs(options.dataContract, options.decisionSchema),
21449
21519
  selectedCapabilityRoots: [],
21450
21520
  experimentalRawEvents: false,
21451
21521
  developerInstructions: options.systemPrompt,
@@ -21457,9 +21527,9 @@ child.once('close', async (code, signal) => {
21457
21527
  web_search: "live",
21458
21528
  features: {
21459
21529
  apps: false,
21460
- code_mode: false,
21530
+ code_mode: true,
21461
21531
  code_mode_buffered_exec: false,
21462
- code_mode_host: false,
21532
+ code_mode_host: true,
21463
21533
  code_mode_only: false,
21464
21534
  in_app_browser: false,
21465
21535
  js_repl: false,
@@ -23648,6 +23718,7 @@ var init_codex_adapter = __esm({
23648
23718
  deadlineAtMs,
23649
23719
  signal,
23650
23720
  spawnProcess: this.dependencies.spawnProcess,
23721
+ enableAgentCodeModeHost: true,
23651
23722
  guardian: this.guardianProcessToken && this.guardianReceiptPath ? {
23652
23723
  processToken: this.guardianProcessToken,
23653
23724
  receiptPath: this.guardianReceiptPath
@@ -23695,6 +23766,8 @@ var init_codex_adapter = __esm({
23695
23766
  systemPrompt: input.systemPrompt,
23696
23767
  requestedModel: input.requestedModel,
23697
23768
  requestedReasoningEffort: input.requestedReasoningEffort,
23769
+ dataContract: input.dataContract,
23770
+ decisionSchema: input.decisionSchema,
23698
23771
  deadlineAtMs: input.deadlineAtMs,
23699
23772
  signal: input.signal
23700
23773
  });
@@ -23707,6 +23780,8 @@ var init_codex_adapter = __esm({
23707
23780
  systemPrompt: input.systemPrompt,
23708
23781
  requestedModel: input.requestedModel,
23709
23782
  requestedReasoningEffort: input.requestedReasoningEffort,
23783
+ dataContract: input.dataContract,
23784
+ decisionSchema: input.decisionSchema,
23710
23785
  deadlineAtMs: input.deadlineAtMs,
23711
23786
  signal: input.signal
23712
23787
  });
@@ -33015,7 +33090,10 @@ var init_runner = __esm({
33015
33090
  };
33016
33091
  createCodexAgentControlClient = (mcp) => ({
33017
33092
  nextAssignment: async (request, options) => {
33018
- const result2 = await mcp.callTool("inference.agent.assignment.next", request, options);
33093
+ const result2 = await mcp.callTool("inference.agent.assignment.next", {
33094
+ ...request,
33095
+ contract_version: "agent_assignment_v2"
33096
+ }, options);
33019
33097
  if (result2.claim_state === "empty") return null;
33020
33098
  return {
33021
33099
  assignment_id: result2.assignment_id,
@@ -33025,6 +33103,7 @@ var init_runner = __esm({
33025
33103
  bot_mode: result2.bot_mode,
33026
33104
  execution_mode: result2.execution_mode,
33027
33105
  allowed_symbols: result2.allowed_symbols,
33106
+ data_contract: result2.data_contract,
33028
33107
  output_schema: result2.output_schema,
33029
33108
  minimum_wake_seconds: result2.minimum_wake_seconds,
33030
33109
  maximum_wake_seconds: result2.maximum_wake_seconds,
@@ -33119,13 +33198,20 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33119
33198
  }
33120
33199
  async runOnce(signal) {
33121
33200
  const nowIso = () => new Date(this.now()).toISOString();
33122
- let state = await readCodexAgentRuntimeState(this.options.statePath);
33123
- if (state && state.host_id !== this.options.hostId) {
33201
+ const recoveredState = await readCodexAgentRuntimeState(this.options.statePath);
33202
+ if (recoveredState && recoveredState.host_id !== this.options.hostId) {
33124
33203
  throw new InferenceHostRunnerError(
33125
33204
  "agent_recovery_scope_mismatch",
33126
33205
  "Codex Agent recovery state belongs to another host."
33127
33206
  );
33128
33207
  }
33208
+ let state;
33209
+ if (recoveredState?.schema_version === "vtx_codex_agent_runtime_v1") {
33210
+ state = await this.upgradeLegacyRuntimeState(recoveredState, signal);
33211
+ if (!state) return this.now() + (this.options.idlePollMs ?? 5e3);
33212
+ } else {
33213
+ state = recoveredState ?? null;
33214
+ }
33129
33215
  if (!state) {
33130
33216
  const assignment2 = await this.options.controlClient.nextAssignment({
33131
33217
  operation_id: randomUUID(),
@@ -33134,7 +33220,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33134
33220
  }, { signal });
33135
33221
  if (!assignment2) return this.now() + (this.options.idlePollMs ?? 5e3);
33136
33222
  state = {
33137
- schema_version: "vtx_codex_agent_runtime_v1",
33223
+ schema_version: "vtx_codex_agent_runtime_v2",
33138
33224
  host_id: this.options.hostId,
33139
33225
  assignment: assignment2,
33140
33226
  thread: null,
@@ -33150,8 +33236,11 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33150
33236
  if (wakeOutcome !== "ready") {
33151
33237
  return this.now() + (this.options.idlePollMs ?? 5e3);
33152
33238
  }
33153
- state = await readCodexAgentRuntimeState(this.options.statePath);
33154
- if (!state) return this.now() + (this.options.idlePollMs ?? 5e3);
33239
+ const rereadState = await readCodexAgentRuntimeState(this.options.statePath);
33240
+ if (rereadState?.schema_version !== "vtx_codex_agent_runtime_v2") {
33241
+ return this.now() + (this.options.idlePollMs ?? 5e3);
33242
+ }
33243
+ state = rereadState;
33155
33244
  }
33156
33245
  }
33157
33246
  state = await this.resolvePendingDecision(state, signal);
@@ -33213,6 +33302,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33213
33302
  bot_mode: assignment.bot_mode,
33214
33303
  execution_mode: assignment.execution_mode,
33215
33304
  allowed_symbols: assignment.allowed_symbols,
33305
+ data_capability_ids: assignment.data_contract.map((descriptor) => descriptor.id),
33216
33306
  output_schema: assignment.output_schema,
33217
33307
  wake_bounds_seconds: {
33218
33308
  minimum: assignment.minimum_wake_seconds,
@@ -33220,6 +33310,8 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33220
33310
  }
33221
33311
  }),
33222
33312
  outputSchema: CODEX_AGENT_WAKE_SCHEMA,
33313
+ dataContract: assignment.data_contract,
33314
+ decisionSchema: assignment.output_schema,
33223
33315
  requestedModel: assignment.model_id,
33224
33316
  requestedReasoningEffort: assignment.reasoning_effort,
33225
33317
  deadlineAtMs,
@@ -33232,7 +33324,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33232
33324
  if (call.tool === "vtx_get_data") {
33233
33325
  const capability = typeof call.arguments.capability === "string" ? call.arguments.capability.trim() : "";
33234
33326
  const args = call.arguments.arguments;
33235
- if (!capability || !args || typeof args !== "object" || Array.isArray(args)) {
33327
+ if (!capability || !assignment.data_contract.some((descriptor) => descriptor.id === capability) || !args || typeof args !== "object" || Array.isArray(args)) {
33236
33328
  return { success: false, value: { error: "invalid_data_request" } };
33237
33329
  }
33238
33330
  const value = await this.options.controlClient.dataCall({
@@ -33368,6 +33460,40 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33368
33460
  await heartbeatTask.catch(() => void 0);
33369
33461
  }
33370
33462
  }
33463
+ async upgradeLegacyRuntimeState(legacyState, signal) {
33464
+ const state = await this.resolveLegacyPendingDecision(legacyState, signal);
33465
+ if (state.pending_decision) return null;
33466
+ if (state.thread) {
33467
+ await this.options.adapter.releaseThread(state.thread).catch(() => void 0);
33468
+ }
33469
+ await clearCodexAgentRuntimeState(this.options.statePath);
33470
+ return null;
33471
+ }
33472
+ async resolveLegacyPendingDecision(state, signal) {
33473
+ const pending = state.pending_decision;
33474
+ if (!pending) return state;
33475
+ const checkedAt = new Date(this.now()).toISOString();
33476
+ const checking = {
33477
+ ...state,
33478
+ pending_decision: { ...pending, last_status_check_at: checkedAt },
33479
+ updated_at: checkedAt
33480
+ };
33481
+ await writeCodexAgentRuntimeState(this.options.statePath, checking);
33482
+ const status = await this.options.controlClient.decisionStatus({
33483
+ host_id: this.options.hostId,
33484
+ assignment_id: state.assignment.assignment_id,
33485
+ assignment_generation: state.assignment.assignment_generation,
33486
+ operation_id: pending.operation_id
33487
+ }, { signal });
33488
+ if (status.status !== "applied" && status.status !== "not_applied") return checking;
33489
+ const resolved = {
33490
+ ...checking,
33491
+ pending_decision: null,
33492
+ updated_at: new Date(this.now()).toISOString()
33493
+ };
33494
+ await writeCodexAgentRuntimeState(this.options.statePath, resolved);
33495
+ return resolved;
33496
+ }
33371
33497
  async resolvePendingDecision(state, signal) {
33372
33498
  const pending = state.pending_decision;
33373
33499
  if (!pending) return state;
@@ -33415,7 +33541,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33415
33541
  if (this.stopped || signal?.aborted) return "stopped";
33416
33542
  if (this.now() >= nextWakeAtMs) return "ready";
33417
33543
  const state = await readCodexAgentRuntimeState(this.options.statePath);
33418
- if (!state) return "cancelled";
33544
+ if (state?.schema_version !== "vtx_codex_agent_runtime_v2") return "cancelled";
33419
33545
  const requestedAt = new Date(this.now()).toISOString();
33420
33546
  const heartbeat = await this.options.controlClient.heartbeat({
33421
33547
  operation_id: randomUUID(),
@@ -33443,7 +33569,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33443
33569
  let state = await readCodexAgentRuntimeState(this.options.statePath);
33444
33570
  if (!state) return;
33445
33571
  try {
33446
- state = await this.resolvePendingDecision(state);
33572
+ state = state.schema_version === "vtx_codex_agent_runtime_v1" ? await this.resolveLegacyPendingDecision(state) : await this.resolvePendingDecision(state);
33447
33573
  } catch {
33448
33574
  return;
33449
33575
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vtxmacro/cli",
3
- "version": "2026.8.50",
3
+ "version": "2026.8.51",
4
4
  "description": "VTX Macro CLI, MCP server, and durable subscription inference host.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",