@vtxmacro/cli 2026.8.56 → 2026.8.58

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.58",
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.58",
51
51
  codex_package_name: "@openai/codex",
52
52
  codex_version: "0.147.0",
53
53
  copilot_sdk_package_name: "@github/copilot-sdk",
@@ -18157,7 +18157,7 @@ ${body}`;
18157
18157
  });
18158
18158
 
18159
18159
  // lib/inference-host/mcp-client.ts
18160
- 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;
18160
+ var EXTERNAL_INFERENCE_MCP_PROTOCOL_VERSION, EXTERNAL_INFERENCE_AUTOMATED_HOST_TOOLS, EXTERNAL_INFERENCE_OPERATIONAL_TOOLS, ExternalInferenceMcpError, DEFAULT_REQUEST_TIMEOUT_MS, MAX_RETRY_AFTER_MS, PUBLIC_TOOL_ERROR_PREFIX, parseRetryAfterMs, identifierSchema2, safeCodeSchema2, publicToolErrorSchema, parsePublicToolError, 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;
18161
18161
  var init_mcp_client = __esm({
18162
18162
  "lib/inference-host/mcp-client.ts"() {
18163
18163
  "use strict";
@@ -18209,6 +18209,7 @@ var init_mcp_client = __esm({
18209
18209
  };
18210
18210
  DEFAULT_REQUEST_TIMEOUT_MS = 15e3;
18211
18211
  MAX_RETRY_AFTER_MS = 24 * 60 * 60 * 1e3;
18212
+ PUBLIC_TOOL_ERROR_PREFIX = "VTX_INSIGHTS_ERROR_V1:";
18212
18213
  parseRetryAfterMs = (response, observedAtMs = Date.now()) => {
18213
18214
  const value = response.headers.get("retry-after")?.trim();
18214
18215
  if (!value) return null;
@@ -18219,6 +18220,23 @@ var init_mcp_client = __esm({
18219
18220
  };
18220
18221
  identifierSchema2 = external_exports.string().min(1).max(128);
18221
18222
  safeCodeSchema2 = external_exports.string().min(1).max(96);
18223
+ publicToolErrorSchema = external_exports.object({
18224
+ failure_code: safeCodeSchema2,
18225
+ phase: safeCodeSchema2,
18226
+ retryable: external_exports.boolean(),
18227
+ terminal_before_execution: external_exports.boolean()
18228
+ }).passthrough();
18229
+ parsePublicToolError = (text) => {
18230
+ const marker = text.lastIndexOf(PUBLIC_TOOL_ERROR_PREFIX);
18231
+ if (marker < 0) return null;
18232
+ const raw = text.slice(marker + PUBLIC_TOOL_ERROR_PREFIX.length).trim();
18233
+ try {
18234
+ const parsed = publicToolErrorSchema.safeParse(JSON.parse(raw));
18235
+ return parsed.success ? parsed.data : null;
18236
+ } catch {
18237
+ return null;
18238
+ }
18239
+ };
18222
18240
  hostMutationResultSchema = external_exports.strictObject({
18223
18241
  host: hostStatusReadSchema,
18224
18242
  replayed: external_exports.boolean()
@@ -18754,9 +18772,12 @@ var init_mcp_client = __esm({
18754
18772
  }).passthrough().parse(rawResult);
18755
18773
  if (callResult.isError === true) {
18756
18774
  const errorText = (callResult.content ?? []).filter((block) => block.type === "text").map((block) => block.text ?? "").join("\n");
18775
+ const publicToolError = parsePublicToolError(errorText);
18776
+ const hasPublicToolErrorMarker = errorText.includes(PUBLIC_TOOL_ERROR_PREFIX);
18777
+ 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"));
18757
18778
  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
18779
  "External inference claim request was not applied before its generation became stale"
18759
- ) || errorText.includes("External inference host advertisement is expired or superseded"));
18780
+ ) || errorText.includes("External inference host advertisement is expired or superseded")) || name === "inference.job.complete" && completionEvidenceExpired;
18760
18781
  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
18782
  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
18783
  const retryableHeartbeatClockSkew = name === "inference.host.heartbeat" && definitivelyNotApplied;
@@ -18766,7 +18787,7 @@ var init_mcp_client = __esm({
18766
18787
  "External inference claim replay is no longer dispatchable"
18767
18788
  );
18768
18789
  throw new ExternalInferenceMcpError(
18769
- staleHostHeartbeatGeneration ? "generation_stale" : obsoleteClaimReplay ? "claim_replay_obsolete" : "tool_rejected",
18790
+ completionEvidenceExpired ? "completion_evidence_expired" : staleHostHeartbeatGeneration ? "generation_stale" : obsoleteClaimReplay ? "claim_replay_obsolete" : "tool_rejected",
18770
18791
  `Insights MCP rejected ${name}.`,
18771
18792
  {
18772
18793
  definitivelyNotApplied: definitivelyNotApplied || staleHostHeartbeatGeneration,
@@ -32426,7 +32447,7 @@ function createDefaultInferenceHostRunnerDependencies(options) {
32426
32447
  envelopePublicKey: options.envelopePublicKey
32427
32448
  };
32428
32449
  }
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;
32450
+ 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
32451
  var init_runner = __esm({
32431
32452
  "lib/inference-host/runner.ts"() {
32432
32453
  "use strict";
@@ -33050,6 +33071,7 @@ var init_runner = __esm({
33050
33071
  if (failure.state !== request.attempt_status || failure.failure_category !== request.failure_category || failure.failure_code !== request.failure_code) runnerIdentityMismatch("Job failure receipt");
33051
33072
  }
33052
33073
  };
33074
+ isDefinitiveCompletionEvidenceExpiry = (error48, terminal) => terminal?.schema_version === "external_inference_job_complete_v1" && error48 instanceof ExternalInferenceMcpError && error48.code === "completion_evidence_expired" && error48.definitivelyNotApplied;
33053
33075
  classifyFailure = (error48, result2) => {
33054
33076
  if (error48 instanceof CodexAppServerError) {
33055
33077
  const category2 = error48.code === "quota_exceeded" ? "quota" : error48.category;
@@ -33907,10 +33929,19 @@ var init_runner = __esm({
33907
33929
  }
33908
33930
  return attemptId;
33909
33931
  };
33910
- const removeRecoveredAttempt = async (attemptId) => {
33932
+ const removeRecoveredAttempt = async (recovery) => {
33911
33933
  await mutateReceipt((current) => {
33934
+ const persisted = current.attempts[recovery.attempt_id];
33935
+ const persistedTerminal = persisted?.terminal_request;
33936
+ const recoveryTerminal = recovery.terminal_request;
33937
+ const sameTerminalRequest = Boolean(
33938
+ 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)
33939
+ );
33940
+ if (persisted?.phase !== "terminal_pending" || persisted.job_id !== recovery.job_id || persisted.terminal_operation_id !== recovery.terminal_operation_id || !sameTerminalRequest) {
33941
+ return current;
33942
+ }
33912
33943
  const attempts = { ...current.attempts };
33913
- delete attempts[attemptId];
33944
+ delete attempts[recovery.attempt_id];
33914
33945
  return { ...current, attempts, updated_at: isoAt(now()) };
33915
33946
  });
33916
33947
  };
@@ -33936,8 +33967,22 @@ var init_runner = __esm({
33936
33967
  failed += 1;
33937
33968
  }
33938
33969
  await this.dependencies.codexAdapter.acknowledgeAttempt?.(recovery.attempt_id);
33939
- await removeRecoveredAttempt(recovery.attempt_id);
33970
+ await removeRecoveredAttempt(recovery);
33940
33971
  } catch (error48) {
33972
+ if (isDefinitiveCompletionEvidenceExpiry(error48, recovery.terminal_request)) {
33973
+ await this.dependencies.codexAdapter.acknowledgeAttempt?.(recovery.attempt_id);
33974
+ await removeRecoveredAttempt(recovery);
33975
+ failed += 1;
33976
+ emitDiagnostic("terminal_recovery_retired", {
33977
+ job_id: recovery.job_id,
33978
+ attempt_id: recovery.attempt_id,
33979
+ attempt_phase: recovery.phase,
33980
+ terminal_operation: "complete",
33981
+ error_code: error48.code,
33982
+ definitively_not_applied: true
33983
+ });
33984
+ continue;
33985
+ }
33941
33986
  emitTerminalRecoveryFailure(recovery, error48);
33942
33987
  requestDrain(controlPlaneFatal(error48) ? "authority_lost" : "attempt_terminal_unconfirmed");
33943
33988
  break;
@@ -34568,6 +34613,22 @@ var init_runner = __esm({
34568
34613
  assertTerminalResult(completion, completionResult);
34569
34614
  await this.dependencies.codexAdapter.acknowledgeAttempt?.(attemptId);
34570
34615
  } catch (error48) {
34616
+ if (isDefinitiveCompletionEvidenceExpiry(error48, completion)) {
34617
+ await this.dependencies.codexAdapter.acknowledgeAttempt?.(attemptId);
34618
+ await stopHeartbeat();
34619
+ await removeAttempt();
34620
+ options.onAttemptOutcome?.({
34621
+ outcome: "failed",
34622
+ failure_category: "deadline",
34623
+ failure_code: error48.code,
34624
+ retryable: false,
34625
+ dispatch_outcome: completion.outcome.dispatch_outcome,
34626
+ response_outcome: "none",
34627
+ latency_ms: completion.latency_ms,
34628
+ usage: completion.usage
34629
+ });
34630
+ return "failed";
34631
+ }
34571
34632
  throw new InferenceHostRunnerError(
34572
34633
  "terminal_outcome_unconfirmed",
34573
34634
  "The exact completion receipt could not be confirmed; redispatch is fenced.",
@@ -41828,12 +41889,13 @@ var init_hyperliquid_account_state_adapter = __esm({
41828
41889
  buildUserFillsStorageKey = (cacheKey) => {
41829
41890
  return `${USER_FILLS_CACHE_STORAGE_PREFIX}${cacheKey}`;
41830
41891
  };
41831
- buildAccountStateCacheKey = (apiUrl, walletAddress, symbol2, aggregatePerpDexs, dexNames, includeEffectiveTakerRate, includeExactAccountMode, includeActiveAssetData) => {
41892
+ buildAccountStateCacheKey = (apiUrl, walletAddress, symbol2, aggregatePerpDexs, scopeAccountSummaryToSelectedDex, dexNames, includeEffectiveTakerRate, includeExactAccountMode, includeActiveAssetData) => {
41832
41893
  return [
41833
41894
  apiUrl.replace(/\/$/, "").toLowerCase(),
41834
41895
  walletAddress.trim().toLowerCase(),
41835
41896
  normalizeHyperliquidMarketSymbol(symbol2),
41836
41897
  aggregatePerpDexs ? "aggregate" : "selected",
41898
+ scopeAccountSummaryToSelectedDex ? "selected-summary" : "aggregate-summary",
41837
41899
  includeEffectiveTakerRate ? "with-effective-taker-rate" : "without-effective-taker-rate",
41838
41900
  includeExactAccountMode ? "with-exact-account-mode" : "without-exact-account-mode",
41839
41901
  includeActiveAssetData ? "with-active-asset" : "without-active-asset",
@@ -42505,15 +42567,20 @@ var init_hyperliquid_account_state_adapter = __esm({
42505
42567
  const activeAssetCacheKey = buildActiveAssetCacheKey(apiUrl, walletAddress, symbol2);
42506
42568
  const activeAssetRequestTypes = getBrowserActiveAssetTypeCandidates(apiUrl, walletAddress, symbol2);
42507
42569
  const aggregatePerpDexs = input.aggregatePerpDexs !== false;
42570
+ const scopeAccountSummaryToSelectedDex = input.scopeAccountSummaryToSelectedDex === true;
42508
42571
  const includeEffectiveTakerRate = input.includeEffectiveTakerRate === true;
42509
42572
  const includeExactAccountMode = input.includeExactAccountMode === true;
42510
42573
  const includeActiveAssetData = input.includeActiveAssetData !== false;
42511
42574
  const dexNames = listPerpDexsForAccountState(input.config, dex, aggregatePerpDexs);
42575
+ if (scopeAccountSummaryToSelectedDex && dex && !dexNames.includes(dex)) {
42576
+ dexNames.push(dex);
42577
+ }
42512
42578
  const cacheKey = buildAccountStateCacheKey(
42513
42579
  apiUrl,
42514
42580
  walletAddress,
42515
42581
  symbol2,
42516
42582
  aggregatePerpDexs,
42583
+ scopeAccountSummaryToSelectedDex,
42517
42584
  dexNames,
42518
42585
  includeEffectiveTakerRate,
42519
42586
  includeExactAccountMode,
@@ -42541,6 +42608,7 @@ var init_hyperliquid_account_state_adapter = __esm({
42541
42608
  apiUrl,
42542
42609
  walletAddress,
42543
42610
  symbol: symbol2,
42611
+ selectedDex: dex,
42544
42612
  activeAssetCacheKey,
42545
42613
  activeAssetRequestTypes,
42546
42614
  dexNames,
@@ -42580,6 +42648,7 @@ var init_hyperliquid_account_state_adapter = __esm({
42580
42648
  apiUrl,
42581
42649
  walletAddress,
42582
42650
  symbol: symbol2,
42651
+ selectedDex,
42583
42652
  activeAssetCacheKey,
42584
42653
  activeAssetRequestTypes,
42585
42654
  dexNames,
@@ -42604,11 +42673,22 @@ var init_hyperliquid_account_state_adapter = __esm({
42604
42673
  if (input.includeEffectiveTakerRate === true) {
42605
42674
  requirePromptClearinghouseState(response, dexName);
42606
42675
  }
42607
- return prefixHip3PositionCoins(response, dexName);
42676
+ return {
42677
+ dex: dexName,
42678
+ payload: prefixHip3PositionCoins(response, dexName)
42679
+ };
42608
42680
  })
42609
42681
  );
42682
+ const selectedPayload = selectedDex ? dexResponses.find((entry) => entry.dex === selectedDex)?.payload : defaultResponse;
42683
+ if (!selectedPayload) {
42684
+ throw new Error(`Missing selected Hyperliquid clearinghouse state for DEX ${selectedDex}.`);
42685
+ }
42610
42686
  return {
42611
- payload: aggregateClearinghouseResponses([defaultResponse, ...dexResponses]),
42687
+ payload: aggregateClearinghouseResponses([
42688
+ defaultResponse,
42689
+ ...dexResponses.map((entry) => entry.payload)
42690
+ ]),
42691
+ selectedPayload,
42612
42692
  capturedAt: (/* @__PURE__ */ new Date()).toISOString()
42613
42693
  };
42614
42694
  })();
@@ -42691,6 +42771,7 @@ var init_hyperliquid_account_state_adapter = __esm({
42691
42771
  exactAccountModePromise
42692
42772
  ]);
42693
42773
  const perpsResponse = perpsResult.payload;
42774
+ const accountSummaryPerpsResponse = input.scopeAccountSummaryToSelectedDex === true ? perpsResult.selectedPayload : perpsResponse;
42694
42775
  const spotResponse = spotResult.payload;
42695
42776
  const userFeesResponse = userFeesResult?.payload ?? null;
42696
42777
  if (input.includeEffectiveTakerRate === true) {
@@ -42712,18 +42793,35 @@ var init_hyperliquid_account_state_adapter = __esm({
42712
42793
  takerRate = parsedUserCrossRate;
42713
42794
  }
42714
42795
  const accountStateConfig = input.config.client_runtime_hyperliquid_account_state;
42715
- const summaryPerpsResponse = exactAccountMode ? { ...perpsResponse, accountMode: exactAccountMode.accountMode } : perpsResponse;
42796
+ const summaryPerpsResponse = exactAccountMode ? { ...accountSummaryPerpsResponse, accountMode: exactAccountMode.accountMode } : accountSummaryPerpsResponse;
42716
42797
  const accountSummaryOptions = {
42717
42798
  spotDominatesMinTotalUsd: accountStateConfig?.spot_dominates_min_total_usd,
42718
42799
  spotDominatesPerpsMultiplier: accountStateConfig?.spot_dominates_perps_multiplier,
42719
42800
  mirroredAccountValueAbsoluteToleranceUsd: accountStateConfig?.mirrored_account_value_absolute_tolerance_usd,
42720
42801
  mirroredAccountValueRelativeTolerance: accountStateConfig?.mirrored_account_value_relative_tolerance
42721
42802
  };
42722
- const normalizedSummary = exactAccountMode ? buildServerPromptRescueAccountSummary(
42803
+ const walletSummary = exactAccountMode && input.scopeAccountSummaryToSelectedDex !== true ? buildServerPromptRescueAccountSummary(
42723
42804
  perpsResponse,
42724
42805
  spotResponse,
42725
42806
  exactAccountMode.accountMode,
42726
42807
  accountSummaryOptions
42808
+ ) : buildAccountSummaryFromInfoResponses(
42809
+ perpsResponse,
42810
+ spotResponse,
42811
+ accountSummaryOptions
42812
+ );
42813
+ const normalizedSummary = input.scopeAccountSummaryToSelectedDex === true ? {
42814
+ ...buildAccountSummaryFromInfoResponses(
42815
+ summaryPerpsResponse,
42816
+ {},
42817
+ accountSummaryOptions
42818
+ ),
42819
+ balances: walletSummary.balances
42820
+ } : exactAccountMode ? buildServerPromptRescueAccountSummary(
42821
+ accountSummaryPerpsResponse,
42822
+ spotResponse,
42823
+ exactAccountMode.accountMode,
42824
+ accountSummaryOptions
42727
42825
  ) : buildAccountSummaryFromInfoResponses(
42728
42826
  summaryPerpsResponse,
42729
42827
  spotResponse,
@@ -42733,7 +42831,7 @@ var init_hyperliquid_account_state_adapter = __esm({
42733
42831
  ...normalizedSummary,
42734
42832
  ...exactAccountMode == null ? {} : { account_mode: exactAccountMode.accountMode, mode_source: "canonical" },
42735
42833
  address: walletAddress,
42736
- dex: "all",
42834
+ dex: input.scopeAccountSummaryToSelectedDex === true ? selectedDex : "all",
42737
42835
  market_type: "perp"
42738
42836
  };
42739
42837
  const activeAssetPayload = activeAssetResult?.payload ?? null;
@@ -43570,9 +43668,12 @@ async function postClientRuntime(path, profileId, body, options) {
43570
43668
  const numericProfileId = toNumericProfileId(profileId);
43571
43669
  const keepalive = options?.keepalive === true;
43572
43670
  const signal = options?.signal;
43671
+ const parsedRequestTimeoutMs = Number(options?.requestTimeoutMs);
43672
+ const requestTimeoutMs = Number.isFinite(parsedRequestTimeoutMs) && parsedRequestTimeoutMs > 0 ? Math.round(parsedRequestTimeoutMs) : null;
43573
43673
  const maxAttempts = keepalive ? 1 : 3;
43574
43674
  const requestContext = parseClientRuntimeRequestContext(body);
43575
- const idempotencyKey = shouldAttachRuntimeIdempotencyKey(path) ? createIdempotencyKey(`runtime-${path.replace(/\//g, "-")}`) : null;
43675
+ const explicitIdempotencyKey = String(options?.idempotencyKey ?? "").trim();
43676
+ const idempotencyKey = shouldAttachRuntimeIdempotencyKey(path) ? explicitIdempotencyKey || createIdempotencyKey(`runtime-${path.replace(/\//g, "-")}`) : null;
43576
43677
  const requestHeaders = getProfileHeaders({
43577
43678
  "Content-Type": "application/json"
43578
43679
  }, numericProfileId);
@@ -43589,6 +43690,24 @@ async function postClientRuntime(path, profileId, body, options) {
43589
43690
  let missingRuntimeLeaseRecoveryAttempted = false;
43590
43691
  for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
43591
43692
  let response = null;
43693
+ let requestTimedOut = false;
43694
+ let timeoutId = null;
43695
+ let relayCallerAbort = null;
43696
+ let requestSignal = signal;
43697
+ if (requestTimeoutMs !== null) {
43698
+ const timeoutController = new AbortController();
43699
+ relayCallerAbort = () => timeoutController.abort(signal?.reason);
43700
+ if (signal?.aborted) {
43701
+ relayCallerAbort();
43702
+ } else {
43703
+ signal?.addEventListener("abort", relayCallerAbort, { once: true });
43704
+ }
43705
+ timeoutId = globalThis.setTimeout(() => {
43706
+ requestTimedOut = true;
43707
+ timeoutController.abort(new DOMException("Runtime request timeout reached.", "TimeoutError"));
43708
+ }, requestTimeoutMs);
43709
+ requestSignal = timeoutController.signal;
43710
+ }
43592
43711
  const trace = startRuntimeNetworkDebugTrace({
43593
43712
  kind: "runtime",
43594
43713
  label: "client_runtime_api",
@@ -43601,7 +43720,7 @@ async function postClientRuntime(path, profileId, body, options) {
43601
43720
  method: "POST",
43602
43721
  credentials: "include",
43603
43722
  keepalive,
43604
- signal,
43723
+ signal: requestSignal,
43605
43724
  headers: { ...requestHeaders },
43606
43725
  body
43607
43726
  });
@@ -43609,7 +43728,11 @@ async function postClientRuntime(path, profileId, body, options) {
43609
43728
  const error48 = await createRuntimeRequestError(response, "Client runtime request failed");
43610
43729
  if (!resolvedRuntimeLeaseToken && !missingRuntimeLeaseRecoveryAttempted && shouldRecoverMissingRuntimeLease(path, requestContext, keepalive) && isMissingRuntimeLeaseError(response.status, error48.message)) {
43611
43730
  missingRuntimeLeaseRecoveryAttempted = true;
43612
- const recoveredRuntimeLeaseToken = await recoverMissingRuntimeLease(numericProfileId, requestContext);
43731
+ const recoveredRuntimeLeaseToken = await recoverMissingRuntimeLease(
43732
+ numericProfileId,
43733
+ requestContext,
43734
+ requestSignal
43735
+ );
43613
43736
  if (recoveredRuntimeLeaseToken) {
43614
43737
  resolvedRuntimeLeaseToken = recoveredRuntimeLeaseToken;
43615
43738
  attachRuntimeLeaseHeader(requestHeaders, resolvedRuntimeLeaseToken);
@@ -43627,7 +43750,7 @@ async function postClientRuntime(path, profileId, body, options) {
43627
43750
  hadRuntimeLeaseToken: Boolean(resolvedRuntimeLeaseToken),
43628
43751
  leaseCleared: shouldClearLease
43629
43752
  });
43630
- if (!keepalive && attempt < maxAttempts && !shouldClearLease && shouldRetryClientRuntimeHttpStatus(path, response.status)) {
43753
+ if (!keepalive && attempt < maxAttempts && !shouldClearLease && (shouldRetryClientRuntimeHttpStatus(path, response.status) || isRuntimeIdempotencyInProgressError(response.status, error48.message) || Boolean(idempotencyKey) && isRetryableRuntimeConflictError(response.status, error48))) {
43631
43754
  await sleep2(resolveClientRuntimeRetryDelayMs(attempt, response.headers.get("Retry-After")));
43632
43755
  continue;
43633
43756
  }
@@ -43642,10 +43765,11 @@ async function postClientRuntime(path, profileId, body, options) {
43642
43765
  trace.completeSuccess(response.status);
43643
43766
  return payload;
43644
43767
  } catch (error48) {
43645
- lastNetworkError = error48;
43646
- trace.completeError(error48, response?.status ?? null);
43647
- if (!isTransientNetworkFetchError(error48) || attempt >= maxAttempts) {
43648
- throw annotateRuntimeRequestError(error48, {
43768
+ const requestError = requestTimedOut && !signal?.aborted ? new TypeError("Runtime request timeout reached.") : error48;
43769
+ lastNetworkError = requestError;
43770
+ trace.completeError(requestError, response?.status ?? null);
43771
+ if (signal?.aborted || !requestTimedOut && !isTransientNetworkFetchError(requestError) || attempt >= maxAttempts) {
43772
+ throw annotateRuntimeRequestError(requestError, {
43649
43773
  path,
43650
43774
  method: "POST",
43651
43775
  attempt,
@@ -43657,6 +43781,13 @@ async function postClientRuntime(path, profileId, body, options) {
43657
43781
  }
43658
43782
  await sleep2(resolveClientRuntimeRetryDelayMs(attempt, null));
43659
43783
  continue;
43784
+ } finally {
43785
+ if (timeoutId !== null) {
43786
+ globalThis.clearTimeout(timeoutId);
43787
+ }
43788
+ if (signal && relayCallerAbort) {
43789
+ signal.removeEventListener("abort", relayCallerAbort);
43790
+ }
43660
43791
  }
43661
43792
  }
43662
43793
  if (lastNetworkError instanceof Error) {
@@ -43859,7 +43990,7 @@ async function reconcileActiveClientRuntimeExchangeMutation(profileId, requestOp
43859
43990
  }
43860
43991
  return rememberCompletedDeferredClientRuntimeStop(profileId, result2);
43861
43992
  }
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;
43993
+ 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
43994
  var init_api2 = __esm({
43864
43995
  "lib/api.ts"() {
43865
43996
  "use strict";
@@ -44058,7 +44189,9 @@ var init_api2 = __esm({
44058
44189
  };
44059
44190
  isMissingRuntimeLeaseError = (statusCode, message) => statusCode === 401 && String(message ?? "").trim().toLowerCase().includes("runtime lease required");
44060
44191
  createRuntimeRequestError = async (response, defaultMessage) => {
44061
- const rawMessage = await getErrorMessageFromResponse(response, defaultMessage);
44192
+ const payload = await getErrorPayloadOrEmpty(response);
44193
+ const nestedDetail = payload.detail && typeof payload.detail === "object" && !Array.isArray(payload.detail) ? payload.detail : null;
44194
+ const rawMessage = getErrorMessage(payload, defaultMessage);
44062
44195
  const walletCohortMessage = response.status === 409 ? {
44063
44196
  client_wallet_unavailable: "The active profile wallet is unavailable. Save a wallet for this profile, then try again.",
44064
44197
  client_wallet_mismatch: "The active profile wallet does not match this Client Mode session. Reload the profile, then try again.",
@@ -44067,6 +44200,15 @@ var init_api2 = __esm({
44067
44200
  const message = walletCohortMessage ?? rawMessage;
44068
44201
  const error48 = new Error(message);
44069
44202
  error48.status = response.status;
44203
+ error48.detail = payload.detail;
44204
+ const code = typeof payload.code === "string" ? payload.code.trim() : typeof nestedDetail?.code === "string" ? nestedDetail.code.trim() : "";
44205
+ if (code) {
44206
+ error48.code = code;
44207
+ }
44208
+ const retryable = payload.retryable ?? nestedDetail?.retryable;
44209
+ if (typeof retryable === "boolean") {
44210
+ error48.retryable = retryable;
44211
+ }
44070
44212
  return error48;
44071
44213
  };
44072
44214
  parseClientRuntimeRequestContext = (body) => {
@@ -44167,7 +44309,7 @@ var init_api2 = __esm({
44167
44309
  }
44168
44310
  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
44311
  };
44170
- recoverMissingRuntimeLease = async (profileId, requestContext) => {
44312
+ recoverMissingRuntimeLease = async (profileId, requestContext, signal) => {
44171
44313
  if (!requestContext.sessionId || !requestContext.deviceId) {
44172
44314
  return null;
44173
44315
  }
@@ -44181,6 +44323,7 @@ var init_api2 = __esm({
44181
44323
  method: "POST",
44182
44324
  credentials: "include",
44183
44325
  cache: "no-store",
44326
+ signal,
44184
44327
  headers,
44185
44328
  body: JSON.stringify({
44186
44329
  session_id: requestContext.sessionId,
@@ -44195,7 +44338,10 @@ var init_api2 = __esm({
44195
44338
  return null;
44196
44339
  }
44197
44340
  payload = await response.json();
44198
- } catch {
44341
+ } catch (error48) {
44342
+ if (signal?.aborted) {
44343
+ throw signal.reason ?? error48;
44344
+ }
44199
44345
  return null;
44200
44346
  }
44201
44347
  persistRuntimeLeaseFromPayload(payload);
@@ -44216,6 +44362,8 @@ var init_api2 = __esm({
44216
44362
  }
44217
44363
  return true;
44218
44364
  };
44365
+ isRuntimeIdempotencyInProgressError = (status, message) => status === 409 && (message.toLowerCase().includes("duplicate request already in progress") || message.toLowerCase().includes("duplicate request in-flight"));
44366
+ isRetryableRuntimeConflictError = (status, error48) => status === 409 && error48.retryable === true && (error48.code === "profile_runtime_contract_busy" || error48.code === "runtime_trade_sync_finalizing");
44219
44367
  resolveClientRuntimeRetryDelayMs = (attempt, retryAfterHeader) => {
44220
44368
  const retryAfterMs = parseRuntimeRetryAfterMs(retryAfterHeader);
44221
44369
  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.58",
4
4
  "description": "VTX Macro CLI, MCP server, and durable external inference host.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",