@vtxmacro/cli 2026.9.19 → 2026.9.20

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/README.md CHANGED
@@ -250,10 +250,22 @@ vtx inference-host agent-next --wait-seconds 50 --json
250
250
  That is the **Provider** loop. `agent-next` returns separate exact
251
251
  `system_prompt`, `user_prompt`,
252
252
  `context_json`, and `output_schema_json` fields. The agent reasons in its own
253
- session, then writes one JSON object to `agent-complete` stdin. At minimum that
254
- object contains a `result` string. If the harness exposes exact token usage,
255
- include the published usage object; otherwise VTX records usage as explicitly
256
- unavailable. For `agent-fail`, choose the truthful dispatch state and set
253
+ session, then writes one JSON object to `agent-complete` stdin. The CLI reports
254
+ its actual release version and negotiates `foreground_v1` Provider freshness.
255
+ Prewarm the harness before requesting work. For Server Mode jobs, the handoff includes
256
+ `provider_dispatch_not_after`, `provider_dispatch_local_not_after`, and
257
+ `provider_dispatch_freshness_remaining_ms`; the local deadline and remaining
258
+ budget account conservatively for RPC time and pending-request replay. Enforce
259
+ both deadlines immediately before the real provider request. If either expires
260
+ before dispatch, do not send stale work: use `agent-fail` with
261
+ `dispatch_outcome: not_dispatched`, `failure_category: freshness`,
262
+ `failure_code: provider_dispatch_freshness_expired`, and `retryable: false`.
263
+ Completion contains a `result` string; negotiated server jobs also require
264
+ `provider_dispatched_at`, the ISO 8601 timestamp captured at provider request
265
+ entry. This is harness-reported evidence, not provider attestation. If the harness
266
+ exposes exact token usage, include the published usage object; otherwise VTX
267
+ records usage as explicitly unavailable. For `agent-fail`, choose the truthful
268
+ dispatch state and set
257
269
  `retryable` true only when a fresh attempt is safe:
258
270
 
