@vtxmacro/cli 2026.9.67 → 2026.9.69

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.
@@ -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.67",
19
+ package_version: "2026.9.69",
20
20
  codex_package_name: "@openai/codex",
21
21
  codex_version: "0.155.0",
22
22
  copilot_sdk_package_name: "@github/copilot-sdk",
@@ -133,6 +133,14 @@ var runtime_policy_generated_default = {
133
133
  min_delay_milliseconds: 250,
134
134
  max_delay_milliseconds: 1e4
135
135
  },
136
+ trade_refresh_policy: {
137
+ server_config_stream_timeout_ms: 1e4,
138
+ config_retry_interval_ms: 5e3,
139
+ copy_trading_status_poll_ms: 5e3,
140
+ post_execution_refresh_delay_ms: 3e3,
141
+ account_read_backoff_min_ms: 2e3,
142
+ account_read_backoff_max_ms: 6e4
143
+ },
136
144
  deployment_reload_observability: {
137
145
  bootstrap_max_error_events_per_page: 4,
138
146
  bootstrap_max_profiles: 10
@@ -210,10 +218,12 @@ var runtime_policy_generated_default = {
210
218
  },
211
219
  server_runtime: {
212
220
  prompt_rescue: {
221
+ request_ttl_seconds: 20,
213
222
  snapshot_max_age_seconds: 5,
214
223
  snapshot_component_max_skew_seconds: 2,
215
- client_long_poll_seconds: 20,
216
- client_claim_http_timeout_milliseconds: 25e3,
224
+ client_claim_http_timeout_milliseconds: 5e3,
225
+ client_claim_retry_delay_milliseconds: 1e3,
226
+ client_failure_report_timeout_milliseconds: 2e3,
217
227
  client_presence_heartbeat_interval_milliseconds: 3e4,
218
228
  client_presence_http_timeout_milliseconds: 5e3
219
229
  }
@@ -16,6 +16,14 @@ var runtime_policy_generated_default = {
16
16
  min_delay_milliseconds: 250,
17
17
  max_delay_milliseconds: 1e4
18
18
  },
19
+ trade_refresh_policy: {
20
+ server_config_stream_timeout_ms: 1e4,
21
+ config_retry_interval_ms: 5e3,
22
+ copy_trading_status_poll_ms: 5e3,
23
+ post_execution_refresh_delay_ms: 3e3,
24
+ account_read_backoff_min_ms: 2e3,
25
+ account_read_backoff_max_ms: 6e4
26
+ },
19
27
  deployment_reload_observability: {
20
28
  bootstrap_max_error_events_per_page: 4,
21
29
  bootstrap_max_profiles: 10
@@ -93,10 +101,12 @@ var runtime_policy_generated_default = {
93
101
  },
94
102
  server_runtime: {
95
103
  prompt_rescue: {
104
+ request_ttl_seconds: 20,
96
105
  snapshot_max_age_seconds: 5,
97
106
  snapshot_component_max_skew_seconds: 2,
98
- client_long_poll_seconds: 20,
99
- client_claim_http_timeout_milliseconds: 25e3,
107
+ client_claim_http_timeout_milliseconds: 5e3,
108
+ client_claim_retry_delay_milliseconds: 1e3,
109
+ client_failure_report_timeout_milliseconds: 2e3,
100
110
  client_presence_heartbeat_interval_milliseconds: 3e4,
101
111
  client_presence_http_timeout_milliseconds: 5e3
102
112
  }
package/bin/vtx.js CHANGED
@@ -77,7 +77,7 @@ var init_agent_cli_release = __esm({
77
77
  "agent-cli-release.json"() {
78
78
  agent_cli_release_default = {
79
79
  package_name: "@vtxmacro/cli",
80
- package_version: "2026.9.67",
80
+ package_version: "2026.9.69",
81
81
  codex_package_name: "@openai/codex",
82
82
  codex_version: "0.155.0",
83
83
  copilot_sdk_package_name: "@github/copilot-sdk",
@@ -15727,6 +15727,8 @@ var init_external_inference_contract = __esm({
15727
15727
  }
15728
15728
  });
15729
15729
  providerWeeklyQuotaReadSchema = external_exports.strictObject({
15730
+ credits_available: external_exports.boolean().nullable().optional(),
15731
+ rate_limit_reached: external_exports.boolean().nullable().optional(),
15730
15732
  source: external_exports.literal("codex_app_server"),
15731
15733
  used_percent: external_exports.number().finite().min(0).max(1e6),
15732
15734
  resets_at: timestampSchema,
@@ -20516,6 +20518,14 @@ var init_runtime_policy_generated = __esm({
20516
20518
  min_delay_milliseconds: 250,
20517
20519
  max_delay_milliseconds: 1e4
20518
20520
  },
20521
+ trade_refresh_policy: {
20522
+ server_config_stream_timeout_ms: 1e4,
20523
+ config_retry_interval_ms: 5e3,
20524
+ copy_trading_status_poll_ms: 5e3,
20525
+ post_execution_refresh_delay_ms: 3e3,
20526
+ account_read_backoff_min_ms: 2e3,
20527
+ account_read_backoff_max_ms: 6e4
20528
+ },
20519
20529
  deployment_reload_observability: {
20520
20530
  bootstrap_max_error_events_per_page: 4,
20521
20531
  bootstrap_max_profiles: 10
@@ -20593,10 +20603,12 @@ var init_runtime_policy_generated = __esm({
20593
20603
  },
20594
20604
  server_runtime: {
20595
20605
  prompt_rescue: {
20606
+ request_ttl_seconds: 20,
20596
20607
  snapshot_max_age_seconds: 5,
20597
20608
  snapshot_component_max_skew_seconds: 2,
20598
- client_long_poll_seconds: 20,
20599
- client_claim_http_timeout_milliseconds: 25e3,
20609
+ client_claim_http_timeout_milliseconds: 5e3,
20610
+ client_claim_retry_delay_milliseconds: 1e3,
20611
+ client_failure_report_timeout_milliseconds: 2e3,
20600
20612
  client_presence_heartbeat_interval_milliseconds: 3e4,
20601
20613
  client_presence_http_timeout_milliseconds: 5e3
20602
20614
  }
@@ -21099,6 +21111,7 @@ var init_mcp_client = __esm({
21099
21111
  agentDecisionTimingSchema = external_exports.strictObject({
21100
21112
  analysis_started_at: timestampSchema2,
21101
21113
  model_latency_ms: external_exports.number().int().nonnegative().nullable(),
21114
+ analysis_duration_ms: external_exports.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).nullable().optional(),
21102
21115
  model_latency_source: external_exports.literal("harness_invocation").nullable()
21103
21116
  }).refine((timing) => timing.model_latency_ms === null === (timing.model_latency_source === null), {
21104
21117
  message: "Model latency and its measurement source must be supplied together."
@@ -21111,7 +21124,7 @@ var init_mcp_client = __esm({
21111
21124
  observed_at: timestampSchema2,
21112
21125
  timing: agentDecisionTimingSchema.optional(),
21113
21126
  provenance: jsonObjectSchema.nullable().optional()
21114
- }).refine((request) => !request.timing || Date.parse(request.timing.analysis_started_at) <= Date.parse(request.observed_at), {
21127
+ }).refine((request) => !request.timing || Date.parse(request.timing.analysis_started_at) <= Date.parse(request.observed_at) && (request.timing.analysis_duration_ms == null || request.timing.analysis_duration_ms <= Date.parse(request.observed_at) - Date.parse(request.timing.analysis_started_at)), {
21115
21128
  message: "Analysis start must precede decision observation."
21116
21129
  });
21117
21130
  agentDecisionSubmitResultSchema = external_exports.strictObject({
@@ -21464,6 +21477,8 @@ var init_mcp_client = __esm({
21464
21477
  #requestId = 0;
21465
21478
  #initialized = false;
21466
21479
  #providerQuotaRecoverySupported = false;
21480
+ #providerCreditsSupported = false;
21481
+ #agentAnalysisDurationSupported = false;
21467
21482
  #runtimeRecoveryDiagnosticsSupported = false;
21468
21483
  #providerHttpStatusTools = /* @__PURE__ */ new Set();
21469
21484
  #grokToolValidationTools = /* @__PURE__ */ new Set();
@@ -21510,6 +21525,21 @@ var init_mcp_client = __esm({
21510
21525
  supportsRuntimeRecoveryDiagnostics() {
21511
21526
  return this.#runtimeRecoveryDiagnosticsSupported;
21512
21527
  }
21528
+ supportsAgentAnalysisDuration() {
21529
+ return this.#agentAnalysisDurationSupported;
21530
+ }
21531
+ async refreshAgentAnalysisDurationSupport(options = {}) {
21532
+ if (this.supportsAgentAnalysisDuration()) return true;
21533
+ try {
21534
+ await this.initialize(options);
21535
+ } catch {
21536
+ return false;
21537
+ }
21538
+ return this.supportsAgentAnalysisDuration();
21539
+ }
21540
+ supportsProviderCredits() {
21541
+ return this.#providerCreditsSupported;
21542
+ }
21513
21543
  supportsProviderQuotaRecovery() {
21514
21544
  return this.#providerQuotaRecoverySupported;
21515
21545
  }
@@ -21572,6 +21602,35 @@ var init_mcp_client = __esm({
21572
21602
  "inference.host.heartbeat",
21573
21603
  ["provider_quota_recovery"]
21574
21604
  ) && advertisesFields("inference.job.fail", ["provider_retry_at", "provider_retry_source"]);
21605
+ const hostHeartbeatSchema = listed.tools.find(
21606
+ (tool) => tool.name === "inference.host.heartbeat"
21607
+ )?.inputSchema;
21608
+ const advertisesCredits = (value, depth = 0) => {
21609
+ if (depth > 4 || !value || typeof value !== "object" || Array.isArray(value)) return false;
21610
+ const node = value;
21611
+ const properties = node.properties;
21612
+ if (properties && typeof properties === "object" && Object.hasOwn(properties, "credits_available") && Object.hasOwn(properties, "rate_limit_reached")) return true;
21613
+ if (typeof node.$ref === "string" && /^#\/\$defs\/[^/]+$/u.test(node.$ref)) {
21614
+ const definition = node.$ref.slice("#/$defs/".length).replace(/~1/gu, "/").replace(/~0/gu, "~");
21615
+ return advertisesCredits(hostHeartbeatSchema?.$defs?.[definition], depth + 1);
21616
+ }
21617
+ return Array.isArray(node.anyOf) && node.anyOf.some((branch) => advertisesCredits(branch, depth + 1));
21618
+ };
21619
+ this.#providerCreditsSupported = advertisesCredits(hostHeartbeatSchema?.properties?.provider_weekly_quota);
21620
+ const decisionSchema = listed.tools.find(
21621
+ (tool) => tool.name === "inference.agent.decision.submit"
21622
+ )?.inputSchema;
21623
+ const advertisesAnalysisDuration = (value, depth = 0) => {
21624
+ if (depth > 4 || !value || typeof value !== "object" || Array.isArray(value)) return false;
21625
+ const node = value;
21626
+ if (node.properties && typeof node.properties === "object" && Object.hasOwn(node.properties, "analysis_duration_ms")) return true;
21627
+ if (typeof node.$ref === "string" && /^#\/\$defs\/[^/]+$/u.test(node.$ref)) {
21628
+ const definition = node.$ref.slice("#/$defs/".length).replace(/~1/gu, "/").replace(/~0/gu, "~");
21629
+ return advertisesAnalysisDuration(decisionSchema?.$defs?.[definition], depth + 1);
21630
+ }
21631
+ return Array.isArray(node.anyOf) && node.anyOf.some((branch) => advertisesAnalysisDuration(branch, depth + 1));
21632
+ };
21633
+ this.#agentAnalysisDurationSupported = advertisesAnalysisDuration(decisionSchema?.properties?.timing);
21575
21634
  this.#grokToolValidationTools.clear();
21576
21635
  if (advertisesFields("inference.job.fail", ["grok_tool_validation"])) {
21577
21636
  this.#grokToolValidationTools.add("inference.job.fail");
@@ -28355,7 +28414,7 @@ async function logoutCodexSubscription(options) {
28355
28414
  await session.close();
28356
28415
  }
28357
28416
  }
28358
- 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;
28417
+ 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, parseCreditsSnapshot, codexCreditsAvailable, 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;
28359
28418
  var init_codex_app_server = __esm({
28360
28419
  "lib/inference-host/codex-app-server.ts"() {
28361
28420
  "use strict";
@@ -28470,6 +28529,19 @@ var init_codex_app_server = __esm({
28470
28529
  DEFAULT_CODEX_QUOTA_COOLDOWN_MS = 5 * 60 * 1e3;
28471
28530
  MAX_CODEX_QUOTA_COOLDOWN_MS = 8 * 24 * 60 * 60 * 1e3;
28472
28531
  CODEX_TRANSIENT_RATE_LIMIT_COOLDOWN_MS = 30 * 1e3;
28532
+ parseCreditsSnapshot = (value) => {
28533
+ const candidate = objectOrNull(value);
28534
+ if (!candidate || typeof candidate.hasCredits !== "boolean" || typeof candidate.unlimited !== "boolean" || candidate.balance != null && typeof candidate.balance !== "string") return null;
28535
+ return {
28536
+ hasCredits: candidate.hasCredits,
28537
+ unlimited: candidate.unlimited,
28538
+ balance: candidate.balance ?? null
28539
+ };
28540
+ };
28541
+ codexCreditsAvailable = (snapshot) => {
28542
+ const credits = parseCreditsSnapshot(snapshot.credits);
28543
+ return credits !== null && (credits.hasCredits || credits.unlimited);
28544
+ };
28473
28545
  parseRateLimitSnapshot = (value) => {
28474
28546
  const candidate = objectOrNull(value);
28475
28547
  if (!candidate) throw new Error("invalid rate-limit snapshot");
@@ -28483,6 +28555,7 @@ var init_codex_app_server = __esm({
28483
28555
  limitId,
28484
28556
  limitName,
28485
28557
  planType,
28558
+ credits: parseCreditsSnapshot(candidate.credits),
28486
28559
  primary: parseRateLimitWindow(candidate.primary ?? null),
28487
28560
  secondary: parseRateLimitWindow(candidate.secondary ?? null),
28488
28561
  rateLimitReachedType: reached,
@@ -28490,6 +28563,7 @@ var init_codex_app_server = __esm({
28490
28563
  };
28491
28564
  };
28492
28565
  codexRateLimitRetryAtMs = (accountRateLimits) => {
28566
+ if (!codexAccountRateLimitReached(accountRateLimits)) return null;
28493
28567
  const snapshots = [accountRateLimits.rateLimits];
28494
28568
  const exhaustedResets = [];
28495
28569
  const reachedResets = [];
@@ -28510,7 +28584,12 @@ var init_codex_app_server = __esm({
28510
28584
  const candidates = exhaustedResets.length > 0 ? exhaustedResets : reachedResets.length > 0 ? reachedResets : [];
28511
28585
  return candidates.length > 0 ? Math.max(...candidates) : null;
28512
28586
  };
28513
- codexAccountRateLimitReached = (accountRateLimits) => [accountRateLimits.rateLimits].some((snapshot) => snapshot.rateLimitReachedType !== null || snapshot.spendControlReached === true || snapshot.primary?.usedPercent !== void 0 && snapshot.primary.usedPercent >= 100 || snapshot.secondary?.usedPercent !== void 0 && snapshot.secondary.usedPercent >= 100);
28587
+ codexAccountRateLimitReached = (accountRateLimits) => [accountRateLimits.rateLimits].some((snapshot) => (
28588
+ // The account snapshot reports generic included-usage exhaustion even when
28589
+ // purchased credits remain. Workspace restrictions are distinct hard stops;
28590
+ // actual turn failures remain authoritative in classifyCodexTurnFailure.
28591
+ snapshot.rateLimitReachedType !== null && (snapshot.rateLimitReachedType !== "rate_limit_reached" || !codexCreditsAvailable(snapshot)) || snapshot.spendControlReached === true || !codexCreditsAvailable(snapshot) && (snapshot.primary?.usedPercent !== void 0 && snapshot.primary.usedPercent >= 100 || snapshot.secondary?.usedPercent !== void 0 && snapshot.secondary.usedPercent >= 100)
28592
+ ));
28514
28593
  forbiddenMethod = (method) => method.startsWith("mcpServer/") || method.startsWith("serverRequest/") || method.startsWith("item/mcpToolCall") || method.startsWith("item/commandExecution") || method.startsWith("item/fileChange") || method.startsWith("item/dynamicToolCall") || method.startsWith("item/collabAgentToolCall");
28515
28594
  forbiddenTerminalItem = (item) => ![
28516
28595
  "userMessage",
@@ -30850,7 +30929,7 @@ async function clearInferenceAgentNextState(statePath) {
30850
30929
  "Agent-driven inference next recovery state"
30851
30930
  );
30852
30931
  }
30853
- var inferenceAgentAttemptStatePath, inferenceAgentNextStatePath, assertDecisionTiming, inferenceAgentRuntimeStatePath, inferenceAgentFailureFencePath, isIsoTimestamp, assertPlainObject, hasExactKeys, assertInferenceAgentFailureFence, assertInferenceAgentRuntimeState, readCodexAgentRuntimeState, clearCodexAgentRuntimeState, foregroundAgentControlStatePath, assertRuntimeAssignment, assertForegroundAgentControlState, assertNextState, assertAttemptState;
30932
+ var inferenceAgentAttemptStatePath, inferenceAgentNextStatePath, measureAgentReviewTiming, assertDecisionTiming, inferenceAgentRuntimeStatePath, inferenceAgentFailureFencePath, isIsoTimestamp, assertPlainObject, hasExactKeys, assertInferenceAgentFailureFence, assertInferenceAgentRuntimeState, readCodexAgentRuntimeState, clearCodexAgentRuntimeState, foregroundAgentControlStatePath, assertRuntimeAssignment, assertForegroundAgentControlState, assertNextState, assertAttemptState;
30854
30933
  var init_agent_state = __esm({
30855
30934
  "lib/inference-host/agent-state.ts"() {
30856
30935
  "use strict";
@@ -30861,9 +30940,20 @@ var init_agent_state = __esm({
30861
30940
  init_external_inference_contract();
30862
30941
  inferenceAgentAttemptStatePath = (statePath) => `${statePath}.agent-attempt.json`;
30863
30942
  inferenceAgentNextStatePath = (statePath) => `${statePath}.agent-next.json`;
30943
+ measureAgentReviewTiming = (analysisStartedAt, observedAt, measureDuration = true) => ({
30944
+ analysis_started_at: analysisStartedAt,
30945
+ model_latency_ms: null,
30946
+ model_latency_source: null,
30947
+ ...measureDuration ? { analysis_duration_ms: Date.parse(observedAt) - Date.parse(analysisStartedAt) } : {}
30948
+ });
30864
30949
  assertDecisionTiming = (value, observedAt, message) => {
30865
30950
  const timing = assertPlainObject(value, message);
30866
- if (!hasExactKeys(timing, ["analysis_started_at", "model_latency_ms", "model_latency_source"]) || !isIsoTimestamp(timing.analysis_started_at) || Date.parse(timing.analysis_started_at) > Date.parse(String(observedAt)) || (timing.model_latency_ms === null ? timing.model_latency_source !== null : !Number.isSafeInteger(timing.model_latency_ms) || Number(timing.model_latency_ms) < 0 || timing.model_latency_source !== "harness_invocation")) throw new Error(message);
30951
+ if (!hasExactKeys(timing, [
30952
+ "analysis_started_at",
30953
+ "model_latency_ms",
30954
+ "model_latency_source",
30955
+ ..."analysis_duration_ms" in timing ? ["analysis_duration_ms"] : []
30956
+ ]) || !isIsoTimestamp(timing.analysis_started_at) || Date.parse(timing.analysis_started_at) > Date.parse(String(observedAt)) || timing.analysis_duration_ms != null && (!Number.isSafeInteger(timing.analysis_duration_ms) || Number(timing.analysis_duration_ms) < 0 || Number(timing.analysis_duration_ms) > Date.parse(String(observedAt)) - Date.parse(timing.analysis_started_at)) || (timing.model_latency_ms === null ? timing.model_latency_source !== null : !Number.isSafeInteger(timing.model_latency_ms) || Number(timing.model_latency_ms) < 0 || timing.model_latency_source !== "harness_invocation")) throw new Error(message);
30867
30957
  };
30868
30958
  inferenceAgentRuntimeStatePath = (statePath) => `${statePath}.codex-agent-runtime.json`;
30869
30959
  inferenceAgentFailureFencePath = (statePath) => `${statePath}.agent-failure-fence.json`;
@@ -31514,12 +31604,16 @@ var init_runner = __esm({
31514
31604
  started_at: startedAt
31515
31605
  });
31516
31606
  isoAt = (milliseconds) => new Date(milliseconds).toISOString();
31517
- providerWeeklyQuotaFromRateLimits = (rateLimits, observedAtMs, currentTimeMs = observedAtMs) => {
31607
+ providerWeeklyQuotaFromRateLimits = (rateLimits, observedAtMs, currentTimeMs = observedAtMs, includeCredits = true) => {
31518
31608
  if (!rateLimits) return null;
31519
31609
  for (const window2 of [rateLimits.rateLimits.primary, rateLimits.rateLimits.secondary]) {
31520
31610
  if (window2?.windowDurationMins !== 7 * 24 * 60 || window2.resetsAt === null || window2.resetsAt * 1e3 <= currentTimeMs) continue;
31521
31611
  return {
31522
31612
  source: "codex_app_server",
31613
+ ...includeCredits ? {
31614
+ credits_available: codexCreditsAvailable(rateLimits.rateLimits),
31615
+ rate_limit_reached: codexAccountRateLimitReached(rateLimits)
31616
+ } : {},
31523
31617
  used_percent: window2.usedPercent,
31524
31618
  resets_at: isoAt(window2.resetsAt * 1e3),
31525
31619
  observed_at: isoAt(observedAtMs)
@@ -31531,7 +31625,7 @@ var init_runner = __esm({
31531
31625
  const window2 = rateLimits.rateLimits[key];
31532
31626
  const known = previous?.[key];
31533
31627
  if (known && (!window2 || window2.windowDurationMins !== known.windowDurationMins)) return false;
31534
- return window2 === null || window2.resetsAt !== null && window2.resetsAt * 1e3 > nowMs && window2.usedPercent < 100;
31628
+ return window2 === null || window2.resetsAt !== null && window2.resetsAt * 1e3 > nowMs && (window2.usedPercent < 100 || codexCreditsAvailable(rateLimits.rateLimits));
31535
31629
  });
31536
31630
  finitePositiveOption = (value, fallback, label) => {
31537
31631
  const result2 = value ?? fallback;
@@ -32563,7 +32657,8 @@ var init_runner = __esm({
32563
32657
  provider_weekly_quota: providerWeeklyQuotaFromRateLimits(
32564
32658
  providerRateLimits,
32565
32659
  providerRateLimitsObservedAtMs,
32566
- now()
32660
+ now(),
32661
+ mcp.supportsProviderCredits?.() === true
32567
32662
  ),
32568
32663
  ...mcp.supportsProviderQuotaRecovery?.() === true && providerQuotaRecoveryObservedAtMs !== null && status === "healthy" && active.size === 0 && (providerRetryAtMs ?? 0) <= now() && providerFailureRetryAtMs <= now() && now() - providerQuotaRecoveryObservedAtMs <= 2 * settings.providerRateLimitRefreshMs && providerRateLimits !== null && usableProviderQuotaSnapshot(providerRateLimits, knownProviderQuotaSnapshot, now()) ? { provider_quota_recovery: {
32569
32664
  source: "codex_app_server",
@@ -33181,14 +33276,7 @@ var init_runner = __esm({
33181
33276
  providerRetryAtMs = Math.max(providerRetryAtMs ?? 0, refreshedRetryAt);
33182
33277
  providerCooldownReason = "provider_limit_snapshot";
33183
33278
  retainQuotaSnapshot(providerRateLimits);
33184
- } else if (providerRetryAtMs !== null && !codexAccountRateLimitReached(providerRateLimits) && providerRateLimits.rateLimits.limitId === providerQuotaSnapshot?.limitId && [providerRateLimits.rateLimits.primary, providerRateLimits.rateLimits.secondary].some((window2) => window2 !== null) && ["primary", "secondary"].every((key) => {
33185
- const window2 = refreshedRateLimits.rateLimits[key];
33186
- const previous = providerQuotaSnapshot?.[key];
33187
- if (previous && (!window2 || window2.windowDurationMins !== previous.windowDurationMins)) {
33188
- return false;
33189
- }
33190
- return window2 === null || window2.resetsAt !== null && window2.resetsAt * 1e3 > refreshedAt && window2.usedPercent < 100;
33191
- })) {
33279
+ } else if (providerRetryAtMs !== null && usableProviderQuotaSnapshot(providerRateLimits, providerQuotaSnapshot, refreshedAt)) {
33192
33280
  emitDiagnostic("provider_cooldown_cleared", {
33193
33281
  reason: providerCooldownReason,
33194
33282
  recovery: "provider_quota_restored",
@@ -34560,6 +34648,7 @@ var init_runner = __esm({
34560
34648
  }
34561
34649
  };
34562
34650
  createInferenceAgentControlClient = (mcp) => ({
34651
+ supportsAgentAnalysisDuration: async (options = {}) => mcp.supportsAgentAnalysisDuration?.() === true || await mcp.refreshAgentAnalysisDurationSupport?.(options) === true,
34563
34652
  supportsProviderHttpStatusDiagnostics: async (options = {}) => mcp.supportsProviderHttpStatusDiagnostics?.("inference.agent.assignment.heartbeat") === true || await mcp.refreshProviderHttpStatusSupport?.("inference.agent.assignment.heartbeat", options) === true,
34564
34653
  supportsGrokResponseIdentityDiagnostics: async (options = {}) => mcp.supportsGrokResponseIdentityDiagnostics?.("inference.agent.assignment.heartbeat") === true || await mcp.refreshGrokResponseIdentitySupport?.("inference.agent.assignment.heartbeat", options) === true,
34565
34654
  supportsGrokToolValidationDiagnostics: async (options = {}) => mcp.supportsGrokToolValidationDiagnostics?.("inference.agent.assignment.heartbeat") === true || await mcp.refreshGrokToolValidationSupport?.("inference.agent.assignment.heartbeat", options) === true,
@@ -34979,15 +35068,19 @@ var init_runner = __esm({
34979
35068
  if (state.pending_decision) {
34980
35069
  return { success: false, value: { error: "decision_outcome_unresolved" } };
34981
35070
  }
35071
+ const measureDuration = state.pending_turn.decision_operation_ids.length === 0 && await this.options.controlClient.supportsAgentAnalysisDuration?.({ signal: turnAbort.signal }) === true;
35072
+ const observedAt = nowIso();
34982
35073
  const pending3 = {
34983
35074
  operation_id: randomUUID(),
34984
35075
  candidate,
34985
- observed_at: nowIso(),
34986
- timing: {
34987
- analysis_started_at: state.pending_turn.started_at,
34988
- model_latency_ms: null,
34989
- model_latency_source: null
34990
- },
35076
+ observed_at: observedAt,
35077
+ // A later decision in the same turn has no independent review
35078
+ // boundary. Do not report the whole turn again as its duration.
35079
+ timing: measureAgentReviewTiming(
35080
+ state.pending_turn.started_at,
35081
+ observedAt,
35082
+ measureDuration
35083
+ ),
34991
35084
  provenance: {
34992
35085
  source: "external_agent",
34993
35086
  agent_run_id: liveThread.threadId,
@@ -42642,6 +42735,14 @@ var init_runtime_policy_generated2 = __esm({
42642
42735
  min_delay_milliseconds: 250,
42643
42736
  max_delay_milliseconds: 1e4
42644
42737
  },
42738
+ trade_refresh_policy: {
42739
+ server_config_stream_timeout_ms: 1e4,
42740
+ config_retry_interval_ms: 5e3,
42741
+ copy_trading_status_poll_ms: 5e3,
42742
+ post_execution_refresh_delay_ms: 3e3,
42743
+ account_read_backoff_min_ms: 2e3,
42744
+ account_read_backoff_max_ms: 6e4
42745
+ },
42645
42746
  deployment_reload_observability: {
42646
42747
  bootstrap_max_error_events_per_page: 4,
42647
42748
  bootstrap_max_profiles: 10
@@ -42719,10 +42820,12 @@ var init_runtime_policy_generated2 = __esm({
42719
42820
  },
42720
42821
  server_runtime: {
42721
42822
  prompt_rescue: {
42823
+ request_ttl_seconds: 20,
42722
42824
  snapshot_max_age_seconds: 5,
42723
42825
  snapshot_component_max_skew_seconds: 2,
42724
- client_long_poll_seconds: 20,
42725
- client_claim_http_timeout_milliseconds: 25e3,
42826
+ client_claim_http_timeout_milliseconds: 5e3,
42827
+ client_claim_retry_delay_milliseconds: 1e3,
42828
+ client_failure_report_timeout_milliseconds: 2e3,
42726
42829
  client_presence_heartbeat_interval_milliseconds: 3e4,
42727
42830
  client_presence_http_timeout_milliseconds: 5e3
42728
42831
  }
@@ -46747,11 +46850,11 @@ Waiting for approval...
46747
46850
  operation_id: agentOperationId("agent-decision-submit"),
46748
46851
  candidate: input.candidate,
46749
46852
  observed_at: observedAt,
46750
- ...state.review ? { timing: {
46751
- analysis_started_at: state.review.analysis_started_at,
46752
- model_latency_ms: null,
46753
- model_latency_source: null
46754
- } } : {},
46853
+ ...state.review ? { timing: measureAgentReviewTiming(
46854
+ state.review.analysis_started_at,
46855
+ observedAt,
46856
+ session.client.supportsAgentAnalysisDuration?.() === true
46857
+ ) } : {},
46755
46858
  provenance: input.provenance
46756
46859
  },
46757
46860
  first_transmit_at: null,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vtxmacro/cli",
3
- "version": "2026.9.67",
3
+ "version": "2026.9.69",
4
4
  "description": "VTX Macro CLI, MCP server, and durable external inference host.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",