@vtxmacro/cli 2026.10.18 → 2026.10.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/vtx.js CHANGED
@@ -113,7 +113,7 @@ var init_routing = __esm({
113
113
  var agent_cli_release_default;
114
114
  var init_agent_cli_release = __esm({
115
115
  "agent-cli-release.json"() {
116
- agent_cli_release_default = { package_name: "@vtxmacro/cli", package_version: "2026.10.18", codex_package_name: "@openai/codex", codex_version: "0.155.0", copilot_sdk_package_name: "@github/copilot-sdk", copilot_sdk_version: "1.0.0-beta.8", copilot_cli_package_name: "@github/copilot", copilot_cli_version: "1.0.80", deepseek_harness_version: "0.1.1-rc.2", deepseek_harness_packages: ["@deepseek-ai/dsh-agent", "@deepseek-ai/dsh-agent-instructions", "@deepseek-ai/dsh-agent-loop", "@deepseek-ai/dsh-agent-spine-demo", "@deepseek-ai/dsh-anonymous-user-id", "@deepseek-ai/dsh-atomic-write", "@deepseek-ai/dsh-attachment", "@deepseek-ai/dsh-brand", "@deepseek-ai/dsh-code-runtime", "@deepseek-ai/dsh-credentials", "@deepseek-ai/dsh-fs", "@deepseek-ai/dsh-goal", "@deepseek-ai/dsh-goal-round-driver", "@deepseek-ai/dsh-home-paths", "@deepseek-ai/dsh-invariants", "@deepseek-ai/dsh-jobs", "@deepseek-ai/dsh-jobs-local", "@deepseek-ai/dsh-launch-environment", "@deepseek-ai/dsh-llm", "@deepseek-ai/dsh-llm-deepseek", "@deepseek-ai/dsh-llm-retry", "@deepseek-ai/dsh-output-retention", "@deepseek-ai/dsh-sandbox", "@deepseek-ai/dsh-sandbox-policy", "@deepseek-ai/dsh-scope", "@deepseek-ai/dsh-session", "@deepseek-ai/dsh-session-checkpoint-policy", "@deepseek-ai/dsh-session-persistence", "@deepseek-ai/dsh-session-persistence-jsonl", "@deepseek-ai/dsh-session-projection", "@deepseek-ai/dsh-session-title", "@deepseek-ai/dsh-settings", "@deepseek-ai/dsh-shell", "@deepseek-ai/dsh-shell-env", "@deepseek-ai/dsh-skill", "@deepseek-ai/dsh-skill-filesystem", "@deepseek-ai/dsh-subprocess", "@deepseek-ai/dsh-system-prompt", "@deepseek-ai/dsh-timeout", "@deepseek-ai/dsh-tool-bash", "@deepseek-ai/dsh-tool-goal", "@deepseek-ai/dsh-tool-jobs", "@deepseek-ai/dsh-tool-skill", "@deepseek-ai/dsh-tools", "@deepseek-ai/dsh-typert-protocol", "@deepseek-ai/dsh-user-approval"], deepseek_cordis_package_name: "@deepseek-ai/cordis", deepseek_cordis_version: "4.0.1", deepseek_support_packages: { "@deepseek-ai/cordis-plugin-timer": "1.1.3" }, platforms: { "linux-x64": { package_name: "@openai/codex-linux-x64", target: "x86_64-unknown-linux-musl", binary_name: "codex", sha256: "660e159a49e823ac8e5986cb238f73158ce4b957d40d9292f8de90862644b501" }, "win32-x64": { package_name: "@openai/codex-win32-x64", target: "x86_64-pc-windows-msvc", binary_name: "codex.exe", sha256: "e4c11374bd9de8ad5c3b7617fd4654bb7839901edb0863f9930666863c7a021b" } }, pi_coding_agent_package_name: "@earendil-works/pi-coding-agent", pi_ai_package_name: "@earendil-works/pi-ai", pi_version: "0.85.1", pi_support_packages: ["@earendil-works/pi-agent-core", "@earendil-works/pi-telemetry", "@earendil-works/pi-tui", "@earendil-works/chord"], grok_version: "1.0.30", grok_platforms: { "linux-x64": { package_name: "@xai-official/grok-linux-x64", binary_name: "grok", sha256: "504dd6546ab991b75d36698242875ce461489cd1f8cd84285873cb55bd5c7d54" }, "win32-x64": { package_name: "@xai-official/grok-win32-x64", binary_name: "grok.exe", sha256: "48736d1a4342a801ea26d0ecde4c516b653f791399065adaa55973f83abd8867" } } };
116
+ agent_cli_release_default = { package_name: "@vtxmacro/cli", package_version: "2026.10.19", codex_package_name: "@openai/codex", codex_version: "0.155.0", copilot_sdk_package_name: "@github/copilot-sdk", copilot_sdk_version: "1.0.0-beta.8", copilot_cli_package_name: "@github/copilot", copilot_cli_version: "1.0.80", deepseek_harness_version: "0.1.1-rc.2", deepseek_harness_packages: ["@deepseek-ai/dsh-agent", "@deepseek-ai/dsh-agent-instructions", "@deepseek-ai/dsh-agent-loop", "@deepseek-ai/dsh-agent-spine-demo", "@deepseek-ai/dsh-anonymous-user-id", "@deepseek-ai/dsh-atomic-write", "@deepseek-ai/dsh-attachment", "@deepseek-ai/dsh-brand", "@deepseek-ai/dsh-code-runtime", "@deepseek-ai/dsh-credentials", "@deepseek-ai/dsh-fs", "@deepseek-ai/dsh-goal", "@deepseek-ai/dsh-goal-round-driver", "@deepseek-ai/dsh-home-paths", "@deepseek-ai/dsh-invariants", "@deepseek-ai/dsh-jobs", "@deepseek-ai/dsh-jobs-local", "@deepseek-ai/dsh-launch-environment", "@deepseek-ai/dsh-llm", "@deepseek-ai/dsh-llm-deepseek", "@deepseek-ai/dsh-llm-retry", "@deepseek-ai/dsh-output-retention", "@deepseek-ai/dsh-sandbox", "@deepseek-ai/dsh-sandbox-policy", "@deepseek-ai/dsh-scope", "@deepseek-ai/dsh-session", "@deepseek-ai/dsh-session-checkpoint-policy", "@deepseek-ai/dsh-session-persistence", "@deepseek-ai/dsh-session-persistence-jsonl", "@deepseek-ai/dsh-session-projection", "@deepseek-ai/dsh-session-title", "@deepseek-ai/dsh-settings", "@deepseek-ai/dsh-shell", "@deepseek-ai/dsh-shell-env", "@deepseek-ai/dsh-skill", "@deepseek-ai/dsh-skill-filesystem", "@deepseek-ai/dsh-subprocess", "@deepseek-ai/dsh-system-prompt", "@deepseek-ai/dsh-timeout", "@deepseek-ai/dsh-tool-bash", "@deepseek-ai/dsh-tool-goal", "@deepseek-ai/dsh-tool-jobs", "@deepseek-ai/dsh-tool-skill", "@deepseek-ai/dsh-tools", "@deepseek-ai/dsh-typert-protocol", "@deepseek-ai/dsh-user-approval"], deepseek_cordis_package_name: "@deepseek-ai/cordis", deepseek_cordis_version: "4.0.1", deepseek_support_packages: { "@deepseek-ai/cordis-plugin-timer": "1.1.3" }, platforms: { "linux-x64": { package_name: "@openai/codex-linux-x64", target: "x86_64-unknown-linux-musl", binary_name: "codex", sha256: "660e159a49e823ac8e5986cb238f73158ce4b957d40d9292f8de90862644b501" }, "win32-x64": { package_name: "@openai/codex-win32-x64", target: "x86_64-pc-windows-msvc", binary_name: "codex.exe", sha256: "e4c11374bd9de8ad5c3b7617fd4654bb7839901edb0863f9930666863c7a021b" } }, pi_coding_agent_package_name: "@earendil-works/pi-coding-agent", pi_ai_package_name: "@earendil-works/pi-ai", pi_version: "0.85.1", pi_support_packages: ["@earendil-works/pi-agent-core", "@earendil-works/pi-telemetry", "@earendil-works/pi-tui", "@earendil-works/chord"], grok_version: "1.0.30", grok_platforms: { "linux-x64": { package_name: "@xai-official/grok-linux-x64", binary_name: "grok", sha256: "504dd6546ab991b75d36698242875ce461489cd1f8cd84285873cb55bd5c7d54" }, "win32-x64": { package_name: "@xai-official/grok-win32-x64", binary_name: "grok.exe", sha256: "48736d1a4342a801ea26d0ecde4c516b653f791399065adaa55973f83abd8867" } } };
117
117
  }
118
118
  });
119
119
 
@@ -961,6 +961,10 @@ var init_runtime_policy_generated = __esm({
961
961
  },
962
962
  defaults: {
963
963
  server_ai_max_slippage: 5
964
+ },
965
+ risk: {
966
+ max_order_notional: 5e3,
967
+ max_position_notional: 1e4
964
968
  }
965
969
  },
966
970
  agent_cli: {
@@ -1213,6 +1217,7 @@ var init_runtime_policy_generated = __esm({
1213
1217
  metadata_ttl_seconds: 300,
1214
1218
  user_fees_ttl_seconds: 300,
1215
1219
  account_mode_ttl_seconds: 30,
1220
+ ui_account_mode_ttl_seconds: 300,
1216
1221
  default_request_weight: 20,
1217
1222
  cache_max_entries: 512
1218
1223
  },
@@ -1457,7 +1462,7 @@ var init_runtime_policy_generated = __esm({
1457
1462
  });
1458
1463
 
1459
1464
  // lib/constants.ts
1460
- var MS_PER_SECOND, SECONDS_PER_MINUTE, MINUTES_PER_HOUR, HOURS_PER_DAY, DAYS_PER_WEEK, MS_PER_MINUTE, SECONDS_PER_HOUR, SECONDS_PER_DAY, SECONDS_PER_WEEK, MINUTES_PER_DAY, MINUTES_PER_WEEK, MS_PER_HOUR, MS_PER_DAY, READ_STAMP_TIE_MS, READ_STAMP_STEP_BACK_MS, CLOCK_FIELD_DIGITS, BACKOFF_GROWTH_FACTOR, BYTES_PER_KIB, BYTES_PER_MIB, BITS_PER_BYTE, BYTE_MASK, OWNER_ONLY_FILE_MODE, OWNER_ONLY_DIRECTORY_MODE, GROUP_OTHER_PERMISSION_BITS, DECIMAL_RADIX, HEX_RADIX, BASE36_RADIX, BYTE_HEX_DIGITS, UINT32_HEX_DIGITS, RANDOM_FRACTION_PREFIX_LENGTH, PERCENT_SCALE, MIDPOINT_DIVISOR, SQUARE_EXPONENT, FNV1A_32_OFFSET_BASIS, FNV1A_32_PRIME, JSON_INDENT_SPACES, INT32_MIN, INT32_MAX, SET_TIMEOUT_MAX_DELAY_MS, POSITION_SIZE_EPSILON, CANDLE_TIMEFRAME_SECONDS, HTTP_STATUS, HTTP_STATUS_MIN, HTTP_STATUS_MAX, HTTP_CLIENT_ERROR_MIN, HTTP_SERVER_ERROR_MIN, AI_COST_ESTIMATE_PERIOD_DAYS, SECONDS_PER_AI_COST_ESTIMATE_PERIOD, DATE_FIELD_DIGITS, EXTERNAL_INFERENCE_LIMITS, NODE_ARGV_COMMAND_ARGS_START, EXIT_CODE_TEMPFAIL, SHA256_INITIAL_STATE, SHA256_ROUND_CONSTANTS, SHA256, UINT64_HIGH_WORD_DIVISOR, CANONICAL_BASE64URL, INFERENCE_ENVELOPE_CRYPTO, EXTERNAL_INFERENCE_SCHEMA_BOUNDS, JSON_RPC_ERROR_CODES, INFERENCE_MCP_SCHEMA_PROBE_MAX_DEPTH, INFERENCE_HOST_PROCESS_LOCK_RECORD_SCHEMA_VERSION, INFERENCE_HOST_RECLAIM_GUARD_CREATE_PASSES, LINUX_PROC_STAT_COMM_TERMINATOR_CHARS, INFERENCE_HOST_RANDOM_BYTES, INFERENCE_OAUTH_TOKEN_MAX_LENGTH, INFERENCE_CREDENTIAL_WINDOWS_NOT_FOUND_EXIT_CODE, MACOS_SECURITY_ITEM_NOT_FOUND_EXIT_CODE, INFERENCE_CREDENTIAL_LABEL_ACCOUNT_KEY_CHARS, INFERENCE_HOST_STABLE_OPERATION_ID_HASH_CHARS, INFERENCE_HOST_DRAIN_PRIORITY, INFERENCE_JOB_CLAIM_SCHEMA_VERSION, INFERENCE_HOST_WINDOWS_TASK_IDENTITY_MAX_CHARS, INFERENCE_HOST_OWNER_ONLY_EXECUTABLE_MODE, WINDOWS_TASKKILL_PROCESS_NOT_FOUND_EXIT_CODE, INFERENCE_HOST_CLI_MAX_SERVICE_POSITIONALS, INFERENCE_HOST_CLI_MAX_COMMAND_POSITIONALS, INFERENCE_HOST_DISPLAY_NAME_MAX_CHARS, INFERENCE_HOST_REVOCATION_CHECKPOINT_MAX_CHARS, INFERENCE_HOST_MODEL_ID_MAX_CHARS, CODEX_RECOVERY_RECEIPT_MAX_CHARS, CODEX_HOSTED_ATTEMPT_PATH_SEGMENTS, CODEX_GUARDIAN_PROCESS_TOKEN_BYTES, CODEX_RATE_LIMIT_EXHAUSTED_PERCENT, INFERENCE_HOST_PROXY_TOKEN_BYTES, GROK_TOOL_SERVER_TOKEN_BYTES, GROK_NATIVE_SESSION_GROUP_NAME_MAX_CHARS, GROK_POLICY_TRANSPORT_MAX_BYTES, EXO_POLICY_MAX_TOOL_ROUNDS, EXO_POLICY_MAX_MODELS, EXO_POLICY_MODEL_NAME_MAX_CHARS, EXO_RUNTIME_VERSION_COMMIT_CHARS, PI_QUALIFIED_MODEL_ID_MAX_CHARS, PI_STRUCTURED_OUTPUT_MAX_DEPTH, PI_STRUCTURED_OUTPUT_MAX_PROPERTIES, INFERENCE_HOST_API_KEY_MIN_CHARS, INFERENCE_HOST_API_KEY_MAX_BYTES, INFERENCE_HOST_API_KEY_IDENTITY_HEX_CHARS, DEEPSEEK_HARNESS_NODE_LTS_MAJOR, DEEPSEEK_HARNESS_NODE_LTS_MIN_MINOR, DEEPSEEK_HARNESS_NODE_CURRENT_MAJOR, PROMPT_FIXED_DIGITS, PROMPT_SIGNIFICANT_DIGITS, PROMPT_NUMBER_MAX_DIGITS, PROMPT_PRICE_INTEGER_THRESHOLD, PROMPT_MARGIN_UTILIZATION_DECIMALS, PROMPT_SYMBOL_MAX_CHARS, PROMPT_PARTIAL_UNIT_ROUND_UP_FRACTION, HALF_UP_ROUNDING_OFFSET, PROMPT_ENTRY_PRICE_MATCH_ABS_TOLERANCE, PROMPT_ENTRY_PRICE_MATCH_REL_TOLERANCE, DECISION_OUTPUT_EXAMPLE_TRADABILITY, INDICATOR_RSI_PERIOD, INDICATOR_ATR_PERIOD, INDICATOR_MACD_FAST_PERIOD, INDICATOR_MACD_SLOW_PERIOD, INDICATOR_MACD_SIGNAL_PERIOD, INDICATOR_BOLLINGER_PERIOD, INDICATOR_BOLLINGER_STD_DEV, INDICATOR_OSCILLATOR_MAX, EMA_SMOOTHING_NUMERATOR, PROMPT_EMA_PERIODS, JSON_UNICODE_ESCAPE_PREFIX_LENGTH, JSON_UNICODE_ESCAPE_HEX_DIGITS, JSON_CONTROL_CHARACTER_MAX, RUNTIME_DEBUG_SNIPPET_CHARS, RUNTIME_DEBUG_PROMPT_SNIPPET_CHARS, RUNTIME_DEBUG_TOKEN_PREFIX_CHARS, RUNTIME_DEBUG_USD_DECIMALS, REVIEW_FAILURE_DETAIL_MAX_CHARS, RUNTIME_LATENCY_SECONDS_DECIMALS, AI_SCHEDULE_CLOCK_PARTS, ESTIMATED_CHARS_PER_TOKEN, PROVIDER_ERROR_RAW_TEXT_MAX_CHARS, AI_CALL_COST_DECIMALS, PROVIDER_DIAGNOSTIC_LIMITS, AI_INVOCATION_CONTRACT_VERSION, AI_INVOCATION_TELEMETRY_LIMITS, PROVIDER_USAGE_DETAIL_LIMITS, HYPERLIQUID_EXCHANGE_SPECIFICATION, HYPERLIQUID_TPSL_BATCH_MIN_ORDERS, HYPERLIQUID_USER_FILLS_PROVIDER_PAGE_CAP, HYPERLIQUID_ROW_WEIGHTED_INFO_REQUESTS, HYPERLIQUID_INFO_ROWS_PER_EXTRA_WEIGHT, HYPERLIQUID_META_AND_ASSET_CTXS_PARTS, HYPERLIQUID_SIDE_PAIR_LENGTH, HYPERLIQUID_SIGNED_SIZE_MATCH_EXTRA_DECIMALS, HYPERLIQUID_OPEN_ORDERS_MAX_NESTING_DEPTH, ACCOUNT_PAYLOAD_MODE_SEARCH_MAX_DEPTH, HYPERLIQUID_ACCOUNT_ROUNDING_DECIMALS, HYPERLIQUID_UNREALIZED_PNL_ZERO_TOLERANCE, HYPERLIQUID_MAX_DEPLOYER_FEE_SCALE, HYPERLIQUID_DEPLOYER_FEE_SCALE_MULTIPLIER, HYPERLIQUID_GROWTH_MODE_FEE_FACTOR, HYPERLIQUID_ALIGNED_QUOTE_NON_DEPLOYER_FEE_FACTOR, HYPERLIQUID_CLOSE_SIZE_RELATIVE_TOLERANCE, HYPERLIQUID_POSITION_SIZE_MATCH_ABS_TOLERANCE, HYPERLIQUID_POSITION_SIZE_MATCH_RELATIVE_TOLERANCE, HYPERLIQUID_LOT_FLOOR_NOISE_DECIMALS, HYPERLIQUID_RECOVERY_BACKOFF_MAX_EXPONENT, HYPERLIQUID_RECOVERY_CONCURRENCY_GROWTH_FACTOR, UUID_BYTES, UUID_HEX_GROUP_ENDS, MSGPACK, CLIENT_RUNTIME_DEFAULT_RETRY_SECONDS, CLIENT_RUNTIME_PROVIDER_ATTEMPT_SUMMARY_MAX_CHARS, CLIENT_RUNTIME_HL_REQUEST_TYPE_MAX_CHARS, CLIENT_RUNTIME_DRAWDOWN_DEBUG_DECIMALS, CLIENT_PROTECTIVE_GROUP_VERSION, CLIENT_PROTECTIVE_TPSL_PAIR_LEGS, CLIENT_PROTECTIVE_FILL_MATCH_ABS_TOLERANCE, CLIENT_PROTECTIVE_FILL_MATCH_REL_TOLERANCE, CLIENT_CLOSE_FILL_EPSILON_ULPS, COPY_TRADING_SIZE_EPSILON, COPY_TRADING_RELATIVE_SIZE_TOLERANCE, COPY_TRADING_NOTIONAL_CAP_TOLERANCE_USD, CLIENT_ACCOUNT_PNL_NONZERO_MIN_USD, RUNTIME_PORTFOLIO_PERIOD_ENTRY_LENGTH, CLIENT_EXCHANGE_RECONCILIATION_MAX_DELAY_MS, RFC1918_172_BLOCK_SECOND_OCTET, AGENT_CLI_TAKEOVER_REQUIRED_EXIT_CODE, EXIT_CODE_INTERRUPTED, EXIT_CODE_SIGNAL_BASE, BYOK_PROVIDER_DISPLAY_ORDER_STEP, TOKENS_PER_MILLION, RENDER_DEBUG_ID_RANDOM_CHARS;
1465
+ var MS_PER_SECOND, SECONDS_PER_MINUTE, MINUTES_PER_HOUR, HOURS_PER_DAY, DAYS_PER_WEEK, MS_PER_MINUTE, SECONDS_PER_HOUR, SECONDS_PER_DAY, SECONDS_PER_WEEK, MINUTES_PER_DAY, MINUTES_PER_WEEK, MS_PER_HOUR, MS_PER_DAY, READ_STAMP_TIE_MS, READ_STAMP_STEP_BACK_MS, CLOCK_FIELD_DIGITS, BACKOFF_GROWTH_FACTOR, BYTES_PER_KIB, BYTES_PER_MIB, BITS_PER_BYTE, BYTE_MASK, OWNER_ONLY_FILE_MODE, OWNER_ONLY_DIRECTORY_MODE, GROUP_OTHER_PERMISSION_BITS, DECIMAL_RADIX, HEX_RADIX, BASE36_RADIX, BYTE_HEX_DIGITS, UINT32_HEX_DIGITS, RANDOM_FRACTION_PREFIX_LENGTH, PERCENT_SCALE, MIDPOINT_DIVISOR, SQUARE_EXPONENT, FNV1A_32_OFFSET_BASIS, FNV1A_32_PRIME, JSON_INDENT_SPACES, INT32_MIN, INT32_MAX, SET_TIMEOUT_MAX_DELAY_MS, POSITION_SIZE_EPSILON, CANDLE_TIMEFRAME_SECONDS, HTTP_STATUS, HTTP_STATUS_MIN, HTTP_STATUS_MAX, HTTP_CLIENT_ERROR_MIN, HTTP_SERVER_ERROR_MIN, USD_DISPLAY_DECIMALS, AI_COST_ESTIMATE_PERIOD_DAYS, SECONDS_PER_AI_COST_ESTIMATE_PERIOD, DATE_FIELD_DIGITS, EXTERNAL_INFERENCE_LIMITS, NODE_ARGV_COMMAND_ARGS_START, EXIT_CODE_TEMPFAIL, SHA256_INITIAL_STATE, SHA256_ROUND_CONSTANTS, SHA256, UINT64_HIGH_WORD_DIVISOR, CANONICAL_BASE64URL, INFERENCE_ENVELOPE_CRYPTO, EXTERNAL_INFERENCE_SCHEMA_BOUNDS, JSON_RPC_ERROR_CODES, INFERENCE_MCP_SCHEMA_PROBE_MAX_DEPTH, INFERENCE_HOST_PROCESS_LOCK_RECORD_SCHEMA_VERSION, INFERENCE_HOST_RECLAIM_GUARD_CREATE_PASSES, LINUX_PROC_STAT_COMM_TERMINATOR_CHARS, INFERENCE_HOST_RANDOM_BYTES, INFERENCE_OAUTH_TOKEN_MAX_LENGTH, INFERENCE_CREDENTIAL_WINDOWS_NOT_FOUND_EXIT_CODE, MACOS_SECURITY_ITEM_NOT_FOUND_EXIT_CODE, INFERENCE_CREDENTIAL_LABEL_ACCOUNT_KEY_CHARS, INFERENCE_HOST_STABLE_OPERATION_ID_HASH_CHARS, INFERENCE_HOST_DRAIN_PRIORITY, INFERENCE_JOB_CLAIM_SCHEMA_VERSION, INFERENCE_HOST_WINDOWS_TASK_IDENTITY_MAX_CHARS, INFERENCE_HOST_OWNER_ONLY_EXECUTABLE_MODE, WINDOWS_TASKKILL_PROCESS_NOT_FOUND_EXIT_CODE, INFERENCE_HOST_CLI_MAX_SERVICE_POSITIONALS, INFERENCE_HOST_CLI_MAX_COMMAND_POSITIONALS, INFERENCE_HOST_DISPLAY_NAME_MAX_CHARS, INFERENCE_HOST_REVOCATION_CHECKPOINT_MAX_CHARS, INFERENCE_HOST_MODEL_ID_MAX_CHARS, CODEX_RECOVERY_RECEIPT_MAX_CHARS, CODEX_HOSTED_ATTEMPT_PATH_SEGMENTS, CODEX_GUARDIAN_PROCESS_TOKEN_BYTES, CODEX_RATE_LIMIT_EXHAUSTED_PERCENT, INFERENCE_HOST_PROXY_TOKEN_BYTES, GROK_TOOL_SERVER_TOKEN_BYTES, GROK_NATIVE_SESSION_GROUP_NAME_MAX_CHARS, GROK_POLICY_TRANSPORT_MAX_BYTES, EXO_POLICY_MAX_TOOL_ROUNDS, EXO_POLICY_MAX_MODELS, EXO_POLICY_MODEL_NAME_MAX_CHARS, EXO_RUNTIME_VERSION_COMMIT_CHARS, PI_QUALIFIED_MODEL_ID_MAX_CHARS, PI_STRUCTURED_OUTPUT_MAX_DEPTH, PI_STRUCTURED_OUTPUT_MAX_PROPERTIES, INFERENCE_HOST_API_KEY_MIN_CHARS, INFERENCE_HOST_API_KEY_MAX_BYTES, INFERENCE_HOST_API_KEY_IDENTITY_HEX_CHARS, DEEPSEEK_HARNESS_NODE_LTS_MAJOR, DEEPSEEK_HARNESS_NODE_LTS_MIN_MINOR, DEEPSEEK_HARNESS_NODE_CURRENT_MAJOR, PROMPT_FIXED_DIGITS, PROMPT_SIGNIFICANT_DIGITS, PROMPT_NUMBER_MAX_DIGITS, PROMPT_PRICE_INTEGER_THRESHOLD, PROMPT_MARGIN_UTILIZATION_DECIMALS, PROMPT_SYMBOL_MAX_CHARS, PROMPT_PARTIAL_UNIT_ROUND_UP_FRACTION, HALF_UP_ROUNDING_OFFSET, PROMPT_ENTRY_PRICE_MATCH_ABS_TOLERANCE, PROMPT_ENTRY_PRICE_MATCH_REL_TOLERANCE, DECISION_OUTPUT_EXAMPLE_TRADABILITY, INDICATOR_RSI_PERIOD, INDICATOR_ATR_PERIOD, INDICATOR_MACD_FAST_PERIOD, INDICATOR_MACD_SLOW_PERIOD, INDICATOR_MACD_SIGNAL_PERIOD, INDICATOR_BOLLINGER_PERIOD, INDICATOR_BOLLINGER_STD_DEV, INDICATOR_OSCILLATOR_MAX, EMA_SMOOTHING_NUMERATOR, PROMPT_EMA_PERIODS, JSON_UNICODE_ESCAPE_PREFIX_LENGTH, JSON_UNICODE_ESCAPE_HEX_DIGITS, JSON_CONTROL_CHARACTER_MAX, RUNTIME_DEBUG_SNIPPET_CHARS, RUNTIME_DEBUG_PROMPT_SNIPPET_CHARS, RUNTIME_DEBUG_TOKEN_PREFIX_CHARS, RUNTIME_DEBUG_USD_DECIMALS, REVIEW_FAILURE_DETAIL_MAX_CHARS, RUNTIME_LATENCY_SECONDS_DECIMALS, AI_SCHEDULE_CLOCK_PARTS, ESTIMATED_CHARS_PER_TOKEN, PROVIDER_ERROR_RAW_TEXT_MAX_CHARS, AI_CALL_COST_DECIMALS, PROVIDER_DIAGNOSTIC_LIMITS, AI_INVOCATION_CONTRACT_VERSION, AI_INVOCATION_TELEMETRY_LIMITS, PROVIDER_USAGE_DETAIL_LIMITS, HYPERLIQUID_EXCHANGE_SPECIFICATION, HYPERLIQUID_TPSL_BATCH_MIN_ORDERS, HYPERLIQUID_USER_FILLS_PROVIDER_PAGE_CAP, HYPERLIQUID_ROW_WEIGHTED_INFO_REQUESTS, HYPERLIQUID_INFO_ROWS_PER_EXTRA_WEIGHT, HYPERLIQUID_META_AND_ASSET_CTXS_PARTS, HYPERLIQUID_SIDE_PAIR_LENGTH, HYPERLIQUID_SIGNED_SIZE_MATCH_EXTRA_DECIMALS, HYPERLIQUID_OPEN_ORDERS_MAX_NESTING_DEPTH, ACCOUNT_PAYLOAD_MODE_SEARCH_MAX_DEPTH, HYPERLIQUID_ACCOUNT_ROUNDING_DECIMALS, HYPERLIQUID_UNREALIZED_PNL_ZERO_TOLERANCE, HYPERLIQUID_MAX_DEPLOYER_FEE_SCALE, HYPERLIQUID_DEPLOYER_FEE_SCALE_MULTIPLIER, HYPERLIQUID_GROWTH_MODE_FEE_FACTOR, HYPERLIQUID_ALIGNED_QUOTE_NON_DEPLOYER_FEE_FACTOR, HYPERLIQUID_CLOSE_SIZE_RELATIVE_TOLERANCE, HYPERLIQUID_POSITION_SIZE_MATCH_ABS_TOLERANCE, HYPERLIQUID_POSITION_SIZE_MATCH_RELATIVE_TOLERANCE, HYPERLIQUID_LOT_FLOOR_NOISE_DECIMALS, HYPERLIQUID_RECOVERY_BACKOFF_MAX_EXPONENT, HYPERLIQUID_RECOVERY_CONCURRENCY_GROWTH_FACTOR, UUID_BYTES, UUID_HEX_GROUP_ENDS, MSGPACK, CLIENT_RUNTIME_DEFAULT_RETRY_SECONDS, CLIENT_RUNTIME_PROVIDER_ATTEMPT_SUMMARY_MAX_CHARS, CLIENT_RUNTIME_HL_REQUEST_TYPE_MAX_CHARS, CLIENT_RUNTIME_DRAWDOWN_DEBUG_DECIMALS, CLIENT_PROTECTIVE_GROUP_VERSION, CLIENT_PROTECTIVE_TPSL_PAIR_LEGS, CLIENT_PROTECTIVE_FILL_MATCH_ABS_TOLERANCE, CLIENT_PROTECTIVE_FILL_MATCH_REL_TOLERANCE, CLIENT_CLOSE_FILL_EPSILON_ULPS, COPY_TRADING_SIZE_EPSILON, COPY_TRADING_RELATIVE_SIZE_TOLERANCE, COPY_TRADING_NOTIONAL_CAP_TOLERANCE_USD, CLIENT_ACCOUNT_PNL_NONZERO_MIN_USD, RUNTIME_PORTFOLIO_PERIOD_ENTRY_LENGTH, CLIENT_EXCHANGE_RECONCILIATION_MAX_DELAY_MS, RFC1918_172_BLOCK_SECOND_OCTET, AGENT_CLI_TAKEOVER_REQUIRED_EXIT_CODE, EXIT_CODE_INTERRUPTED, EXIT_CODE_SIGNAL_BASE, BYOK_PROVIDER_DISPLAY_ORDER_STEP, TOKENS_PER_MILLION, RENDER_DEBUG_ID_RANDOM_CHARS;
1461
1466
  var init_constants = __esm({
1462
1467
  "lib/constants.ts"() {
1463
1468
  "use strict";
@@ -1550,6 +1555,7 @@ var init_constants = __esm({
1550
1555
  HTTP_STATUS_MAX = 599;
1551
1556
  HTTP_CLIENT_ERROR_MIN = 400;
1552
1557
  HTTP_SERVER_ERROR_MIN = 500;
1558
+ USD_DISPLAY_DECIMALS = 2;
1553
1559
  AI_COST_ESTIMATE_PERIOD_DAYS = 30;
1554
1560
  SECONDS_PER_AI_COST_ESTIMATE_PERIOD = SECONDS_PER_DAY * AI_COST_ESTIMATE_PERIOD_DAYS;
1555
1561
  DATE_FIELD_DIGITS = 2;
@@ -20766,6 +20772,10 @@ var init_runtime_policy_generated2 = __esm({
20766
20772
  },
20767
20773
  defaults: {
20768
20774
  server_ai_max_slippage: 5
20775
+ },
20776
+ risk: {
20777
+ max_order_notional: 5e3,
20778
+ max_position_notional: 1e4
20769
20779
  }
20770
20780
  },
20771
20781
  agent_cli: {
@@ -21018,6 +21028,7 @@ var init_runtime_policy_generated2 = __esm({
21018
21028
  metadata_ttl_seconds: 300,
21019
21029
  user_fees_ttl_seconds: 300,
21020
21030
  account_mode_ttl_seconds: 30,
21031
+ ui_account_mode_ttl_seconds: 300,
21021
21032
  default_request_weight: 20,
21022
21033
  cache_max_entries: 512
21023
21034
  },
@@ -54314,7 +54325,7 @@ var init_hyperliquid_market_symbol = __esm({
54314
54325
  });
54315
54326
 
54316
54327
  // lib/runtime/bot-exchanges.ts
54317
- var exchangesByProfile, profileKey, dexList, recordBotExchanges, recordStatusExchanges;
54328
+ var exchangesByProfile, exchangesVersion, exchangeListeners, exchangesChanged, profileKey, dexList, recordBotExchanges, recordStatusExchanges;
54318
54329
  var init_bot_exchanges = __esm({
54319
54330
  "lib/runtime/bot-exchanges.ts"() {
54320
54331
  "use strict";
@@ -54323,6 +54334,12 @@ var init_bot_exchanges = __esm({
54323
54334
  init_define_VTX_PI_MODEL_POLICY();
54324
54335
  init_hyperliquid_market_symbol();
54325
54336
  exchangesByProfile = /* @__PURE__ */ new Map();
54337
+ exchangesVersion = 0;
54338
+ exchangeListeners = /* @__PURE__ */ new Set();
54339
+ exchangesChanged = () => {
54340
+ exchangesVersion += 1;
54341
+ exchangeListeners.forEach((listener) => listener());
54342
+ };
54326
54343
  profileKey = (profileId) => {
54327
54344
  const id2 = Number(profileId);
54328
54345
  return Number.isInteger(id2) && id2 > 0 ? id2 : null;
@@ -54333,11 +54350,14 @@ var init_bot_exchanges = __esm({
54333
54350
  if (id2 === null) return;
54334
54351
  const equity = dexList(equityVenues);
54335
54352
  const read = readVenues === void 0 ? equity : dexList(readVenues);
54353
+ const previous = exchangesByProfile.get(id2);
54336
54354
  if (!equity || !read) {
54337
- exchangesByProfile.delete(id2);
54355
+ if (exchangesByProfile.delete(id2)) exchangesChanged();
54338
54356
  return;
54339
54357
  }
54358
+ if (previous && previous.equity.join() === equity.join() && previous.read.join() === read.join()) return;
54340
54359
  exchangesByProfile.set(id2, { equity, read });
54360
+ exchangesChanged();
54341
54361
  };
54342
54362
  recordStatusExchanges = (status) => {
54343
54363
  const fields = status;
@@ -54774,6 +54794,7 @@ async function getLiveTicker(symbol2 = "PI_XBTUSD", exchange = "kraken", signal)
54774
54794
  async function getExecutionAssetMetadata(exchange, symbol2, options) {
54775
54795
  const params = new URLSearchParams();
54776
54796
  if (options?.includePrivateContext) params.set("include_private_context", "true");
54797
+ if (options?.forceCatalogRefresh) params.set("force_catalog_refresh", "true");
54777
54798
  if (options?.publicRequestPriority) params.set("public_request_priority", options.publicRequestPriority);
54778
54799
  const query = params.size > 0 ? `?${params.toString()}` : "";
54779
54800
  const url2 = `${getApiUrl()}/trading/execution-metadata/${encodeURIComponent(exchange)}/${encodeURIComponent(symbol2)}${query}`;
@@ -55253,8 +55274,225 @@ var init_hyperliquid_account_mode_contract = __esm({
55253
55274
  }
55254
55275
  });
55255
55276
 
55277
+ // lib/runtime/server-loop-account-value.ts
55278
+ var STABLE_SPOT_SYMBOLS, toNumber, firstTruthy, spotContainers, extractCanonicalSpotMetrics, stableOrPricedValueUsd, sumBalanceValueUsd, sumBalanceHoldUsd, approximatelyEqual, balancesMirrorUnifiedAccountValue, computeEffectiveAccountValue, requireThreshold, serverLoopAccountValue;
55279
+ var init_server_loop_account_value = __esm({
55280
+ "lib/runtime/server-loop-account-value.ts"() {
55281
+ "use strict";
55282
+ init_define_VTX_EXO_POLICY();
55283
+ init_define_VTX_GROK_POLICY();
55284
+ init_define_VTX_PI_MODEL_POLICY();
55285
+ init_hyperliquid_account_mode_contract();
55286
+ STABLE_SPOT_SYMBOLS = /* @__PURE__ */ new Set(["USDC", "USD", "USDT"]);
55287
+ toNumber = (value, fallback = 0) => {
55288
+ const numeric2 = Number(value);
55289
+ return Number.isFinite(numeric2) ? numeric2 : fallback;
55290
+ };
55291
+ firstTruthy = (values, fallback) => {
55292
+ for (const value of values) {
55293
+ if (value) return value;
55294
+ }
55295
+ return fallback;
55296
+ };
55297
+ spotContainers = (spotResponse) => {
55298
+ if (!spotResponse || typeof spotResponse !== "object" || Array.isArray(spotResponse)) return [];
55299
+ const response = spotResponse;
55300
+ const containers = [response];
55301
+ for (const key of ["spotState", "userState", "clearinghouseState", "state", "data"]) {
55302
+ const child = response[key];
55303
+ if (child && typeof child === "object" && !Array.isArray(child)) containers.push(child);
55304
+ }
55305
+ return containers;
55306
+ };
55307
+ extractCanonicalSpotMetrics = (spotResponse) => {
55308
+ const response = spotResponse && typeof spotResponse === "object" && !Array.isArray(spotResponse) ? spotResponse : {};
55309
+ const containers = spotContainers(response);
55310
+ let accountValue = 0;
55311
+ let totalMarginUsed = 0;
55312
+ let withdrawable = 0;
55313
+ for (const container of containers) {
55314
+ const marginSummary = container.marginSummary && typeof container.marginSummary === "object" && !Array.isArray(container.marginSummary) ? container.marginSummary : {};
55315
+ accountValue = Math.max(accountValue, toNumber(marginSummary.accountValue));
55316
+ totalMarginUsed = Math.max(totalMarginUsed, toNumber(marginSummary.totalMarginUsed));
55317
+ withdrawable = Math.max(withdrawable, toNumber(container.withdrawable));
55318
+ }
55319
+ if (accountValue <= 0) {
55320
+ for (const key of ["accountValue", "totalValue", "equity", "totalRawUsd", "usdValue", "usdcValue"]) {
55321
+ accountValue = Math.max(accountValue, toNumber(response[key]));
55322
+ }
55323
+ }
55324
+ const balances = [];
55325
+ const listKeys = ["balances", "tokenBalances", "spotBalances", "assets"];
55326
+ for (const container of containers) {
55327
+ for (const listKey of listKeys) {
55328
+ const bucket = container[listKey];
55329
+ if (!Array.isArray(bucket)) continue;
55330
+ let stableTotal = 0;
55331
+ let anyTotal = 0;
55332
+ for (const rawEntry of bucket) {
55333
+ if (!rawEntry || typeof rawEntry !== "object" || Array.isArray(rawEntry)) continue;
55334
+ const entry = rawEntry;
55335
+ const coin = String(firstTruthy([
55336
+ entry.coin,
55337
+ entry.token,
55338
+ entry.asset,
55339
+ entry.symbol
55340
+ ], "")).trim().toUpperCase();
55341
+ if (!coin) continue;
55342
+ const total = toNumber(firstTruthy([entry.total, entry.balance, entry.amount], "0"));
55343
+ const hold = toNumber(firstTruthy([entry.hold, entry.locked], "0"));
55344
+ const available = Math.max(
55345
+ 0,
55346
+ toNumber(firstTruthy([entry.available, entry.free, total - hold], "0"))
55347
+ );
55348
+ let valueUsd = toNumber(firstTruthy([entry.usdValue, entry.usdcValue], "0"));
55349
+ if (valueUsd <= 0 && STABLE_SPOT_SYMBOLS.has(coin)) {
55350
+ valueUsd = available > 0 ? available : total;
55351
+ }
55352
+ balances.push({ coin, total, hold, available, value_usd: valueUsd });
55353
+ const entryValue = valueUsd > 0 ? valueUsd : total;
55354
+ if (entryValue > 0) {
55355
+ anyTotal += entryValue;
55356
+ if (STABLE_SPOT_SYMBOLS.has(coin)) stableTotal += entryValue;
55357
+ }
55358
+ }
55359
+ if (accountValue <= 0) {
55360
+ if (stableTotal > 0) accountValue = stableTotal;
55361
+ else if (anyTotal > 0) accountValue = anyTotal;
55362
+ }
55363
+ }
55364
+ if (balances.length > 0) break;
55365
+ }
55366
+ return { accountValue, totalMarginUsed, withdrawable, balances };
55367
+ };
55368
+ stableOrPricedValueUsd = (balance) => {
55369
+ const valueUsd = toNumber(balance.value_usd);
55370
+ if (valueUsd <= 0 && STABLE_SPOT_SYMBOLS.has(String(balance.coin || "").trim().toUpperCase())) {
55371
+ return toNumber(balance.total);
55372
+ }
55373
+ return valueUsd;
55374
+ };
55375
+ sumBalanceValueUsd = (balances) => balances.reduce(
55376
+ (total, balance) => total + Math.max(stableOrPricedValueUsd(balance), 0),
55377
+ 0
55378
+ );
55379
+ sumBalanceHoldUsd = (balances) => balances.reduce((total, balance) => {
55380
+ const valueUsd = stableOrPricedValueUsd(balance);
55381
+ const amount = toNumber(balance.total);
55382
+ if (valueUsd <= 0 || amount <= 0) return total;
55383
+ return total + Math.max(0, valueUsd * (toNumber(balance.hold) / amount));
55384
+ }, 0);
55385
+ approximatelyEqual = (left, right, absoluteToleranceUsd, relativeTolerance) => {
55386
+ const reference = Math.max(Math.abs(left), Math.abs(right), 1);
55387
+ return Math.abs(left - right) <= Math.max(absoluteToleranceUsd, reference * relativeTolerance);
55388
+ };
55389
+ balancesMirrorUnifiedAccountValue = (input) => input.perpsEquity > 0 && input.spotEquity > 0 && input.balancesEquity > 0 && approximatelyEqual(
55390
+ input.perpsEquity,
55391
+ input.spotEquity,
55392
+ input.absoluteToleranceUsd,
55393
+ input.relativeTolerance
55394
+ ) && approximatelyEqual(
55395
+ input.spotEquity,
55396
+ input.balancesEquity,
55397
+ input.absoluteToleranceUsd,
55398
+ input.relativeTolerance
55399
+ );
55400
+ computeEffectiveAccountValue = (input) => {
55401
+ if (!input.unifiedLike) return input.perpsEquity;
55402
+ if (input.balancesEquity > 0) {
55403
+ if (input.mirrored) {
55404
+ return Math.max(input.perpsEquity, input.spotEquity, input.balancesEquity);
55405
+ }
55406
+ return Math.max(
55407
+ input.perpsEquity + input.balancesEquity,
55408
+ input.spotEquity,
55409
+ input.balancesEquity
55410
+ );
55411
+ }
55412
+ return Math.max(input.perpsEquity, input.spotEquity);
55413
+ };
55414
+ requireThreshold = (value, key) => {
55415
+ const numeric2 = typeof value === "number" ? value : Number.NaN;
55416
+ if (!Number.isFinite(numeric2) || numeric2 < 0) {
55417
+ throw new Error(`Missing required Hyperliquid account-state configuration: ${key}`);
55418
+ }
55419
+ return numeric2;
55420
+ };
55421
+ serverLoopAccountValue = (input) => {
55422
+ const { classification } = input;
55423
+ const spotDominatesMinTotalUsd = requireThreshold(
55424
+ input.spotDominatesMinTotalUsd,
55425
+ "client_runtime_hyperliquid_account_state.spot_dominates_min_total_usd"
55426
+ );
55427
+ const spotDominatesPerpsMultiplier = requireThreshold(
55428
+ input.spotDominatesPerpsMultiplier,
55429
+ "client_runtime_hyperliquid_account_state.spot_dominates_perps_multiplier"
55430
+ );
55431
+ const spotAvailableToTradeRatioThreshold = requireThreshold(
55432
+ classification.spotAvailableToTradeRatioThreshold,
55433
+ "client_runtime_hyperliquid_account_state.spot_available_to_trade_ratio_threshold"
55434
+ );
55435
+ const spotMeaningfulHoldUsd = requireThreshold(
55436
+ classification.spotMeaningfulHoldUsd,
55437
+ "client_runtime_hyperliquid_account_state.spot_meaningful_hold_usd"
55438
+ );
55439
+ const spotVeryStrongTotalUsd = requireThreshold(
55440
+ classification.spotVeryStrongTotalUsd,
55441
+ "client_runtime_hyperliquid_account_state.spot_very_strong_total_usd"
55442
+ );
55443
+ const spotVeryStrongPerpsEquityThresholdUsd = requireThreshold(
55444
+ classification.spotVeryStrongPerpsEquityThresholdUsd,
55445
+ "client_runtime_hyperliquid_account_state.spot_very_strong_perps_equity_threshold_usd"
55446
+ );
55447
+ const absoluteToleranceUsd = requireThreshold(
55448
+ input.mirroredAccountValueAbsoluteToleranceUsd,
55449
+ "client_runtime_hyperliquid_account_state.mirrored_account_value_absolute_tolerance_usd"
55450
+ );
55451
+ const relativeTolerance = requireThreshold(
55452
+ input.mirroredAccountValueRelativeTolerance,
55453
+ "client_runtime_hyperliquid_account_state.mirrored_account_value_relative_tolerance"
55454
+ );
55455
+ const perps = input.perpsResponse && typeof input.perpsResponse === "object" && !Array.isArray(input.perpsResponse) ? input.perpsResponse : {};
55456
+ const rawPerpsAccountValue = toNumber(perps.marginSummary?.accountValue);
55457
+ const perpsEquity = Math.max(rawPerpsAccountValue, 0);
55458
+ const spot = extractCanonicalSpotMetrics(input.spotResponse);
55459
+ const spotEquity = Math.max(spot.accountValue, 0);
55460
+ const balancesEquity = sumBalanceValueUsd(spot.balances);
55461
+ const accountMode = classification.exactAccountMode ?? input.accountMode;
55462
+ let unifiedLike = isUnifiedAccountMode(accountMode);
55463
+ const defaultMode = String(accountMode ?? "").trim() === "" || normalizeCanonicalHyperliquidAccountMode(accountMode) === "default";
55464
+ if (!unifiedLike && defaultMode) {
55465
+ const [availableBuy, availableSell] = classification.availableToTrade ?? [0, 0];
55466
+ const equityBase = rawPerpsAccountValue > 0 ? rawPerpsAccountValue : spotEquity;
55467
+ const spotRatio = equityBase > 0 ? spot.accountValue / equityBase : 0;
55468
+ const tradableWithSpotCollateral = classification.availableToTrade !== null && balancesEquity >= spotDominatesMinTotalUsd && Math.max(availableBuy, availableSell) > 0 && spotRatio >= spotAvailableToTradeRatioThreshold;
55469
+ const spotDominates = balancesEquity >= spotDominatesMinTotalUsd && (perpsEquity <= 0 || balancesEquity >= perpsEquity * spotDominatesPerpsMultiplier);
55470
+ const meaningfulHold = sumBalanceHoldUsd(spot.balances) >= spotMeaningfulHoldUsd;
55471
+ const veryStrongSpot = balancesEquity >= spotVeryStrongTotalUsd && perpsEquity <= spotVeryStrongPerpsEquityThresholdUsd;
55472
+ unifiedLike = tradableWithSpotCollateral || spot.balances.length > 0 && spotDominates && (meaningfulHold || veryStrongSpot);
55473
+ }
55474
+ return {
55475
+ accountValue: computeEffectiveAccountValue({
55476
+ perpsEquity,
55477
+ spotEquity,
55478
+ balancesEquity,
55479
+ unifiedLike,
55480
+ mirrored: balancesMirrorUnifiedAccountValue({
55481
+ perpsEquity,
55482
+ spotEquity,
55483
+ balancesEquity,
55484
+ absoluteToleranceUsd,
55485
+ relativeTolerance
55486
+ })
55487
+ }),
55488
+ valuedAsUnified: unifiedLike
55489
+ };
55490
+ };
55491
+ }
55492
+ });
55493
+
55256
55494
  // lib/runtime/hyperliquid-account-contract.ts
55257
- var toNumber, firstNumber, roundTo, canonicalAvailableMargin, STABLE_SPOT_SYMBOLS, spotBalanceValueUsd, normalizeSpotBalancesFromInfoResponse, sumBalanceHoldUsd, sumPositionUnrealizedPnl, resolveTotalUnrealizedPnl, approximatelyEqualAccountValues, buildAccountSummaryFromInfoResponses;
55495
+ var toNumber2, firstNumber, roundTo, canonicalAvailableMargin, spotBalanceValueUsd, normalizeSpotBalancesFromInfoResponse, sumBalanceHoldUsd2, sumPositionUnrealizedPnl, resolveTotalUnrealizedPnl, approximatelyEqualAccountValues, accountValueThresholds, serverLoopValuation, serverLoopValuationCountsSpot, buildAccountSummaryFromInfoResponses;
55258
55496
  var init_hyperliquid_account_contract = __esm({
55259
55497
  "lib/runtime/hyperliquid-account-contract.ts"() {
55260
55498
  "use strict";
@@ -55263,7 +55501,8 @@ var init_hyperliquid_account_contract = __esm({
55263
55501
  init_define_VTX_PI_MODEL_POLICY();
55264
55502
  init_hyperliquid_account_mode_contract();
55265
55503
  init_constants();
55266
- toNumber = (value, fallback = 0) => {
55504
+ init_server_loop_account_value();
55505
+ toNumber2 = (value, fallback = 0) => {
55267
55506
  const numeric2 = Number(value);
55268
55507
  return Number.isFinite(numeric2) ? numeric2 : fallback;
55269
55508
  };
@@ -55281,7 +55520,6 @@ var init_hyperliquid_account_contract = __esm({
55281
55520
  };
55282
55521
  roundTo = (value, digits = HYPERLIQUID_ACCOUNT_ROUNDING_DECIMALS) => Number(value.toFixed(digits));
55283
55522
  canonicalAvailableMargin = (accountValue, totalMarginUsed) => Math.max(0, accountValue - totalMarginUsed);
55284
- STABLE_SPOT_SYMBOLS = /* @__PURE__ */ new Set(["USDC", "USD", "USDT"]);
55285
55523
  spotBalanceValueUsd = (balance, coin, total) => {
55286
55524
  const explicit = firstNumber([balance?.value_usd, balance?.usdValue, balance?.usdcValue], Number.NaN);
55287
55525
  if (Number.isFinite(explicit)) {
@@ -55304,8 +55542,8 @@ var init_hyperliquid_account_contract = __esm({
55304
55542
  const balances = Array.isArray(firstWithBalances?.balances) ? firstWithBalances.balances : [];
55305
55543
  return balances.map((balance) => {
55306
55544
  const coin = String(balance?.coin ?? "").toUpperCase();
55307
- const total = toNumber(balance?.total, 0);
55308
- const hold = toNumber(balance?.hold, 0);
55545
+ const total = toNumber2(balance?.total, 0);
55546
+ const hold = toNumber2(balance?.hold, 0);
55309
55547
  const available = roundTo(Math.max(0, total - hold));
55310
55548
  const value_usd = spotBalanceValueUsd(balance, coin, total);
55311
55549
  return {
@@ -55317,10 +55555,10 @@ var init_hyperliquid_account_contract = __esm({
55317
55555
  };
55318
55556
  }).filter((balance) => balance.coin.length > 0);
55319
55557
  };
55320
- sumBalanceHoldUsd = (balances) => balances.reduce((acc, balance) => {
55321
- const hold = toNumber(balance.hold, 0);
55322
- const total = toNumber(balance.total, 0);
55323
- const valueUsd = toNumber(balance.value_usd, 0);
55558
+ sumBalanceHoldUsd2 = (balances) => balances.reduce((acc, balance) => {
55559
+ const hold = toNumber2(balance.hold, 0);
55560
+ const total = toNumber2(balance.total, 0);
55561
+ const valueUsd = toNumber2(balance.value_usd, 0);
55324
55562
  if (hold <= 0 || total <= 0 || valueUsd <= 0) {
55325
55563
  return acc;
55326
55564
  }
@@ -55329,12 +55567,12 @@ var init_hyperliquid_account_contract = __esm({
55329
55567
  sumPositionUnrealizedPnl = (perpsResponse) => {
55330
55568
  const assetPositions = Array.isArray(perpsResponse?.assetPositions) ? perpsResponse.assetPositions : [];
55331
55569
  return assetPositions.reduce((total, entry) => {
55332
- const unrealizedPnl = toNumber(entry?.position?.unrealizedPnl, 0);
55570
+ const unrealizedPnl = toNumber2(entry?.position?.unrealizedPnl, 0);
55333
55571
  return total + unrealizedPnl;
55334
55572
  }, 0);
55335
55573
  };
55336
55574
  resolveTotalUnrealizedPnl = (perpsResponse) => {
55337
- const topLevel = toNumber(perpsResponse?.totalUnrealizedPnl, 0);
55575
+ const topLevel = toNumber2(perpsResponse?.totalUnrealizedPnl, 0);
55338
55576
  const positionTotal = sumPositionUnrealizedPnl(perpsResponse);
55339
55577
  if (Math.abs(topLevel) < HYPERLIQUID_UNREALIZED_PNL_ZERO_TOLERANCE && Math.abs(positionTotal) >= HYPERLIQUID_UNREALIZED_PNL_ZERO_TOLERANCE) {
55340
55578
  return positionTotal;
@@ -55348,33 +55586,49 @@ var init_hyperliquid_account_contract = __esm({
55348
55586
  reference * relativeTolerance
55349
55587
  );
55350
55588
  };
55589
+ accountValueThresholds = (options) => ({
55590
+ spotDominatesMinTotalUsd: Number(options.spotDominatesMinTotalUsd ?? options.spot_dominates_min_total_usd),
55591
+ spotDominatesPerpsMultiplier: Number(options.spotDominatesPerpsMultiplier ?? options.spot_dominates_perps_multiplier),
55592
+ mirroredAccountValueAbsoluteToleranceUsd: Number(
55593
+ options.mirroredAccountValueAbsoluteToleranceUsd ?? options.mirrored_account_value_absolute_tolerance_usd
55594
+ ),
55595
+ mirroredAccountValueRelativeTolerance: Number(
55596
+ options.mirroredAccountValueRelativeTolerance ?? options.mirrored_account_value_relative_tolerance
55597
+ )
55598
+ });
55599
+ serverLoopValuation = (perpsResponse, spotResponse, options) => options.serverLoopClassification ? serverLoopAccountValue({
55600
+ perpsResponse,
55601
+ spotResponse,
55602
+ accountMode: extractAccountModeFromPayload(perpsResponse),
55603
+ classification: options.serverLoopClassification,
55604
+ ...accountValueThresholds(options)
55605
+ }) : null;
55606
+ serverLoopValuationCountsSpot = (perpsResponse, spotResponse, options) => serverLoopValuation(perpsResponse, spotResponse, options)?.valuedAsUnified === true;
55351
55607
  buildAccountSummaryFromInfoResponses = (perpsResponse, spotResponse, options = {}) => {
55352
55608
  const marginSummary = perpsResponse?.marginSummary ?? {};
55353
- const perpsAccountValue = toNumber(marginSummary?.accountValue, 0);
55354
- const total_margin_used = toNumber(marginSummary?.totalMarginUsed, 0);
55355
- const totalNtlPos = toNumber(marginSummary?.totalNtlPos, 0);
55356
- const withdrawable = toNumber(perpsResponse?.withdrawable, 0);
55609
+ const perpsAccountValue = toNumber2(marginSummary?.accountValue, 0);
55610
+ const total_margin_used = toNumber2(marginSummary?.totalMarginUsed, 0);
55611
+ const totalNtlPos = toNumber2(marginSummary?.totalNtlPos, 0);
55612
+ const withdrawable = toNumber2(perpsResponse?.withdrawable, 0);
55357
55613
  const maintenance_margin = firstNumber([
55358
55614
  perpsResponse?.crossMaintenanceMarginUsed,
55359
55615
  marginSummary?.crossMaintenanceMarginUsed,
55360
55616
  marginSummary?.totalMaintenanceMargin
55361
55617
  ], 0);
55362
55618
  const balances = normalizeSpotBalancesFromInfoResponse(spotResponse);
55363
- const spotPortfolioValue = balances.reduce((acc, balance) => acc + toNumber(balance.value_usd, 0), 0);
55364
- const balancesHoldUsd = sumBalanceHoldUsd(balances);
55619
+ const spotPortfolioValue = balances.reduce((acc, balance) => acc + toNumber2(balance.value_usd, 0), 0);
55620
+ const balancesHoldUsd = sumBalanceHoldUsd2(balances);
55365
55621
  const account_mode = extractAccountModeFromPayload(perpsResponse);
55366
55622
  const crossMarginSummary = perpsResponse?.crossMarginSummary && typeof perpsResponse.crossMarginSummary === "object" ? perpsResponse.crossMarginSummary : null;
55367
- const crossMarginAccountValue = crossMarginSummary ? toNumber(crossMarginSummary.accountValue, 0) : 0;
55623
+ const crossMarginAccountValue = crossMarginSummary ? toNumber2(crossMarginSummary.accountValue, 0) : 0;
55368
55624
  const normalizedMode = String(account_mode || "").trim().toLowerCase().replace(/[_\s-]/g, "");
55369
55625
  const isAmbiguousDefaultMode = normalizedMode.length === 0 || normalizedMode === "default";
55370
- const spotDominatesMinTotalUsd = Number(options.spotDominatesMinTotalUsd ?? options.spot_dominates_min_total_usd);
55371
- const spotDominatesPerpsMultiplier = Number(options.spotDominatesPerpsMultiplier ?? options.spot_dominates_perps_multiplier);
55372
- const mirroredAccountValueAbsoluteToleranceUsd = Number(
55373
- options.mirroredAccountValueAbsoluteToleranceUsd ?? options.mirrored_account_value_absolute_tolerance_usd
55374
- );
55375
- const mirroredAccountValueRelativeTolerance = Number(
55376
- options.mirroredAccountValueRelativeTolerance ?? options.mirrored_account_value_relative_tolerance
55377
- );
55626
+ const {
55627
+ spotDominatesMinTotalUsd,
55628
+ spotDominatesPerpsMultiplier,
55629
+ mirroredAccountValueAbsoluteToleranceUsd,
55630
+ mirroredAccountValueRelativeTolerance
55631
+ } = accountValueThresholds(options);
55378
55632
  const hasSpotDominanceThresholds = Number.isFinite(spotDominatesMinTotalUsd) && spotDominatesMinTotalUsd >= 0 && Number.isFinite(spotDominatesPerpsMultiplier) && spotDominatesPerpsMultiplier >= 0;
55379
55633
  const hasMirroredAccountValueTolerances = Number.isFinite(mirroredAccountValueAbsoluteToleranceUsd) && mirroredAccountValueAbsoluteToleranceUsd >= 0 && Number.isFinite(mirroredAccountValueRelativeTolerance) && mirroredAccountValueRelativeTolerance >= 0;
55380
55634
  const spotDominatesPerps = hasSpotDominanceThresholds && spotPortfolioValue >= spotDominatesMinTotalUsd && (perpsAccountValue <= 0 || spotPortfolioValue >= perpsAccountValue * spotDominatesPerpsMultiplier);
@@ -55385,7 +55639,8 @@ var init_hyperliquid_account_contract = __esm({
55385
55639
  mirroredAccountValueAbsoluteToleranceUsd,
55386
55640
  mirroredAccountValueRelativeTolerance
55387
55641
  );
55388
- const account_value = isUnifiedAccountMode(account_mode) && crossMarginSummary !== null && crossMarginAccountValue > 0 ? crossMarginAccountValue + spotPortfolioValue : ambiguousDefaultLooksUnified && !ambiguousDefaultSpotAlreadyIncludesPerps ? perpsAccountValue + spotPortfolioValue : Math.max(perpsAccountValue, spotPortfolioValue);
55642
+ const deviceAccountValue = isUnifiedAccountMode(account_mode) && crossMarginSummary !== null && crossMarginAccountValue > 0 ? crossMarginAccountValue + spotPortfolioValue : ambiguousDefaultLooksUnified && !ambiguousDefaultSpotAlreadyIncludesPerps ? perpsAccountValue + spotPortfolioValue : Math.max(perpsAccountValue, spotPortfolioValue);
55643
+ const account_value = serverLoopValuation(perpsResponse, spotResponse, options)?.accountValue ?? deviceAccountValue;
55389
55644
  return {
55390
55645
  account_value,
55391
55646
  total_margin_used,
@@ -55403,7 +55658,7 @@ var init_hyperliquid_account_contract = __esm({
55403
55658
  });
55404
55659
 
55405
55660
  // lib/runtime/order-identity.ts
55406
- var clientOrderIdForMutation, clientDecisionMutationId;
55661
+ var clientOrderIdForMutation, mutationIdForClientOrderId, clientDecisionMutationId;
55407
55662
  var init_order_identity = __esm({
55408
55663
  "lib/runtime/order-identity.ts"() {
55409
55664
  "use strict";
@@ -55412,6 +55667,12 @@ var init_order_identity = __esm({
55412
55667
  init_define_VTX_PI_MODEL_POLICY();
55413
55668
  init_constants();
55414
55669
  clientOrderIdForMutation = (mutationId) => `0x${String(mutationId).trim().toLowerCase().replaceAll("-", "")}`;
55670
+ mutationIdForClientOrderId = (clientOrderId) => {
55671
+ const cloid = String(clientOrderId).trim().toLowerCase();
55672
+ if (!/^0x[0-9a-f]{32}$/.test(cloid)) return null;
55673
+ const hex4 = cloid.slice("0x".length);
55674
+ return UUID_HEX_GROUP_ENDS.map((end, index) => hex4.slice(index === 0 ? 0 : UUID_HEX_GROUP_ENDS[index - 1], end)).join("-");
55675
+ };
55415
55676
  clientDecisionMutationId = async (input) => {
55416
55677
  const key = [
55417
55678
  "client-decision:v1",
@@ -55642,7 +55903,14 @@ var init_hyperliquid_public_read = __esm({
55642
55903
  const ticket = crypto.randomUUID();
55643
55904
  const deadline = Math.min(deadlineMs ?? Infinity, Date.now() + recoveryPolicy.recovery_queue_wait_seconds * MS_PER_SECOND);
55644
55905
  if (hostTransport) {
55645
- const permit = await hostTransport.admission.acquire({ requestType, weight, priority: priority.value, deadlineMs: deadline, signal });
55906
+ const permit = await hostTransport.admission.acquire({
55907
+ requestType,
55908
+ weight,
55909
+ priority: priority.value,
55910
+ currentPriority: () => priority.value,
55911
+ deadlineMs: deadline,
55912
+ signal
55913
+ });
55646
55914
  return { ...permit, endpoint: apiUrl, fleet: true };
55647
55915
  }
55648
55916
  let admitted = false;
@@ -55808,7 +56076,7 @@ var init_hyperliquid_public_read = __esm({
55808
56076
  };
55809
56077
  cacheTtlMs = (body, options) => {
55810
56078
  const requestType = String(body.type);
55811
- return (["meta", "spotMeta", "perpDexs"].includes(requestType) ? policy.metadata_ttl_seconds : requestType === "userFees" ? policy.user_fees_ttl_seconds : options.cacheAccountMode && ["userAbstraction", "userDexAbstraction"].includes(requestType) ? policy.account_mode_ttl_seconds : 0) * MS_PER_SECOND;
56079
+ return (["meta", "spotMeta", "perpDexs"].includes(requestType) ? policy.metadata_ttl_seconds : requestType === "userFees" ? policy.user_fees_ttl_seconds : options.cacheAccountMode && ["userAbstraction", "userDexAbstraction"].includes(requestType) ? options.cacheAccountMode === "display" ? policy.ui_account_mode_ttl_seconds : policy.account_mode_ttl_seconds : 0) * MS_PER_SECOND;
55812
56080
  };
55813
56081
  eligibleCache = (apiUrl, body, options) => {
55814
56082
  const ttl = cacheTtlMs(body, options);
@@ -57453,7 +57721,7 @@ function getNumber(value, name) {
57453
57721
  }
57454
57722
  assertArgument(false, "invalid numeric value", name || "value", value);
57455
57723
  }
57456
- function toNumber2(value) {
57724
+ function toNumber3(value) {
57457
57725
  return getNumber(toBigInt(value));
57458
57726
  }
57459
57727
  function toBeHex(_value, _width) {
@@ -59875,7 +60143,7 @@ var init_abstract_coder = __esm({
59875
60143
  return toBigInt(this.readBytes(WordSize));
59876
60144
  }
59877
60145
  readIndex() {
59878
- return toNumber2(this.readBytes(WordSize));
60146
+ return toNumber3(this.readBytes(WordSize));
59879
60147
  }
59880
60148
  };
59881
60149
  }
@@ -86312,7 +86580,7 @@ __export(ethers_exports, {
86312
86580
  toBeArray: () => toBeArray,
86313
86581
  toBeHex: () => toBeHex,
86314
86582
  toBigInt: () => toBigInt,
86315
- toNumber: () => toNumber2,
86583
+ toNumber: () => toNumber3,
86316
86584
  toQuantity: () => toQuantity,
86317
86585
  toTwos: () => toTwos,
86318
86586
  toUtf8Bytes: () => toUtf8Bytes,
@@ -86530,7 +86798,7 @@ __export(lib_exports, {
86530
86798
  toBeArray: () => toBeArray,
86531
86799
  toBeHex: () => toBeHex,
86532
86800
  toBigInt: () => toBigInt,
86533
- toNumber: () => toNumber2,
86801
+ toNumber: () => toNumber3,
86534
86802
  toQuantity: () => toQuantity,
86535
86803
  toTwos: () => toTwos,
86536
86804
  toUtf8Bytes: () => toUtf8Bytes,
@@ -87442,7 +87710,7 @@ var init_hyperliquid_signer = __esm({
87442
87710
  });
87443
87711
 
87444
87712
  // lib/runtime/hyperliquid-client.ts
87445
- var HyperliquidExchangeRejectionError, durableMutationAuthorityArgs, assertFreshPreparedExecutionContext, normalizeSymbol, HYPERLIQUID_NONCE_STORAGE_KEY, HYPERLIQUID_NONCE_LOCK_NAME, lastGeneratedNonce, readBrowserStoredHyperliquidNonce, writeBrowserStoredHyperliquidNonce, browserNonceCoordinator, allocateHyperliquidNonce, hostNonceAllocator, allocateActionNonce, generateHyperliquidNonce, normalizeDecimalString, HYPERLIQUID_PRICE_SIGNIFICANT_FIGURES, HYPERLIQUID_INTEGER_PRICE_MINIMUM, shortestDecimalParts, formatHyperliquidPerpPriceGrid, formatHyperliquidTriggerPriceWire, hyperliquidOrderPriceRounding, formatHyperliquidOrderPriceWire, countSignificantDigits, countDecimalPlaces, validateHyperliquidPerpPriceWire, validateHyperliquidSizeWire, formatSizeWire, inferApiUrl, inferIsTestnet, postHyperliquidInfoRead, postHyperliquidInfo, fetchBrowserHyperliquidInfoPayload, fetchBrowserHyperliquidInfoRead, fetchBrowserHyperliquidInfoText, coerceMarketMaxLeverage, toFiniteNumber, OPEN_ORDER_NUMERIC_STRING, OPEN_ORDER_ID_STRING, parseCanonicalOpenOrderId, parseOpenOrderFiniteNumber, parseOpenOrderPositiveNumber, parseOpenOrderPresentationNumber, readOpenOrderField, firstFiniteNumber, parseFundingUsdcFromInfoPosition, isExchangeIsolatedOnly, computeHip3AssetId, getPerpDexIndexMap, buildAssetInfosFromMetaResponse, requireWalletAddress, assertPositiveInteger, assertPositiveNumber, normalizeOrderSide, normalizeHyperliquidClientOrderId, resolveAssets, findResolvedAsset, normalizeExecutionAssetMetadata, resolveHyperliquidAsset, resolveHyperliquidAssetIndex, decimalUnits, quantizeHyperliquidOrderSizeValue, hyperliquidSignedSizeMatchesRequestedSize, finitePositive, readDevicePrivateExecutionContext, quantizeHyperliquidOrderSize, fetchBrowserAvailableAssets, fetchBrowserAllMids, fetchBrowserSymbolMidPrice, fetchBrowserOpenOrders, parseCanonicalHyperliquidOrderStatusEvidence, fetchBrowserOrderStatusEvidence, fetchBrowserUserRole, fetchBrowserAccountState, fetchBrowserPosition, buildHyperliquidOrderWire, buildHyperliquidTriggerOrderWire, signHyperliquidPayload, signHyperliquidPreparedAction, buildHyperliquidCancelPayload, buildHyperliquidUpdateLeveragePayload, buildHyperliquidMarketOrderPayload, buildHyperliquidLimitOrderPayload, buildHyperliquidTriggerOrderPayload, buildHyperliquidOrderBatchPayload, buildHyperliquidModifyOrderPayload, extractHyperliquidExchangeError, resolveHyperliquidTriggerAcknowledgements, isDefinitiveHyperliquidExchangeResponse, extractDefinitiveHyperliquidOrderId, CANONICAL_POSITIVE_DECIMAL_PATTERN, extractCanonicalHyperliquidOrderStateAcknowledgement, extractCanonicalHyperliquidOrderStateAcknowledgements, extractCanonicalHyperliquidFilledOrderAcknowledgement, extractDefinitiveHyperliquidOrderMemberResults, buildHyperliquidOrderDiagnostics, loadClientExecutionReferenceEvidence, sha256Hex, extractSignedPayloadClientOrderId, extractSignedPayloadMutationCorrelation, assertDurableMutationMatchesSignedAction, exchangeRejectionReason, exchangeActionPriority, submitHyperliquidExchangePayload;
87713
+ var HyperliquidExchangeRejectionError, durableMutationAuthorityArgs, assertFreshPreparedExecutionContext, normalizeSymbol, HYPERLIQUID_NONCE_STORAGE_KEY, HYPERLIQUID_NONCE_LOCK_NAME, lastGeneratedNonce, readBrowserStoredHyperliquidNonce, writeBrowserStoredHyperliquidNonce, browserNonceCoordinator, allocateHyperliquidNonce, hostNonceAllocator, allocateActionNonce, generateHyperliquidNonce, normalizeDecimalString, HYPERLIQUID_PRICE_SIGNIFICANT_FIGURES, HYPERLIQUID_INTEGER_PRICE_MINIMUM, shortestDecimalParts, formatHyperliquidPerpPriceGrid, formatHyperliquidTriggerPriceWire, hyperliquidOrderPriceRounding, formatHyperliquidOrderPriceWire, countSignificantDigits, countDecimalPlaces, validateHyperliquidPerpPriceWire, validateHyperliquidSizeWire, formatSizeWire, inferApiUrl, inferIsTestnet, postHyperliquidInfoRead, postHyperliquidInfo, fetchBrowserHyperliquidInfoPayload, fetchBrowserHyperliquidInfoRead, fetchBrowserHyperliquidInfoText, coerceMarketMaxLeverage, toFiniteNumber, OPEN_ORDER_NUMERIC_STRING, OPEN_ORDER_ID_STRING, parseCanonicalOpenOrderId, parseOpenOrderFiniteNumber, parseOpenOrderPositiveNumber, parseOpenOrderPresentationNumber, readOpenOrderField, firstFiniteNumber, parseFundingUsdcFromInfoPosition, isExchangeIsolatedOnly, resolveLeverageTarget, computeHip3AssetId, getPerpDexIndexMap, buildAssetInfosFromMetaResponse, requireWalletAddress, assertPositiveInteger, assertPositiveNumber, normalizeOrderSide, normalizeHyperliquidClientOrderId, resolveAssets, findResolvedAsset, normalizeExecutionAssetMetadata, resolveHyperliquidAsset, resolveHyperliquidAssetIndex, decimalUnits, quantizeHyperliquidOrderSizeValue, hyperliquidSignedSizeMatchesRequestedSize, finitePositive, readDevicePrivateExecutionContext, quantizeHyperliquidOrderSize, fetchBrowserAvailableAssets, fetchBrowserAllMids, fetchBrowserSymbolMidPrice, fetchBrowserOpenOrders, parseCanonicalHyperliquidOrderStatusEvidence, fetchBrowserOrderStatusEvidence, fetchBrowserUserRole, fetchBrowserAccountState, fetchBrowserPosition, buildHyperliquidOrderWire, buildHyperliquidTriggerOrderWire, signHyperliquidPayload, signHyperliquidPreparedAction, buildHyperliquidCancelPayload, buildHyperliquidUpdateLeveragePayload, buildHyperliquidMarketOrderPayload, buildHyperliquidLimitOrderPayload, buildHyperliquidTriggerOrderPayload, buildHyperliquidOrderBatchPayload, buildHyperliquidModifyOrderPayload, extractHyperliquidExchangeError, resolveHyperliquidTriggerAcknowledgements, isDefinitiveHyperliquidExchangeResponse, extractDefinitiveHyperliquidOrderId, CANONICAL_POSITIVE_DECIMAL_PATTERN, extractCanonicalHyperliquidOrderStateAcknowledgement, extractCanonicalHyperliquidOrderStateAcknowledgements, extractCanonicalHyperliquidFilledOrderAcknowledgement, extractDefinitiveHyperliquidOrderMemberResults, buildHyperliquidOrderDiagnostics, loadClientExecutionReferenceEvidence, sha256Hex, extractSignedPayloadClientOrderId, extractSignedPayloadMutationCorrelation, assertDurableMutationMatchesSignedAction, exchangeRejectionReason, exchangeActionPriority, submitHyperliquidExchangePayload;
87446
87714
  var init_hyperliquid_client = __esm({
87447
87715
  "lib/runtime/hyperliquid-client.ts"() {
87448
87716
  "use strict";
@@ -87819,6 +88087,10 @@ var init_hyperliquid_client = __esm({
87819
88087
  return null;
87820
88088
  };
87821
88089
  isExchangeIsolatedOnly = (asset) => asset.only_isolated === true || ["nocross", "strictisolated"].includes(String(asset.margin_mode || "").trim().toLowerCase());
88090
+ resolveLeverageTarget = (asset, leverage, isCross) => ({
88091
+ leverage: Math.max(1, Math.min(asset.max_leverage, Math.trunc(leverage))),
88092
+ isCross: isExchangeIsolatedOnly(asset) ? false : isCross !== false
88093
+ });
87822
88094
  computeHip3AssetId = (perpDexIndex, indexInMeta) => HYPERLIQUID_EXCHANGE_SPECIFICATION.hip3_asset_id_base + Math.trunc(perpDexIndex) * HYPERLIQUID_EXCHANGE_SPECIFICATION.hip3_asset_id_dex_stride + Math.trunc(indexInMeta);
87823
88095
  getPerpDexIndexMap = (payload) => {
87824
88096
  if (!Array.isArray(payload)) {
@@ -87972,6 +88244,12 @@ var init_hyperliquid_client = __esm({
87972
88244
  if (!symbol2) {
87973
88245
  throw new Error("Missing Hyperliquid symbol.");
87974
88246
  }
88247
+ if (input.refreshCatalog) {
88248
+ return normalizeExecutionAssetMetadata(symbol2, await getExecutionAssetMetadata("hyperliquid", symbol2, {
88249
+ forceCatalogRefresh: true,
88250
+ ...input.publicRequestPriority === "trading_reduce" ? { publicRequestPriority: "trading_reduce" } : {}
88251
+ }));
88252
+ }
87975
88253
  if (Array.isArray(input.assets) && input.assets.length > 0) {
87976
88254
  const explicitAsset = findResolvedAsset(symbol2, input.assets);
87977
88255
  if (explicitAsset) {
@@ -88731,8 +89009,7 @@ var init_hyperliquid_client = __esm({
88731
89009
  const { signHyperliquidAction: signHyperliquidAction2 } = await Promise.resolve().then(() => (init_hyperliquid_signer(), hyperliquid_signer_exports));
88732
89010
  const nonce = input.nonce ?? await allocateActionNonce(input, apiUrl);
88733
89011
  const expiresAfter = input.expiresAfterSeconds == null ? null : nonce + input.expiresAfterSeconds * MS_PER_SECOND;
88734
- const leverage = Math.max(1, Math.min(asset.max_leverage, Math.trunc(input.leverage)));
88735
- const isCross = isExchangeIsolatedOnly(asset) ? false : input.isCross !== false;
89012
+ const { leverage, isCross } = resolveLeverageTarget(asset, input.leverage, input.isCross);
88736
89013
  const action = {
88737
89014
  type: "updateLeverage",
88738
89015
  asset: asset.asset_index,
@@ -90000,9 +90277,6 @@ async function pollCopyTradingRuntimeSource(profileId, options) {
90000
90277
  ...schedulerInstanceId ? { "x-client-runtime-instance": schedulerInstanceId } : {}
90001
90278
  }, profileId),
90002
90279
  body: JSON.stringify({
90003
- dry_run: Boolean(options?.dryRun),
90004
- force_refresh: Boolean(options?.forceRefresh),
90005
- ...options?.maxEvents ? { max_events: options.maxEvents } : {},
90006
90280
  ...options?.accountEvidence ? { account_evidence: options.accountEvidence } : {}
90007
90281
  }),
90008
90282
  credentials: "include",
@@ -93617,6 +93891,7 @@ var init_browser_trading = __esm({
93617
93891
  estimatedPrice: input.estimatedPrice,
93618
93892
  slippage: input.slippage,
93619
93893
  reduceOnly: true,
93894
+ assets: input.assets,
93620
93895
  onExchangeOrderDispatched: input.onExchangeOrderDispatched
93621
93896
  });
93622
93897
  };
@@ -93651,15 +93926,15 @@ var init_hyperliquid_active_asset_contract = __esm({
93651
93926
  };
93652
93927
  normalizePair = (raw) => {
93653
93928
  if (Array.isArray(raw) && raw.length >= HYPERLIQUID_SIDE_PAIR_LENGTH) {
93654
- return [toNumber(raw[0], 0), toNumber(raw[1], 0)];
93929
+ return [toNumber2(raw[0], 0), toNumber2(raw[1], 0)];
93655
93930
  }
93656
93931
  if (raw && typeof raw === "object") {
93657
- const buy = toNumber(raw.buy ?? raw.long ?? raw.b, 0);
93658
- const sell = toNumber(raw.sell ?? raw.short ?? raw.s, 0);
93932
+ const buy = toNumber2(raw.buy ?? raw.long ?? raw.b, 0);
93933
+ const sell = toNumber2(raw.sell ?? raw.short ?? raw.s, 0);
93659
93934
  return [buy, sell];
93660
93935
  }
93661
93936
  if (typeof raw === "string" || typeof raw === "number") {
93662
- const value = toNumber(raw, 0);
93937
+ const value = toNumber2(raw, 0);
93663
93938
  return [value, value];
93664
93939
  }
93665
93940
  return [0, 0];
@@ -93670,28 +93945,28 @@ var init_hyperliquid_active_asset_contract = __esm({
93670
93945
  const directSell = source.available_to_trade_sell;
93671
93946
  const hasDirectAvailable = directBuy !== void 0 || directSell !== void 0;
93672
93947
  const [pairBuy, pairSell] = normalizePair(source.availableToTrade);
93673
- const available_to_trade_buy = hasDirectAvailable ? toNumber(directBuy, pairBuy) : pairBuy;
93674
- const available_to_trade_sell = hasDirectAvailable ? toNumber(directSell, pairSell) : pairSell;
93948
+ const available_to_trade_buy = hasDirectAvailable ? toNumber2(directBuy, pairBuy) : pairBuy;
93949
+ const available_to_trade_sell = hasDirectAvailable ? toNumber2(directSell, pairSell) : pairSell;
93675
93950
  const directMaxBuy = source.max_trade_size_buy;
93676
93951
  const directMaxSell = source.max_trade_size_sell;
93677
93952
  const hasDirectMax = directMaxBuy !== void 0 || directMaxSell !== void 0;
93678
93953
  const [pairMaxBuy, pairMaxSell] = normalizePair(source.maxTradeSzs);
93679
- const max_trade_size_buy = hasDirectMax ? toNumber(directMaxBuy, pairMaxBuy) : pairMaxBuy;
93680
- const max_trade_size_sell = hasDirectMax ? toNumber(directMaxSell, pairMaxSell) : pairMaxSell;
93954
+ const max_trade_size_buy = hasDirectMax ? toNumber2(directMaxBuy, pairMaxBuy) : pairMaxBuy;
93955
+ const max_trade_size_sell = hasDirectMax ? toNumber2(directMaxSell, pairMaxSell) : pairMaxSell;
93681
93956
  return {
93682
93957
  symbol: String(source.coin || symbol2),
93683
93958
  available_to_trade_buy,
93684
93959
  available_to_trade_sell,
93685
93960
  max_trade_size_buy,
93686
93961
  max_trade_size_sell,
93687
- mark_price: toNumber(source.markPx ?? source.mark_price, 0)
93962
+ mark_price: toNumber2(source.markPx ?? source.mark_price, 0)
93688
93963
  };
93689
93964
  };
93690
93965
  }
93691
93966
  });
93692
93967
 
93693
93968
  // lib/runtime/server-prompt-rescue-account-contract.ts
93694
- var toNumber3, firstNumber2, firstTruthy, spotContainers, extractCanonicalSpotMetrics, sumBalanceValueUsd, approximatelyEqual, balancesMirrorUnifiedAccountValue, computeEffectiveAccountValue, equityFormula, buildServerPromptRescueAccountSummary;
93969
+ var firstNumber2, equityFormula, buildServerPromptRescueAccountSummary;
93695
93970
  var init_server_prompt_rescue_account_contract = __esm({
93696
93971
  "lib/runtime/server-prompt-rescue-account-contract.ts"() {
93697
93972
  "use strict";
@@ -93700,10 +93975,7 @@ var init_server_prompt_rescue_account_contract = __esm({
93700
93975
  init_define_VTX_PI_MODEL_POLICY();
93701
93976
  init_hyperliquid_account_mode_contract();
93702
93977
  init_hyperliquid_account_contract();
93703
- toNumber3 = (value, fallback = 0) => {
93704
- const numeric2 = Number(value);
93705
- return Number.isFinite(numeric2) ? numeric2 : fallback;
93706
- };
93978
+ init_server_loop_account_value();
93707
93979
  firstNumber2 = (values, fallback = 0) => {
93708
93980
  for (const value of values) {
93709
93981
  if (value == null || value === "") continue;
@@ -93712,119 +93984,6 @@ var init_server_prompt_rescue_account_contract = __esm({
93712
93984
  }
93713
93985
  return fallback;
93714
93986
  };
93715
- firstTruthy = (values, fallback) => {
93716
- for (const value of values) {
93717
- if (value) return value;
93718
- }
93719
- return fallback;
93720
- };
93721
- spotContainers = (spotResponse) => {
93722
- if (!spotResponse || typeof spotResponse !== "object" || Array.isArray(spotResponse)) return [];
93723
- const response = spotResponse;
93724
- const containers = [response];
93725
- for (const key of ["spotState", "userState", "clearinghouseState", "state", "data"]) {
93726
- const child = response[key];
93727
- if (child && typeof child === "object" && !Array.isArray(child)) containers.push(child);
93728
- }
93729
- return containers;
93730
- };
93731
- extractCanonicalSpotMetrics = (spotResponse) => {
93732
- const response = spotResponse && typeof spotResponse === "object" && !Array.isArray(spotResponse) ? spotResponse : {};
93733
- const containers = spotContainers(response);
93734
- let accountValue = 0;
93735
- let totalMarginUsed = 0;
93736
- let withdrawable = 0;
93737
- for (const container of containers) {
93738
- const marginSummary = container.marginSummary && typeof container.marginSummary === "object" && !Array.isArray(container.marginSummary) ? container.marginSummary : {};
93739
- accountValue = Math.max(accountValue, toNumber3(marginSummary.accountValue));
93740
- totalMarginUsed = Math.max(totalMarginUsed, toNumber3(marginSummary.totalMarginUsed));
93741
- withdrawable = Math.max(withdrawable, toNumber3(container.withdrawable));
93742
- }
93743
- if (accountValue <= 0) {
93744
- for (const key of ["accountValue", "totalValue", "equity", "totalRawUsd", "usdValue", "usdcValue"]) {
93745
- accountValue = Math.max(accountValue, toNumber3(response[key]));
93746
- }
93747
- }
93748
- const balances = [];
93749
- const listKeys = ["balances", "tokenBalances", "spotBalances", "assets"];
93750
- for (const container of containers) {
93751
- for (const listKey of listKeys) {
93752
- const bucket = container[listKey];
93753
- if (!Array.isArray(bucket)) continue;
93754
- let stableTotal = 0;
93755
- let anyTotal = 0;
93756
- for (const rawEntry of bucket) {
93757
- if (!rawEntry || typeof rawEntry !== "object" || Array.isArray(rawEntry)) continue;
93758
- const entry = rawEntry;
93759
- const coin = String(firstTruthy([
93760
- entry.coin,
93761
- entry.token,
93762
- entry.asset,
93763
- entry.symbol
93764
- ], "")).trim().toUpperCase();
93765
- if (!coin) continue;
93766
- const total = toNumber3(firstTruthy([entry.total, entry.balance, entry.amount], "0"));
93767
- const hold = toNumber3(firstTruthy([entry.hold, entry.locked], "0"));
93768
- const available = Math.max(
93769
- 0,
93770
- toNumber3(firstTruthy([entry.available, entry.free, total - hold], "0"))
93771
- );
93772
- let valueUsd = toNumber3(firstTruthy([entry.usdValue, entry.usdcValue], "0"));
93773
- if (valueUsd <= 0 && STABLE_SPOT_SYMBOLS.has(coin)) {
93774
- valueUsd = available > 0 ? available : total;
93775
- }
93776
- balances.push({ coin, total, hold, available, value_usd: valueUsd });
93777
- const entryValue = valueUsd > 0 ? valueUsd : total;
93778
- if (entryValue > 0) {
93779
- anyTotal += entryValue;
93780
- if (STABLE_SPOT_SYMBOLS.has(coin)) stableTotal += entryValue;
93781
- }
93782
- }
93783
- if (accountValue <= 0) {
93784
- if (stableTotal > 0) accountValue = stableTotal;
93785
- else if (anyTotal > 0) accountValue = anyTotal;
93786
- }
93787
- }
93788
- if (balances.length > 0) break;
93789
- }
93790
- return { accountValue, totalMarginUsed, withdrawable, balances };
93791
- };
93792
- sumBalanceValueUsd = (balances) => balances.reduce((total, balance) => {
93793
- let valueUsd = toNumber3(balance.value_usd);
93794
- if (valueUsd <= 0 && STABLE_SPOT_SYMBOLS.has(String(balance.coin || "").trim().toUpperCase())) {
93795
- valueUsd = toNumber3(balance.total);
93796
- }
93797
- return total + Math.max(valueUsd, 0);
93798
- }, 0);
93799
- approximatelyEqual = (left, right, absoluteToleranceUsd, relativeTolerance) => {
93800
- const reference = Math.max(Math.abs(left), Math.abs(right), 1);
93801
- return Math.abs(left - right) <= Math.max(absoluteToleranceUsd, reference * relativeTolerance);
93802
- };
93803
- balancesMirrorUnifiedAccountValue = (input) => input.perpsEquity > 0 && input.spotEquity > 0 && input.balancesEquity > 0 && approximatelyEqual(
93804
- input.perpsEquity,
93805
- input.spotEquity,
93806
- input.absoluteToleranceUsd,
93807
- input.relativeTolerance
93808
- ) && approximatelyEqual(
93809
- input.spotEquity,
93810
- input.balancesEquity,
93811
- input.absoluteToleranceUsd,
93812
- input.relativeTolerance
93813
- );
93814
- computeEffectiveAccountValue = (input) => {
93815
- if (!input.unifiedLike) return input.perpsEquity;
93816
- if (input.balancesEquity > 0) {
93817
- if (input.mirrored) {
93818
- return Math.max(input.perpsEquity, input.spotEquity, input.balancesEquity);
93819
- }
93820
- return Math.max(
93821
- input.perpsEquity + input.balancesEquity,
93822
- input.spotEquity,
93823
- input.balancesEquity
93824
- );
93825
- }
93826
- return Math.max(input.perpsEquity, input.spotEquity);
93827
- };
93828
93987
  equityFormula = (input) => {
93829
93988
  if (!input.unifiedLike) return "perps_account_value";
93830
93989
  if (input.balancesEquity > 0) {
@@ -93839,11 +93998,11 @@ var init_server_prompt_rescue_account_contract = __esm({
93839
93998
  const perps = perpsResponse && typeof perpsResponse === "object" && !Array.isArray(perpsResponse) ? perpsResponse : {};
93840
93999
  const marginSummary = perps.marginSummary && typeof perps.marginSummary === "object" && !Array.isArray(perps.marginSummary) ? perps.marginSummary : {};
93841
94000
  const crossMarginSummary = perps.crossMarginSummary && typeof perps.crossMarginSummary === "object" && !Array.isArray(perps.crossMarginSummary) ? perps.crossMarginSummary : {};
93842
- const rawPerpsAccountValue = toNumber3(marginSummary.accountValue);
94001
+ const rawPerpsAccountValue = toNumber(marginSummary.accountValue);
93843
94002
  const perpsAccountValue = Math.max(0, rawPerpsAccountValue);
93844
- const crossMarginAccountValue = toNumber3(crossMarginSummary.accountValue);
93845
- let totalMarginUsed = toNumber3(marginSummary.totalMarginUsed);
93846
- let withdrawable = toNumber3(perps.withdrawable);
94003
+ const crossMarginAccountValue = toNumber(crossMarginSummary.accountValue);
94004
+ let totalMarginUsed = toNumber(marginSummary.totalMarginUsed);
94005
+ let withdrawable = toNumber(perps.withdrawable);
93847
94006
  const spot = accountMode === "disabled" ? { accountValue: 0, totalMarginUsed: 0, withdrawable: 0, balances: [] } : extractCanonicalSpotMetrics(spotResponse);
93848
94007
  const balances = spot.balances;
93849
94008
  const balancesEquity = sumBalanceValueUsd(balances);
@@ -93875,7 +94034,7 @@ var init_server_prompt_rescue_account_contract = __esm({
93875
94034
  mirrored
93876
94035
  };
93877
94036
  const accountValue = computeEffectiveAccountValue(formulaInput);
93878
- const maintenanceMargin = toNumber3(perps.crossMaintenanceMarginUsed);
94037
+ const maintenanceMargin = toNumber(perps.crossMaintenanceMarginUsed);
93879
94038
  const availableMargin = canonicalAvailableMargin(accountValue, totalMarginUsed);
93880
94039
  let totalNotional = 0;
93881
94040
  let totalUnrealizedPnl = 0;
@@ -93883,10 +94042,10 @@ var init_server_prompt_rescue_account_contract = __esm({
93883
94042
  for (const entry of positions) {
93884
94043
  const position = entry && typeof entry === "object" && !Array.isArray(entry) ? entry.position : null;
93885
94044
  if (!position || typeof position !== "object" || Array.isArray(position)) continue;
93886
- const size = toNumber3(position.szi);
93887
- const unrealizedPnl = toNumber3(position.unrealizedPnl);
94045
+ const size = toNumber(position.szi);
94046
+ const unrealizedPnl = toNumber(position.unrealizedPnl);
93888
94047
  totalUnrealizedPnl += unrealizedPnl;
93889
- totalNotional += Math.abs(size * toNumber3(position.entryPx) + unrealizedPnl);
94048
+ totalNotional += Math.abs(size * toNumber(position.entryPx) + unrealizedPnl);
93890
94049
  }
93891
94050
  return {
93892
94051
  account_value: accountValue,
@@ -94033,7 +94192,7 @@ var init_hyperliquid_account_state_adapter = __esm({
94033
94192
  buildUserFillsStorageKey = (cacheKey) => {
94034
94193
  return `${USER_FILLS_CACHE_STORAGE_PREFIX}${cacheKey}`;
94035
94194
  };
94036
- buildAccountStateCacheKey = (apiUrl, walletAddress, symbol2, aggregatePerpDexs, scopeAccountSummaryToSelectedDex, dexNames, includeEffectiveTakerRate, includeExactAccountMode, includeActiveAssetData, feeSymbols) => {
94195
+ buildAccountStateCacheKey = (apiUrl, walletAddress, symbol2, aggregatePerpDexs, scopeAccountSummaryToSelectedDex, dexNames, includeEffectiveTakerRate, includeExactAccountMode, includeActiveAssetData, feeSymbols, serverLoopAccountValue2) => {
94037
94196
  return [
94038
94197
  apiUrl.replace(/\/$/, "").toLowerCase(),
94039
94198
  walletAddress.trim().toLowerCase(),
@@ -94043,6 +94202,8 @@ var init_hyperliquid_account_state_adapter = __esm({
94043
94202
  includeEffectiveTakerRate ? "with-effective-taker-rate" : "without-effective-taker-rate",
94044
94203
  includeExactAccountMode ? "with-exact-account-mode" : "without-exact-account-mode",
94045
94204
  includeActiveAssetData ? "with-active-asset" : "without-active-asset",
94205
+ // A device read's key is unchanged; a Server-loop valuation never shares it.
94206
+ ...serverLoopAccountValue2 ? ["server-loop-account-value"] : [],
94046
94207
  ...dexNames.map(normalizePerpDexName).sort(),
94047
94208
  "fee-symbols",
94048
94209
  ...feeSymbols
@@ -94633,7 +94794,8 @@ var init_hyperliquid_account_state_adapter = __esm({
94633
94794
  includeEffectiveTakerRate,
94634
94795
  includeExactAccountMode,
94635
94796
  includeActiveAssetData,
94636
- [...new Set((input.feeSymbols ?? [symbol2]).map(normalizeHyperliquidMarketSymbol).filter(Boolean))].sort()
94797
+ [...new Set((input.feeSymbols ?? [symbol2]).map(normalizeHyperliquidMarketSymbol).filter(Boolean))].sort(),
94798
+ input.serverLoopAccountValue === true
94637
94799
  );
94638
94800
  const now = Date.now();
94639
94801
  const cached2 = readBrowserAccountStateCache(cacheKey);
@@ -94701,17 +94863,19 @@ var init_hyperliquid_account_state_adapter = __esm({
94701
94863
  staleIf429MaxAgeMs
94702
94864
  }) => {
94703
94865
  const metadataBodies = input.includeEffectiveTakerRate === true ? ["", ...dexNames].map((dex) => ({ type: "meta", ...dex ? { dex } : {} })) : [];
94866
+ const accountModeCache = input.publicRequestPriority === "ui" ? "display" : true;
94704
94867
  const reservation = await reserveHyperliquidPublicReads(apiUrl, [
94705
94868
  { type: "clearinghouseState", user: walletAddress },
94706
94869
  ...dexNames.map((dex) => ({ type: "clearinghouseState", user: walletAddress, dex })),
94707
94870
  { type: "spotClearinghouseState", user: walletAddress },
94708
94871
  ...input.includeActiveAssetData === false ? [] : [{ type: "activeAssetData", user: walletAddress, coin: symbol2 }],
94709
94872
  ...input.includeEffectiveTakerRate === true ? [{ type: "userFees", user: walletAddress }, ...metadataBodies] : [],
94710
- ...input.includeExactAccountMode === true ? [
94873
+ // A Server-loop valuation may need the mode too; a reservation claims no weight.
94874
+ ...input.includeExactAccountMode === true || input.serverLoopAccountValue === true ? [
94711
94875
  { type: "userAbstraction", user: walletAddress },
94712
94876
  { type: "userDexAbstraction", user: walletAddress }
94713
94877
  ] : []
94714
- ], input.signal, { cacheAccountMode: true, cacheValidUntilMs: input.publicReadDeadlineMs });
94878
+ ], input.signal, { cacheAccountMode: accountModeCache, cacheValidUntilMs: input.publicReadDeadlineMs });
94715
94879
  const priorityScope = input.priorityScope ?? createHyperliquidPublicPriorityScope(input.publicRequestPriority);
94716
94880
  reservation.priorityScope = priorityScope;
94717
94881
  if (input.onPublicReadPendingChange) {
@@ -94741,8 +94905,8 @@ var init_hyperliquid_account_state_adapter = __esm({
94741
94905
  return { payload: null, fetchedAtMs: Date.now() };
94742
94906
  }).then((result) => ({ payload: result.payload, capturedAt: new Date(result.fetchedAtMs).toISOString() }))
94743
94907
  }))() : Promise.resolve(null);
94744
- const exactAccountModePromise = input.includeExactAccountMode === true ? (async () => {
94745
- const abstractionRead = await readHyperliquidPublicInfo(apiUrl, { type: "userAbstraction", user: walletAddress }, { signal: input.signal, reservation, cacheAccountMode: true, priorityScope });
94908
+ const readExactAccountMode = async () => {
94909
+ const abstractionRead = await readHyperliquidPublicInfo(apiUrl, { type: "userAbstraction", user: walletAddress }, { signal: input.signal, reservation, cacheAccountMode: accountModeCache, priorityScope });
94746
94910
  const userAbstraction = abstractionRead.payload;
94747
94911
  let capturedAtMs = abstractionRead.fetchedAtMs;
94748
94912
  const preliminaryMode = extractCanonicalHyperliquidAccountMode(userAbstraction);
@@ -94751,7 +94915,7 @@ var init_hyperliquid_account_state_adapter = __esm({
94751
94915
  }
94752
94916
  let userDexAbstraction;
94753
94917
  if (preliminaryMode === "default" || preliminaryMode === "disabled") {
94754
- const dexRead = await readHyperliquidPublicInfo(apiUrl, { type: "userDexAbstraction", user: walletAddress }, { signal: input.signal, reservation, cacheAccountMode: true, priorityScope });
94918
+ const dexRead = await readHyperliquidPublicInfo(apiUrl, { type: "userDexAbstraction", user: walletAddress }, { signal: input.signal, reservation, cacheAccountMode: accountModeCache, priorityScope });
94755
94919
  userDexAbstraction = dexRead.payload;
94756
94920
  capturedAtMs = Math.min(capturedAtMs, dexRead.fetchedAtMs);
94757
94921
  }
@@ -94762,7 +94926,8 @@ var init_hyperliquid_account_state_adapter = __esm({
94762
94926
  ),
94763
94927
  capturedAt: new Date(capturedAtMs).toISOString()
94764
94928
  };
94765
- })() : Promise.resolve(null);
94929
+ };
94930
+ const exactAccountModePromise = input.includeExactAccountMode === true ? readExactAccountMode() : Promise.resolve(null);
94766
94931
  await awaitAccountReads([userFeesPromise, exactAccountModePromise]);
94767
94932
  const metadataByDex = /* @__PURE__ */ new Map();
94768
94933
  if (input.includeEffectiveTakerRate === true) {
@@ -94871,12 +95036,31 @@ var init_hyperliquid_account_state_adapter = __esm({
94871
95036
  }
94872
95037
  const accountStateConfig = input.config.client_runtime_hyperliquid_account_state;
94873
95038
  const summaryPerpsResponse = exactAccountMode ? { ...accountSummaryPerpsResponse, accountMode: exactAccountMode.accountMode } : accountSummaryPerpsResponse;
94874
- const accountSummaryOptions = {
95039
+ const deviceSummaryOptions = {
94875
95040
  spotDominatesMinTotalUsd: accountStateConfig?.spot_dominates_min_total_usd,
94876
95041
  spotDominatesPerpsMultiplier: accountStateConfig?.spot_dominates_perps_multiplier,
94877
95042
  mirroredAccountValueAbsoluteToleranceUsd: accountStateConfig?.mirrored_account_value_absolute_tolerance_usd,
94878
95043
  mirroredAccountValueRelativeTolerance: accountStateConfig?.mirrored_account_value_relative_tolerance
94879
95044
  };
95045
+ let serverLoopClassification = input.serverLoopAccountValue === true ? {
95046
+ spotAvailableToTradeRatioThreshold: accountStateConfig?.spot_available_to_trade_ratio_threshold,
95047
+ spotMeaningfulHoldUsd: accountStateConfig?.spot_meaningful_hold_usd,
95048
+ spotVeryStrongTotalUsd: accountStateConfig?.spot_very_strong_total_usd,
95049
+ spotVeryStrongPerpsEquityThresholdUsd: accountStateConfig?.spot_very_strong_perps_equity_threshold_usd,
95050
+ // The Python loop probes BTC's activeAssetData. This read's own probe
95051
+ // answers for the same collateral only on the default Perps DEX.
95052
+ availableToTrade: activeAssetResult?.payload != null && !selectedDex ? ((probe) => [probe.available_to_trade_buy, probe.available_to_trade_sell])(
95053
+ normalizeActiveAssetData(activeAssetResult.payload, symbol2)
95054
+ ) : null
95055
+ } : null;
95056
+ if (serverLoopClassification && !exactAccountMode && input.scopeAccountSummaryToSelectedDex !== true && serverLoopValuationCountsSpot(accountSummaryPerpsResponse, spotResponse, { ...deviceSummaryOptions, serverLoopClassification })) {
95057
+ const [serverLoopExactAccountMode] = await awaitAccountReads([readExactAccountMode()]);
95058
+ serverLoopClassification = { ...serverLoopClassification, exactAccountMode: serverLoopExactAccountMode.accountMode };
95059
+ }
95060
+ const accountSummaryOptions = {
95061
+ ...deviceSummaryOptions,
95062
+ ...serverLoopClassification ? { serverLoopClassification } : {}
95063
+ };
94880
95064
  const walletSummary = exactAccountMode && input.scopeAccountSummaryToSelectedDex !== true ? buildServerPromptRescueAccountSummary(
94881
95065
  perpsResponse,
94882
95066
  spotResponse,
@@ -95890,7 +96074,7 @@ var init_client_exchange_mutations = __esm({
95890
96074
  });
95891
96075
 
95892
96076
  // lib/runtime/execution-guard-contract.ts
95893
- var unitsFromPosition, signedUnitsFromPosition, signedUnitsFromEntryPosition, classifyExecutionIntent, reductionFirstOrder, resolveExecutionTarget, decisionOrderSizeAsset, flipExecutionLegs, executedOrderPositionEvent;
96077
+ var unitsFromPosition, signedUnitsFromPosition, signedUnitsFromEntryPosition, classifyExecutionIntent, reductionFirstOrder, usdAmount, orderMetadataRetryReason, orderCeilingRefusal, resolveExecutionTarget, decisionOrderSizeAsset, flipExecutionLegs, executedOrderPositionEvent;
95894
96078
  var init_execution_guard_contract = __esm({
95895
96079
  "lib/runtime/execution-guard-contract.ts"() {
95896
96080
  "use strict";
@@ -96090,6 +96274,28 @@ var init_execution_guard_contract = __esm({
96090
96274
  const reduces = plans.map((plan) => classifyExecutionIntent(plan.decision, plan.units, plan.signedUnits).reduceOnly);
96091
96275
  return plans.map((_, index) => index).sort((left, right) => Number(reduces[right]) - Number(reduces[left]));
96092
96276
  };
96277
+ usdAmount = (value) => `$${value.toLocaleString("en-US", {
96278
+ minimumFractionDigits: USD_DISPLAY_DECIMALS,
96279
+ maximumFractionDigits: USD_DISPLAY_DECIMALS
96280
+ })}`;
96281
+ orderMetadataRetryReason = (rejection) => {
96282
+ const message = String(rejection ?? "").toLowerCase();
96283
+ if (message.includes("invalid size")) return "invalid_size";
96284
+ if (message.includes("reference price") && message.includes("95% away")) return "reference_price";
96285
+ return null;
96286
+ };
96287
+ orderCeilingRefusal = (input) => {
96288
+ const orderNotional = input.size * input.price;
96289
+ if (orderNotional > input.maxOrderNotional) {
96290
+ return `Order notional ${usdAmount(orderNotional)} exceeds limit ${usdAmount(input.maxOrderNotional)}`;
96291
+ }
96292
+ const resultingSize = input.side === "buy" ? input.currentPositionSize + input.size : input.currentPositionSize - input.size;
96293
+ const resultingNotional = Math.abs(resultingSize) * input.price;
96294
+ if (resultingNotional > input.maxPositionNotional) {
96295
+ return `Resulting position notional ${usdAmount(resultingNotional)} exceeds limit ${usdAmount(input.maxPositionNotional)}`;
96296
+ }
96297
+ return null;
96298
+ };
96093
96299
  resolveExecutionTarget = (classified, liveSignedUnits, livePositionDirection) => {
96094
96300
  const liveUnits = Number.isFinite(liveSignedUnits) ? Math.trunc(liveSignedUnits) : 0;
96095
96301
  const exactLiveDirection = livePositionDirection == null ? liveUnits > 0 ? 1 : liveUnits < 0 ? -1 : 0 : livePositionDirection;
@@ -96639,6 +96845,27 @@ var init_protective_leg_evidence = __esm({
96639
96845
  }
96640
96846
  });
96641
96847
 
96848
+ // lib/runtime/protective-entry-cover.ts
96849
+ var protectiveEntryCover, protectiveEntryLegSize;
96850
+ var init_protective_entry_cover = __esm({
96851
+ "lib/runtime/protective-entry-cover.ts"() {
96852
+ "use strict";
96853
+ init_define_VTX_EXO_POLICY();
96854
+ init_define_VTX_GROK_POLICY();
96855
+ init_define_VTX_PI_MODEL_POLICY();
96856
+ protectiveEntryCover = (input) => {
96857
+ const cover = { sl: 0, tp: 0 };
96858
+ for (const leg of input.storedLegs) {
96859
+ if (leg.isLong !== input.entryIsLong) continue;
96860
+ const rests = leg.orderId == null ? leg.canStillExist : input.liveOrderIds.has(String(leg.orderId));
96861
+ if (rests) cover[leg.kind] += leg.size;
96862
+ }
96863
+ return cover;
96864
+ };
96865
+ protectiveEntryLegSize = (input) => Math.min(input.filledSize, Math.max(0, input.liveExposure - input.cover));
96866
+ }
96867
+ });
96868
+
96642
96869
  // lib/runtime/runtime-execution.ts
96643
96870
  function capCopiedToActual(copied, actual) {
96644
96871
  if (Math.abs(copied) <= COPY_TRADING_SIZE_EPSILON) return 0;
@@ -96674,7 +96901,7 @@ function copiedTargetNow(reconciliation, recordedTarget, actualPosition) {
96674
96901
  );
96675
96902
  return { copiedNow, targetNow, kept: copiedTargetBesideOwnPosition(targetNow, copiedNow, actualPosition) };
96676
96903
  }
96677
- var clientProtectiveMutationAuthority, executionReadPriority, serverEntryLeverageAlreadyHeld, fetchClientRuntimeOpenOrders, _extractOrderResponseStates, createRuntimeId, _extractFilledSize, _extractOrderId, _toExecutionMetadata, _extractClientMutationId, _stableMutationIdentity, trailingStopMemory, protectiveGroupMemory, protectiveGroupReadFailures, windowHandoffCleanupAttempts, clientRuntimeProtectionStorage, resolveClientRuntimeProtectionStorage, setClientRuntimeProtectionStorage, trailingStopStorageKey, readTrackedTrailingStops, writeTrackedTrailingStops, rememberTrailingStop, protectiveGroupStorageKey, LOST_LEG_EVIDENCE_MAX_AGE_MS, EPISODE_END_FILL_LOOKBACK_MS, withClientProtectivePlanSetLock, readClientProtectiveGroups, writeClientProtectiveGroups, hasClientProtectiveGroupReadFailure, readFreshClientProtectiveGroups, stableProtectionSnapshot, exactClientProtectiveGroupSnapshot, exactClientProtectiveGroupSetSnapshot, storableClientProtectiveGroup, replaceExactClientProtectiveGroup, replaceExactClientProtectiveGroupSet, isClientRuntimeLeaseOwnershipError, hasClientRuntimeProtectionState, clearClientRuntimeVetoedProtectiveIntent, rethrowWindowHandoffAfterProtectiveReplacementVeto, canPersistClientProtectiveGroups, removeTrackedTrailingStop, replaceTrackedTrailingStop, replaceProtectiveLeg, replacementJournalEntryOrderId, buildProtectiveReplacementJournalGroup, isProtectiveReplacementJournalGroup, reserveProtectiveLegReplacement, ensureProtectiveReplacementJournalCompanion, buildVetoedProtectiveReplacementCleanup, assertExactProtectiveReplacementDispatchAuthority, transitionProtectiveReplacementAcknowledgement, transitionTerminalProtectiveReplacement, pendingProtectiveReplacementReport, isConfiguredProtectionRequested, protectiveAction, executedProtectiveReport, isExactClientPositionTpslPair, deviceOwnsClientProtectiveLegKind, isAdoptionNarrowedPositionTpslLeg, hasAmbiguousClientPositionTpslAuthority, protectiveStableShapeMatches, observedProtectiveGroupingMatches, protectiveLiveShapeMatches, protectiveTerminalShapeMatches, cancelClientProtectiveLeg, buildPendingProtectivePlan, persistPendingClientProtectiveGroup, storedClientProtectiveCover, attachClientProtectivePlan, resolveJournaledAttachmentContinuity, protectiveMemberRested, recoverJournaledClientProtectiveAttachments, readPendingEntryMutation, requireClientRuntimeConfigSeconds, replacePendingEntryRecovery, recoverPendingClientProtectiveGroups, recoverPendingProtectiveReplacements, liveProtectiveOrderShape, observedStandaloneProtectiveGroup, migrateTrackedTrailingStopsToStandalone, reconcileClientProtectiveGroups, cancelAllClientProtectiveGroups, tightenClientTrailingStops, throwIfAborted2, sleep2, isDefinitiveEntryRejection, resolveExchangeSizeDecimals, roundAssetSize, resolvePositionSize, resolveCurrentPositionSize, buildPositionSnapshot, signedRemainingExposureAfterConfirmedReduction, runtimeProtectionAuthority, runtimeProtectionOwners, resolveRuntimeProtectionOwner, drainServerProtectionForRuntime, drainServerProtectionIfOwned, verifyNoLiveClientProtectiveTriggers, clientExecutionMutations, CLIENT_EXECUTION_QUEUE_TIMEOUT_MESSAGE, withClientExecutionMutation, withClientProtectivePlanSetMutation, allocateServerExecutionCapacity, withClientProtectiveAdoptionMutation, executeClientRuntimeDecisionLocked, SERVER_AUDIT_RECORDED_ELSEWHERE, serverExecutionAuditOutcome, decisionLegOf, withExecutionAuditId, executeClientRuntimeDecision, waitForFlipCloseFreshness, maintainClientRuntimeTrailingStops, listPendingClientProtectiveSymbols, listStoredClientProtectiveSymbols, hasUnresolvedClientProtectiveIdentity, resolveClientProtectiveIdentitiesForAdoption, exportClientProtectiveGroupsForAdoption, adoptionGroupKey, applyClientProtectiveAdoptionOutcomes, hasStoredClientProtectiveGroupsForWallet, hasPendingClientProtectiveGroups, recoverManualClientProtectiveGroups, clientRuntimeDecisionSizesOrders, COMMITTED_EXECUTION_REPORTS, getCommittedExecutionReports, withCommittedExecutionReports, executeClientRuntimeDecisionUnlocked, executeClientCopyTradingIntent, _copyCancelOrderId, executeClientCopyTradingOrderAction;
96904
+ var clientProtectiveMutationAuthority, executionReadPriority, serverEntryLeverageAlreadyHeld, fetchClientRuntimeOpenOrders, _extractOrderResponseStates, createRuntimeId, _extractFilledSize, _extractOrderId, _toExecutionMetadata, _extractClientMutationId, _stableMutationIdentity, trailingStopMemory, protectiveGroupMemory, protectiveGroupReadFailures, windowHandoffCleanupAttempts, clientRuntimeProtectionStorage, resolveClientRuntimeProtectionStorage, setClientRuntimeProtectionStorage, trailingStopStorageKey, readTrackedTrailingStops, writeTrackedTrailingStops, rememberTrailingStop, protectiveGroupStorageKey, LOST_LEG_EVIDENCE_MAX_AGE_MS, EPISODE_END_FILL_LOOKBACK_MS, withClientProtectivePlanSetLock, readClientProtectiveGroups, writeClientProtectiveGroups, hasClientProtectiveGroupReadFailure, readFreshClientProtectiveGroups, stableProtectionSnapshot, exactClientProtectiveGroupSnapshot, exactClientProtectiveGroupSetSnapshot, storableClientProtectiveGroup, replaceExactClientProtectiveGroup, replaceExactClientProtectiveGroupSet, isClientRuntimeLeaseOwnershipError, hasClientRuntimeProtectionState, clearClientRuntimeVetoedProtectiveIntent, rethrowWindowHandoffAfterProtectiveReplacementVeto, canPersistClientProtectiveGroups, removeTrackedTrailingStop, replaceTrackedTrailingStop, replaceProtectiveLeg, replacementJournalEntryOrderId, buildProtectiveReplacementJournalGroup, isProtectiveReplacementJournalGroup, reserveProtectiveLegReplacement, ensureProtectiveReplacementJournalCompanion, buildVetoedProtectiveReplacementCleanup, assertExactProtectiveReplacementDispatchAuthority, transitionProtectiveReplacementAcknowledgement, transitionTerminalProtectiveReplacement, pendingProtectiveReplacementReport, isConfiguredProtectionRequested, protectiveAction, executedProtectiveReport, isExactClientPositionTpslPair, deviceOwnsClientProtectiveLegKind, isAdoptionNarrowedPositionTpslLeg, hasAmbiguousClientPositionTpslAuthority, protectiveStableShapeMatches, observedProtectiveGroupingMatches, protectiveLiveShapeMatches, protectiveTerminalShapeMatches, cancelClientProtectiveLeg, buildPendingProtectivePlan, persistPendingClientProtectiveGroup, attachmentMemberNeverLanded, storedClientProtectiveCover, attachClientProtectivePlan, resolveJournaledAttachmentContinuity, protectiveMemberRested, ledgerOrderIdsByClientOrderId, journaledAttachmentNeverLanded, recoverJournaledClientProtectiveAttachments, readClientOrderMutation, readPendingEntryMutation, clientOrderNeverLandsAfterMs, requireClientRuntimeConfigSeconds, replacePendingEntryRecovery, recoverPendingClientProtectiveGroups, recoverPendingProtectiveReplacements, liveProtectiveOrderShape, observedStandaloneProtectiveGroup, migrateTrackedTrailingStopsToStandalone, reconcileClientProtectiveGroups, cancelAllClientProtectiveGroups, tightenClientTrailingStops, throwIfAborted2, sleep2, isDefinitiveEntryRejection, resolveExchangeSizeDecimals, roundAssetSize, resolvePositionSize, readServerOrderMarkPrice, serverOrderMetadataRetry, resolveCurrentPositionSize, buildPositionSnapshot, signedRemainingExposureAfterConfirmedReduction, runtimeProtectionAuthority, runtimeProtectionOwners, resolveRuntimeProtectionOwner, drainServerProtectionForRuntime, drainServerProtectionIfOwned, verifyNoLiveClientProtectiveTriggers, clientExecutionMutations, CLIENT_EXECUTION_QUEUE_TIMEOUT_MESSAGE, withClientExecutionMutation, withClientProtectivePlanSetMutation, allocateServerExecutionCapacity, withClientProtectiveAdoptionMutation, executeClientRuntimeDecisionLocked, unsentDecisionOrderReport, withCapacityTrim, SERVER_AUDIT_RECORDED_ELSEWHERE, serverExecutionAuditOutcome, decisionLegOf, withExecutionAuditId, executeClientRuntimeDecision, waitForFlipCloseFreshness, maintainClientRuntimeTrailingStops, listPendingClientProtectiveSymbols, listStoredClientProtectiveSymbols, hasUnresolvedClientProtectiveIdentity, resolveClientProtectiveIdentitiesForAdoption, exportClientProtectiveGroupsForAdoption, adoptionGroupKey, applyClientProtectiveAdoptionOutcomes, hasStoredClientProtectiveGroupsForWallet, hasPendingClientProtectiveGroups, recoverManualClientProtectiveGroups, clientRuntimeDecisionSizesOrders, COMMITTED_EXECUTION_REPORTS, getCommittedExecutionReports, withCommittedExecutionReports, executeClientRuntimeDecisionUnlocked, executeClientCopyTradingIntent, _copyCancelOrderId, executeClientCopyTradingOrderAction;
96678
96905
  var init_runtime_execution = __esm({
96679
96906
  "lib/runtime/runtime-execution.ts"() {
96680
96907
  "use strict";
@@ -96701,6 +96928,7 @@ var init_runtime_execution = __esm({
96701
96928
  init_runtime_redaction();
96702
96929
  init_protective_leg_evidence();
96703
96930
  init_protective_stop_replacement();
96931
+ init_protective_entry_cover();
96704
96932
  init_error_surface_contract();
96705
96933
  init_runtime_handoff();
96706
96934
  clientProtectiveMutationAuthority = (request) => request.mutationAuthority === "manual_session" ? {} : {
@@ -96725,7 +96953,13 @@ var init_runtime_execution = __esm({
96725
96953
  const wallet = String(context.walletAddress || "").trim();
96726
96954
  if (!symbol2 || !wallet || !Number.isInteger(context.leverage) || context.leverage <= 0 || !Number.isFinite(context.currentPositionSize) || context.currentPositionSize === 0) return false;
96727
96955
  let active;
96956
+ let target;
96728
96957
  try {
96958
+ target = resolveLeverageTarget(
96959
+ await resolveHyperliquidAsset({ symbol: symbol2, config: input.config ?? null, publicRequestPriority: "trading_reconcile" }),
96960
+ context.leverage,
96961
+ context.marginMode !== "isolated"
96962
+ );
96729
96963
  active = await fetchBrowserHyperliquidInfoPayload(
96730
96964
  { config: input.config ?? null, signal: input.signal, publicRequestPriority: "trading_reconcile" },
96731
96965
  { type: "activeAssetData", user: wallet, coin: symbol2 },
@@ -96736,7 +96970,7 @@ var init_runtime_execution = __esm({
96736
96970
  return false;
96737
96971
  }
96738
96972
  const leverage = active?.leverage;
96739
- return leverage?.value === context.leverage && leverage?.type === (context.marginMode === "isolated" ? "isolated" : "cross");
96973
+ return leverage?.value === target.leverage && leverage?.type === (target.isCross ? "cross" : "isolated");
96740
96974
  };
96741
96975
  fetchClientRuntimeOpenOrders = async (request, publicRequestPriority = "trading_reconcile") => {
96742
96976
  const normalizedSymbol = normalizeHyperliquidMarketSymbol(
@@ -97176,7 +97410,9 @@ var init_runtime_execution = __esm({
97176
97410
  const phase = journal.phase == null ? "awaiting_member_outcome" : journal.phase;
97177
97411
  const filledSize = Number(journal.filledSize);
97178
97412
  const averagePrice = Number(journal.averagePrice);
97179
- if (phase !== "awaiting_member_outcome" && phase !== "cancel_survivors" && phase !== "cancel_stale_members" || !/^[1-9]\d*$/.test(journalEntryOrderId) || !Number.isFinite(filledSize) || filledSize <= 0 || !Number.isFinite(averagePrice) || averagePrice <= 0 || !Array.isArray(journal.members) || journal.members.length < 1 || journal.members.length > CLIENT_PROTECTIVE_TPSL_PAIR_LEGS) {
97413
+ const invalidJournalTime = (value) => value != null && (typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0);
97414
+ const journalMutationId = journal.mutationId == null ? void 0 : String(journal.mutationId).trim().toLowerCase();
97415
+ if (phase !== "awaiting_member_outcome" && phase !== "cancel_survivors" && phase !== "cancel_stale_members" || journalMutationId !== void 0 && !/^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/.test(journalMutationId) || invalidJournalTime(journal.createdAtMs) || invalidJournalTime(journal.unknownOidFirstSeenAtMs) || invalidJournalTime(journal.unknownOidObservedAtMs) || !/^[1-9]\d*$/.test(journalEntryOrderId) || !Number.isFinite(filledSize) || filledSize <= 0 || !Number.isFinite(averagePrice) || averagePrice <= 0 || !Array.isArray(journal.members) || journal.members.length < 1 || journal.members.length > CLIENT_PROTECTIVE_TPSL_PAIR_LEGS) {
97180
97416
  protectiveGroupReadFailures.add(key);
97181
97417
  return [];
97182
97418
  }
@@ -97186,7 +97422,7 @@ var init_runtime_execution = __esm({
97186
97422
  const clientOrderId = String(member.clientOrderId ?? "").trim().toLowerCase();
97187
97423
  const triggerPrice = Number(member.triggerPrice);
97188
97424
  const size = Number(member.size);
97189
- if (member.kind !== "sl" && member.kind !== "tp" || !/^0x[0-9a-f]{32}$/.test(clientOrderId) || !Number.isFinite(triggerPrice) || triggerPrice <= 0 || !Number.isFinite(size) || size <= 0 || typeof member.isTrailing !== "boolean" || typeof member.positionTpsl !== "boolean") {
97425
+ if (member.kind !== "sl" && member.kind !== "tp" || !/^0x[0-9a-f]{32}$/.test(clientOrderId) || !Number.isFinite(triggerPrice) || triggerPrice <= 0 || !Number.isFinite(size) || size <= 0 || typeof member.isTrailing !== "boolean" || typeof member.positionTpsl !== "boolean" || invalidJournalTime(member.neverLandedAtMs)) {
97190
97426
  return [];
97191
97427
  }
97192
97428
  return [{
@@ -97195,7 +97431,8 @@ var init_runtime_execution = __esm({
97195
97431
  triggerPrice,
97196
97432
  size,
97197
97433
  isTrailing: member.isTrailing,
97198
- positionTpsl: member.positionTpsl
97434
+ positionTpsl: member.positionTpsl,
97435
+ ...typeof member.neverLandedAtMs === "number" ? { neverLandedAtMs: member.neverLandedAtMs } : {}
97199
97436
  }];
97200
97437
  });
97201
97438
  if (members.length !== journal.members.length || pendingEntry == null || legs.length > 0 && (members.length !== legs.length || members.some((member, index) => {
@@ -97210,6 +97447,10 @@ var init_runtime_execution = __esm({
97210
97447
  entryOrderId: journalEntryOrderId,
97211
97448
  filledSize,
97212
97449
  averagePrice,
97450
+ ...journalMutationId !== void 0 ? { mutationId: journalMutationId } : {},
97451
+ ...typeof journal.createdAtMs === "number" ? { createdAtMs: journal.createdAtMs } : {},
97452
+ ...typeof journal.unknownOidFirstSeenAtMs === "number" ? { unknownOidFirstSeenAtMs: journal.unknownOidFirstSeenAtMs } : {},
97453
+ ...typeof journal.unknownOidObservedAtMs === "number" ? { unknownOidObservedAtMs: journal.unknownOidObservedAtMs } : {},
97213
97454
  members
97214
97455
  };
97215
97456
  }
@@ -97970,21 +98211,27 @@ var init_runtime_execution = __esm({
97970
98211
  );
97971
98212
  return { group, cleanup, persistedGroupSet: persistenceFailed ? null : nextGroups };
97972
98213
  };
97973
- storedClientProtectiveCover = async (request, legs) => {
97974
- const cover = { sl: 0, tp: 0 };
97975
- if (legs.length === 0) return cover;
97976
- const symbol2 = request.executionContext.symbol.trim().toUpperCase();
97977
- const orders = await fetchClientRuntimeOpenOrders(request, "trading_reduce");
97978
- if (!Array.isArray(orders)) {
97979
- throw new Error("Malformed live protective-order snapshot.");
97980
- }
97981
- const liveOrderIds = new Set(orders.filter((order) => String(order.coin).trim().toUpperCase() === symbol2).map((order) => String(order.oid)));
97982
- for (const leg of legs) {
97983
- if (typeof leg.orderId === "string" || liveOrderIds.has(String(leg.orderId))) {
97984
- cover[leg.kind] += leg.size;
98214
+ attachmentMemberNeverLanded = (group, leg) => group.attachmentJournal?.members.some((member) => member.clientOrderId === leg.orderId && member.neverLandedAtMs != null) === true;
98215
+ storedClientProtectiveCover = async (request, entryIsLong, groups) => {
98216
+ const storedLegs = groups.filter((group) => group.isLong === entryIsLong).flatMap((group) => group.legs.map((leg) => ({
98217
+ isLong: group.isLong,
98218
+ kind: leg.kind,
98219
+ size: leg.size,
98220
+ orderId: typeof leg.orderId === "number" ? leg.orderId : null,
98221
+ canStillExist: !attachmentMemberNeverLanded(group, leg)
98222
+ })));
98223
+ const liveOrderIds = /* @__PURE__ */ new Set();
98224
+ if (storedLegs.length > 0) {
98225
+ const symbol2 = request.executionContext.symbol.trim().toUpperCase();
98226
+ const orders = await fetchClientRuntimeOpenOrders(request, "trading_reduce");
98227
+ if (!Array.isArray(orders)) {
98228
+ throw new Error("Malformed live protective-order snapshot.");
98229
+ }
98230
+ for (const order of orders) {
98231
+ if (String(order.coin).trim().toUpperCase() === symbol2) liveOrderIds.add(String(order.oid));
97985
98232
  }
97986
98233
  }
97987
- return cover;
98234
+ return protectiveEntryCover({ entryIsLong, storedLegs, liveOrderIds });
97988
98235
  };
97989
98236
  attachClientProtectivePlan = async (request, group, fill) => {
97990
98237
  const reports = [];
@@ -98082,10 +98329,7 @@ var init_runtime_execution = __esm({
98082
98329
  const liveExposure = Math.abs(livePositionSize);
98083
98330
  let storedCover;
98084
98331
  try {
98085
- storedCover = await storedClientProtectiveCover(
98086
- request,
98087
- existingGroups.flatMap((existing) => existing.legs)
98088
- );
98332
+ storedCover = await storedClientProtectiveCover(request, isLong, existingGroups);
98089
98333
  } catch (error48) {
98090
98334
  if (request.signal?.aborted) throw error48;
98091
98335
  reports.push({
@@ -98101,9 +98345,12 @@ var init_runtime_execution = __esm({
98101
98345
  return reports;
98102
98346
  }
98103
98347
  const allocatedCandidates = planned.flatMap((candidate) => {
98104
- const allocated = storedCover[candidate.kind];
98105
98348
  const size = roundAssetSize(
98106
- Math.min(fill.filledSize, Math.max(0, liveExposure - allocated)),
98349
+ protectiveEntryLegSize({
98350
+ filledSize: fill.filledSize,
98351
+ liveExposure,
98352
+ cover: storedCover[candidate.kind]
98353
+ }),
98107
98354
  request.executionContext.sizeDecimals
98108
98355
  );
98109
98356
  if (!Number.isFinite(size) || size <= 0) {
@@ -98211,6 +98458,9 @@ var init_runtime_execution = __esm({
98211
98458
  entryOrderId: fill.orderId,
98212
98459
  filledSize: fill.filledSize,
98213
98460
  averagePrice: fill.averagePrice,
98461
+ // One signed mutation carries every member (its first member's).
98462
+ mutationId: candidates[0].mutationId,
98463
+ createdAtMs: Date.now(),
98214
98464
  members: candidates.map((candidate) => ({
98215
98465
  kind: candidate.kind,
98216
98466
  clientOrderId: candidate.clientOrderId,
@@ -98723,6 +98973,82 @@ var init_runtime_execution = __esm({
98723
98973
  const endedAt = evidence.statusTimestampMs;
98724
98974
  return placedAt != null && endedAt != null && endedAt > placedAt;
98725
98975
  };
98976
+ ledgerOrderIdsByClientOrderId = (mutation) => {
98977
+ const orderIds = /* @__PURE__ */ new Map();
98978
+ const add = (clientOrderId, exchangeOrderId) => {
98979
+ const cloid = String(clientOrderId ?? "").trim().toLowerCase();
98980
+ const orderId = String(exchangeOrderId ?? "").trim();
98981
+ if (/^0x[0-9a-f]{32}$/.test(cloid) && /^[1-9]\d*$/.test(orderId) && Number.isSafeInteger(Number(orderId))) {
98982
+ orderIds.set(cloid, Number(orderId));
98983
+ }
98984
+ };
98985
+ add(mutation.client_order_id, mutation.exchange_order_id);
98986
+ for (const member of mutation.order_members ?? []) {
98987
+ add(member.client_order_id, member.exchange_order_id);
98988
+ }
98989
+ return orderIds;
98990
+ };
98991
+ journaledAttachmentNeverLanded = async (request, group) => {
98992
+ const journal = group.attachmentJournal;
98993
+ let ledgerOrderIds = /* @__PURE__ */ new Map();
98994
+ if (journal == null) return { group, proven: false, ledgerOrderIds };
98995
+ const observedAtMs = Date.now();
98996
+ const firstSeenAtMs = journal.unknownOidFirstSeenAtMs ?? observedAtMs;
98997
+ const waiting = (unknownOidObservedAtMs) => {
98998
+ if (journal.unknownOidFirstSeenAtMs != null && unknownOidObservedAtMs === void 0) {
98999
+ return { group, proven: false, ledgerOrderIds };
99000
+ }
99001
+ const recorded = {
99002
+ ...group,
99003
+ attachmentJournal: {
99004
+ ...journal,
99005
+ unknownOidFirstSeenAtMs: firstSeenAtMs,
99006
+ ...unknownOidObservedAtMs !== void 0 ? { unknownOidObservedAtMs } : {}
99007
+ }
99008
+ };
99009
+ if (!replaceExactClientProtectiveGroup(
99010
+ String(request.profileId).trim(),
99011
+ request.executionContext.symbol,
99012
+ group,
99013
+ recorded
99014
+ )) {
99015
+ throw new Error("Journaled attachment recovery state could not be saved durably.");
99016
+ }
99017
+ return { group: recorded, proven: false, ledgerOrderIds };
99018
+ };
99019
+ const mutationId = journal.mutationId ?? mutationIdForClientOrderId(journal.members[0]?.clientOrderId ?? "");
99020
+ let provableAtMs;
99021
+ if (mutationId == null) {
99022
+ provableAtMs = clientOrderNeverLandsAfterMs(request.config, { kind: "absent", ageStartMs: firstSeenAtMs });
99023
+ } else {
99024
+ const ledger = await readClientOrderMutation(
99025
+ request,
99026
+ mutationId,
99027
+ clientOrderIdForMutation(mutationId)
99028
+ );
99029
+ if (ledger.kind === "found") {
99030
+ ledgerOrderIds = ledgerOrderIdsByClientOrderId(ledger.mutation);
99031
+ if (String(ledger.mutation.exchange_order_id ?? "").trim().length > 0) {
99032
+ return { group, proven: false, ledgerOrderIds };
99033
+ }
99034
+ const expiresAfterMs = Number(ledger.mutation.exchange_expires_after_ms);
99035
+ if (!Number.isSafeInteger(expiresAfterMs) || expiresAfterMs <= 0) return waiting();
99036
+ provableAtMs = clientOrderNeverLandsAfterMs(request.config, { kind: "found", expiresAfterMs });
99037
+ } else if (ledger.kind === "absent") {
99038
+ provableAtMs = clientOrderNeverLandsAfterMs(request.config, {
99039
+ kind: "absent",
99040
+ ageStartMs: journal.createdAtMs ?? firstSeenAtMs
99041
+ });
99042
+ } else {
99043
+ return waiting();
99044
+ }
99045
+ }
99046
+ if (observedAtMs < provableAtMs) return waiting();
99047
+ if (journal.unknownOidObservedAtMs == null || journal.unknownOidObservedAtMs < provableAtMs) {
99048
+ return waiting(observedAtMs);
99049
+ }
99050
+ return { group, proven: true, ledgerOrderIds };
99051
+ };
98726
99052
  recoverJournaledClientProtectiveAttachments = async (request, journaledGroups) => {
98727
99053
  const reports = [];
98728
99054
  const profileId = String(request.profileId).trim();
@@ -98744,24 +99070,64 @@ var init_runtime_execution = __esm({
98744
99070
  }
98745
99071
  })));
98746
99072
  }
98747
- for (const group of journaledGroups) {
99073
+ const boundOrderIds = new Set(readClientProtectiveGroups(profileId, symbol2).flatMap((stored) => stored.legs.flatMap((leg) => typeof leg.orderId === "number" ? [String(leg.orderId)] : [])));
99074
+ for (const journaledGroup of journaledGroups) {
99075
+ let group = journaledGroup;
98748
99076
  const plan = group.pendingEntry;
98749
- const journal = group.attachmentJournal;
99077
+ let journal = group.attachmentJournal;
98750
99078
  if (plan == null || journal == null || group.legs.length === 0) continue;
98751
99079
  const inspected = [];
98752
99080
  let unresolved = false;
99081
+ let ledgerVerdict = null;
99082
+ const newlyNeverLanded = /* @__PURE__ */ new Set();
98753
99083
  for (const provisionalLeg of group.legs) {
99084
+ if (attachmentMemberNeverLanded(group, provisionalLeg)) {
99085
+ inspected.push({ leg: provisionalLeg, state: "terminal", rested: false, neverLanded: true });
99086
+ continue;
99087
+ }
98754
99088
  let openOrder = liveOrders.find((order) => String(order.oid) === String(provisionalLeg.orderId)) ?? null;
98755
99089
  let canonicalLeg = provisionalLeg;
98756
99090
  if (openOrder == null) {
98757
99091
  try {
98758
- const evidence = await fetchBrowserOrderStatusEvidence({
99092
+ let evidence = await fetchBrowserOrderStatusEvidence({
98759
99093
  publicRequestPriority: "trading_reconcile",
98760
99094
  config: request.config ?? null,
98761
99095
  walletAddress,
98762
99096
  signal: request.signal,
98763
99097
  orderId: provisionalLeg.orderId
98764
99098
  });
99099
+ if (typeof provisionalLeg.orderId === "string" && evidence.responseValid && evidence.responseStatus === "unknownOid") {
99100
+ if (ledgerVerdict == null) {
99101
+ ledgerVerdict = await journaledAttachmentNeverLanded(request, group);
99102
+ group = ledgerVerdict.group;
99103
+ journal = group.attachmentJournal ?? journal;
99104
+ }
99105
+ const ledgerOrderId = ledgerVerdict.ledgerOrderIds.get(provisionalLeg.orderId);
99106
+ if (ledgerOrderId != null) {
99107
+ evidence = await fetchBrowserOrderStatusEvidence({
99108
+ publicRequestPriority: "trading_reconcile",
99109
+ config: request.config ?? null,
99110
+ walletAddress,
99111
+ signal: request.signal,
99112
+ orderId: ledgerOrderId
99113
+ });
99114
+ if (!evidence.responseValid || !evidence.orderMatches) {
99115
+ throw new Error("Journaled protective order identity is unresolved.");
99116
+ }
99117
+ } else {
99118
+ const mayRestUnseen = liveOrders.some((order) => !boundOrderIds.has(String(order.oid)) && protectiveLiveShapeMatches({
99119
+ shape: liveProtectiveOrderShape(order),
99120
+ symbol: symbol2,
99121
+ isLong: group.isLong,
99122
+ leg: provisionalLeg
99123
+ }));
99124
+ if (ledgerVerdict.proven && !mayRestUnseen) {
99125
+ newlyNeverLanded.add(provisionalLeg.orderId);
99126
+ inspected.push({ leg: provisionalLeg, state: "terminal", rested: false, neverLanded: true });
99127
+ continue;
99128
+ }
99129
+ }
99130
+ }
98765
99131
  const resolvedOrderId = Number(evidence.orderId);
98766
99132
  if (!Number.isSafeInteger(resolvedOrderId) || resolvedOrderId <= 0) {
98767
99133
  throw new Error("Journaled protective order identity is unresolved.");
@@ -98829,6 +99195,28 @@ var init_runtime_execution = __esm({
98829
99195
  inspected.push({ leg: canonicalLeg, state: "open" });
98830
99196
  }
98831
99197
  if (unresolved || inspected.length !== group.legs.length) continue;
99198
+ if (newlyNeverLanded.size > 0) {
99199
+ const neverLandedAtMs = Date.now();
99200
+ const proven = {
99201
+ ...group,
99202
+ attachmentJournal: {
99203
+ ...journal,
99204
+ members: journal.members.map((member) => newlyNeverLanded.has(member.clientOrderId) ? { ...member, neverLandedAtMs } : member)
99205
+ }
99206
+ };
99207
+ if (!replaceExactClientProtectiveGroup(profileId, symbol2, group, proven)) {
99208
+ reports.push({
99209
+ order_id: journal.entryOrderId,
99210
+ symbol: symbol2,
99211
+ action: "PROTECTIVE_RECONCILIATION",
99212
+ status: "failed",
99213
+ execution_metadata: { reason_code: "protective_lifecycle_persistence_failed" }
99214
+ });
99215
+ continue;
99216
+ }
99217
+ group = proven;
99218
+ journal = proven.attachmentJournal ?? journal;
99219
+ }
98832
99220
  const hasFulfilled = inspected.some((entry) => entry.state === "fulfilled");
98833
99221
  const hasNonfulfilledTerminal = inspected.some((entry) => entry.state === "terminal");
98834
99222
  const openEntries = inspected.filter((entry) => entry.state === "open");
@@ -99073,6 +99461,47 @@ var init_runtime_execution = __esm({
99073
99461
  });
99074
99462
  continue;
99075
99463
  }
99464
+ if (inspected.every((entry) => entry.neverLanded === true)) {
99465
+ let livePositionSize = Number.NaN;
99466
+ let positionError = null;
99467
+ try {
99468
+ livePositionSize = Number((await fetchBrowserPositionSnapshot(
99469
+ request.config ?? {},
99470
+ walletAddress,
99471
+ symbol2,
99472
+ request.signal,
99473
+ "trading_reconcile"
99474
+ )).size);
99475
+ } catch (error48) {
99476
+ if (request.signal?.aborted) throw error48;
99477
+ positionError = error48;
99478
+ }
99479
+ if (!Number.isFinite(livePositionSize)) {
99480
+ reports.push({
99481
+ order_id: journal.entryOrderId,
99482
+ symbol: symbol2,
99483
+ action: "PROTECTIVE_RECONCILIATION",
99484
+ status: "failed",
99485
+ execution_metadata: {
99486
+ reason_code: "protective_attachment_continuity_unresolved",
99487
+ error: getSanitizedRuntimeErrorMessage(positionError) || "Unable to verify live position exposure."
99488
+ }
99489
+ });
99490
+ continue;
99491
+ }
99492
+ if (!(group.isLong ? livePositionSize > 0 : livePositionSize < 0)) {
99493
+ if (!replaceExactClientProtectiveGroup(profileId, symbol2, group, null)) {
99494
+ reports.push({
99495
+ order_id: journal.entryOrderId,
99496
+ symbol: symbol2,
99497
+ action: "PROTECTIVE_RECONCILIATION",
99498
+ status: "failed",
99499
+ execution_metadata: { reason_code: "protective_lifecycle_persistence_failed" }
99500
+ });
99501
+ }
99502
+ continue;
99503
+ }
99504
+ }
99076
99505
  let disposition;
99077
99506
  try {
99078
99507
  ({ disposition } = await resolveJournaledAttachmentContinuity(
@@ -99114,20 +99543,35 @@ var init_runtime_execution = __esm({
99114
99543
  }
99115
99544
  return reports;
99116
99545
  };
99117
- readPendingEntryMutation = async (request, plan) => {
99546
+ readClientOrderMutation = async (request, mutationId, clientOrderId) => {
99118
99547
  try {
99119
99548
  const mutation = await getClientRuntimeExchangeMutation(
99120
99549
  request.profileId,
99121
- plan.entryMutationId,
99550
+ mutationId,
99122
99551
  request.signal
99123
99552
  );
99124
99553
  if (mutation == null) return { kind: "absent" };
99125
- return mutation.operation_kind === "order" && String(mutation.client_order_id ?? "").trim().toLowerCase() === plan.entryClientOrderId ? { kind: "found", mutation } : { kind: "unavailable" };
99554
+ return mutation.operation_kind === "order" && String(mutation.client_order_id ?? "").trim().toLowerCase() === clientOrderId ? { kind: "found", mutation } : { kind: "unavailable" };
99126
99555
  } catch (error48) {
99127
99556
  if (request.signal?.aborted) throw error48;
99128
99557
  return { kind: "unavailable" };
99129
99558
  }
99130
99559
  };
99560
+ readPendingEntryMutation = (request, plan) => readClientOrderMutation(request, plan.entryMutationId, plan.entryClientOrderId);
99561
+ clientOrderNeverLandsAfterMs = (config2, ledger) => {
99562
+ const marginMs = requireClientRuntimeConfigSeconds(
99563
+ config2,
99564
+ "client_pending_entry_never_landed_margin_seconds"
99565
+ ) * MS_PER_SECOND;
99566
+ if (ledger.kind === "found") return ledger.expiresAfterMs + marginMs;
99567
+ const signedLifetimeSeconds = Number(
99568
+ config2?.client_runtime_exchange_mutation?.expires_after_seconds
99569
+ );
99570
+ if (!Number.isInteger(signedLifetimeSeconds) || signedLifetimeSeconds <= 0) {
99571
+ throw new Error("Missing required client runtime config: client_runtime_exchange_mutation.expires_after_seconds");
99572
+ }
99573
+ return ledger.ageStartMs + signedLifetimeSeconds * MS_PER_SECOND + marginMs;
99574
+ };
99131
99575
  requireClientRuntimeConfigSeconds = (config2, key) => {
99132
99576
  const value = Number(config2?.[key]);
99133
99577
  if (!Number.isFinite(value) || value < 0) {
@@ -99268,10 +99712,6 @@ var init_runtime_execution = __esm({
99268
99712
  });
99269
99713
  if (evidence.responseValid && evidence.responseStatus === "unknownOid") {
99270
99714
  const observedAtMs = Date.now();
99271
- const marginMs = requireClientRuntimeConfigSeconds(
99272
- request.config,
99273
- "client_pending_entry_never_landed_margin_seconds"
99274
- ) * MS_PER_SECOND;
99275
99715
  const firstSeenAtMs = plan.recovery?.unknownOidFirstSeenAtMs ?? observedAtMs;
99276
99716
  const recordFirstSeen = () => {
99277
99717
  if (plan.recovery?.unknownOidFirstSeenAtMs != null) return;
@@ -99286,16 +99726,12 @@ var init_runtime_execution = __esm({
99286
99726
  if (!Number.isSafeInteger(expiresAfterMs) || expiresAfterMs <= 0) {
99287
99727
  throw new Error("Pending entry is unknown to Hyperliquid and its signed expiry is unavailable.");
99288
99728
  }
99289
- provableAtMs = expiresAfterMs + marginMs;
99729
+ provableAtMs = clientOrderNeverLandsAfterMs(request.config, { kind: "found", expiresAfterMs });
99290
99730
  } else if (ledger.kind === "absent") {
99291
- const ageStartMs = plan.createdAtMs ?? firstSeenAtMs;
99292
- const signedLifetimeSeconds = Number(
99293
- request.config?.client_runtime_exchange_mutation?.expires_after_seconds
99294
- );
99295
- if (!Number.isInteger(signedLifetimeSeconds) || signedLifetimeSeconds <= 0) {
99296
- throw new Error("Missing required client runtime config: client_runtime_exchange_mutation.expires_after_seconds");
99297
- }
99298
- provableAtMs = ageStartMs + signedLifetimeSeconds * MS_PER_SECOND + marginMs;
99731
+ provableAtMs = clientOrderNeverLandsAfterMs(request.config, {
99732
+ kind: "absent",
99733
+ ageStartMs: plan.createdAtMs ?? firstSeenAtMs
99734
+ });
99299
99735
  } else {
99300
99736
  recordFirstSeen();
99301
99737
  throw new Error("Pending entry is unknown to Hyperliquid and the ledger cannot answer.");
@@ -100138,37 +100574,16 @@ var init_runtime_execution = __esm({
100138
100574
  }]
100139
100575
  });
100140
100576
  const observedAtMs = Date.now();
100141
- const marginMs = requireClientRuntimeConfigSeconds(
100142
- request.config,
100143
- "client_pending_entry_never_landed_margin_seconds"
100144
- ) * MS_PER_SECOND;
100145
- let ledgerKind;
100146
- let expiresAfterMs = Number.NaN;
100147
- try {
100148
- const mutation = await getClientRuntimeExchangeMutation(request.profileId, journal.mutationId, request.signal);
100149
- if (mutation == null) {
100150
- ledgerKind = "absent";
100151
- } else if (mutation.operation_kind === "order" && String(mutation.client_order_id ?? "").trim().toLowerCase() === String(leg.orderId)) {
100152
- ledgerKind = "found";
100153
- expiresAfterMs = Number(mutation.exchange_expires_after_ms);
100154
- } else {
100155
- ledgerKind = "unavailable";
100156
- }
100157
- } catch (error48) {
100158
- if (request.signal?.aborted) throw error48;
100159
- ledgerKind = "unavailable";
100160
- }
100577
+ const ledger = await readClientOrderMutation(request, journal.mutationId, String(leg.orderId));
100578
+ const expiresAfterMs = ledger.kind === "found" ? Number(ledger.mutation.exchange_expires_after_ms) : Number.NaN;
100161
100579
  let provableAtMs;
100162
- if (ledgerKind === "found" && Number.isSafeInteger(expiresAfterMs) && expiresAfterMs > 0) {
100163
- provableAtMs = expiresAfterMs + marginMs;
100164
- } else if (ledgerKind === "absent") {
100165
- const signedLifetimeSeconds = Number(
100166
- request.config?.client_runtime_exchange_mutation?.expires_after_seconds
100167
- );
100168
- if (!Number.isInteger(signedLifetimeSeconds) || signedLifetimeSeconds <= 0) {
100169
- throw new Error("Missing required client runtime config: client_runtime_exchange_mutation.expires_after_seconds");
100170
- }
100171
- provableAtMs = journal.createdAtMs + signedLifetimeSeconds * MS_PER_SECOND + marginMs;
100580
+ if (ledger.kind === "found" && Number.isSafeInteger(expiresAfterMs) && expiresAfterMs > 0) {
100581
+ provableAtMs = clientOrderNeverLandsAfterMs(request.config, { kind: "found", expiresAfterMs });
100582
+ } else if (ledger.kind === "absent") {
100583
+ provableAtMs = clientOrderNeverLandsAfterMs(request.config, {
100584
+ kind: "absent",
100585
+ ageStartMs: journal.createdAtMs
100586
+ });
100172
100587
  } else {
100173
100588
  return waiting("protective_stop_replacement_unresolved", "The stop re-place ledger cannot answer yet.");
100174
100589
  }
@@ -101643,7 +102058,64 @@ var init_runtime_execution = __esm({
101643
102058
  const parsed = Number(position?.size ?? 0);
101644
102059
  return Number.isFinite(parsed) ? parsed : 0;
101645
102060
  };
101646
- resolveCurrentPositionSize = async (input) => {
102061
+ readServerOrderMarkPrice = async (input) => {
102062
+ const symbol2 = normalizeHyperliquidMarketSymbol(input.executionContext.symbol);
102063
+ const active = await fetchBrowserHyperliquidInfoPayload(
102064
+ { config: input.config ?? null, signal: input.signal, publicRequestPriority: executionReadPriority(input) },
102065
+ { type: "activeAssetData", user: String(input.executionContext.walletAddress || "").trim(), coin: symbol2 },
102066
+ "hyperliquid.activeAssetData"
102067
+ );
102068
+ const markPrice = Number(active?.markPx);
102069
+ if (!Number.isFinite(markPrice) || !(markPrice > 0)) {
102070
+ throw new Error(`Missing Hyperliquid mark price for ${input.executionContext.symbol}.`);
102071
+ }
102072
+ return markPrice;
102073
+ };
102074
+ serverOrderMetadataRetry = async (input, rejection, leg, rejectedMutationId) => {
102075
+ const decisionSnapshotId = String(input.executionContext.decisionSnapshotId ?? "").trim();
102076
+ if (input.executionMode !== "server" || !decisionSnapshotId || !isDefinitiveEntryRejection(rejection, rejectedMutationId)) return null;
102077
+ const reason = orderMetadataRetryReason(rejection.message);
102078
+ if (reason === null) return null;
102079
+ throwIfAborted2(input.signal);
102080
+ try {
102081
+ const asset = await resolveHyperliquidAsset({
102082
+ symbol: input.executionContext.symbol,
102083
+ config: input.config ?? void 0,
102084
+ publicRequestPriority: executionReadPriority(input),
102085
+ refreshCatalog: true
102086
+ });
102087
+ if (!Number.isInteger(asset.sz_decimals) || asset.sz_decimals < 0) return null;
102088
+ const markPrice = reason === "reference_price" ? await readServerOrderMarkPrice(input) : null;
102089
+ appendRuntimeDebugEvent({
102090
+ label: "execution_order_metadata_retry",
102091
+ note: `symbol=${input.executionContext.symbol} leg=${leg} reason=${reason}`
102092
+ });
102093
+ return {
102094
+ mutationId: await clientDecisionMutationId({
102095
+ profileId: input.profileId,
102096
+ decisionSnapshotId,
102097
+ symbol: input.executionContext.symbol,
102098
+ leg,
102099
+ attempt: 1
102100
+ }),
102101
+ assets: [{
102102
+ symbol: input.executionContext.symbol,
102103
+ asset_id: asset.asset_index,
102104
+ asset_index: asset.asset_index,
102105
+ max_leverage: asset.max_leverage,
102106
+ sz_decimals: asset.sz_decimals,
102107
+ margin_mode: asset.margin_mode ?? null,
102108
+ only_isolated: asset.only_isolated === true
102109
+ }],
102110
+ sizeDecimals: asset.sz_decimals,
102111
+ markPrice
102112
+ };
102113
+ } catch {
102114
+ throwIfAborted2(input.signal);
102115
+ return null;
102116
+ }
102117
+ };
102118
+ resolveCurrentPositionSize = async (input, orderPrice = "decision") => {
101647
102119
  throwIfAborted2(input.signal);
101648
102120
  const snapshotPositionSize = Number.isFinite(input.executionContext.currentPositionSize) ? Number(input.executionContext.currentPositionSize) : 0;
101649
102121
  const decisionPrice = Number.isFinite(input.executionContext.lastPrice) ? Number(input.executionContext.lastPrice) : 0;
@@ -101655,7 +102127,7 @@ var init_runtime_execution = __esm({
101655
102127
  const decisionCapturedAtMs = Date.parse(String(input.executionContext.decisionSnapshotCapturedAt || ""));
101656
102128
  const maxAgeSeconds = Number(input.executionContext.executionFreshnessMaxAgeSeconds);
101657
102129
  const shouldRefreshExecutionSnapshot = Number.isFinite(decisionCapturedAtMs) && Number.isFinite(maxAgeSeconds) && maxAgeSeconds > 0 && (nowMs2 - decisionCapturedAtMs) / MS_PER_SECOND > maxAgeSeconds;
101658
- if (shouldRefreshExecutionSnapshot) {
102130
+ if (shouldRefreshExecutionSnapshot && orderPrice !== "fresh_mark") {
101659
102131
  try {
101660
102132
  const refreshed = await fetchBrowserAccountState2({
101661
102133
  publicRequestPriority: executionReadPriority(input),
@@ -101698,10 +102170,12 @@ var init_runtime_execution = __esm({
101698
102170
  symbol: input.executionContext.symbol,
101699
102171
  size: liveBrowserSnapshot.size
101700
102172
  });
102173
+ const liveMarkPrice = Number(liveBrowserSnapshot.markPrice);
102174
+ const executionPrice = orderPrice !== "fresh_mark" ? decisionPrice : parsedLiveSize !== 0 && Number.isFinite(liveMarkPrice) && liveMarkPrice > 0 ? liveMarkPrice : await readServerOrderMarkPrice(input);
101701
102175
  return {
101702
102176
  currentPositionSize: Number.isFinite(parsedLiveSize) ? parsedLiveSize : snapshotPositionSize,
101703
102177
  currentPositionEntryPrice: liveBrowserSnapshot.entryPrice,
101704
- executionPrice: decisionPrice,
102178
+ executionPrice,
101705
102179
  executionSnapshotId: createRuntimeId(),
101706
102180
  executionSnapshotCapturedAt: (/* @__PURE__ */ new Date()).toISOString()
101707
102181
  };
@@ -101905,6 +102379,27 @@ var init_runtime_execution = __esm({
101905
102379
  throw withCommittedExecutionReports(error48, progress.committedReports);
101906
102380
  }
101907
102381
  });
102382
+ unsentDecisionOrderReport = (input, reasonCode, metadata = {}) => ({
102383
+ order_id: null,
102384
+ symbol: input.executionContext.symbol,
102385
+ action: String(input.decision).toUpperCase(),
102386
+ status: "blocked",
102387
+ execution_metadata: {
102388
+ reason_code: reasonCode,
102389
+ ...metadata,
102390
+ ...input.cycleId ? { cycle_id: input.cycleId } : {},
102391
+ ...input.executionContext.decisionSnapshotId ? { decision_snapshot_id: input.executionContext.decisionSnapshotId } : {}
102392
+ }
102393
+ });
102394
+ withCapacityTrim = (result, trim) => {
102395
+ const decisionOrders = result.executionReports.filter((report) => report.status === "executed" && (report.action === "BUY" || report.action === "SELL") && (result.intent !== "flip" || report.execution_metadata?.decision_leg === "entry"));
102396
+ const trimmed = decisionOrders[decisionOrders.length - 1];
102397
+ if (!trimmed) return result;
102398
+ return {
102399
+ ...result,
102400
+ executionReports: result.executionReports.map((report) => report === trimmed ? { ...report, execution_metadata: { ...report.execution_metadata, ...trim } } : report)
102401
+ };
102402
+ };
101908
102403
  SERVER_AUDIT_RECORDED_ELSEWHERE = /* @__PURE__ */ new Set([
101909
102404
  "suppressed_duplicate_decision",
101910
102405
  "same_intent_cooldown",
@@ -101918,7 +102413,7 @@ var init_runtime_execution = __esm({
101918
102413
  return ["executed", "executed"];
101919
102414
  }
101920
102415
  if (result.status === "skipped") {
101921
- if (result.reasonCode === "noop_already_at_target" || result.reasonCode === "stale_target_conflict") {
102416
+ if (result.reasonCode === "noop_already_at_target" || result.reasonCode === "stale_target_conflict" || result.reasonCode === "order_below_lot_size") {
101922
102417
  return ["noop", result.reasonCode];
101923
102418
  }
101924
102419
  if (result.reasonCode === "protective_reconciliation_unresolved") return ["blocked", result.reasonCode];
@@ -102038,7 +102533,7 @@ var init_runtime_execution = __esm({
102038
102533
  reasonCode: blockedByProtection ? "protective_reconciliation_unresolved" : "executed",
102039
102534
  orderId: flipClose.order_id == null ? null : String(flipClose.order_id)
102040
102535
  });
102041
- const [entryStatus, entryReason] = entryReport ? ["executed", "executed"] : blockedByProtection ? ["blocked", "protective_reconciliation_unresolved"] : result.reasonCode === "noop_already_at_target" ? ["noop", "noop_already_at_target"] : ["blocked", "local_safety_block"];
102536
+ const [entryStatus, entryReason] = entryReport ? ["executed", "executed"] : blockedByProtection ? ["blocked", "protective_reconciliation_unresolved"] : result.reasonCode === "noop_already_at_target" || result.reasonCode === "order_below_lot_size" ? ["noop", result.reasonCode] : ["blocked", "local_safety_block"];
102042
102537
  const entryAuditId = await recordAudit(null, {
102043
102538
  ...auditFields,
102044
102539
  status: entryStatus,
@@ -102499,7 +102994,7 @@ var init_runtime_execution = __esm({
102499
102994
  };
102500
102995
  }
102501
102996
  if (unsizedInput.executionMode === "server" && !unsizedInput.serverCapacityChecked && (unsizedInput.decision === "BUY" || unsizedInput.decision === "SELL") && requestedUnits > 0) {
102502
- const skipped = (reasonCode, message) => ({
102997
+ const skipped = (reasonCode, constraintReasonCode) => ({
102503
102998
  status: "skipped",
102504
102999
  intent: "hold",
102505
103000
  side: null,
@@ -102507,8 +103002,13 @@ var init_runtime_execution = __esm({
102507
103002
  requestedUnits,
102508
103003
  targetSignedUnits: 0,
102509
103004
  executedSizeAsset: 0,
102510
- executionReports: [],
102511
- message,
103005
+ // The decision keeps its order; this record says it was not placed and
103006
+ // which limit refused it.
103007
+ executionReports: [unsentDecisionOrderReport(unsizedInput, reasonCode, {
103008
+ constraint_reason_code: constraintReasonCode,
103009
+ requested_units: requestedUnits
103010
+ })],
103011
+ message: `Skipped: runtime constraint ${constraintReasonCode}.`,
102512
103012
  reasonCode,
102513
103013
  executionSnapshotId: createRuntimeId(),
102514
103014
  executionSnapshotCapturedAt: (/* @__PURE__ */ new Date()).toISOString()
@@ -102526,13 +103026,19 @@ var init_runtime_execution = __esm({
102526
103026
  note: `symbol=${unsizedInput.executionContext.symbol} reason=${capacity.reason_code ?? "unknown"}`,
102527
103027
  outcome: "ok"
102528
103028
  });
102529
- return skipped("execution_capacity_refused", `Skipped: runtime constraint ${capacity.reason_code ?? "capacity"}.`);
103029
+ return skipped("execution_capacity_refused", capacity.reason_code ?? "capacity_reached");
102530
103030
  }
102531
- return executeClientRuntimeDecisionUnlocked({
103031
+ const acceptedUnits = Math.min(requestedUnits, Math.trunc(capacity.units));
103032
+ const result = await executeClientRuntimeDecisionUnlocked({
102532
103033
  ...unsizedInput,
102533
- units: Math.min(requestedUnits, Math.trunc(capacity.units)),
103034
+ units: acceptedUnits,
102534
103035
  serverCapacityChecked: true
102535
103036
  }, progress);
103037
+ return acceptedUnits < requestedUnits ? withCapacityTrim(result, {
103038
+ requested_units: requestedUnits,
103039
+ accepted_units: acceptedUnits,
103040
+ constraint_reason_code: capacity.reason_code ?? "units_capped"
103041
+ }) : result;
102536
103042
  }
102537
103043
  const input = {
102538
103044
  ...unsizedInput,
@@ -102624,13 +103130,15 @@ var init_runtime_execution = __esm({
102624
103130
  executionSnapshotCapturedAt: (/* @__PURE__ */ new Date()).toISOString()
102625
103131
  };
102626
103132
  }
103133
+ const serverOrder = input.executionMode === "server";
102627
103134
  const {
102628
103135
  currentPositionSize,
102629
103136
  currentPositionEntryPrice,
102630
- executionPrice,
103137
+ executionPrice: resolvedExecutionPrice,
102631
103138
  executionSnapshotId,
102632
103139
  executionSnapshotCapturedAt
102633
- } = await resolveCurrentPositionSize(input);
103140
+ } = await resolveCurrentPositionSize(input, serverOrder ? "fresh_mark" : "decision");
103141
+ let executionPrice = resolvedExecutionPrice;
102634
103142
  throwIfAborted2(input.signal);
102635
103143
  const currentPosition = buildPositionSnapshot(input.executionContext.symbol, currentPositionSize);
102636
103144
  const decisionSnapshotId = String(input.executionContext.decisionSnapshotId ?? "").trim();
@@ -102641,6 +103149,15 @@ var init_runtime_execution = __esm({
102641
103149
  leg,
102642
103150
  attempt: 0
102643
103151
  }) : Promise.resolve(void 0);
103152
+ const closeWithServerMetadataRetry = async (leg, mutationId, send) => {
103153
+ try {
103154
+ return await send(mutationId, executionPrice);
103155
+ } catch (rejection) {
103156
+ const retry = await serverOrderMetadataRetry(input, rejection, leg, mutationId);
103157
+ if (retry === null) throw rejection;
103158
+ return send(retry.mutationId, retry.markPrice ?? executionPrice, retry.assets);
103159
+ }
103160
+ };
102644
103161
  const liveSignedUnits = signedUnitsFromEntryPosition(
102645
103162
  currentPositionSize,
102646
103163
  currentPositionEntryPrice,
@@ -102691,7 +103208,12 @@ var init_runtime_execution = __esm({
102691
103208
  requestedUnits: classified.requestedUnits,
102692
103209
  targetSignedUnits: classified.targetSignedUnits,
102693
103210
  executedSizeAsset: 0,
102694
- executionReports: reconciliationReports,
103211
+ // A Server bot's skip is its execution audit row; a Client bot's is this record.
103212
+ executionReports: input.executionMode === "server" ? reconciliationReports : [...reconciliationReports, unsentDecisionOrderReport(
103213
+ input,
103214
+ staleTargetConflict ? "stale_target_conflict" : "noop_already_at_target",
103215
+ { intent: classified.intent }
103216
+ )],
102695
103217
  message: staleTargetConflict ? "Live state moved beyond the requested target; skipping stale decision" : "No-op: live position already matches target state",
102696
103218
  reasonCode: staleTargetConflict ? "stale_target_conflict" : "noop_already_at_target",
102697
103219
  executionSnapshotId,
@@ -102827,8 +103349,9 @@ var init_runtime_execution = __esm({
102827
103349
  if (classified.intent === "close") {
102828
103350
  throwIfAborted2(input.signal);
102829
103351
  const closeMutationId = await decisionLegMutationId("close");
102830
- const closeResponse = await executeClientClosePosition({
102831
- mutationId: closeMutationId,
103352
+ const closeResponse = await closeWithServerMetadataRetry("close", closeMutationId, (mutationId, estimatedPrice, assets) => executeClientClosePosition({
103353
+ mutationId,
103354
+ ...assets ? { assets } : {},
102832
103355
  profileId: input.profileId,
102833
103356
  runtimeSessionId: input.sessionId || "__missing_runtime_session__",
102834
103357
  runtimeLeaseToken: input.runtimeLeaseToken,
@@ -102841,9 +103364,9 @@ var init_runtime_execution = __esm({
102841
103364
  onExchangeOrderDispatched: () => input.onExchangeOrderDispatched?.("action"),
102842
103365
  symbol: input.executionContext.symbol,
102843
103366
  position: currentPosition,
102844
- estimatedPrice: executionPrice,
103367
+ estimatedPrice,
102845
103368
  slippage: input.executionContext.maxSlippageFraction
102846
- });
103369
+ }));
102847
103370
  const confirmedClose = extractCanonicalHyperliquidFilledOrderAcknowledgement(
102848
103371
  closeResponse
102849
103372
  );
@@ -102902,8 +103425,9 @@ var init_runtime_execution = __esm({
102902
103425
  if (targetResolution.closeOpposingPosition) {
102903
103426
  throwIfAborted2(input.signal);
102904
103427
  const flipCloseMutationId = await decisionLegMutationId("flip_close");
102905
- const closeResponse = await executeClientClosePosition({
102906
- mutationId: flipCloseMutationId,
103428
+ const closeResponse = await closeWithServerMetadataRetry("flip_close", flipCloseMutationId, (mutationId, estimatedPrice, assets) => executeClientClosePosition({
103429
+ mutationId,
103430
+ ...assets ? { assets } : {},
102907
103431
  profileId: input.profileId,
102908
103432
  runtimeSessionId: input.sessionId || "__missing_runtime_session__",
102909
103433
  runtimeLeaseToken: input.runtimeLeaseToken,
@@ -102916,9 +103440,9 @@ var init_runtime_execution = __esm({
102916
103440
  onExchangeOrderDispatched: () => input.onExchangeOrderDispatched?.("action"),
102917
103441
  symbol: input.executionContext.symbol,
102918
103442
  position: currentPosition,
102919
- estimatedPrice: executionPrice,
103443
+ estimatedPrice,
102920
103444
  slippage: input.executionContext.maxSlippageFraction
102921
- });
103445
+ }));
102922
103446
  const confirmedFlipClose = extractCanonicalHyperliquidFilledOrderAcknowledgement(
102923
103447
  closeResponse
102924
103448
  );
@@ -103037,6 +103561,7 @@ var init_runtime_execution = __esm({
103037
103561
  isCross: input.executionContext.marginMode !== "isolated"
103038
103562
  });
103039
103563
  throwIfAborted2(input.signal);
103564
+ if (serverOrder) executionPrice = await readServerOrderMarkPrice(input);
103040
103565
  }
103041
103566
  const actualUnits = targetResolution.orderUnits;
103042
103567
  const intendedSizeAsset = decisionOrderSizeAsset({
@@ -103047,7 +103572,7 @@ var init_runtime_execution = __esm({
103047
103572
  entryPrice: currentPositionEntryPrice,
103048
103573
  livePositionSize: currentPositionSize
103049
103574
  });
103050
- const sizeAsset = Number.isFinite(intendedSizeAsset) && intendedSizeAsset > 0 ? quantizeHyperliquidOrderSizeValue(intendedSizeAsset, input.executionContext.sizeDecimals, "nearest") : 0;
103575
+ let sizeAsset = Number.isFinite(intendedSizeAsset) && intendedSizeAsset > 0 ? quantizeHyperliquidOrderSizeValue(intendedSizeAsset, input.executionContext.sizeDecimals, "nearest") : 0;
103051
103576
  appendRuntimeDebugEvent({
103052
103577
  label: "execution_size_computed",
103053
103578
  note: `symbol=${input.executionContext.symbol} actualUnits=${actualUnits} sizeAsset=${sizeAsset} price=${executionPrice}`
@@ -103055,7 +103580,7 @@ var init_runtime_execution = __esm({
103055
103580
  if (sizeAsset <= 0) {
103056
103581
  appendRuntimeDebugEvent({
103057
103582
  label: "execution_skipped_zero_size",
103058
- note: `reason=size_below_lot_precision actualUnits=${actualUnits} unitSize=${input.executionContext.unitSizeUsdc} intendedSize=${intendedSizeAsset} decimals=${input.executionContext.sizeDecimals}`,
103583
+ note: `reason=order_below_lot_size actualUnits=${actualUnits} unitSize=${input.executionContext.unitSizeUsdc} intendedSize=${intendedSizeAsset} decimals=${input.executionContext.sizeDecimals}`,
103059
103584
  outcome: "error"
103060
103585
  });
103061
103586
  return {
@@ -103067,13 +103592,27 @@ var init_runtime_execution = __esm({
103067
103592
  requestedUnits: classified.requestedUnits,
103068
103593
  targetSignedUnits: classified.targetSignedUnits,
103069
103594
  executedSizeAsset: 0,
103070
- executionReports,
103595
+ // Too small to place is not "already at target": it has its own reason,
103596
+ // on a Server bot's audit row and on a Client bot's record.
103597
+ executionReports: input.executionMode === "server" ? executionReports : [...executionReports, unsentDecisionOrderReport(input, "order_below_lot_size", { intent: classified.intent })],
103071
103598
  message: "Skipped: calculated size is zero",
103072
- reasonCode: "noop_already_at_target",
103599
+ reasonCode: "order_below_lot_size",
103073
103600
  executionSnapshotId,
103074
103601
  executionSnapshotCapturedAt
103075
103602
  };
103076
103603
  }
103604
+ if (input.executionMode === "server") {
103605
+ const ceilingRefusal = orderCeilingRefusal({
103606
+ side: classified.side,
103607
+ size: sizeAsset,
103608
+ price: executionPrice,
103609
+ // A flip's close has filled by now: its new position starts from flat.
103610
+ currentPositionSize: targetResolution.closeOpposingPosition ? 0 : currentPositionSize,
103611
+ maxOrderNotional: runtime_policy_generated_default2.trading.risk.max_order_notional,
103612
+ maxPositionNotional: runtime_policy_generated_default2.trading.risk.max_position_notional
103613
+ });
103614
+ if (ceilingRefusal !== null) throw new Error(`Order rejected by risk manager: ${ceilingRefusal}`);
103615
+ }
103077
103616
  const entryRequiresFlatAbsenceProof = Number.isFinite(currentPositionSize) && currentPositionSize === 0 || targetResolution.closeOpposingPosition;
103078
103617
  if (entryRequiresFlatAbsenceProof) {
103079
103618
  const finalProtectionObservation = await verifyNoLiveClientProtectiveTriggers(
@@ -103201,53 +103740,70 @@ var init_runtime_execution = __esm({
103201
103740
  let marketOrderResponse;
103202
103741
  let entryDispatchBoundaryPassed = false;
103203
103742
  let settledServerProtectedEntry = null;
103204
- try {
103205
- marketOrderResponse = await executeClientMarketOrder({
103206
- profileId: input.profileId,
103207
- runtimeSessionId: input.sessionId || "__missing_runtime_session__",
103208
- runtimeLeaseToken: input.runtimeLeaseToken,
103209
- runtimeDeviceId: input.runtimeDeviceId,
103210
- schedulerInstanceId: input.schedulerInstanceId,
103211
- walletAddress: input.executionContext.walletAddress,
103212
- config: input.config ?? null,
103213
- signal: input.signal,
103214
- signingKey: input.signingKey,
103215
- onExchangeOrderDispatched: () => {
103216
- if (persistedProtectiveGroupSet != null && pendingProtectiveCleanup != null && !replaceExactClientProtectiveGroupSet(
103217
- pendingProtectiveCleanup.profileId,
103218
- pendingProtectiveCleanup.symbol,
103219
- persistedProtectiveGroupSet,
103220
- persistedProtectiveGroupSet
103221
- )) {
103222
- throw createClientRuntimeWindowHandoffBeforePlanDispatchError(
103223
- pendingProtectiveCleanup
103224
- );
103225
- }
103226
- input.onExchangeOrderDispatched?.(
103227
- classified.intent === "open" || classified.intent === "add" || classified.intent === "flip" ? "entry" : "action"
103743
+ const entrySide = classified.side;
103744
+ let entryAssets;
103745
+ const sendEntry = () => executeClientMarketOrder({
103746
+ ...entryAssets ? { assets: entryAssets } : {},
103747
+ profileId: input.profileId,
103748
+ runtimeSessionId: input.sessionId || "__missing_runtime_session__",
103749
+ runtimeLeaseToken: input.runtimeLeaseToken,
103750
+ runtimeDeviceId: input.runtimeDeviceId,
103751
+ schedulerInstanceId: input.schedulerInstanceId,
103752
+ walletAddress: input.executionContext.walletAddress,
103753
+ config: input.config ?? null,
103754
+ signal: input.signal,
103755
+ signingKey: input.signingKey,
103756
+ onExchangeOrderDispatched: () => {
103757
+ if (persistedProtectiveGroupSet != null && pendingProtectiveCleanup != null && !replaceExactClientProtectiveGroupSet(
103758
+ pendingProtectiveCleanup.profileId,
103759
+ pendingProtectiveCleanup.symbol,
103760
+ persistedProtectiveGroupSet,
103761
+ persistedProtectiveGroupSet
103762
+ )) {
103763
+ throw createClientRuntimeWindowHandoffBeforePlanDispatchError(
103764
+ pendingProtectiveCleanup
103228
103765
  );
103229
- entryDispatchBoundaryPassed = true;
103766
+ }
103767
+ input.onExchangeOrderDispatched?.(
103768
+ classified.intent === "open" || classified.intent === "add" || classified.intent === "flip" ? "entry" : "action"
103769
+ );
103770
+ entryDispatchBoundaryPassed = true;
103771
+ },
103772
+ symbol: input.executionContext.symbol,
103773
+ side: entrySide,
103774
+ size: sizeAsset,
103775
+ estimatedPrice: executionPrice,
103776
+ slippage: input.executionContext.maxSlippageFraction,
103777
+ reduceOnly: classified.reduceOnly,
103778
+ mutationId: entryMutationId,
103779
+ clientOrderId: entryClientOrderId,
103780
+ ...serverOwnedProtection ? {
103781
+ // The server attaches the configured Auto SL/TP to this entry.
103782
+ protection: {
103783
+ source: "runtime_config",
103784
+ requested_entry_size: sizeAsset,
103785
+ is_long: entrySide === "buy"
103230
103786
  },
103231
- symbol: input.executionContext.symbol,
103232
- side: classified.side,
103233
- size: sizeAsset,
103234
- estimatedPrice: executionPrice,
103235
- slippage: input.executionContext.maxSlippageFraction,
103236
- reduceOnly: classified.reduceOnly,
103237
- mutationId: entryMutationId,
103238
- clientOrderId: entryClientOrderId,
103239
- ...serverOwnedProtection ? {
103240
- // The server attaches the configured Auto SL/TP to this entry.
103241
- protection: {
103242
- source: "runtime_config",
103243
- requested_entry_size: sizeAsset,
103244
- is_long: classified.side === "buy"
103245
- },
103246
- onSettled: (mutation) => {
103247
- settledServerProtectedEntry = mutation;
103248
- }
103249
- } : {}
103250
- });
103787
+ onSettled: (mutation) => {
103788
+ settledServerProtectedEntry = mutation;
103789
+ }
103790
+ } : {}
103791
+ });
103792
+ try {
103793
+ try {
103794
+ marketOrderResponse = await sendEntry();
103795
+ } catch (rejection) {
103796
+ const retry = await serverOrderMetadataRetry(input, rejection, "entry", entryMutationId);
103797
+ const retrySize = retry === null ? 0 : quantizeHyperliquidOrderSizeValue(intendedSizeAsset, retry.sizeDecimals, "nearest");
103798
+ if (retry === null || !(retrySize > 0)) throw rejection;
103799
+ sizeAsset = retrySize;
103800
+ entryAssets = retry.assets;
103801
+ executionPrice = retry.markPrice ?? executionPrice;
103802
+ entryMutationId = retry.mutationId;
103803
+ entryClientOrderId = clientOrderIdForMutation(retry.mutationId);
103804
+ entryDispatchBoundaryPassed = false;
103805
+ marketOrderResponse = await sendEntry();
103806
+ }
103251
103807
  } catch (entryDispatchError) {
103252
103808
  const handoffVeto = isClientRuntimeWindowHandoffBeforePlanDispatch(entryDispatchError);
103253
103809
  const handoffBeforeDispatch = handoffVeto || !entryDispatchBoundaryPassed && input.shouldCancelBeforeExchangeOrderDispatch?.() === true;
@@ -103471,10 +104027,11 @@ var init_runtime_execution = __esm({
103471
104027
  const kind = triggerInput.isTakeProfit ? "tp" : "sl";
103472
104028
  const alreadyProtected = (liveDirectionMatches ? (await storedClientProtectiveCover(
103473
104029
  input,
104030
+ isLong,
103474
104031
  readClientProtectiveGroups(
103475
104032
  String(input.profileId).trim(),
103476
104033
  input.executionContext.symbol
103477
- ).flatMap((group) => group.legs)
104034
+ )
103478
104035
  ))[kind] : 0) + activeLegs.filter((leg2) => leg2.kind === kind).reduce((total, leg2) => total + leg2.size, 0);
103479
104036
  const liveExposure = Math.abs(livePositionSize);
103480
104037
  const availableExposure = Math.max(0, liveExposure - alreadyProtected);
@@ -104643,6 +105200,7 @@ var init_provider_observability = __esm({
104643
105200
  }
104644
105201
  if (typeof raw.credential_ref === "string" && /^[a-f0-9]{64}$/.test(raw.credential_ref)) result.credential_ref = raw.credential_ref;
104645
105202
  if (raw.execution_mode === "client" || raw.execution_mode === "server") result.execution_mode = raw.execution_mode;
105203
+ if (raw.timeout_bound === "attempt_cap") result.timeout_bound = "attempt_cap";
104646
105204
  if (typeof raw.quota_project_ref === "string" && /^[a-f0-9]{64}$/.test(raw.quota_project_ref) && raw.quota_project_source === "provider_quota_subject") {
104647
105205
  result.quota_project_ref = raw.quota_project_ref;
104648
105206
  result.quota_project_source = "provider_quota_subject";
@@ -107468,7 +108026,7 @@ var init_client_runtime_status_store = __esm({
107468
108026
  });
107469
108027
 
107470
108028
  // lib/runtime/perp-dex-scope.ts
107471
- var perpDexScopeForSymbols, equityVenuesForSymbols, profileEquityVenues, positionsOnVenues;
108029
+ var perpDexScopeForSymbols, equityVenuesForSymbols, profileEquityVenues, profileExchanges, positionsOnVenues;
107472
108030
  var init_perp_dex_scope = __esm({
107473
108031
  "lib/runtime/perp-dex-scope.ts"() {
107474
108032
  "use strict";
@@ -107497,6 +108055,14 @@ var init_perp_dex_scope = __esm({
107497
108055
  profileEquityVenues = (tradingSymbols, defaultTradingSymbols) => equityVenuesForSymbols(
107498
108056
  Array.isArray(tradingSymbols) && tradingSymbols.length > 0 ? tradingSymbols : defaultTradingSymbols ?? []
107499
108057
  );
108058
+ profileExchanges = (exchanges, tradingSymbols, defaultTradingSymbols, configuredDexes) => {
108059
+ if (Array.isArray(exchanges) && exchanges.length > 0) {
108060
+ const configured2 = /* @__PURE__ */ new Set(["", ...(configuredDexes ?? []).map((dex) => String(dex).trim().toLowerCase())]);
108061
+ const names2 = exchanges.map((exchange) => typeof exchange === "string" ? exchange.trim().toLowerCase() : null);
108062
+ if (names2.every((name) => name !== null && configured2.has(name))) return [...new Set(names2)].sort();
108063
+ }
108064
+ return profileEquityVenues(tradingSymbols, defaultTradingSymbols);
108065
+ };
107500
108066
  positionsOnVenues = (positions, venues) => venues ? positions.filter((position) => normalizeHyperliquidMarketSymbol(position.symbol) && venues.includes(getHyperliquidMarketDex(position.symbol))) : [...positions];
107501
108067
  }
107502
108068
  });
@@ -107567,6 +108133,12 @@ var init_client_killswitch = __esm({
107567
108133
  const symbol2 = firstConfiguredSymbol(settings, input.config);
107568
108134
  const leverage = toPositiveFinite2(settings.leverage) ?? 1;
107569
108135
  const equityVenues = profileEquityVenues(settings.trading_symbols, input.config.default_trading_symbols);
108136
+ const closeVenues = profileExchanges(
108137
+ settings.exchanges,
108138
+ settings.trading_symbols,
108139
+ input.config.default_trading_symbols,
108140
+ input.config.client_runtime_hyperliquid_perp_dexs?.allowed_dexes
108141
+ );
107570
108142
  const accountState = await fetchBrowserAccountState2({
107571
108143
  publicRequestPriority: "trading_reduce",
107572
108144
  config: input.config,
@@ -107609,7 +108181,8 @@ var init_client_killswitch = __esm({
107609
108181
  accountState,
107610
108182
  walletAddress,
107611
108183
  symbol: symbol2,
107612
- equityVenues
108184
+ equityVenues,
108185
+ closeVenues
107613
108186
  };
107614
108187
  }
107615
108188
  if (!context.snapshot_trusted || context.status === "untrusted") {
@@ -107621,7 +108194,8 @@ var init_client_killswitch = __esm({
107621
108194
  accountState,
107622
108195
  walletAddress,
107623
108196
  symbol: symbol2,
107624
- equityVenues
108197
+ equityVenues,
108198
+ closeVenues
107625
108199
  };
107626
108200
  }
107627
108201
  const peakEquity = toPositiveFinite2(context.peak_equity);
@@ -107634,7 +108208,8 @@ var init_client_killswitch = __esm({
107634
108208
  accountState,
107635
108209
  walletAddress,
107636
108210
  symbol: symbol2,
107637
- equityVenues
108211
+ equityVenues,
108212
+ closeVenues
107638
108213
  };
107639
108214
  }
107640
108215
  const drawdownPercent = calculateClientKillswitchDrawdownPercent(
@@ -107650,7 +108225,8 @@ var init_client_killswitch = __esm({
107650
108225
  accountState,
107651
108226
  walletAddress,
107652
108227
  symbol: symbol2,
107653
- equityVenues
108228
+ equityVenues,
108229
+ closeVenues
107654
108230
  };
107655
108231
  };
107656
108232
  closeClientKillswitchPositions = async (input) => {
@@ -109446,8 +110022,14 @@ var init_native_provider_budget = __esm({
109446
110022
  init_define_VTX_GROK_POLICY();
109447
110023
  init_define_VTX_PI_MODEL_POLICY();
109448
110024
  NativeModelTimeoutError = class extends Error {
109449
- constructor() {
110025
+ /**
110026
+ * attemptCapExpired: one Google egress attempt ran out its per-attempt cap
110027
+ * while the model's own budget had time left, which the Server loop reads
110028
+ * as an unreachable route (google_runtime_transport), not as a timeout.
110029
+ */
110030
+ constructor(attemptCapExpired = false) {
109450
110031
  super("Native model request timed out.");
110032
+ this.attemptCapExpired = attemptCapExpired;
109451
110033
  this.runtimeNativeFailureKind = "timeout";
109452
110034
  this.name = "NativeModelTimeoutError";
109453
110035
  }
@@ -109819,7 +110401,10 @@ var init_provider_client = __esm({
109819
110401
  }
109820
110402
  sanitizedError.runtimeProviderStatusCode = response?.status ?? null;
109821
110403
  sanitizedError.runtimeProviderRequestId = providerRequestId(response);
109822
- sanitizedError.runtimeProviderDiagnostics = marker?.providerDiagnostics ?? {};
110404
+ sanitizedError.runtimeProviderDiagnostics = {
110405
+ ...marker?.providerDiagnostics ?? {},
110406
+ ...error48 instanceof NativeModelTimeoutError && error48.attemptCapExpired ? { timeout_bound: "attempt_cap" } : {}
110407
+ };
109823
110408
  if (marker?.googleQuotaFailure) sanitizedError.runtimeGoogleQuotaFailure = true;
109824
110409
  sanitizedError.runtimeRequestInputTokens = marker?.requestInputTokens ?? null;
109825
110410
  if (marker) {
@@ -112095,7 +112680,8 @@ var init_provider_client = __esm({
112095
112680
  if (egress && (timeoutMs <= 0 || !googleEgressHasBudget(egress))) throw new NativeModelTimeoutError();
112096
112681
  signal?.addEventListener("abort", cancelAttempt, { once: true });
112097
112682
  if (signal?.aborted) cancelAttempt();
112098
- const attemptTimer = attemptController ? setTimeout(() => attemptController.abort(new NativeModelTimeoutError()), timeoutMs) : void 0;
112683
+ const capBound = Boolean(egress && egress.policy.attempt_timeout_seconds * MS_PER_SECOND < egress.deadline - Date.now());
112684
+ const attemptTimer = attemptController ? setTimeout(() => attemptController.abort(new NativeModelTimeoutError(capBound)), timeoutMs) : void 0;
112099
112685
  try {
112100
112686
  response = await callGoogle(
112101
112687
  remoteApiKey,
@@ -113940,6 +114526,7 @@ __export(local_analysis_exports, {
113940
114526
  ClientRuntimeAgentInstructionEmpty: () => ClientRuntimeAgentInstructionEmpty,
113941
114527
  ClientRuntimeAiSchedulePaused: () => ClientRuntimeAiSchedulePaused,
113942
114528
  ClientRuntimeAiScheduleStillActive: () => ClientRuntimeAiScheduleStillActive,
114529
+ SERVER_UNREADABLE_REPLY_HOLD_REASONING: () => SERVER_UNREADABLE_REPLY_HOLD_REASONING,
113943
114530
  ServerDispatchAccountStateStale: () => ServerDispatchAccountStateStale,
113944
114531
  aiOrderSlippageFraction: () => aiOrderSlippageFraction,
113945
114532
  buildLocalRuntimePromptArtifacts: () => buildLocalRuntimePromptArtifacts,
@@ -113960,7 +114547,7 @@ __export(local_analysis_exports, {
113960
114547
  runLocalRuntimeCycle: () => runLocalRuntimeCycle,
113961
114548
  summarizeReviewFailureExplanation: () => summarizeReviewFailureExplanation
113962
114549
  });
113963
- var CYCLE_TIMEOUT_FLOOR_MS, DECISION_SETTLEMENT_RESERVE_MAX_BUDGET_DIVISOR, MIN_AGENT_INSTRUCTION_RETRY_AFTER_MS, PROMPT_PARITY_ERROR_DETAIL_MAX_CHARS, EXTERNAL_INFERENCE_RUNTIME_POLL_INTERVAL_MS, REVIEW_PROVIDER_SERVER_ERROR_STATUSES, TRUNCATION_ELLIPSIS2, normalizeNativeValues, assertPromptModelController, resolveRuntimeReasoningControlsForModel, modelScopedKey, resolveNativeValuesForModel, observeRuntimeCycle, observeAccountState, aiOrderSlippageFraction, serverBehaviorStateArtifacts, ClientRuntimeAgentInstructionEmpty, isClientRuntimeAgentInstructionEmpty, ClientRuntimeAiSchedulePaused, ClientRuntimeAiScheduleStillActive, isClientRuntimeAiScheduleStillActive, ServerDispatchAccountStateStale, isServerDispatchAccountStateStale, isClientRuntimeAiSchedulePaused, acceptancePositionCaps, accountSnapshotCapturedAt, buildClaimedAgentRuntimeCycleResult, resolveRuntimeMarginModePreference, resolveRuntimeLeveragePreference, resolveBooleanSetting2, CLIENT_RUNTIME_LIVE_CONTEXT_UNAVAILABLE_ERRORS, BEHAVIOR_STATE_UNAVAILABLE_ERROR, CriticalBehaviorStateError, clampNumber, resolveExternalInferenceRuntimeTimeoutSeconds, toPositiveFinite3, compactSnippet, hashRuntimeDebugText, EFFECTIVE_INPUT_MANIFEST_SCHEMA_VERSION, PROMPT_ASSEMBLY_DEFINITION_VERSION, RUNTIME_SOURCE_DEFINITION_VERSION, DECISION_INPUT_DEFINITION_VERSION, CONTEXT_ENVELOPE_DEFINITION_VERSION, CLIENT_RUNTIME_SOURCE_VERSION, CLIENT_MAIN_PROMPT_RENDERER, SERVER_MAIN_PROMPT_RENDERER, CLIENT_REVIEW_PROMPT_RENDERER, SERVER_REVIEW_PROMPT_RENDERER, resolveEffectivePromptRuntimeProvenance, canonicalManifestValue, canonicalManifestJson, sha256ManifestHex, effectiveInputComponent, buildEffectiveInputManifest, derivePromptVisibleSections, decodeDecisionTracePayload, extractDecisionSymbolTrace, formatDecisionSymbolTrace, formatActionableDecisionSymbols, decisionRecordsBySymbol, normalizePromptSymbols, JSON_MODEL_OUTPUT_FENCE_PATTERN, STRICT_MODEL_OUTPUT_KEYS, currentModelOutputValidationErrors, currentModelOutputMatchesContract, projectCurrentModelDecisionContent, modelOutputValidationError, buildMissingDecisionHold, buildDecisionPlansFromResponse, buildReviewCandidatePlansFromResponse, forceUnavailableSymbolsToHold, extractTemplatePlaceholders, requireReviewPrimaryUserPromptTemplate, containsCompetingBehaviorStateMarkup, containsCompetingMainBehaviorStateMarkup, requireStrategyReviewTemplates, preflightStrategyReviewPromptContract, extractRuntimeReasoningSelection, isAbortError, isRuntimeTimeoutAbortReason, REVIEW_FAILURE_SENSITIVE_DB_TOKENS, REVIEW_FAILURE_SCHEMA_DISCLOSURE_TOKENS, REVIEW_FAILURE_SQL_STATEMENT_PATTERN, REVIEW_FAILURE_TRACEBACK_PATTERN, isSensitiveReviewFailureDetail, summarizeReviewFailureExplanation, buildReviewFailureHoldReason, createAbortError2, settleRuntimeCyclePromise, unwrapRuntimeCycleSettledResult, normalizeDecisionLabel, normalizeRuntimeSymbol, PromptContractFetchError, isLivePromptContextUnavailableError, buildFailClosedHoldResult, buildPromptConstructionFailureResult, buildLivePromptContextUnavailableFailureResult, pickFirstString, normalizeRuntimeStringList, requirePositiveRuntimeLimit, resolveRuntimeTradingScope, normalizeRuntimeProviderAlias, resolveCatalogModelEntry, createClientRuntimeProviderSetupError, createProviderSetupRejectionError, evaluateModelEligibility, extractReviewRuntimeReasoningSelection, isUsableRuntimeSettingsFallback, resolveRuntimeSettings, formatRuntimeDurationMs, normalizeRuntimeTimingNote, appendRuntimeTimingEvent, reportPromptParityTelemetry, resolveLocalRuntimeSecretRequirements, resolveLocalRuntimeSecretProvider, toEpochSeconds, REQUIRED_AI_INDICATOR_KEYS, sortTradingTimeframes, normalizePromptIdentityTimestamp, resolveCompletedCandleBoundary, normalizeAiIndicatorFlags, getPromptLookback, computeSma, computeEma, computeRsi, computeAtr, computeMacd, computeBollingerBands, getIndicatorValue, buildPromptCandlesComponent, CANDLE_CLOSE_TICKER_TIMEFRAME, candleCloseTicker, buildPromptCandlesPayload, formatUtcTimestampWithWeekday, formatUtcNowWithWeekday, formatPromptPrice, capacityUnitSize, computePromptUnitsUsedForPosition, buildPromptAccountStatusValue, buildPromptPositionsValue, sanitizePromptSymbol, fillTimeMs, fillSize, normalizeFillSide, normalizeFillOrderId, normalizeFillRiskOrderIdentity, fillStartPosition, fillSortValue, sortFillsAscending, sortFillsDescending, inferEntryFromStartPositionChain, inferEntryFromCurrentPositionSize, calculateCurrentPositionState, calculatePositionEntryTimes, countPositionAdds, latestPositionRiskIncreaseTimeMs, latestPositionRiskIncreaseEvidence, compactPromptRiskIncrease, roundPositiveDecimalHalfUp, compactPromptLastTrade, ENTRY_TRADE_FIELDS, PREVIOUS_DECISION_FIELDS, PREVIOUS_CAMPAIGN_FIELDS, hasExactKeys2, isNonnegativeInteger, isFiniteNumber, isExactEnumString, isNonemptyPromptText, isCampaignReasoningText, projectBackendDecisionMemoryItem, requireRenderedStrategyBehaviorState, canonicalFillSideForRiskEvidence, isValidRiskEvidenceFill, isValidCampaignBoundaryFill, normalizeFillHistoryCoverage, resolveFillHistoryCoverageForSymbol, buildPromptBehaviorStateArtifacts, buildPromptBehaviorStateValue, shouldCompareServerPromptParity, buildLocalRuntimePromptArtifacts, createRuntimeId2, asRecord, buildRuntimeConstraintRejectionMessage, hasDeviceProviderSecret, requireNonEmptyStringField, requirePositiveIntegerField, compareContractVersion, parsePromptContractTimestamp, assertPromptContractCompatibility, assertPromptContractTemporalBounds, sleepWithAbort, requireAgentPollRetryAfterMs, materializeClaimedClientRuntimeAgentInstruction, attachClientRuntimeErrorProvenance, isExternalRuntimeProviderResult, invokeClientExternalInference, assertPromptContractBindingTupleEqual, assertPromptContractScopeMatch, fetchBoundPromptContracts, formatTemplateWithNamedVariables, carryReturnedModelCalls, runLocalRuntimeCycle;
114550
+ var CYCLE_TIMEOUT_FLOOR_MS, DECISION_SETTLEMENT_RESERVE_MAX_BUDGET_DIVISOR, MIN_AGENT_INSTRUCTION_RETRY_AFTER_MS, PROMPT_PARITY_ERROR_DETAIL_MAX_CHARS, EXTERNAL_INFERENCE_RUNTIME_POLL_INTERVAL_MS, REVIEW_PROVIDER_SERVER_ERROR_STATUSES, TRUNCATION_ELLIPSIS2, normalizeNativeValues, assertPromptModelController, resolveRuntimeReasoningControlsForModel, modelScopedKey, resolveNativeValuesForModel, observeRuntimeCycle, observeAccountState, aiOrderSlippageFraction, serverBehaviorStateArtifacts, ClientRuntimeAgentInstructionEmpty, isClientRuntimeAgentInstructionEmpty, ClientRuntimeAiSchedulePaused, ClientRuntimeAiScheduleStillActive, isClientRuntimeAiScheduleStillActive, ServerDispatchAccountStateStale, isServerDispatchAccountStateStale, isClientRuntimeAiSchedulePaused, acceptancePositionCaps, accountSnapshotCapturedAt, buildClaimedAgentRuntimeCycleResult, resolveRuntimeMarginModePreference, resolveRuntimeLeveragePreference, resolveBooleanSetting2, CLIENT_RUNTIME_LIVE_CONTEXT_UNAVAILABLE_ERRORS, BEHAVIOR_STATE_UNAVAILABLE_ERROR, CriticalBehaviorStateError, clampNumber, resolveExternalInferenceRuntimeTimeoutSeconds, toPositiveFinite3, compactSnippet, hashRuntimeDebugText, EFFECTIVE_INPUT_MANIFEST_SCHEMA_VERSION, PROMPT_ASSEMBLY_DEFINITION_VERSION, RUNTIME_SOURCE_DEFINITION_VERSION, DECISION_INPUT_DEFINITION_VERSION, CONTEXT_ENVELOPE_DEFINITION_VERSION, CLIENT_RUNTIME_SOURCE_VERSION, CLIENT_MAIN_PROMPT_RENDERER, SERVER_MAIN_PROMPT_RENDERER, CLIENT_REVIEW_PROMPT_RENDERER, SERVER_REVIEW_PROMPT_RENDERER, resolveEffectivePromptRuntimeProvenance, canonicalManifestValue, canonicalManifestJson, sha256ManifestHex, effectiveInputComponent, buildEffectiveInputManifest, derivePromptVisibleSections, decodeDecisionTracePayload, extractDecisionSymbolTrace, formatDecisionSymbolTrace, formatActionableDecisionSymbols, decisionRecordsBySymbol, normalizePromptSymbols, JSON_MODEL_OUTPUT_FENCE_PATTERN, STRICT_MODEL_OUTPUT_KEYS, currentModelOutputValidationErrors, currentModelOutputMatchesContract, projectCurrentModelDecisionContent, modelOutputValidationError, SERVER_UNREADABLE_REPLY_HOLD_REASONING, buildMissingDecisionHold, buildDecisionPlansFromResponse, buildReviewCandidatePlansFromResponse, forceUnavailableSymbolsToHold, extractTemplatePlaceholders, requireReviewPrimaryUserPromptTemplate, containsCompetingBehaviorStateMarkup, containsCompetingMainBehaviorStateMarkup, requireStrategyReviewTemplates, preflightStrategyReviewPromptContract, extractRuntimeReasoningSelection, isAbortError, isRuntimeTimeoutAbortReason, REVIEW_FAILURE_SENSITIVE_DB_TOKENS, REVIEW_FAILURE_SCHEMA_DISCLOSURE_TOKENS, REVIEW_FAILURE_SQL_STATEMENT_PATTERN, REVIEW_FAILURE_TRACEBACK_PATTERN, isSensitiveReviewFailureDetail, summarizeReviewFailureExplanation, buildReviewFailureHoldReason, createAbortError2, settleRuntimeCyclePromise, unwrapRuntimeCycleSettledResult, normalizeDecisionLabel, normalizeRuntimeSymbol, PromptContractFetchError, isLivePromptContextUnavailableError, buildFailClosedHoldResult, buildPromptConstructionFailureResult, buildLivePromptContextUnavailableFailureResult, pickFirstString, normalizeRuntimeStringList, requirePositiveRuntimeLimit, resolveRuntimeTradingScope, normalizeRuntimeProviderAlias, resolveCatalogModelEntry, createClientRuntimeProviderSetupError, createProviderSetupRejectionError, evaluateModelEligibility, extractReviewRuntimeReasoningSelection, isUsableRuntimeSettingsFallback, resolveRuntimeSettings, formatRuntimeDurationMs, normalizeRuntimeTimingNote, appendRuntimeTimingEvent, reportPromptParityTelemetry, resolveLocalRuntimeSecretRequirements, resolveLocalRuntimeSecretProvider, toEpochSeconds, REQUIRED_AI_INDICATOR_KEYS, sortTradingTimeframes, normalizePromptIdentityTimestamp, resolveCompletedCandleBoundary, normalizeAiIndicatorFlags, getPromptLookback, computeSma, computeEma, computeRsi, computeAtr, computeMacd, computeBollingerBands, getIndicatorValue, buildPromptCandlesComponent, CANDLE_CLOSE_TICKER_TIMEFRAME, candleCloseTicker, buildPromptCandlesPayload, formatUtcTimestampWithWeekday, formatUtcNowWithWeekday, formatPromptPrice, capacityUnitSize, computePromptUnitsUsedForPosition, buildPromptAccountStatusValue, buildPromptPositionsValue, sanitizePromptSymbol, fillTimeMs, fillSize, normalizeFillSide, normalizeFillOrderId, normalizeFillRiskOrderIdentity, fillStartPosition, fillSortValue, sortFillsAscending, sortFillsDescending, inferEntryFromStartPositionChain, inferEntryFromCurrentPositionSize, calculateCurrentPositionState, calculatePositionEntryTimes, countPositionAdds, latestPositionRiskIncreaseTimeMs, latestPositionRiskIncreaseEvidence, compactPromptRiskIncrease, roundPositiveDecimalHalfUp, compactPromptLastTrade, ENTRY_TRADE_FIELDS, PREVIOUS_DECISION_FIELDS, PREVIOUS_CAMPAIGN_FIELDS, hasExactKeys2, isNonnegativeInteger, isFiniteNumber, isExactEnumString, isNonemptyPromptText, isCampaignReasoningText, projectBackendDecisionMemoryItem, requireRenderedStrategyBehaviorState, canonicalFillSideForRiskEvidence, isValidRiskEvidenceFill, isValidCampaignBoundaryFill, normalizeFillHistoryCoverage, resolveFillHistoryCoverageForSymbol, buildPromptBehaviorStateArtifacts, buildPromptBehaviorStateValue, shouldCompareServerPromptParity, buildLocalRuntimePromptArtifacts, createRuntimeId2, asRecord, buildRuntimeConstraintRejectionMessage, hasDeviceProviderSecret, requireNonEmptyStringField, requirePositiveIntegerField, compareContractVersion, parsePromptContractTimestamp, assertPromptContractCompatibility, assertPromptContractTemporalBounds, sleepWithAbort, requireAgentPollRetryAfterMs, materializeClaimedClientRuntimeAgentInstruction, attachClientRuntimeErrorProvenance, isExternalRuntimeProviderResult, invokeClientExternalInference, assertPromptContractBindingTupleEqual, assertPromptContractScopeMatch, fetchBoundPromptContracts, formatTemplateWithNamedVariables, carryReturnedModelCalls, runLocalRuntimeCycle;
113964
114551
  var init_local_analysis = __esm({
113965
114552
  "lib/runtime/local-analysis.ts"() {
113966
114553
  "use strict";
@@ -114178,6 +114765,8 @@ var init_local_analysis = __esm({
114178
114765
  perpDexScope: perpDexScopeForSymbols(symbols),
114179
114766
  feeSymbols: symbols,
114180
114767
  includeEffectiveTakerRate: true,
114768
+ // A Server bot's account is valued as the Python Server loop valued it.
114769
+ serverLoopAccountValue: runtimeInput.executionMode === "server",
114181
114770
  sessionId: String(runtimeInput.sessionId || "").trim(),
114182
114771
  signal
114183
114772
  });
@@ -114352,7 +114941,8 @@ var init_local_analysis = __esm({
114352
114941
  decision: "HOLD",
114353
114942
  units: 0,
114354
114943
  reasoning: `Skipped by client runtime constraints: ${accepted.reason_code}`,
114355
- executionContext
114944
+ executionContext,
114945
+ ...entry.decision === "BUY" || entry.decision === "SELL" ? { unsentOrder: { decision: entry.decision, units: entry.units, constraintReasonCode: accepted.reason_code } } : {}
114356
114946
  };
114357
114947
  }
114358
114948
  throw new Error(buildRuntimeConstraintRejectionMessage({
@@ -114925,6 +115515,7 @@ var init_local_analysis = __esm({
114925
115515
  }
114926
115516
  );
114927
115517
  };
115518
+ SERVER_UNREADABLE_REPLY_HOLD_REASONING = "Configured symbol was omitted from the model response. Defaulted to HOLD.";
114928
115519
  buildMissingDecisionHold = (symbol2, reasoning = `No valid model decision was returned for configured symbol ${symbol2}.`) => ({
114929
115520
  symbol: symbol2,
114930
115521
  decision: "HOLD",
@@ -117492,7 +118083,7 @@ ${behaviorJson}
117492
118083
  );
117493
118084
  }
117494
118085
  };
117495
- fetchBoundPromptContracts = async (profileId, payload, signal, walletAddress, getEquity, getTotalUnrealizedPnl, getAccountStateResolvedAtMs, getUserFills, waitForLiveAccountState, initialMetadata, getPositions, getPerpDexAccounts) => {
118086
+ fetchBoundPromptContracts = async (profileId, payload, signal, walletAddress, getEquity, getTotalUnrealizedPnl, getAccountStateResolvedAtMs, getUserFills, waitForLiveAccountState, initialMetadata, getPositions, getPerpDexAccounts, runsWithoutEquity = false) => {
117496
118087
  let attempt = 0;
117497
118088
  while (true) {
117498
118089
  if (waitForLiveAccountState) {
@@ -117542,7 +118133,7 @@ ${behaviorJson}
117542
118133
  const liveEquity = Number.isFinite(Number(liveEquityRaw)) ? Number(liveEquityRaw) : 0;
117543
118134
  const liveUnrealizedPnlRaw = getTotalUnrealizedPnl ? getTotalUnrealizedPnl() : null;
117544
118135
  const liveUnrealizedPnl = liveUnrealizedPnlRaw !== null && liveUnrealizedPnlRaw !== void 0 && Number.isFinite(Number(liveUnrealizedPnlRaw)) ? Number(liveUnrealizedPnlRaw) : null;
117545
- const parityIncluded = liveEquity > 0;
118136
+ const parityIncluded = liveEquity > 0 || runsWithoutEquity;
117546
118137
  const parityPreparedAtMs = Date.now();
117547
118138
  const accountStateResolvedAtMs = getAccountStateResolvedAtMs ? getAccountStateResolvedAtMs() : null;
117548
118139
  const accountStateAgeMs = typeof accountStateResolvedAtMs === "number" ? Math.max(0, parityPreparedAtMs - accountStateResolvedAtMs) : null;
@@ -118126,6 +118717,10 @@ ${behaviorJson}
118126
118717
  // A Server bot's cycle reads the account authoritatively, as the Python
118127
118718
  // Server loop does: never a cached or rate-limit-stale observation.
118128
118719
  forceRefresh: input.executionMode === "server",
118720
+ // And values it as that loop does: Perps equity alone unless the loop's
118721
+ // own tests count Spot (serverLoopAccountValue). A Client bot's cycle
118722
+ // keeps the device rule.
118723
+ serverLoopAccountValue: input.executionMode === "server",
118129
118724
  sessionId,
118130
118725
  signal: timeoutController.signal
118131
118726
  }).catch(async (error48) => {
@@ -118236,7 +118831,8 @@ ${behaviorJson}
118236
118831
  },
118237
118832
  initialPromptMetadata,
118238
118833
  () => latestPositions,
118239
- () => _latestPerpDexAccounts
118834
+ () => _latestPerpDexAccounts,
118835
+ input.executionMode === "server"
118240
118836
  ).then((contracts) => {
118241
118837
  appendRuntimeTimingEvent("prompt_contract_loaded", promptContractStartedAtMs);
118242
118838
  return contracts;
@@ -119268,18 +119864,31 @@ ${stringifyPromptJson(candlesPayload)}
119268
119864
  `provider=${provider} requested_model=${authoritativeModel} response_model=${providerResponse.model} llm_latency_s=${providerResponse.latency} snippet=${responseSnippet || "(empty)"}`
119269
119865
  );
119270
119866
  let primaryDecisionContent = providerResponse.content;
119867
+ let mainReplyUnreadable = false;
119271
119868
  if (!allPromptSymbolsUnavailable && !isExternalRuntimeProviderResult(providerResponse)) {
119272
119869
  const validationErrors = currentModelOutputValidationErrors(providerResponse.content, promptSymbols);
119273
- if (validationErrors.length > 0) {
119870
+ if (validationErrors.length > 0 && input.executionMode !== "server") {
119274
119871
  throw modelOutputValidationError("Main", providerResponse.invocations, validationErrors, promptSymbols);
119275
119872
  }
119276
- primaryDecisionContent = projectCurrentModelDecisionContent(providerResponse.content);
119873
+ if (validationErrors.length > 0) {
119874
+ mainReplyUnreadable = true;
119875
+ primaryDecisionContent = JSON.stringify(Object.fromEntries(promptSymbols.map((promptSymbol) => [promptSymbol, {
119876
+ decision: "HOLD",
119877
+ units: 0,
119878
+ tradability: null,
119879
+ reasoning: SERVER_UNREADABLE_REPLY_HOLD_REASONING
119880
+ }])));
119881
+ } else {
119882
+ primaryDecisionContent = projectCurrentModelDecisionContent(providerResponse.content);
119883
+ }
119277
119884
  }
119278
- const primaryParseOutcome = classifyDecisionParseOutcome(
119279
- providerResponse.content,
119280
- symbol2,
119281
- promptSymbols
119282
- );
119885
+ const primaryParseOutcome = mainReplyUnreadable ? {
119886
+ status: "failed",
119887
+ fallbackStrategy: null,
119888
+ // The loop records this one code for a reply its strict parser rejects.
119889
+ validationErrorCodes: ["model_output_schema_invalid"],
119890
+ discardedFields: []
119891
+ } : classifyDecisionParseOutcome(providerResponse.content, symbol2, promptSymbols);
119283
119892
  invocationAttempts = applyInvocationParseOutcome(
119284
119893
  providerResponse.invocations,
119285
119894
  {
@@ -119395,7 +120004,7 @@ ${stringifyPromptJson(candlesPayload)}
119395
120004
  return entry.decision === "BUY" || entry.decision === "SELL" ? total + Math.max(0, Math.trunc(entry.units)) : total;
119396
120005
  }, 0);
119397
120006
  const reviewMaxTrades = Math.max(0, maxTradesPerPrompt - unreviewedPrimaryUnits);
119398
- const shouldReview = !allPromptSymbolsUnavailable && reviewEnabled && reviewCandidatePlans.length > 0;
120007
+ const shouldReview = !allPromptSymbolsUnavailable && reviewEnabled && !mainReplyUnreadable && reviewCandidatePlans.length > 0;
119399
120008
  if (shouldReview) {
119400
120009
  let reviewModel = requireNonEmptyStringField(promptMetadata.review_model, "review_model");
119401
120010
  const requestedReviewModel = reviewModel;
@@ -119696,6 +120305,9 @@ ${reviewOutputContract}`;
119696
120305
  if (error48 instanceof CriticalBehaviorStateError || detail.includes(BEHAVIOR_STATE_UNAVAILABLE_ERROR) || detail.includes("Critical behavior context could not be constructed")) {
119697
120306
  throw new CriticalBehaviorStateError(error48);
119698
120307
  }
120308
+ if (input.executionMode === "server" && error48?.code === "settings_superseded") {
120309
+ throw error48;
120310
+ }
119699
120311
  invocationAttempts = mergeInvocationAttemptChains(
119700
120312
  invocationAttempts,
119701
120313
  Array.isArray(error48?.runtimeInvocationAttempts) ? error48.runtimeInvocationAttempts : []
@@ -119835,7 +120447,14 @@ ${reviewOutputContract}`;
119835
120447
  units: 0,
119836
120448
  tradability: entry.tradability,
119837
120449
  reasoning: `Skipped by client runtime constraints: ${planAcceptance.reason_code || "capacity_reached"}`,
119838
- executionContext: buildExecutionContextForSymbol(entry.symbol)
120450
+ executionContext: buildExecutionContextForSymbol(entry.symbol),
120451
+ ...entry.decision === "BUY" || entry.decision === "SELL" ? {
120452
+ unsentOrder: {
120453
+ decision: entry.decision,
120454
+ units: entry.units,
120455
+ constraintReasonCode: planAcceptance.reason_code || "capacity_reached"
120456
+ }
120457
+ } : {}
119839
120458
  };
119840
120459
  }
119841
120460
  throw new Error(buildRuntimeConstraintRejectionMessage({
@@ -121035,7 +121654,12 @@ var init_engine = __esm({
121035
121654
  await this._trailingMaintenancePromise;
121036
121655
  await this._pendingProtectionRecoveryPromise;
121037
121656
  await waitForBrowserExchangeMutationSettlement(profileId);
121038
- const stopCloseVenues = profileEquityVenues(paused.settings.trading_symbols, paused.config.default_trading_symbols);
121657
+ const stopCloseVenues = profileExchanges(
121658
+ paused.settings.exchanges,
121659
+ paused.settings.trading_symbols,
121660
+ paused.config.default_trading_symbols,
121661
+ paused.config.client_runtime_hyperliquid_perp_dexs?.allowed_dexes
121662
+ );
121039
121663
  const { positions } = await fetchBrowserAccountState2({
121040
121664
  publicRequestPriority: "trading_reduce",
121041
121665
  config: paused.config,
@@ -123815,6 +124439,7 @@ var init_engine = __esm({
123815
124439
  }
123816
124440
  const executionResults = [];
123817
124441
  const executionFailures = [];
124442
+ const executionFailureCauses = [];
123818
124443
  const executionLeaseToken = () => {
123819
124444
  const lease = getPersistedClientRuntimeServerLease(profileId);
123820
124445
  return lease?.runtimeSessionId === sessionId && lease.deviceId === deviceId && lease.mode === "trader" ? lease.runtimeLeaseToken : null;
@@ -123974,6 +124599,7 @@ var init_engine = __esm({
123974
124599
  symbol: plan.executionContext.symbol,
123975
124600
  projection: projectedFailure
123976
124601
  });
124602
+ executionFailureCauses.push(executionError);
123977
124603
  }
123978
124604
  appendRuntimeDebugEvent({
123979
124605
  label: "execution_plan_failed",
@@ -124024,6 +124650,24 @@ var init_engine = __esm({
124024
124650
  }
124025
124651
  }
124026
124652
  }
124653
+ if (plan.unsentOrder) {
124654
+ executionResult = {
124655
+ ...executionResult,
124656
+ executionReports: [...executionResult.executionReports, {
124657
+ order_id: null,
124658
+ symbol: plan.executionContext.symbol,
124659
+ action: plan.unsentOrder.decision,
124660
+ status: "blocked",
124661
+ execution_metadata: {
124662
+ reason_code: "execution_capacity_refused",
124663
+ constraint_reason_code: plan.unsentOrder.constraintReasonCode,
124664
+ requested_units: plan.unsentOrder.units,
124665
+ cycle_id: result.cycleId,
124666
+ decision_snapshot_id: result.decisionSnapshotId
124667
+ }
124668
+ }]
124669
+ };
124670
+ }
124027
124671
  return { control: "continue", result: executionResult };
124028
124672
  };
124029
124673
  const recordPlanResult = (executionResult) => {
@@ -124226,16 +124870,18 @@ var init_engine = __esm({
124226
124870
  cycleReason = "execution_failed";
124227
124871
  cycleFailureStage = "execution";
124228
124872
  const primaryFailure = selectPrimaryExecutionFailure(executionFailures);
124229
- if (!primaryFailure) return;
124230
- await this.reportError(primaryFailure.projection.message, {
124231
- fatal: false,
124232
- model: result.model,
124233
- modelSource: result.model_source ?? result.provider,
124234
- executionSymbol: primaryFailure.symbol,
124235
- executionReasonCode: primaryFailure.projection.reason_code,
124236
- executionStage: primaryFailure.projection.execution_stage,
124237
- dispatchOutcome: primaryFailure.projection.dispatch_outcome
124238
- });
124873
+ const reportedFailures = this._expectedExecutionMode === "server" ? executionFailures.filter((_, index) => executionFailureCauses.indexOf(executionFailureCauses[index]) === index) : primaryFailure ? [primaryFailure] : [];
124874
+ for (const failure2 of reportedFailures) {
124875
+ await this.reportError(failure2.projection.message, {
124876
+ fatal: false,
124877
+ model: result.model,
124878
+ modelSource: result.model_source ?? result.provider,
124879
+ executionSymbol: failure2.symbol,
124880
+ executionReasonCode: failure2.projection.reason_code,
124881
+ executionStage: failure2.projection.execution_stage,
124882
+ dispatchOutcome: failure2.projection.dispatch_outcome
124883
+ });
124884
+ }
124239
124885
  return;
124240
124886
  }
124241
124887
  }
@@ -125314,7 +125960,7 @@ var init_engine = __esm({
125314
125960
  positionCloseFailures: 0
125315
125961
  };
125316
125962
  if (context.close_positions) {
125317
- const stalePositions = positionsOnVenues(evaluation.accountState?.positions ?? [], evaluation.equityVenues);
125963
+ const stalePositions = positionsOnVenues(evaluation.accountState?.positions ?? [], evaluation.closeVenues);
125318
125964
  try {
125319
125965
  const signingKey = String(
125320
125966
  this._deviceSecrets?.hyperliquidSigningKey || ""
@@ -125343,8 +125989,8 @@ var init_engine = __esm({
125343
125989
  tickerPrice: 0,
125344
125990
  leverage: 1,
125345
125991
  aggregatePerpDexs: true,
125346
- // The exchanges the check read: positions elsewhere are not the bot's to close.
125347
- perpDexScope: evaluation.equityVenues?.filter(Boolean),
125992
+ // The bot's exchanges: positions elsewhere are not the bot's to close.
125993
+ perpDexScope: evaluation.closeVenues?.filter(Boolean),
125348
125994
  forceRefresh: true,
125349
125995
  sessionId: this._sessionId ?? void 0,
125350
125996
  signal: refreshController.signal
@@ -125368,7 +126014,7 @@ var init_engine = __esm({
125368
126014
  config: config2,
125369
126015
  signingKey,
125370
126016
  timeoutSeconds: closeTimeoutSeconds,
125371
- venues: evaluation.equityVenues
126017
+ venues: evaluation.closeVenues
125372
126018
  });
125373
126019
  } else {
125374
126020
  closeSummary = {