259
271
  ```json
@@ -16,7 +16,7 @@ import { fileURLToPath } from "node:url";
16
16
  // agent-cli-release.json
17
17
  var agent_cli_release_default = {
18
18
  package_name: "@vtxmacro/cli",
19
- package_version: "2026.9.19",
19
+ package_version: "2026.9.20",
20
20
  codex_package_name: "@openai/codex",
21
21
  codex_version: "0.153.3",
22
22
  copilot_sdk_package_name: "@github/copilot-sdk",
package/bin/vtx.js CHANGED
@@ -69,7 +69,7 @@ var init_agent_cli_release = __esm({
69
69
  "agent-cli-release.json"() {
70
70
  agent_cli_release_default = {
71
71
  package_name: "@vtxmacro/cli",
72
- package_version: "2026.9.19",
72
+ package_version: "2026.9.20",
73
73
  codex_package_name: "@openai/codex",
74
74
  codex_version: "0.153.3",
75
75
  copilot_sdk_package_name: "@github/copilot-sdk",
@@ -15014,12 +15014,16 @@ var init_external_inference_contract = __esm({
15014
15014
  authenticated_account_plan: safeCodeSchema.nullable().optional(),
15015
15015
  protocol_version: protocolVersionSchema,
15016
15016
  host_runtime_version: protocolVersionSchema.optional(),
15017
+ provider_dispatch_freshness_contract: external_exports.literal("foreground_v1").optional(),
15017
15018
  envelope_public_key: base64Url32BytesSchema,
15018
15019
  health: external_exports.enum(["healthy", "degraded", "draining"]),
15019
15020
  advertised_at: timestampSchema,
15020
15021
  expires_at: timestampSchema,
15021
15022
  models: external_exports.array(advertisedModelSchema).min(1).max(64)
15022
15023
  }).superRefine((value, context) => {
15024
+ if (value.provider_dispatch_freshness_contract !== void 0 && !/^\d+\.\d+\.\d+$/.test(value.host_runtime_version ?? "")) {
15025
+ context.addIssue({ code: "custom", message: "Foreground freshness contract requires a numeric runtime version." });
15026
+ }
15023
15027
  const modelIds = value.models.map((model) => model.model_id);
15024
15028
  if (new Set(modelIds).size !== modelIds.length) {
15025
15029
  context.addIssue({
@@ -15420,12 +15424,17 @@ var init_external_inference_contract = __esm({
15420
15424
  model_id: identifierSchema,
15421
15425
  model_label: displayNameSchema,
15422
15426
  reasoning_effort: reasoningEffortSchema,
15423
- requested_at: timestampSchema
15427
+ requested_at: timestampSchema,
15428
+ host_runtime_version: external_exports.string().regex(/^\d+\.\d+\.\d+$/).optional(),
15429
+ provider_dispatch_freshness_contract: external_exports.literal("foreground_v1").optional()
15430
+ }).refine((value) => value.host_runtime_version === void 0 === (value.provider_dispatch_freshness_contract === void 0), {
15431
+ message: "Foreground freshness negotiation requires the actual CLI version."
15424
15432
  });
15425
15433
  agentNextRequestSchema = external_exports.strictObject({
15426
15434
  operation_id: operationIdentifierSchema,
15427
15435
  host_id: identifierSchema,
15428
- requested_at: timestampSchema
15436
+ requested_at: timestampSchema,
15437
+ provider_dispatch_freshness_contract: external_exports.literal("foreground_v1").optional()
15429
15438
  });
15430
15439
  agentHeartbeatRequestSchema = external_exports.strictObject({
15431
15440
  operation_id: operationIdentifierSchema,
@@ -15449,6 +15458,9 @@ var init_external_inference_contract = __esm({
15449
15458
  requested_reasoning_effort: reasoningEffortSchema,
15450
15459
  output_schema_version: protocolVersionSchema,
15451
15460
  deadline_at: timestampSchema,
15461
+ provider_dispatch_freshness_contract: external_exports.literal("foreground_v1").optional(),
15462
+ provider_dispatch_not_after: timestampSchema.optional(),
15463
+ provider_dispatch_freshness_remaining_ms: nonNegativeSafeIntegerSchema.optional(),
15452
15464
  system_prompt: boundedPromptTextSchema,
15453
15465
  system_prompt_sha256: sha256HexSchema,
15454
15466
  user_prompt: boundedPromptTextSchema,
@@ -15458,6 +15470,14 @@ var init_external_inference_contract = __esm({
15458
15470
  output_schema_json: boundedJsonTextSchema,
15459
15471
  output_schema_sha256: sha256HexSchema
15460
15472
  }).superRefine((value, context) => {
15473
+ const freshnessFields = [
15474
+ value.provider_dispatch_freshness_contract,
15475
+ value.provider_dispatch_not_after,
15476
+ value.provider_dispatch_freshness_remaining_ms
15477
+ ];
15478
+ if (freshnessFields.some((field) => field !== void 0) && (freshnessFields.some((field) => field === void 0) || value.execution_mode !== "server")) {
15479
+ context.addIssue({ code: "custom", message: "Foreground freshness handoff is incomplete." });
15480
+ }
15461
15481
  for (const [field, exact, digest] of [
15462
15482
  ["system_prompt", value.system_prompt, value.system_prompt_sha256],
15463
15483
  ["user_prompt", value.user_prompt, value.user_prompt_sha256],
@@ -15489,7 +15509,8 @@ var init_external_inference_contract = __esm({
15489
15509
  time_to_first_token_ms: nonNegativeSafeIntegerSchema.nullable().optional(),
15490
15510
  finish_reason: safeCodeSchema.nullable().optional(),
15491
15511
  refusal_status: external_exports.enum(["none", "refused", "blocked", "unknown"]),
15492
- completed_at: timestampSchema
15512
+ completed_at: timestampSchema,
15513
+ provider_dispatched_at: timestampSchema.nullable().optional()
15493
15514
  }).superRefine((value, context) => {
15494
15515
  if (value.time_to_first_token_ms !== void 0 && value.time_to_first_token_ms !== null && value.time_to_first_token_ms > value.latency_ms) {
15495
15516
  context.addIssue({
@@ -19850,7 +19871,7 @@ var init_mcp_client = __esm({
19850
19871
  const hasPublicToolErrorMarker = hasStructuredPublicToolErrorMarker || errorText.includes(PUBLIC_TOOL_ERROR_PREFIX);
19851
19872
  const completionEvidenceExpired = name === "inference.job.complete" && (publicToolError ? publicToolError.failure_code === "completion_evidence_expired" && publicToolError.phase === "validation" && publicToolError.retryable === false && publicToolError.terminal_before_execution === true : !hasPublicToolErrorMarker && errorText.includes("External inference completion evidence window expired"));
19852
19873
  const hostNotClaimable = name === "inference.job.claim" && publicToolError?.failure_code === "host_not_claimable" && publicToolError.phase === "admission" && publicToolError.retryable === true && publicToolError.terminal_before_execution === true;
19853
- const definitivelyNotApplied = (name === "inference.host.register" || name === "inference.host.advertise") && (errorText.includes("Advertisement time is outside the allowed clock skew.") || errorText.includes("Advertisement is already expired.")) || (name === "inference.agent.next" || name === "inference.agent.heartbeat") && (errorText.includes("Advertisement time is outside the allowed clock skew.") || errorText.includes("Advertisement is already expired.") || errorText.includes("Heartbeat time is outside the allowed clock skew.")) || name === "inference.host.heartbeat" && errorText.includes("Heartbeat time is outside the allowed clock skew.") || name === "inference.job.claim" && (errorText.includes(
19874
+ const definitivelyNotApplied = name === "inference.agent.decision.submit" && publicToolError?.phase === "validation" && publicToolError.retryable === false && publicToolError.terminal_before_execution === true && (publicToolError.failure_code === "agent_decision_schema_invalid" || publicToolError.failure_code === "invalid_arguments" && publicToolError.reason_code === "schema_validation") || (name === "inference.host.register" || name === "inference.host.advertise") && (errorText.includes("Advertisement time is outside the allowed clock skew.") || errorText.includes("Advertisement is already expired.")) || (name === "inference.agent.next" || name === "inference.agent.heartbeat") && (errorText.includes("Advertisement time is outside the allowed clock skew.") || errorText.includes("Advertisement is already expired.") || errorText.includes("Heartbeat time is outside the allowed clock skew.")) || name === "inference.host.heartbeat" && errorText.includes("Heartbeat time is outside the allowed clock skew.") || name === "inference.job.claim" && (errorText.includes(
19854
19875
  "External inference claim request was not applied before its generation became stale"
19855
19876
  ) || errorText.includes("External inference host advertisement is expired or superseded")) || name === "inference.job.complete" && completionEvidenceExpired;
19856
19877
  const retryableInfrastructureRejection = EXTERNAL_INFERENCE_AUTOMATED_HOST_TOOLS.includes(name) && (errorText.includes("External inference polling is at its configured concurrency limit") || errorText.includes("The Insights action reached the response timeout") || errorText.includes("Insights capability failed without exposing private runtime details"));
@@ -21222,6 +21243,19 @@ var init_agent_state = __esm({
21222
21243
  "received_at",
21223
21244
  "pending_terminal"
21224
21245
  ];
21246
+ const freshnessKeys = ["provider_dispatch_not_after", "provider_dispatch_local_not_after"];
21247
+ if ("execution_mode" in record3) {
21248
+ if (!["server", "client"].includes(String(record3.execution_mode))) {
21249
+ throw new Error("Agent-driven inference execution mode is invalid.");
21250
+ }
21251
+ exactKeys.push("execution_mode");
21252
+ }
21253
+ if (freshnessKeys.some((key) => key in record3)) {
21254
+ if (freshnessKeys.some((key) => typeof record3[key] !== "string" || !Number.isFinite(Date.parse(record3[key])))) {
21255
+ throw new Error("Agent-driven inference freshness recovery state is invalid.");
21256
+ }
21257
+ exactKeys.push(...freshnessKeys);
21258
+ }
21225
21259
  if (Object.keys(record3).sort().join("\0") !== exactKeys.slice().sort().join("\0") || record3.schema_version !== "vtx_inference_agent_attempt_v1" || typeof record3.host_id !== "string" || !record3.host_id || typeof record3.job_id !== "string" || !record3.job_id || typeof record3.attempt_id !== "string" || !record3.attempt_id || typeof record3.claim_handle !== "string" || !record3.claim_handle || typeof record3.completion_operation_id !== "string" || !record3.completion_operation_id || typeof record3.failure_operation_id !== "string" || !record3.failure_operation_id || typeof record3.requested_model !== "string" || !record3.requested_model || typeof record3.requested_reasoning_effort !== "string" || !record3.requested_reasoning_effort || !["provider_response", "decision_candidate"].includes(String(record3.response_mode)) || typeof record3.deadline_at !== "string" || !Number.isFinite(Date.parse(record3.deadline_at)) || typeof record3.received_at !== "string" || !Number.isFinite(Date.parse(record3.received_at))) {
21226
21260
  throw new Error("Agent-driven inference attempt state is invalid.");
21227
21261
  }
@@ -42400,7 +42434,9 @@ Waiting for approval...
42400
42434
  model_id: parsed.modelId,
42401
42435
  model_label: parsed.modelLabel ?? parsed.modelId,
42402
42436
  reasoning_effort: parsed.reasoningEffort,
42403
- requested_at: now.toISOString()
42437
+ requested_at: now.toISOString(),
42438
+ host_runtime_version: INFERENCE_HOST_CLI_VERSION,
42439
+ provider_dispatch_freshness_contract: "foreground_v1"
42404
42440
  });
42405
42441
  return {
42406
42442
  exitCode: 0,
@@ -42771,6 +42807,14 @@ Waiting for approval...
42771
42807
  ` : ""
