@vtxmacro/cli 2026.8.56 → 2026.8.57

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.8.56",
19
+ package_version: "2026.8.57",
20
20
  codex_package_name: "@openai/codex",
21
21
  codex_version: "0.147.0",
22
22
  copilot_sdk_package_name: "@github/copilot-sdk",
package/bin/vtx.js CHANGED
@@ -47,7 +47,7 @@ var init_agent_cli_release = __esm({
47
47
  "agent-cli-release.json"() {
48
48
  agent_cli_release_default = {
49
49
  package_name: "@vtxmacro/cli",
50
- package_version: "2026.8.56",
50
+ package_version: "2026.8.57",
51
51
  codex_package_name: "@openai/codex",
52
52
  codex_version: "0.147.0",
53
53
  copilot_sdk_package_name: "@github/copilot-sdk",
@@ -18756,7 +18756,8 @@ var init_mcp_client = __esm({
18756
18756
  const errorText = (callResult.content ?? []).filter((block) => block.type === "text").map((block) => block.text ?? "").join("\n");
18757
18757
  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(
18758
18758
  "External inference claim request was not applied before its generation became stale"
18759
- ) || errorText.includes("External inference host advertisement is expired or superseded"));
18759
+ ) || errorText.includes("External inference host advertisement is expired or superseded")) || name === "inference.job.complete" && errorText.includes("External inference completion evidence window expired");
18760
+ const completionEvidenceExpired = name === "inference.job.complete" && errorText.includes("External inference completion evidence window expired");
18760
18761
  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"));
18761
18762
  const retryableClaimRejection = name === "inference.job.claim" && !definitivelyNotApplied && (retryableInfrastructureRejection || errorText.includes("External inference host is not live enough to claim work") || errorText.includes("External inference host request generation is stale") || errorText.includes("External inference claim runtime fence is stale"));
18762
18763
  const retryableHeartbeatClockSkew = name === "inference.host.heartbeat" && definitivelyNotApplied;
@@ -18766,7 +18767,7 @@ var init_mcp_client = __esm({
18766
18767
  "External inference claim replay is no longer dispatchable"
18767
18768
  );
18768
18769
  throw new ExternalInferenceMcpError(
18769
- staleHostHeartbeatGeneration ? "generation_stale" : obsoleteClaimReplay ? "claim_replay_obsolete" : "tool_rejected",
18770
+ completionEvidenceExpired ? "completion_evidence_expired" : staleHostHeartbeatGeneration ? "generation_stale" : obsoleteClaimReplay ? "claim_replay_obsolete" : "tool_rejected",
18770
18771
  `Insights MCP rejected ${name}.`,
18771
18772
  {
18772
18773
  definitivelyNotApplied: definitivelyNotApplied || staleHostHeartbeatGeneration,
@@ -32426,7 +32427,7 @@ function createDefaultInferenceHostRunnerDependencies(options) {
32426
32427
  envelopePublicKey: options.envelopePublicKey
32427
32428
  };
32428
32429
  }
32429
- var import_ajv, RUNTIME_RECEIPT_SCHEMA_VERSION, ATTEMPT_RECEIPT_SCHEMA_VERSION, DEFAULT_ADVERTISEMENT_TTL_MS, DEFAULT_ADVERTISEMENT_REFRESH_LEAD_MS, DEFAULT_HOST_HEARTBEAT_MS, DEFAULT_PROVIDER_RATE_LIMIT_REFRESH_MS, DEFAULT_ATTEMPT_HEARTBEAT_MS, DEFAULT_DRAIN_TIMEOUT_MS, DEFAULT_REMOTE_RETRY_LIMIT, MIN_SLEEP_MS, MIN_HOST_HEARTBEAT_GAP_DIAGNOSTIC_MS, HOST_HEARTBEAT_GAP_DIAGNOSTIC_FACTOR, DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS, DEFAULT_AGENT_RATE_LIMIT_COOLDOWN_MS, DEFAULT_AGENT_QUOTA_COOLDOWN_MS, DEFAULT_AGENT_TRANSIENT_COOLDOWN_MS, MIN_CLAIM_START_WINDOW_MS, MAX_ATTEMPT_START_RETRY_DELAY_MS, UNBOUNDED_AVAILABLE_SLOTS, buildInferenceAdvertisedModels, summarizeInferenceHostRuntimeRecovery, FileInferenceHostRuntimeReceiptStore, InferenceHostRecoveryRequiredError, InferenceHostRunnerError, defaultSleep, abortError, settlesWithin, defaultRegisterSignalHandlers, safeInteger, exactObjectKeys, validIso, validateAttemptReceipt, validateRuntimeReceipt, sha256, stableOperationId, buildAttemptStartRequest, isoAt, providerWeeklyQuotaFromRateLimits, finitePositiveOption, validateRunnerOptions, assertLocalCredentialIdentity, retryableRemoteError, remoteRetryAfterMs, controlPlaneFatal, defaultValidateOutput, objectRecord, positiveUtf8ByteLimit, assertCompilableOutputSchema, parseOutputContract, membershipFailureDisposition, safeFailureCode, attemptStartRetryFallbackMs, exactJson2, runnerIdentityMismatch, assertAdvertisementResult, assertHostHeartbeatResult, assertClaimResult, assertStartResult, assertJobHeartbeatResult, assertTerminalResult, classifyFailure, ambiguousHeartbeatTransport, reportedTokenUsage, reportedUsage, InferenceHostRunner, createInferenceAgentControlClient, INFERENCE_AGENT_SYSTEM_PROMPT, INFERENCE_AGENT_WAKE_SCHEMA, parseInferenceAgentWake, InferenceAgentRuntime;
32430
+ var import_ajv, RUNTIME_RECEIPT_SCHEMA_VERSION, ATTEMPT_RECEIPT_SCHEMA_VERSION, DEFAULT_ADVERTISEMENT_TTL_MS, DEFAULT_ADVERTISEMENT_REFRESH_LEAD_MS, DEFAULT_HOST_HEARTBEAT_MS, DEFAULT_PROVIDER_RATE_LIMIT_REFRESH_MS, DEFAULT_ATTEMPT_HEARTBEAT_MS, DEFAULT_DRAIN_TIMEOUT_MS, DEFAULT_REMOTE_RETRY_LIMIT, MIN_SLEEP_MS, MIN_HOST_HEARTBEAT_GAP_DIAGNOSTIC_MS, HOST_HEARTBEAT_GAP_DIAGNOSTIC_FACTOR, DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS, DEFAULT_AGENT_RATE_LIMIT_COOLDOWN_MS, DEFAULT_AGENT_QUOTA_COOLDOWN_MS, DEFAULT_AGENT_TRANSIENT_COOLDOWN_MS, MIN_CLAIM_START_WINDOW_MS, MAX_ATTEMPT_START_RETRY_DELAY_MS, UNBOUNDED_AVAILABLE_SLOTS, buildInferenceAdvertisedModels, summarizeInferenceHostRuntimeRecovery, FileInferenceHostRuntimeReceiptStore, InferenceHostRecoveryRequiredError, InferenceHostRunnerError, defaultSleep, abortError, settlesWithin, defaultRegisterSignalHandlers, safeInteger, exactObjectKeys, validIso, validateAttemptReceipt, validateRuntimeReceipt, sha256, stableOperationId, buildAttemptStartRequest, isoAt, providerWeeklyQuotaFromRateLimits, finitePositiveOption, validateRunnerOptions, assertLocalCredentialIdentity, retryableRemoteError, remoteRetryAfterMs, controlPlaneFatal, defaultValidateOutput, objectRecord, positiveUtf8ByteLimit, assertCompilableOutputSchema, parseOutputContract, membershipFailureDisposition, safeFailureCode, attemptStartRetryFallbackMs, exactJson2, runnerIdentityMismatch, assertAdvertisementResult, assertHostHeartbeatResult, assertClaimResult, assertStartResult, assertJobHeartbeatResult, assertTerminalResult, isDefinitiveCompletionEvidenceExpiry, classifyFailure, ambiguousHeartbeatTransport, reportedTokenUsage, reportedUsage, InferenceHostRunner, createInferenceAgentControlClient, INFERENCE_AGENT_SYSTEM_PROMPT, INFERENCE_AGENT_WAKE_SCHEMA, parseInferenceAgentWake, InferenceAgentRuntime;
32430
32431
  var init_runner = __esm({
32431
32432
  "lib/inference-host/runner.ts"() {
32432
32433
  "use strict";
@@ -33050,6 +33051,7 @@ var init_runner = __esm({
33050
33051
  if (failure.state !== request.attempt_status || failure.failure_category !== request.failure_category || failure.failure_code !== request.failure_code) runnerIdentityMismatch("Job failure receipt");
33051
33052
  }
33052
33053
  };
33054
+ isDefinitiveCompletionEvidenceExpiry = (error48, terminal) => terminal?.schema_version === "external_inference_job_complete_v1" && error48 instanceof ExternalInferenceMcpError && error48.code === "completion_evidence_expired" && error48.definitivelyNotApplied;
33053
33055
  classifyFailure = (error48, result2) => {
33054
33056
  if (error48 instanceof CodexAppServerError) {
33055
33057
  const category2 = error48.code === "quota_exceeded" ? "quota" : error48.category;
@@ -33907,10 +33909,19 @@ var init_runner = __esm({
33907
33909
  }
33908
33910
  return attemptId;
33909
33911
  };
33910
- const removeRecoveredAttempt = async (attemptId) => {
33912
+ const removeRecoveredAttempt = async (recovery) => {
33911
33913
  await mutateReceipt((current) => {
33914
+ const persisted = current.attempts[recovery.attempt_id];
33915
+ const persistedTerminal = persisted?.terminal_request;
33916
+ const recoveryTerminal = recovery.terminal_request;
33917
+ const sameTerminalRequest = Boolean(
33918
+ persistedTerminal && recoveryTerminal && persistedTerminal.schema_version === recoveryTerminal.schema_version && (persistedTerminal.schema_version === "external_inference_job_complete_v1" && recoveryTerminal.schema_version === "external_inference_job_complete_v1" && persistedTerminal.completion_id === recoveryTerminal.completion_id || persistedTerminal.schema_version === "external_inference_job_fail_v1" && recoveryTerminal.schema_version === "external_inference_job_fail_v1" && persistedTerminal.failure_id === recoveryTerminal.failure_id)
33919
+ );
33920
+ if (persisted?.phase !== "terminal_pending" || persisted.job_id !== recovery.job_id || persisted.terminal_operation_id !== recovery.terminal_operation_id || !sameTerminalRequest) {
33921
+ return current;
33922
+ }
33912
33923
  const attempts = { ...current.attempts };
33913
- delete attempts[attemptId];
33924
+ delete attempts[recovery.attempt_id];
33914
33925
  return { ...current, attempts, updated_at: isoAt(now()) };
33915
33926
  });
33916
33927
  };
@@ -33936,8 +33947,22 @@ var init_runner = __esm({
33936
33947
  failed += 1;
33937
33948
  }
33938
33949
  await this.dependencies.codexAdapter.acknowledgeAttempt?.(recovery.attempt_id);
33939
- await removeRecoveredAttempt(recovery.attempt_id);
33950
+ await removeRecoveredAttempt(recovery);
33940
33951
  } catch (error48) {
33952
+ if (isDefinitiveCompletionEvidenceExpiry(error48, recovery.terminal_request)) {
33953
+ await this.dependencies.codexAdapter.acknowledgeAttempt?.(recovery.attempt_id);
33954
+ await removeRecoveredAttempt(recovery);
33955
+ failed += 1;
33956
+ emitDiagnostic("terminal_recovery_retired", {
33957
+ job_id: recovery.job_id,
33958
+ attempt_id: recovery.attempt_id,
33959
+ attempt_phase: recovery.phase,
33960
+ terminal_operation: "complete",
33961
+ error_code: error48.code,
33962
+ definitively_not_applied: true
33963
+ });
33964
+ continue;
33965
+ }
33941
33966
  emitTerminalRecoveryFailure(recovery, error48);
33942
33967
  requestDrain(controlPlaneFatal(error48) ? "authority_lost" : "attempt_terminal_unconfirmed");
33943
33968
  break;
@@ -34568,6 +34593,22 @@ var init_runner = __esm({
34568
34593
  assertTerminalResult(completion, completionResult);
34569
34594
  await this.dependencies.codexAdapter.acknowledgeAttempt?.(attemptId);
34570
34595
  } catch (error48) {
34596
+ if (isDefinitiveCompletionEvidenceExpiry(error48, completion)) {
34597
+ await this.dependencies.codexAdapter.acknowledgeAttempt?.(attemptId);
34598
+ await stopHeartbeat();
34599
+ await removeAttempt();
34600
+ options.onAttemptOutcome?.({
34601
+ outcome: "failed",
34602
+ failure_category: "deadline",
34603
+ failure_code: error48.code,
34604
+ retryable: false,
34605
+ dispatch_outcome: completion.outcome.dispatch_outcome,
34606
+ response_outcome: "none",
34607
+ latency_ms: completion.latency_ms,
34608
+ usage: completion.usage
34609
+ });
34610
+ return "failed";
34611
+ }
34571
34612
  throw new InferenceHostRunnerError(
34572
34613
  "terminal_outcome_unconfirmed",
34573
34614
  "The exact completion receipt could not be confirmed; redispatch is fenced.",
@@ -41828,12 +41869,13 @@ var init_hyperliquid_account_state_adapter = __esm({
41828
41869
  buildUserFillsStorageKey = (cacheKey) => {
41829
41870
  return `${USER_FILLS_CACHE_STORAGE_PREFIX}${cacheKey}`;
41830
41871
  };
41831
- buildAccountStateCacheKey = (apiUrl, walletAddress, symbol2, aggregatePerpDexs, dexNames, includeEffectiveTakerRate, includeExactAccountMode, includeActiveAssetData) => {
41872
+ buildAccountStateCacheKey = (apiUrl, walletAddress, symbol2, aggregatePerpDexs, scopeAccountSummaryToSelectedDex, dexNames, includeEffectiveTakerRate, includeExactAccountMode, includeActiveAssetData) => {
41832
41873
  return [
41833
41874
  apiUrl.replace(/\/$/, "").toLowerCase(),
41834
41875
  walletAddress.trim().toLowerCase(),
41835
41876
  normalizeHyperliquidMarketSymbol(symbol2),
41836
41877
  aggregatePerpDexs ? "aggregate" : "selected",
41878
+ scopeAccountSummaryToSelectedDex ? "selected-summary" : "aggregate-summary",
41837
41879
  includeEffectiveTakerRate ? "with-effective-taker-rate" : "without-effective-taker-rate",
41838
41880
  includeExactAccountMode ? "with-exact-account-mode" : "without-exact-account-mode",
41839
41881
  includeActiveAssetData ? "with-active-asset" : "without-active-asset",
@@ -42505,15 +42547,20 @@ var init_hyperliquid_account_state_adapter = __esm({
42505
42547
  const activeAssetCacheKey = buildActiveAssetCacheKey(apiUrl, walletAddress, symbol2);
42506
42548
  const activeAssetRequestTypes = getBrowserActiveAssetTypeCandidates(apiUrl, walletAddress, symbol2);
42507
42549
  const aggregatePerpDexs = input.aggregatePerpDexs !== false;
42550
+ const scopeAccountSummaryToSelectedDex = input.scopeAccountSummaryToSelectedDex === true;
42508
42551
  const includeEffectiveTakerRate = input.includeEffectiveTakerRate === true;
42509
42552
  const includeExactAccountMode = input.includeExactAccountMode === true;
42510
42553
  const includeActiveAssetData = input.includeActiveAssetData !== false;
42511
42554
  const dexNames = listPerpDexsForAccountState(input.config, dex, aggregatePerpDexs);
42555
+ if (scopeAccountSummaryToSelectedDex && dex && !dexNames.includes(dex)) {
42556
+ dexNames.push(dex);
42557
+ }
42512
42558
  const cacheKey = buildAccountStateCacheKey(
42513
42559
  apiUrl,
42514
42560
  walletAddress,
42515
42561
  symbol2,
42516
42562
  aggregatePerpDexs,
42563
+ scopeAccountSummaryToSelectedDex,
42517
42564
  dexNames,
42518
42565
  includeEffectiveTakerRate,
42519
42566
  includeExactAccountMode,
@@ -42541,6 +42588,7 @@ var init_hyperliquid_account_state_adapter = __esm({
42541
42588
  apiUrl,
42542
42589
  walletAddress,
42543
42590
  symbol: symbol2,
42591
+ selectedDex: dex,
42544
42592
  activeAssetCacheKey,
42545
42593
  activeAssetRequestTypes,
42546
42594
  dexNames,
@@ -42580,6 +42628,7 @@ var init_hyperliquid_account_state_adapter = __esm({
42580
42628
  apiUrl,
42581
42629
  walletAddress,
42582
42630
  symbol: symbol2,
42631
+ selectedDex,
42583
42632
  activeAssetCacheKey,
42584
42633
  activeAssetRequestTypes,
42585
42634
  dexNames,
@@ -42604,11 +42653,22 @@ var init_hyperliquid_account_state_adapter = __esm({
42604
42653
  if (input.includeEffectiveTakerRate === true) {
42605
42654
  requirePromptClearinghouseState(response, dexName);
42606
42655
  }
42607
- return prefixHip3PositionCoins(response, dexName);
42656
+ return {
42657
+ dex: dexName,
42658
+ payload: prefixHip3PositionCoins(response, dexName)
42659
+ };
42608
42660
  })
42609
42661
  );
42662
+ const selectedPayload = selectedDex ? dexResponses.find((entry) => entry.dex === selectedDex)?.payload : defaultResponse;
42663
+ if (!selectedPayload) {
42664
+ throw new Error(`Missing selected Hyperliquid clearinghouse state for DEX ${selectedDex}.`);
42665
+ }
42610
42666
  return {
42611
- payload: aggregateClearinghouseResponses([defaultResponse, ...dexResponses]),
42667
+ payload: aggregateClearinghouseResponses([
42668
+ defaultResponse,
42669
+ ...dexResponses.map((entry) => entry.payload)
42670
+ ]),
42671
+ selectedPayload,
42612
42672
  capturedAt: (/* @__PURE__ */ new Date()).toISOString()
42613
42673
  };
42614
42674
  })();
@@ -42691,6 +42751,7 @@ var init_hyperliquid_account_state_adapter = __esm({
42691
42751
  exactAccountModePromise
42692
42752
  ]);
42693
42753
  const perpsResponse = perpsResult.payload;
42754
+ const accountSummaryPerpsResponse = input.scopeAccountSummaryToSelectedDex === true ? perpsResult.selectedPayload : perpsResponse;
42694
42755
  const spotResponse = spotResult.payload;
42695
42756
  const userFeesResponse = userFeesResult?.payload ?? null;
42696
42757
  if (input.includeEffectiveTakerRate === true) {
@@ -42712,16 +42773,33 @@ var init_hyperliquid_account_state_adapter = __esm({
42712
42773
  takerRate = parsedUserCrossRate;
42713
42774
  }
42714
42775
  const accountStateConfig = input.config.client_runtime_hyperliquid_account_state;
42715
- const summaryPerpsResponse = exactAccountMode ? { ...perpsResponse, accountMode: exactAccountMode.accountMode } : perpsResponse;
42776
+ const summaryPerpsResponse = exactAccountMode ? { ...accountSummaryPerpsResponse, accountMode: exactAccountMode.accountMode } : accountSummaryPerpsResponse;
42716
42777
  const accountSummaryOptions = {
42717
42778
  spotDominatesMinTotalUsd: accountStateConfig?.spot_dominates_min_total_usd,
42718
42779
  spotDominatesPerpsMultiplier: accountStateConfig?.spot_dominates_perps_multiplier,
42719
42780
  mirroredAccountValueAbsoluteToleranceUsd: accountStateConfig?.mirrored_account_value_absolute_tolerance_usd,
42720
42781
  mirroredAccountValueRelativeTolerance: accountStateConfig?.mirrored_account_value_relative_tolerance
42721
42782
  };
42722
- const normalizedSummary = exactAccountMode ? buildServerPromptRescueAccountSummary(
42783
+ const walletSummary = exactAccountMode && input.scopeAccountSummaryToSelectedDex !== true ? buildServerPromptRescueAccountSummary(
42784
+ perpsResponse,
42785
+ spotResponse,
42786
+ exactAccountMode.accountMode,
42787
+ accountSummaryOptions
42788
+ ) : buildAccountSummaryFromInfoResponses(
42723
42789
  perpsResponse,
42724
42790
  spotResponse,
42791
+ accountSummaryOptions
42792
+ );
42793
+ const normalizedSummary = input.scopeAccountSummaryToSelectedDex === true ? {
42794
+ ...buildAccountSummaryFromInfoResponses(
42795
+ summaryPerpsResponse,
42796
+ {},
42797
+ accountSummaryOptions
42798
+ ),
42799
+ balances: walletSummary.balances
42800
+ } : exactAccountMode ? buildServerPromptRescueAccountSummary(
42801
+ accountSummaryPerpsResponse,
42802
+ spotResponse,
42725
42803
  exactAccountMode.accountMode,
42726
42804
  accountSummaryOptions
42727
42805
  ) : buildAccountSummaryFromInfoResponses(
@@ -42733,7 +42811,7 @@ var init_hyperliquid_account_state_adapter = __esm({
42733
42811
  ...normalizedSummary,
42734
42812
  ...exactAccountMode == null ? {} : { account_mode: exactAccountMode.accountMode, mode_source: "canonical" },
42735
42813
  address: walletAddress,
42736
- dex: "all",
42814
+ dex: input.scopeAccountSummaryToSelectedDex === true ? selectedDex : "all",
42737
42815
  market_type: "perp"
42738
42816
  };
42739
42817
  const activeAssetPayload = activeAssetResult?.payload ?? null;
@@ -43570,9 +43648,12 @@ async function postClientRuntime(path, profileId, body, options) {
43570
43648
  const numericProfileId = toNumericProfileId(profileId);
43571
43649
  const keepalive = options?.keepalive === true;
43572
43650
  const signal = options?.signal;
43651
+ const parsedRequestTimeoutMs = Number(options?.requestTimeoutMs);
43652
+ const requestTimeoutMs = Number.isFinite(parsedRequestTimeoutMs) && parsedRequestTimeoutMs > 0 ? Math.round(parsedRequestTimeoutMs) : null;
43573
43653
  const maxAttempts = keepalive ? 1 : 3;
43574
43654
  const requestContext = parseClientRuntimeRequestContext(body);
43575
- const idempotencyKey = shouldAttachRuntimeIdempotencyKey(path) ? createIdempotencyKey(`runtime-${path.replace(/\//g, "-")}`) : null;
43655
+ const explicitIdempotencyKey = String(options?.idempotencyKey ?? "").trim();
43656
+ const idempotencyKey = shouldAttachRuntimeIdempotencyKey(path) ? explicitIdempotencyKey || createIdempotencyKey(`runtime-${path.replace(/\//g, "-")}`) : null;
43576
43657
  const requestHeaders = getProfileHeaders({
43577
43658
  "Content-Type": "application/json"
43578
43659
  }, numericProfileId);
@@ -43589,6 +43670,24 @@ async function postClientRuntime(path, profileId, body, options) {
43589
43670
  let missingRuntimeLeaseRecoveryAttempted = false;
43590
43671
  for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
43591
43672
  let response = null;
43673
+ let requestTimedOut = false;
43674
+ let timeoutId = null;
43675
+ let relayCallerAbort = null;
43676
+ let requestSignal = signal;
43677
+ if (requestTimeoutMs !== null) {
43678
+ const timeoutController = new AbortController();
43679
+ relayCallerAbort = () => timeoutController.abort(signal?.reason);
43680
+ if (signal?.aborted) {
43681
+ relayCallerAbort();
43682
+ } else {
43683
+ signal?.addEventListener("abort", relayCallerAbort, { once: true });
43684
+ }
43685
+ timeoutId = globalThis.setTimeout(() => {
43686
+ requestTimedOut = true;
43687
+ timeoutController.abort(new DOMException("Runtime request timeout reached.", "TimeoutError"));
43688
+ }, requestTimeoutMs);
43689
+ requestSignal = timeoutController.signal;
43690
+ }
43592
43691
  const trace = startRuntimeNetworkDebugTrace({
43593
43692
  kind: "runtime",
43594
43693
  label: "client_runtime_api",
@@ -43601,7 +43700,7 @@ async function postClientRuntime(path, profileId, body, options) {
43601
43700
  method: "POST",
43602
43701
  credentials: "include",
43603
43702
  keepalive,
43604
- signal,
43703
+ signal: requestSignal,
43605
43704
  headers: { ...requestHeaders },
43606
43705
  body
43607
43706
  });
@@ -43609,7 +43708,11 @@ async function postClientRuntime(path, profileId, body, options) {
43609
43708
  const error48 = await createRuntimeRequestError(response, "Client runtime request failed");
43610
43709
  if (!resolvedRuntimeLeaseToken && !missingRuntimeLeaseRecoveryAttempted && shouldRecoverMissingRuntimeLease(path, requestContext, keepalive) && isMissingRuntimeLeaseError(response.status, error48.message)) {
43611
43710
  missingRuntimeLeaseRecoveryAttempted = true;
43612
- const recoveredRuntimeLeaseToken = await recoverMissingRuntimeLease(numericProfileId, requestContext);
43711
+ const recoveredRuntimeLeaseToken = await recoverMissingRuntimeLease(
43712
+ numericProfileId,
43713
+ requestContext,
43714
+ requestSignal
43715
+ );
43613
43716
  if (recoveredRuntimeLeaseToken) {
43614
43717
  resolvedRuntimeLeaseToken = recoveredRuntimeLeaseToken;
43615
43718
  attachRuntimeLeaseHeader(requestHeaders, resolvedRuntimeLeaseToken);
@@ -43627,7 +43730,7 @@ async function postClientRuntime(path, profileId, body, options) {
43627
43730
  hadRuntimeLeaseToken: Boolean(resolvedRuntimeLeaseToken),
43628
43731
  leaseCleared: shouldClearLease
43629
43732
  });
43630
- if (!keepalive && attempt < maxAttempts && !shouldClearLease && shouldRetryClientRuntimeHttpStatus(path, response.status)) {
43733
+ if (!keepalive && attempt < maxAttempts && !shouldClearLease && (shouldRetryClientRuntimeHttpStatus(path, response.status) || isRuntimeIdempotencyInProgressError(response.status, error48.message) || Boolean(idempotencyKey) && isRetryableRuntimeConflictError(response.status, error48))) {
43631
43734
  await sleep2(resolveClientRuntimeRetryDelayMs(attempt, response.headers.get("Retry-After")));
43632
43735
  continue;
43633
43736
  }
@@ -43642,10 +43745,11 @@ async function postClientRuntime(path, profileId, body, options) {
43642
43745
  trace.completeSuccess(response.status);
43643
43746
  return payload;
43644
43747
  } catch (error48) {
43645
- lastNetworkError = error48;
43646
- trace.completeError(error48, response?.status ?? null);
43647
- if (!isTransientNetworkFetchError(error48) || attempt >= maxAttempts) {
43648
- throw annotateRuntimeRequestError(error48, {
43748
+ const requestError = requestTimedOut && !signal?.aborted ? new TypeError("Runtime request timeout reached.") : error48;
43749
+ lastNetworkError = requestError;
43750
+ trace.completeError(requestError, response?.status ?? null);
43751
+ if (signal?.aborted || !requestTimedOut && !isTransientNetworkFetchError(requestError) || attempt >= maxAttempts) {
43752
+ throw annotateRuntimeRequestError(requestError, {
43649
43753
  path,
43650
43754
  method: "POST",
43651
43755
  attempt,
@@ -43657,6 +43761,13 @@ async function postClientRuntime(path, profileId, body, options) {
43657
43761
  }
43658
43762
  await sleep2(resolveClientRuntimeRetryDelayMs(attempt, null));
43659
43763
  continue;
43764
+ } finally {
43765
+ if (timeoutId !== null) {
43766
+ globalThis.clearTimeout(timeoutId);
43767
+ }
43768
+ if (signal && relayCallerAbort) {
43769
+ signal.removeEventListener("abort", relayCallerAbort);
43770
+ }
43660
43771
  }
43661
43772
  }
43662
43773
  if (lastNetworkError instanceof Error) {
@@ -43859,7 +43970,7 @@ async function reconcileActiveClientRuntimeExchangeMutation(profileId, requestOp
43859
43970
  }
43860
43971
  return rememberCompletedDeferredClientRuntimeStop(profileId, result2);
43861
43972
  }
43862
- var getApiUrl, API_URL, sleep2, isTransientNetworkFetchError, createIdempotencyKey, getErrorMessage, getErrorPayloadOrEmpty, getErrorPayloadOrFallbackDetail, getErrorMessageFromResponse, _activeProfileId, PROFILE_STORAGE_KEY, preferencesWriteQueue, CLIENT_SUPPORTED_PROMPT_CONTRACT_VERSION, completedDeferredClientRuntimeStops, rememberCompletedDeferredClientRuntimeStop, toNumericProfileId, shouldAttachRuntimeIdempotencyKey, attachRuntimeLeaseHeader, resolveRuntimeLeaseToken, persistRuntimeLeaseFromPayload, persistRuntimeLeaseStatusMetadata, shouldClearPersistedRuntimeLeaseOnError, isMissingRuntimeLeaseError, createRuntimeRequestError, parseClientRuntimeRequestContext, recordRuntimeAuthFailureBreadcrumb, classifyRuntimeRequestError, annotateRuntimeRequestError, parseRuntimeRetryAfterMs, shouldRecoverMissingRuntimeLease, recoverMissingRuntimeLease, isRetryableClientRuntimeStatus, shouldRetryClientRuntimeHttpStatus, resolveClientRuntimeRetryDelayMs, CLIENT_EXCHANGE_AUTHORITY_DEVICE_KEY, CLIENT_EXCHANGE_AUTHORITY_SESSION_KEY, getOrCreateClientExchangeAuthorityIdentity, resolveClientExchangeMutationAuthority, clientExchangeMutationAuthorityBody, isPendingClientExchangeMutationError, clientExchangeMutationReconciliationTimers, MAX_CLIENT_EXCHANGE_RECONCILIATION_DELAY_MS, CLIENT_EXCHANGE_RECONCILIATION_CLOCK_SKEW_MS, ClientExchangeMutationRebuildRequiredError, isTerminalClientExchangeMutation, clientExchangeMutationReconciliationKey, clearScheduledClientExchangeMutationReconciliation, snapshotClientExchangeMutationReconciliationAuthority, postClientExchangeMutationReconciliation, scheduleClientExchangeMutationReconciliation;
43973
+ var getApiUrl, API_URL, sleep2, isTransientNetworkFetchError, createIdempotencyKey, getErrorMessage, getErrorPayloadOrEmpty, getErrorPayloadOrFallbackDetail, getErrorMessageFromResponse, _activeProfileId, PROFILE_STORAGE_KEY, preferencesWriteQueue, CLIENT_SUPPORTED_PROMPT_CONTRACT_VERSION, completedDeferredClientRuntimeStops, rememberCompletedDeferredClientRuntimeStop, toNumericProfileId, shouldAttachRuntimeIdempotencyKey, attachRuntimeLeaseHeader, resolveRuntimeLeaseToken, persistRuntimeLeaseFromPayload, persistRuntimeLeaseStatusMetadata, shouldClearPersistedRuntimeLeaseOnError, isMissingRuntimeLeaseError, createRuntimeRequestError, parseClientRuntimeRequestContext, recordRuntimeAuthFailureBreadcrumb, classifyRuntimeRequestError, annotateRuntimeRequestError, parseRuntimeRetryAfterMs, shouldRecoverMissingRuntimeLease, recoverMissingRuntimeLease, isRetryableClientRuntimeStatus, shouldRetryClientRuntimeHttpStatus, isRuntimeIdempotencyInProgressError, isRetryableRuntimeConflictError, resolveClientRuntimeRetryDelayMs, CLIENT_EXCHANGE_AUTHORITY_DEVICE_KEY, CLIENT_EXCHANGE_AUTHORITY_SESSION_KEY, getOrCreateClientExchangeAuthorityIdentity, resolveClientExchangeMutationAuthority, clientExchangeMutationAuthorityBody, isPendingClientExchangeMutationError, clientExchangeMutationReconciliationTimers, MAX_CLIENT_EXCHANGE_RECONCILIATION_DELAY_MS, CLIENT_EXCHANGE_RECONCILIATION_CLOCK_SKEW_MS, ClientExchangeMutationRebuildRequiredError, isTerminalClientExchangeMutation, clientExchangeMutationReconciliationKey, clearScheduledClientExchangeMutationReconciliation, snapshotClientExchangeMutationReconciliationAuthority, postClientExchangeMutationReconciliation, scheduleClientExchangeMutationReconciliation;
43863
43974
  var init_api2 = __esm({
43864
43975
  "lib/api.ts"() {
43865
43976
  "use strict";
@@ -44058,7 +44169,9 @@ var init_api2 = __esm({
44058
44169
  };
44059
44170
  isMissingRuntimeLeaseError = (statusCode, message) => statusCode === 401 && String(message ?? "").trim().toLowerCase().includes("runtime lease required");
44060
44171
  createRuntimeRequestError = async (response, defaultMessage) => {
44061
- const rawMessage = await getErrorMessageFromResponse(response, defaultMessage);
44172
+ const payload = await getErrorPayloadOrEmpty(response);
44173
+ const nestedDetail = payload.detail && typeof payload.detail === "object" && !Array.isArray(payload.detail) ? payload.detail : null;
44174
+ const rawMessage = getErrorMessage(payload, defaultMessage);
44062
44175
  const walletCohortMessage = response.status === 409 ? {
44063
44176
  client_wallet_unavailable: "The active profile wallet is unavailable. Save a wallet for this profile, then try again.",
44064
44177
  client_wallet_mismatch: "The active profile wallet does not match this Client Mode session. Reload the profile, then try again.",
@@ -44067,6 +44180,15 @@ var init_api2 = __esm({
44067
44180
  const message = walletCohortMessage ?? rawMessage;
44068
44181
  const error48 = new Error(message);
44069
44182
  error48.status = response.status;
44183
+ error48.detail = payload.detail;
44184
+ const code = typeof payload.code === "string" ? payload.code.trim() : typeof nestedDetail?.code === "string" ? nestedDetail.code.trim() : "";
44185
+ if (code) {
44186
+ error48.code = code;
44187
+ }
44188
+ const retryable = payload.retryable ?? nestedDetail?.retryable;
44189
+ if (typeof retryable === "boolean") {
44190
+ error48.retryable = retryable;
44191
+ }
44070
44192
  return error48;
44071
44193
  };
44072
44194
  parseClientRuntimeRequestContext = (body) => {
@@ -44167,7 +44289,7 @@ var init_api2 = __esm({
44167
44289
  }
44168
44290
  return path === "/runtime/heartbeat" || path === "/runtime/analyze" || path === "/runtime/prompt-contract/metadata" || path === "/runtime/prompt-contract/derived-context" || path === "/runtime/prompt" || path === "/runtime/decision" || path === "/runtime/error" || path === "/runtime/trade-sync";
44169
44291
  };
44170
- recoverMissingRuntimeLease = async (profileId, requestContext) => {
44292
+ recoverMissingRuntimeLease = async (profileId, requestContext, signal) => {
44171
44293
  if (!requestContext.sessionId || !requestContext.deviceId) {
44172
44294
  return null;
44173
44295
  }
@@ -44181,6 +44303,7 @@ var init_api2 = __esm({
44181
44303
  method: "POST",
44182
44304
  credentials: "include",
44183
44305
  cache: "no-store",
44306
+ signal,
44184
44307
  headers,
44185
44308
  body: JSON.stringify({
44186
44309
  session_id: requestContext.sessionId,
@@ -44195,7 +44318,10 @@ var init_api2 = __esm({
44195
44318
  return null;
44196
44319
  }
44197
44320
  payload = await response.json();
44198
- } catch {
44321
+ } catch (error48) {
44322
+ if (signal?.aborted) {
44323
+ throw signal.reason ?? error48;
44324
+ }
44199
44325
  return null;
44200
44326
  }
44201
44327
  persistRuntimeLeaseFromPayload(payload);
@@ -44216,6 +44342,8 @@ var init_api2 = __esm({
44216
44342
  }
44217
44343
  return true;
44218
44344
  };
44345
+ isRuntimeIdempotencyInProgressError = (status, message) => status === 409 && (message.toLowerCase().includes("duplicate request already in progress") || message.toLowerCase().includes("duplicate request in-flight"));
44346
+ isRetryableRuntimeConflictError = (status, error48) => status === 409 && error48.retryable === true && (error48.code === "profile_runtime_contract_busy" || error48.code === "runtime_trade_sync_finalizing");
44219
44347
  resolveClientRuntimeRetryDelayMs = (attempt, retryAfterHeader) => {
44220
44348
  const retryAfterMs = parseRuntimeRetryAfterMs(retryAfterHeader);
44221
44349
  if (retryAfterMs != null) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vtxmacro/cli",
3
- "version": "2026.8.56",
3
+ "version": "2026.8.57",
4
4
  "description": "VTX Macro CLI, MCP server, and durable external inference host.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",