42772
42808
  };
42773
42809
  } catch (error48) {
42810
+ if (error48 instanceof ExternalInferenceMcpError && error48.definitivelyNotApplied) {
42811
+ await writeInferenceForegroundAgentControlState(config2.statePath, {
42812
+ ...state,
42813
+ pending_decision: null,
42814
+ updated_at: now().toISOString()
42815
+ });
42816
+ throw error48;
42817
+ }
42774
42818
  const checkedAt = now().toISOString();
42775
42819
  state = {
42776
42820
  ...state,
@@ -43031,11 +43075,14 @@ Waiting for approval...
43031
43075
  await writeInferenceAgentNextState(config2.statePath, pending);
43032
43076
  }
43033
43077
  let result2;
43078
+ const callStartedAtMs = now().getTime();
43079
+ const callStartedMonotonicMs = performance.now();
43034
43080
  try {
43035
43081
  result2 = await session.client.callTool("inference.agent.next", {
43036
43082
  operation_id: pending.operation_id,
43037
43083
  host_id: session.localState.host_id,
43038
- requested_at: pending.requested_at
43084
+ requested_at: pending.requested_at,
43085
+ provider_dispatch_freshness_contract: "foreground_v1"
43039
43086
  });
43040
43087
  } catch (error48) {
43041
43088
  const definitivelyNotApplied = Boolean(
@@ -43048,10 +43095,31 @@ Waiting for approval...
43048
43095
  }
43049
43096
  if (result2.claim_state === "claimed") {
43050
43097
  const receivedAt = now().toISOString();
43098
+ const receivedAtMs = Date.parse(receivedAt);
43099
+ const roundTripMs = Math.max(0, dependencies.now ? receivedAtMs - callStartedAtMs : performance.now() - callStartedMonotonicMs);
43100
+ let localDispatchDeadline;
43101
+ const validFreshness = result2.provider_dispatch_freshness_contract === "foreground_v1" && typeof result2.provider_dispatch_not_after === "string" && Number.isFinite(Date.parse(result2.provider_dispatch_not_after)) && Number.isSafeInteger(result2.provider_dispatch_freshness_remaining_ms) && Number(result2.provider_dispatch_freshness_remaining_ms) >= 0;
43102
+ if (result2.execution_mode === "server" && validFreshness) {
43103
+ const conservativeDeadline = Math.min(
43104
+ Date.parse(result2.provider_dispatch_not_after),
43105
+ receivedAtMs + Number(result2.provider_dispatch_freshness_remaining_ms) - roundTripMs,
43106
+ Date.parse(pending.requested_at) + Number(result2.provider_dispatch_freshness_remaining_ms),
43107
+ active?.provider_dispatch_local_not_after ? Date.parse(active.provider_dispatch_local_not_after) : Number.POSITIVE_INFINITY
43108
+ );
43109
+ localDispatchDeadline = new Date(conservativeDeadline).toISOString();
43110
+ }
43051
43111
  if (active) {
43052
- if (result2.job_id !== active.job_id || result2.attempt_id !== active.attempt_id || result2.claim_handle !== active.claim_handle || result2.requested_model !== active.requested_model || result2.requested_reasoning_effort !== active.requested_reasoning_effort || result2.response_mode !== active.response_mode || result2.deadline_at !== active.deadline_at) {
43112
+ if (result2.job_id !== active.job_id || result2.attempt_id !== active.attempt_id || result2.claim_handle !== active.claim_handle || result2.requested_model !== active.requested_model || result2.requested_reasoning_effort !== active.requested_reasoning_effort || result2.response_mode !== active.response_mode || result2.deadline_at !== active.deadline_at || active.provider_dispatch_not_after !== void 0 && result2.provider_dispatch_not_after !== active.provider_dispatch_not_after) {
43053
43113
  throw new Error("Recovered agent job does not match the active private attempt state.");
43054
43114
  }
43115
+ if (localDispatchDeadline !== void 0) {
43116
+ await writeInferenceAgentAttemptState(config2.statePath, {
43117
+ ...active,
43118
+ execution_mode: result2.execution_mode,
43119
+ provider_dispatch_not_after: result2.provider_dispatch_not_after,
43120
+ provider_dispatch_local_not_after: localDispatchDeadline
43121
+ });
43122
+ }
43055
43123
  } else {
43056
43124
  await writeInferenceAgentAttemptState(config2.statePath, {
43057
43125
  schema_version: "vtx_inference_agent_attempt_v1",
@@ -43064,17 +43132,35 @@ Waiting for approval...
43064
43132
  requested_model: result2.requested_model,
43065
43133
  requested_reasoning_effort: result2.requested_reasoning_effort,
43066
43134
  response_mode: result2.response_mode,
43135
+ execution_mode: result2.execution_mode,
43067
43136
  deadline_at: result2.deadline_at,
43068
43137
  received_at: receivedAt,
43138
+ ...localDispatchDeadline === void 0 ? {} : {
43139
+ provider_dispatch_not_after: result2.provider_dispatch_not_after,
43140
+ provider_dispatch_local_not_after: localDispatchDeadline
43141
+ },
43069
43142
  pending_terminal: null
43070
43143
  });
43071
43144
  }
43145
+ if (result2.execution_mode === "server" && localDispatchDeadline === void 0) {
43146
+ throw new Error("The Server foreground Provider freshness receipt is unavailable. Fail this attempt without dispatch.");
43147
+ }
43148
+ if (localDispatchDeadline !== void 0 && Date.parse(localDispatchDeadline) <= now().getTime()) {
43149
+ throw new Error("The foreground Provider freshness budget expired before handoff. Use agent-fail with not_dispatched.");
43150
+ }
43072
43151
  const { claim_handle: _claimHandle, ...publicJob } = result2;
43073
43152
  return {
43074
43153
  exitCode: 0,
43075
43154
  stdout: render({
43076
43155
  ...publicJob,
43077
- instructions: "Treat system_prompt and user_prompt as separate VTX-delivered roles. Use context_json and satisfy output_schema_json exactly. Send only the final result through agent-complete stdin; do not execute trading tools yourself.",
43156
+ ...localDispatchDeadline === void 0 ? {} : {
43157
+ provider_dispatch_local_not_after: localDispatchDeadline,
43158
+ provider_dispatch_freshness_remaining_ms: Math.max(
43159
+ 0,
43160
+ Math.floor(Date.parse(localDispatchDeadline) - now().getTime())
43161
+ )
43162
+ },
43163
+ instructions: "Treat system_prompt and user_prompt as separate VTX-delivered roles. Use context_json and satisfy output_schema_json exactly. Send only the final result through agent-complete stdin; do not execute trading tools yourself. For Server Provider jobs enforce both provider dispatch deadlines at actual provider entry and report the self-attested provider_dispatched_at timestamp. If the budget expires before dispatch, use agent-fail with not_dispatched.",
43078
43164
  complete_command: "vtx inference-host agent-complete --json",
43079
43165
  fail_command: "vtx inference-host agent-fail --json"
43080
43166
  }, parsed.json),
@@ -43119,12 +43205,19 @@ Waiting for approval...
43119
43205
  "latency_ms",
43120
43206
  "time_to_first_token_ms",
43121
43207
  "finish_reason",
43122
- "refusal_status"
43208
+ "refusal_status",
43209
+ "provider_dispatched_at"
43123
43210
  ]);
43124
43211
  if (typeof input.result !== "string" || !input.result) {
43125
43212
  throw new Error("agent-complete stdin requires a non-empty result string.");
43126
43213
  }
43127
43214
  const now = (dependencies.now ?? (() => /* @__PURE__ */ new Date()))();
43215
+ if (state.execution_mode === "server" || state.provider_dispatch_not_after !== void 0) {
43216
+ const dispatchedAt = typeof input.provider_dispatched_at === "string" ? Date.parse(input.provider_dispatched_at) : Number.NaN;
43217
+ if (!Number.isFinite(dispatchedAt) || state.provider_dispatch_local_not_after === void 0 || state.provider_dispatch_not_after === void 0 || dispatchedAt < Date.parse(state.received_at) || dispatchedAt > Date.parse(state.provider_dispatch_local_not_after) || dispatchedAt > Date.parse(state.provider_dispatch_not_after) || dispatchedAt > now.getTime()) {
43218
+ throw new Error("agent-complete requires actual provider_dispatched_at within the foreground freshness handoff.");
43219
+ }
43220
+ }
43128
43221
  const measuredLatency = Math.max(0, now.getTime() - Date.parse(state.received_at));
43129
43222
  request = agentCompleteRequestSchema.parse({
43130
43223
  operation_id: state.completion_operation_id,
@@ -43148,7 +43241,10 @@ Waiting for approval...
43148
43241
  time_to_first_token_ms: input.time_to_first_token_ms == null ? null : Number(input.time_to_first_token_ms),
43149
43242
  finish_reason: input.finish_reason == null ? null : String(input.finish_reason),
43150
43243
  refusal_status: String(input.refusal_status ?? "none"),
43151
- completed_at: now.toISOString()
43244
+ completed_at: now.toISOString(),
43245
+ ...input.provider_dispatched_at == null ? {} : {
43246
+ provider_dispatched_at: String(input.provider_dispatched_at)
43247
+ }
43152
43248
  });
43153
43249
  await writeInferenceAgentAttemptState(config2.statePath, {
43154
43250
  ...state,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vtxmacro/cli",
3
- "version": "2026.9.19",
3
+ "version": "2026.9.20",
4
4
  "description": "VTX Macro CLI, MCP server, and durable external inference host.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",