@vtxmacro/cli 2026.10.17 → 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.17", 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
  },
@@ -1254,6 +1259,7 @@ var init_runtime_policy_generated = __esm({
1254
1259
  public_recovery: {
1255
1260
  fallback_initial_seconds: 2,
1256
1261
  fallback_max_seconds: 60,
1262
+ fallback_jitter_min_factor: 0.5,
1257
1263
  permit_lease_seconds: 60,
1258
1264
  recovery_initial_concurrency: 1,
1259
1265
  recovery_max_concurrency: 8,
@@ -1456,7 +1462,7 @@ var init_runtime_policy_generated = __esm({
1456
1462
  });
1457
1463
 
1458
1464
  // lib/constants.ts
1459
- 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_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_JITTER_MIN_FACTOR, 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;
1460
1466
  var init_constants = __esm({
1461
1467
  "lib/constants.ts"() {
1462
1468
  "use strict";
@@ -1549,6 +1555,7 @@ var init_constants = __esm({
1549
1555
  HTTP_STATUS_MAX = 599;
1550
1556
  HTTP_CLIENT_ERROR_MIN = 400;
1551
1557
  HTTP_SERVER_ERROR_MIN = 500;
1558
+ USD_DISPLAY_DECIMALS = 2;
1552
1559
  AI_COST_ESTIMATE_PERIOD_DAYS = 30;
1553
1560
  SECONDS_PER_AI_COST_ESTIMATE_PERIOD = SECONDS_PER_DAY * AI_COST_ESTIMATE_PERIOD_DAYS;
1554
1561
  DATE_FIELD_DIGITS = 2;
@@ -1903,6 +1910,16 @@ var init_constants = __esm({
1903
1910
  };
1904
1911
  HYPERLIQUID_TPSL_BATCH_MIN_ORDERS = 2;
1905
1912
  HYPERLIQUID_USER_FILLS_PROVIDER_PAGE_CAP = 2e3;
1913
+ HYPERLIQUID_ROW_WEIGHTED_INFO_REQUESTS = [
1914
+ "userFills",
1915
+ "userFillsByTime",
1916
+ "historicalOrders",
1917
+ "twapHistory",
1918
+ "userTwapSliceFills",
1919
+ "userFunding",
1920
+ "userNonFundingLedgerUpdates"
1921
+ ];
1922
+ HYPERLIQUID_INFO_ROWS_PER_EXTRA_WEIGHT = 20;
1906
1923
  HYPERLIQUID_META_AND_ASSET_CTXS_PARTS = 2;
1907
1924
  HYPERLIQUID_SIDE_PAIR_LENGTH = 2;
1908
1925
  HYPERLIQUID_SIGNED_SIZE_MATCH_EXTRA_DECIMALS = 4;
@@ -1919,7 +1936,6 @@ var init_constants = __esm({
1919
1936
  HYPERLIQUID_POSITION_SIZE_MATCH_RELATIVE_TOLERANCE = 1e-8;
1920
1937
  HYPERLIQUID_LOT_FLOOR_NOISE_DECIMALS = 6;
1921
1938
  HYPERLIQUID_RECOVERY_BACKOFF_MAX_EXPONENT = 30;
1922
- HYPERLIQUID_RECOVERY_JITTER_MIN_FACTOR = 0.5;
1923
1939
  HYPERLIQUID_RECOVERY_CONCURRENCY_GROWTH_FACTOR = 2;
1924
1940
  UUID_BYTES = 16;
1925
1941
  UUID_HEX_GROUP_ENDS = [8, 12, 16, 20, 32];
@@ -20756,6 +20772,10 @@ var init_runtime_policy_generated2 = __esm({
20756
20772
  },
20757
20773
  defaults: {
20758
20774
  server_ai_max_slippage: 5
20775
+ },
20776
+ risk: {
20777
+ max_order_notional: 5e3,
20778
+ max_position_notional: 1e4
20759
20779
  }
20760
20780
  },
20761
20781
  agent_cli: {
@@ -21008,6 +21028,7 @@ var init_runtime_policy_generated2 = __esm({
21008
21028
  metadata_ttl_seconds: 300,
21009
21029
  user_fees_ttl_seconds: 300,
21010
21030
  account_mode_ttl_seconds: 30,
21031
+ ui_account_mode_ttl_seconds: 300,
21011
21032
  default_request_weight: 20,
21012
21033
  cache_max_entries: 512
21013
21034
  },
@@ -21049,6 +21070,7 @@ var init_runtime_policy_generated2 = __esm({
21049
21070
  public_recovery: {
21050
21071
  fallback_initial_seconds: 2,
21051
21072
  fallback_max_seconds: 60,
21073
+ fallback_jitter_min_factor: 0.5,
21052
21074
  permit_lease_seconds: 60,
21053
21075
  recovery_initial_concurrency: 1,
21054
21076
  recovery_max_concurrency: 8,
@@ -54243,6 +54265,110 @@ var init_monotonic_clock = __esm({
54243
54265
  }
54244
54266
  });
54245
54267
 
54268
+ // lib/runtime/hyperliquid-market-symbol.ts
54269
+ var configuredCaseSensitiveSymbols, isHyperliquidSpotSymbol, normalizeCaseSensitiveSymbols, configureHyperliquidMarketSymbolCasing, canonicalBaseSymbol, normalizeHyperliquidMarketSymbol, getHyperliquidMarketDex;
54270
+ var init_hyperliquid_market_symbol = __esm({
54271
+ "lib/runtime/hyperliquid-market-symbol.ts"() {
54272
+ "use strict";
54273
+ init_define_VTX_EXO_POLICY();
54274
+ init_define_VTX_GROK_POLICY();
54275
+ init_define_VTX_PI_MODEL_POLICY();
54276
+ configuredCaseSensitiveSymbols = [];
54277
+ isHyperliquidSpotSymbol = (value) => {
54278
+ const symbol2 = typeof value === "string" ? value.trim() : "";
54279
+ return symbol2.startsWith("@") || symbol2.includes("/");
54280
+ };
54281
+ normalizeCaseSensitiveSymbols = (symbols) => {
54282
+ if (!Array.isArray(symbols)) return [];
54283
+ const out = [];
54284
+ const seen = /* @__PURE__ */ new Set();
54285
+ for (const item of symbols) {
54286
+ const value = String(item ?? "").trim();
54287
+ if (!value) continue;
54288
+ const key = value.toUpperCase();
54289
+ if (seen.has(key)) continue;
54290
+ seen.add(key);
54291
+ out.push(value);
54292
+ }
54293
+ return out;
54294
+ };
54295
+ configureHyperliquidMarketSymbolCasing = (symbols) => {
54296
+ configuredCaseSensitiveSymbols = normalizeCaseSensitiveSymbols(symbols);
54297
+ };
54298
+ canonicalBaseSymbol = (base) => {
54299
+ const trimmed = base.trim();
54300
+ if (!trimmed) return "";
54301
+ const upper = trimmed.toUpperCase();
54302
+ for (const candidate of configuredCaseSensitiveSymbols) {
54303
+ if (candidate.toUpperCase() === upper) {
54304
+ return candidate;
54305
+ }
54306
+ }
54307
+ return upper;
54308
+ };
54309
+ normalizeHyperliquidMarketSymbol = (value) => {
54310
+ const raw = String(value ?? "").trim();
54311
+ if (!raw) return "";
54312
+ if (!raw.includes(":")) return canonicalBaseSymbol(raw);
54313
+ const [dex, ...rest] = raw.split(":");
54314
+ const base = rest.join(":").trim();
54315
+ const normalizedDex = dex.trim().toLowerCase();
54316
+ if (!normalizedDex || !base) return "";
54317
+ return `${normalizedDex}:${canonicalBaseSymbol(base)}`;
54318
+ };
54319
+ getHyperliquidMarketDex = (value) => {
54320
+ const normalized = normalizeHyperliquidMarketSymbol(value);
54321
+ if (!normalized.includes(":")) return "";
54322
+ return normalized.split(":", 1)[0];
54323
+ };
54324
+ }
54325
+ });
54326
+
54327
+ // lib/runtime/bot-exchanges.ts
54328
+ var exchangesByProfile, exchangesVersion, exchangeListeners, exchangesChanged, profileKey, dexList, recordBotExchanges, recordStatusExchanges;
54329
+ var init_bot_exchanges = __esm({
54330
+ "lib/runtime/bot-exchanges.ts"() {
54331
+ "use strict";
54332
+ init_define_VTX_EXO_POLICY();
54333
+ init_define_VTX_GROK_POLICY();
54334
+ init_define_VTX_PI_MODEL_POLICY();
54335
+ init_hyperliquid_market_symbol();
54336
+ exchangesByProfile = /* @__PURE__ */ new Map();
54337
+ exchangesVersion = 0;
54338
+ exchangeListeners = /* @__PURE__ */ new Set();
54339
+ exchangesChanged = () => {
54340
+ exchangesVersion += 1;
54341
+ exchangeListeners.forEach((listener) => listener());
54342
+ };
54343
+ profileKey = (profileId) => {
54344
+ const id2 = Number(profileId);
54345
+ return Number.isInteger(id2) && id2 > 0 ? id2 : null;
54346
+ };
54347
+ dexList = (value) => Array.isArray(value) && value.every((dex) => typeof dex === "string") ? value.map((dex) => dex.trim().toLowerCase()) : null;
54348
+ recordBotExchanges = (profileId, equityVenues, readVenues) => {
54349
+ const id2 = profileKey(profileId);
54350
+ if (id2 === null) return;
54351
+ const equity = dexList(equityVenues);
54352
+ const read = readVenues === void 0 ? equity : dexList(readVenues);
54353
+ const previous = exchangesByProfile.get(id2);
54354
+ if (!equity || !read) {
54355
+ if (exchangesByProfile.delete(id2)) exchangesChanged();
54356
+ return;
54357
+ }
54358
+ if (previous && previous.equity.join() === equity.join() && previous.read.join() === read.join()) return;
54359
+ exchangesByProfile.set(id2, { equity, read });
54360
+ exchangesChanged();
54361
+ };
54362
+ recordStatusExchanges = (status) => {
54363
+ const fields = status;
54364
+ if (fields && typeof fields === "object" && "equity_venues" in fields) {
54365
+ recordBotExchanges(fields.profile_id, fields.equity_venues, fields.read_venues);
54366
+ }
54367
+ return status;
54368
+ };
54369
+ }
54370
+ });
54371
+
54246
54372
  // lib/runtime/local-breadcrumbs.ts
54247
54373
  var LOCAL_RUNTIME_BREADCRUMBS_STORAGE_KEY, DEVICE_DIAGNOSTICS2, LOCAL_RUNTIME_BREADCRUMBS_MAX_ENTRIES, LOCAL_RUNTIME_BREADCRUMBS_MAX_DETAIL_LENGTH, TRUNCATION_ELLIPSIS, safeWindow, sanitizeText, sanitizeOptionalString, clonePayload, buildBreadcrumbId, coerceBreadcrumb, readLocalRuntimeBreadcrumbs, writeLocalRuntimeBreadcrumbs, buildLocalRuntimeEnvironmentSnapshot, appendClientRuntimeLocalBreadcrumb, clearLocalRuntimeBreadcrumbs, flushLocalRuntimeBreadcrumbs;
54248
54374
  var init_local_breadcrumbs = __esm({
@@ -54668,6 +54794,7 @@ async function getLiveTicker(symbol2 = "PI_XBTUSD", exchange = "kraken", signal)
54668
54794
  async function getExecutionAssetMetadata(exchange, symbol2, options) {
54669
54795
  const params = new URLSearchParams();
54670
54796
  if (options?.includePrivateContext) params.set("include_private_context", "true");
54797
+ if (options?.forceCatalogRefresh) params.set("force_catalog_refresh", "true");
54671
54798
  if (options?.publicRequestPriority) params.set("public_request_priority", options.publicRequestPriority);
54672
54799
  const query = params.size > 0 ? `?${params.toString()}` : "";
54673
54800
  const url2 = `${getApiUrl()}/trading/execution-metadata/${encodeURIComponent(exchange)}/${encodeURIComponent(symbol2)}${query}`;
@@ -54755,6 +54882,17 @@ var init_updates = __esm({
54755
54882
  }
54756
54883
  });
54757
54884
 
54885
+ // lib/api/profile-emoji.ts
54886
+ var init_profile_emoji = __esm({
54887
+ "lib/api/profile-emoji.ts"() {
54888
+ "use strict";
54889
+ init_define_VTX_EXO_POLICY();
54890
+ init_define_VTX_GROK_POLICY();
54891
+ init_define_VTX_PI_MODEL_POLICY();
54892
+ init_shared();
54893
+ }
54894
+ });
54895
+
54758
54896
  // lib/runtime/host-storage.ts
54759
54897
  function configureRuntimeHostStorage(storage3) {
54760
54898
  configuredStorage = storage3;
@@ -55136,8 +55274,225 @@ var init_hyperliquid_account_mode_contract = __esm({
55136
55274
  }
55137
55275
  });
55138
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
+
55139
55494
  // lib/runtime/hyperliquid-account-contract.ts
55140
- 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;
55141
55496
  var init_hyperliquid_account_contract = __esm({
55142
55497
  "lib/runtime/hyperliquid-account-contract.ts"() {
55143
55498
  "use strict";
@@ -55146,7 +55501,8 @@ var init_hyperliquid_account_contract = __esm({
55146
55501
  init_define_VTX_PI_MODEL_POLICY();
55147
55502
  init_hyperliquid_account_mode_contract();
55148
55503
  init_constants();
55149
- toNumber = (value, fallback = 0) => {
55504
+ init_server_loop_account_value();
55505
+ toNumber2 = (value, fallback = 0) => {
55150
55506
  const numeric2 = Number(value);
55151
55507
  return Number.isFinite(numeric2) ? numeric2 : fallback;
55152
55508
  };
@@ -55164,7 +55520,6 @@ var init_hyperliquid_account_contract = __esm({
55164
55520
  };
55165
55521
  roundTo = (value, digits = HYPERLIQUID_ACCOUNT_ROUNDING_DECIMALS) => Number(value.toFixed(digits));
55166
55522
  canonicalAvailableMargin = (accountValue, totalMarginUsed) => Math.max(0, accountValue - totalMarginUsed);
55167
- STABLE_SPOT_SYMBOLS = /* @__PURE__ */ new Set(["USDC", "USD", "USDT"]);
55168
55523
  spotBalanceValueUsd = (balance, coin, total) => {
55169
55524
  const explicit = firstNumber([balance?.value_usd, balance?.usdValue, balance?.usdcValue], Number.NaN);
55170
55525
  if (Number.isFinite(explicit)) {
@@ -55187,8 +55542,8 @@ var init_hyperliquid_account_contract = __esm({
55187
55542
  const balances = Array.isArray(firstWithBalances?.balances) ? firstWithBalances.balances : [];
55188
55543
  return balances.map((balance) => {
55189
55544
  const coin = String(balance?.coin ?? "").toUpperCase();
55190
- const total = toNumber(balance?.total, 0);
55191
- const hold = toNumber(balance?.hold, 0);
55545
+ const total = toNumber2(balance?.total, 0);
55546
+ const hold = toNumber2(balance?.hold, 0);
55192
55547
  const available = roundTo(Math.max(0, total - hold));
55193
55548
  const value_usd = spotBalanceValueUsd(balance, coin, total);
55194
55549
  return {
@@ -55200,10 +55555,10 @@ var init_hyperliquid_account_contract = __esm({
55200
55555
  };
55201
55556
  }).filter((balance) => balance.coin.length > 0);
55202
55557
  };
55203
- sumBalanceHoldUsd = (balances) => balances.reduce((acc, balance) => {
55204
- const hold = toNumber(balance.hold, 0);
55205
- const total = toNumber(balance.total, 0);
55206
- 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);
55207
55562
  if (hold <= 0 || total <= 0 || valueUsd <= 0) {
55208
55563
  return acc;
55209
55564
  }
@@ -55212,12 +55567,12 @@ var init_hyperliquid_account_contract = __esm({
55212
55567
  sumPositionUnrealizedPnl = (perpsResponse) => {
55213
55568
  const assetPositions = Array.isArray(perpsResponse?.assetPositions) ? perpsResponse.assetPositions : [];
55214
55569
  return assetPositions.reduce((total, entry) => {
55215
- const unrealizedPnl = toNumber(entry?.position?.unrealizedPnl, 0);
55570
+ const unrealizedPnl = toNumber2(entry?.position?.unrealizedPnl, 0);
55216
55571
  return total + unrealizedPnl;
55217
55572
  }, 0);
55218
55573
  };
55219
55574
  resolveTotalUnrealizedPnl = (perpsResponse) => {
55220
- const topLevel = toNumber(perpsResponse?.totalUnrealizedPnl, 0);
55575
+ const topLevel = toNumber2(perpsResponse?.totalUnrealizedPnl, 0);
55221
55576
  const positionTotal = sumPositionUnrealizedPnl(perpsResponse);
55222
55577
  if (Math.abs(topLevel) < HYPERLIQUID_UNREALIZED_PNL_ZERO_TOLERANCE && Math.abs(positionTotal) >= HYPERLIQUID_UNREALIZED_PNL_ZERO_TOLERANCE) {
55223
55578
  return positionTotal;
@@ -55231,33 +55586,49 @@ var init_hyperliquid_account_contract = __esm({
55231
55586
  reference * relativeTolerance
55232
55587
  );
55233
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;
55234
55607
  buildAccountSummaryFromInfoResponses = (perpsResponse, spotResponse, options = {}) => {
55235
55608
  const marginSummary = perpsResponse?.marginSummary ?? {};
55236
- const perpsAccountValue = toNumber(marginSummary?.accountValue, 0);
55237
- const total_margin_used = toNumber(marginSummary?.totalMarginUsed, 0);
55238
- const totalNtlPos = toNumber(marginSummary?.totalNtlPos, 0);
55239
- 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);
55240
55613
  const maintenance_margin = firstNumber([
55241
55614
  perpsResponse?.crossMaintenanceMarginUsed,
55242
55615
  marginSummary?.crossMaintenanceMarginUsed,
55243
55616
  marginSummary?.totalMaintenanceMargin
55244
55617
  ], 0);
55245
55618
  const balances = normalizeSpotBalancesFromInfoResponse(spotResponse);
55246
- const spotPortfolioValue = balances.reduce((acc, balance) => acc + toNumber(balance.value_usd, 0), 0);
55247
- const balancesHoldUsd = sumBalanceHoldUsd(balances);
55619
+ const spotPortfolioValue = balances.reduce((acc, balance) => acc + toNumber2(balance.value_usd, 0), 0);
55620
+ const balancesHoldUsd = sumBalanceHoldUsd2(balances);
55248
55621
  const account_mode = extractAccountModeFromPayload(perpsResponse);
55249
55622
  const crossMarginSummary = perpsResponse?.crossMarginSummary && typeof perpsResponse.crossMarginSummary === "object" ? perpsResponse.crossMarginSummary : null;
55250
- const crossMarginAccountValue = crossMarginSummary ? toNumber(crossMarginSummary.accountValue, 0) : 0;
55623
+ const crossMarginAccountValue = crossMarginSummary ? toNumber2(crossMarginSummary.accountValue, 0) : 0;
55251
55624
  const normalizedMode = String(account_mode || "").trim().toLowerCase().replace(/[_\s-]/g, "");
55252
55625
  const isAmbiguousDefaultMode = normalizedMode.length === 0 || normalizedMode === "default";
55253
- const spotDominatesMinTotalUsd = Number(options.spotDominatesMinTotalUsd ?? options.spot_dominates_min_total_usd);
55254
- const spotDominatesPerpsMultiplier = Number(options.spotDominatesPerpsMultiplier ?? options.spot_dominates_perps_multiplier);
55255
- const mirroredAccountValueAbsoluteToleranceUsd = Number(
55256
- options.mirroredAccountValueAbsoluteToleranceUsd ?? options.mirrored_account_value_absolute_tolerance_usd
55257
- );
55258
- const mirroredAccountValueRelativeTolerance = Number(
55259
- options.mirroredAccountValueRelativeTolerance ?? options.mirrored_account_value_relative_tolerance
55260
- );
55626
+ const {
55627
+ spotDominatesMinTotalUsd,
55628
+ spotDominatesPerpsMultiplier,
55629
+ mirroredAccountValueAbsoluteToleranceUsd,
55630
+ mirroredAccountValueRelativeTolerance
55631
+ } = accountValueThresholds(options);
55261
55632
  const hasSpotDominanceThresholds = Number.isFinite(spotDominatesMinTotalUsd) && spotDominatesMinTotalUsd >= 0 && Number.isFinite(spotDominatesPerpsMultiplier) && spotDominatesPerpsMultiplier >= 0;
55262
55633
  const hasMirroredAccountValueTolerances = Number.isFinite(mirroredAccountValueAbsoluteToleranceUsd) && mirroredAccountValueAbsoluteToleranceUsd >= 0 && Number.isFinite(mirroredAccountValueRelativeTolerance) && mirroredAccountValueRelativeTolerance >= 0;
55263
55634
  const spotDominatesPerps = hasSpotDominanceThresholds && spotPortfolioValue >= spotDominatesMinTotalUsd && (perpsAccountValue <= 0 || spotPortfolioValue >= perpsAccountValue * spotDominatesPerpsMultiplier);
@@ -55268,7 +55639,8 @@ var init_hyperliquid_account_contract = __esm({
55268
55639
  mirroredAccountValueAbsoluteToleranceUsd,
55269
55640
  mirroredAccountValueRelativeTolerance
55270
55641
  );
55271
- 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;
55272
55644
  return {
55273
55645
  account_value,
55274
55646
  total_margin_used,
@@ -55286,7 +55658,7 @@ var init_hyperliquid_account_contract = __esm({
55286
55658
  });
55287
55659
 
55288
55660
  // lib/runtime/order-identity.ts
55289
- var clientOrderIdForMutation, clientDecisionMutationId;
55661
+ var clientOrderIdForMutation, mutationIdForClientOrderId, clientDecisionMutationId;
55290
55662
  var init_order_identity = __esm({
55291
55663
  "lib/runtime/order-identity.ts"() {
55292
55664
  "use strict";
@@ -55295,6 +55667,12 @@ var init_order_identity = __esm({
55295
55667
  init_define_VTX_PI_MODEL_POLICY();
55296
55668
  init_constants();
55297
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
+ };
55298
55676
  clientDecisionMutationId = async (input) => {
55299
55677
  const key = [
55300
55678
  "client-decision:v1",
@@ -55361,7 +55739,7 @@ var init_hyperliquid_order_status = __esm({
55361
55739
  });
55362
55740
 
55363
55741
  // lib/runtime/hyperliquid-public-read.ts
55364
- var policy, weights, recoveryPolicy, budgets, unpersistedBudgets, cache, pending2, PREFIX, priorityRank, createHyperliquidPublicPriorityScope, promoteHyperliquidPublicPriority, hostTransport, abortError2, checkAbort, wait, waitUnlessPromoted, storage, loadBudget, saveBudget, withBudgetLock, HyperliquidPublicReadError, getHyperliquidPublicReadBudget, cooldownError, recoveryWaitError, nonTradingWeightCap, nonTradingWaitMs, fallbackDelayMs, admit, cooldown, finishHyperliquidRecoveryRequest, assertHyperliquidRecoveryDispatch, validateHyperliquidRecoveryDispatch, cacheTtlMs, eligibleCache, reserveHyperliquidPublicReads, releaseHyperliquidPublicReadReservation, admitHyperliquidExchangeRequest, recordHyperliquidExchangeResponse, readHyperliquidPublicInfo;
55742
+ var policy, weights, recoveryPolicy, budgets, unpersistedBudgets, cache, pending2, PREFIX, priorityRank, createHyperliquidPublicPriorityScope, promoteHyperliquidPublicPriority, hostTransport, abortError2, checkAbort, wait, waitUnlessPromoted, storage, loadBudget, saveBudget, withBudgetLock, HyperliquidPublicReadError, getHyperliquidPublicReadBudget, cooldownError, recoveryWaitError, nonTradingWeightCap, nonTradingWaitMs, fallbackDelayMs, admit, settleRowWeightedReservation, cooldown, finishHyperliquidRecoveryRequest, assertHyperliquidRecoveryDispatch, validateHyperliquidRecoveryDispatch, cacheTtlMs, eligibleCache, reserveHyperliquidPublicReads, releaseHyperliquidPublicReadReservation, admitHyperliquidExchangeRequest, recordHyperliquidExchangeResponse, readHyperliquidPublicInfo;
55365
55743
  var init_hyperliquid_public_read = __esm({
55366
55744
  "lib/runtime/hyperliquid-public-read.ts"() {
55367
55745
  "use strict";
@@ -55517,15 +55895,22 @@ var init_hyperliquid_public_read = __esm({
55517
55895
  };
55518
55896
  fallbackDelayMs = (failures) => Math.min(
55519
55897
  recoveryPolicy.fallback_max_seconds * MS_PER_SECOND,
55520
- recoveryPolicy.fallback_initial_seconds * MS_PER_SECOND * BACKOFF_GROWTH_FACTOR ** Math.min(HYPERLIQUID_RECOVERY_BACKOFF_MAX_EXPONENT, Math.max(0, failures - 1)) * (HYPERLIQUID_RECOVERY_JITTER_MIN_FACTOR + Math.random())
55898
+ recoveryPolicy.fallback_initial_seconds * MS_PER_SECOND * BACKOFF_GROWTH_FACTOR ** Math.min(HYPERLIQUID_RECOVERY_BACKOFF_MAX_EXPONENT, Math.max(0, failures - 1)) * (recoveryPolicy.fallback_jitter_min_factor + Math.random())
55521
55899
  );
55522
- admit = async (apiUrl, requestType, signal, weightOverride, deadlineMs, priority) => {
55900
+ admit = async (apiUrl, requestType, signal, weightOverride, deadlineMs, priority, reservationId) => {
55523
55901
  const key = `${PREFIX}${apiUrl}`;
55524
55902
  const weight = weightOverride ?? weights[requestType] ?? policy.default_request_weight;
55525
55903
  const ticket = crypto.randomUUID();
55526
55904
  const deadline = Math.min(deadlineMs ?? Infinity, Date.now() + recoveryPolicy.recovery_queue_wait_seconds * MS_PER_SECOND);
55527
55905
  if (hostTransport) {
55528
- 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
+ });
55529
55914
  return { ...permit, endpoint: apiUrl, fleet: true };
55530
55915
  }
55531
55916
  let admitted = false;
@@ -55578,7 +55963,7 @@ var init_hyperliquid_public_read = __esm({
55578
55963
  permit = { endpoint: apiUrl, id: ticket, generation: recovery.generation, expiresAt };
55579
55964
  }
55580
55965
  budget.reservations = budget.reservations.filter((entry) => entry.at > now - policy.window_seconds * MS_PER_SECOND);
55581
- budget.reservations.push({ at: now, weight });
55966
+ budget.reservations.push({ at: now, weight, ...reservationId ? { id: reservationId } : {} });
55582
55967
  saveBudget(key, budget);
55583
55968
  return { ready: true, permit, waitMs: 0 };
55584
55969
  });
@@ -55598,9 +55983,20 @@ var init_hyperliquid_public_read = __esm({
55598
55983
  });
55599
55984
  }
55600
55985
  };
55601
- cooldown = async (apiUrl, retryAfter, requestType) => {
55986
+ settleRowWeightedReservation = async (apiUrl, reservationId, rows) => {
55987
+ const key = `${PREFIX}${apiUrl}`;
55988
+ const charged = policy.default_request_weight + Math.floor(rows / HYPERLIQUID_INFO_ROWS_PER_EXTRA_WEIGHT);
55989
+ await withBudgetLock(key, void 0, () => {
55990
+ const budget = loadBudget(key);
55991
+ const reservation = budget.reservations.find((entry) => entry.id === reservationId);
55992
+ if (!reservation || charged >= reservation.weight) return;
55993
+ reservation.weight = charged;
55994
+ saveBudget(key, budget);
55995
+ });
55996
+ };
55997
+ cooldown = async (apiUrl, retryAfter, requestType, priority) => {
55602
55998
  if (hostTransport) {
55603
- await hostTransport.admission.record429(retryAfter, requestType);
55999
+ await hostTransport.admission.record429(retryAfter, requestType, priority);
55604
56000
  return;
55605
56001
  }
55606
56002
  const key = `${PREFIX}${apiUrl}`;
@@ -55680,7 +56076,7 @@ var init_hyperliquid_public_read = __esm({
55680
56076
  };
55681
56077
  cacheTtlMs = (body, options) => {
55682
56078
  const requestType = String(body.type);
55683
- 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;
55684
56080
  };
55685
56081
  eligibleCache = (apiUrl, body, options) => {
55686
56082
  const ttl = cacheTtlMs(body, options);
@@ -55706,8 +56102,8 @@ var init_hyperliquid_public_read = __esm({
55706
56102
  const weight = weights.exchange + Math.floor(batchLength / runtime_policy_generated_default2.exchange.hyperliquid.read_budget.exchange_action_batch_size);
55707
56103
  return admit(endpoint.replace(/\/$/, ""), "exchange", signal, weight, void 0, createHyperliquidPublicPriorityScope(priority));
55708
56104
  };
55709
- recordHyperliquidExchangeResponse = async (endpoint, response, permit) => {
55710
- if (response.status === HTTP_STATUS.TOO_MANY_REQUESTS) await cooldown(endpoint.replace(/\/$/, ""), response.headers.get("Retry-After"), "exchange");
56105
+ recordHyperliquidExchangeResponse = async (endpoint, response, permit, priority) => {
56106
+ if (response.status === HTTP_STATUS.TOO_MANY_REQUESTS) await cooldown(endpoint.replace(/\/$/, ""), response.headers.get("Retry-After"), "exchange", priority);
55711
56107
  await finishHyperliquidRecoveryRequest(permit, response.status < HTTP_CLIENT_ERROR_MIN ? "success" : "failure");
55712
56108
  };
55713
56109
  readHyperliquidPublicInfo = async (endpoint, body, options) => {
@@ -55737,6 +56133,7 @@ var init_hyperliquid_public_read = __esm({
55737
56133
  };
55738
56134
  armDeadline(deadline);
55739
56135
  let permit = null;
56136
+ const rowWeightedReservationId = !hostTransport && HYPERLIQUID_ROW_WEIGHTED_INFO_REQUESTS.includes(requestType) ? crypto.randomUUID() : void 0;
55740
56137
  let outcome = "cancelled";
55741
56138
  let settled;
55742
56139
  let acquiring = false;
@@ -55791,12 +56188,15 @@ var init_hyperliquid_public_read = __esm({
55791
56188
  if (!privateRoute) {
55792
56189
  acquiring = true;
55793
56190
  setPendingPhase("admission");
55794
- permit = await admit(apiUrl, requestType, signal, void 0, deadline, priority);
56191
+ permit = await admit(apiUrl, requestType, signal, void 0, deadline, priority, rowWeightedReservationId);
55795
56192
  acquiring = false;
55796
56193
  armDeadline(Math.min(deadline, permit?.expiresAt ?? Infinity));
55797
56194
  checkAbort(signal);
55798
56195
  if (options.reservation?.closed) throw new DOMException("Hyperliquid account read was cancelled.", "AbortError");
55799
56196
  await validateHyperliquidRecoveryDispatch(apiUrl, permit, requestType);
56197
+ checkAbort(signal);
56198
+ if (options.reservation?.closed) throw new DOMException("Hyperliquid account read was cancelled.", "AbortError");
56199
+ hostTransport?.onPublicInfoSent?.(body);
55800
56200
  }
55801
56201
  outcome = "failure";
55802
56202
  let transportAborted;
@@ -55819,7 +56219,7 @@ var init_hyperliquid_public_read = __esm({
55819
56219
  checkAbort(signal);
55820
56220
  if (received.status === HTTP_STATUS.TOO_MANY_REQUESTS) {
55821
56221
  observedRateLimit = new HyperliquidPublicReadError("public_rate_limited", "Hyperliquid public API returned HTTP 429.", requestType, HTTP_STATUS.TOO_MANY_REQUESTS);
55822
- if (!privateRoute) await cooldown(apiUrl, received.headers.get("Retry-After"), requestType);
56222
+ if (!privateRoute) await cooldown(apiUrl, received.headers.get("Retry-After"), requestType, priority.value);
55823
56223
  throw observedRateLimit;
55824
56224
  }
55825
56225
  let receivedText;
@@ -55854,6 +56254,12 @@ var init_hyperliquid_public_read = __esm({
55854
56254
  });
55855
56255
  }
55856
56256
  outcome = "success";
56257
+ if (rowWeightedReservationId && !privateRoute && Array.isArray(payload)) {
56258
+ try {
56259
+ await settleRowWeightedReservation(apiUrl, rowWeightedReservationId, payload.length);
56260
+ } catch {
56261
+ }
56262
+ }
55857
56263
  const result = { payload, fetchedAtMs: Date.now(), ...bodyText !== void 0 ? { bodyText } : {} };
55858
56264
  if (ttlMs) {
55859
56265
  cache.set(key, result);
@@ -55922,65 +56328,6 @@ var init_hyperliquid_exchange_rejections = __esm({
55922
56328
  }
55923
56329
  });
55924
56330
 
55925
- // lib/runtime/hyperliquid-market-symbol.ts
55926
- var configuredCaseSensitiveSymbols, isHyperliquidSpotSymbol, normalizeCaseSensitiveSymbols, configureHyperliquidMarketSymbolCasing, canonicalBaseSymbol, normalizeHyperliquidMarketSymbol, getHyperliquidMarketDex;
55927
- var init_hyperliquid_market_symbol = __esm({
55928
- "lib/runtime/hyperliquid-market-symbol.ts"() {
55929
- "use strict";
55930
- init_define_VTX_EXO_POLICY();
55931
- init_define_VTX_GROK_POLICY();
55932
- init_define_VTX_PI_MODEL_POLICY();
55933
- configuredCaseSensitiveSymbols = [];
55934
- isHyperliquidSpotSymbol = (value) => {
55935
- const symbol2 = typeof value === "string" ? value.trim() : "";
55936
- return symbol2.startsWith("@") || symbol2.includes("/");
55937
- };
55938
- normalizeCaseSensitiveSymbols = (symbols) => {
55939
- if (!Array.isArray(symbols)) return [];
55940
- const out = [];
55941
- const seen = /* @__PURE__ */ new Set();
55942
- for (const item of symbols) {
55943
- const value = String(item ?? "").trim();
55944
- if (!value) continue;
55945
- const key = value.toUpperCase();
55946
- if (seen.has(key)) continue;
55947
- seen.add(key);
55948
- out.push(value);
55949
- }
55950
- return out;
55951
- };
55952
- configureHyperliquidMarketSymbolCasing = (symbols) => {
55953
- configuredCaseSensitiveSymbols = normalizeCaseSensitiveSymbols(symbols);
55954
- };
55955
- canonicalBaseSymbol = (base) => {
55956
- const trimmed = base.trim();
55957
- if (!trimmed) return "";
55958
- const upper = trimmed.toUpperCase();
55959
- for (const candidate of configuredCaseSensitiveSymbols) {
55960
- if (candidate.toUpperCase() === upper) {
55961
- return candidate;
55962
- }
55963
- }
55964
- return upper;
55965
- };
55966
- normalizeHyperliquidMarketSymbol = (value) => {
55967
- const raw = String(value ?? "").trim();
55968
- if (!raw) return "";
55969
- if (!raw.includes(":")) return canonicalBaseSymbol(raw);
55970
- const [dex, ...rest] = raw.split(":");
55971
- const base = rest.join(":").trim();
55972
- const normalizedDex = dex.trim().toLowerCase();
55973
- if (!normalizedDex || !base) return "";
55974
- return `${normalizedDex}:${canonicalBaseSymbol(base)}`;
55975
- };
55976
- getHyperliquidMarketDex = (value) => {
55977
- const normalized = normalizeHyperliquidMarketSymbol(value);
55978
- if (!normalized.includes(":")) return "";
55979
- return normalized.split(":", 1)[0];
55980
- };
55981
- }
55982
- });
55983
-
55984
56331
  // lib/runtime/exchange-mutation-fence.ts
55985
56332
  var activeSettlementsByScope, normalizeScope, trackBrowserExchangeMutation, waitForBrowserExchangeMutationSettlement;
55986
56333
  var init_exchange_mutation_fence = __esm({
@@ -57374,7 +57721,7 @@ function getNumber(value, name) {
57374
57721
  }
57375
57722
  assertArgument(false, "invalid numeric value", name || "value", value);
57376
57723
  }
57377
- function toNumber2(value) {
57724
+ function toNumber3(value) {
57378
57725
  return getNumber(toBigInt(value));
57379
57726
  }
57380
57727
  function toBeHex(_value, _width) {
@@ -59796,7 +60143,7 @@ var init_abstract_coder = __esm({
59796
60143
  return toBigInt(this.readBytes(WordSize));
59797
60144
  }
59798
60145
  readIndex() {
59799
- return toNumber2(this.readBytes(WordSize));
60146
+ return toNumber3(this.readBytes(WordSize));
59800
60147
  }
59801
60148
  };
59802
60149
  }
@@ -86233,7 +86580,7 @@ __export(ethers_exports, {
86233
86580
  toBeArray: () => toBeArray,
86234
86581
  toBeHex: () => toBeHex,
86235
86582
  toBigInt: () => toBigInt,
86236
- toNumber: () => toNumber2,
86583
+ toNumber: () => toNumber3,
86237
86584
  toQuantity: () => toQuantity,
86238
86585
  toTwos: () => toTwos,
86239
86586
  toUtf8Bytes: () => toUtf8Bytes,
@@ -86451,7 +86798,7 @@ __export(lib_exports, {
86451
86798
  toBeArray: () => toBeArray,
86452
86799
  toBeHex: () => toBeHex,
86453
86800
  toBigInt: () => toBigInt,
86454
- toNumber: () => toNumber2,
86801
+ toNumber: () => toNumber3,
86455
86802
  toQuantity: () => toQuantity,
86456
86803
  toTwos: () => toTwos,
86457
86804
  toUtf8Bytes: () => toUtf8Bytes,
@@ -87363,7 +87710,7 @@ var init_hyperliquid_signer = __esm({
87363
87710
  });
87364
87711
 
87365
87712
  // lib/runtime/hyperliquid-client.ts
87366
- 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;
87367
87714
  var init_hyperliquid_client = __esm({
87368
87715
  "lib/runtime/hyperliquid-client.ts"() {
87369
87716
  "use strict";
@@ -87740,6 +88087,10 @@ var init_hyperliquid_client = __esm({
87740
88087
  return null;
87741
88088
  };
87742
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
+ });
87743
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);
87744
88095
  getPerpDexIndexMap = (payload) => {
87745
88096
  if (!Array.isArray(payload)) {
@@ -87893,6 +88244,12 @@ var init_hyperliquid_client = __esm({
87893
88244
  if (!symbol2) {
87894
88245
  throw new Error("Missing Hyperliquid symbol.");
87895
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
+ }
87896
88253
  if (Array.isArray(input.assets) && input.assets.length > 0) {
87897
88254
  const explicitAsset = findResolvedAsset(symbol2, input.assets);
87898
88255
  if (explicitAsset) {
@@ -88652,8 +89009,7 @@ var init_hyperliquid_client = __esm({
88652
89009
  const { signHyperliquidAction: signHyperliquidAction2 } = await Promise.resolve().then(() => (init_hyperliquid_signer(), hyperliquid_signer_exports));
88653
89010
  const nonce = input.nonce ?? await allocateActionNonce(input, apiUrl);
88654
89011
  const expiresAfter = input.expiresAfterSeconds == null ? null : nonce + input.expiresAfterSeconds * MS_PER_SECOND;
88655
- const leverage = Math.max(1, Math.min(asset.max_leverage, Math.trunc(input.leverage)));
88656
- const isCross = isExchangeIsolatedOnly(asset) ? false : input.isCross !== false;
89012
+ const { leverage, isCross } = resolveLeverageTarget(asset, input.leverage, input.isCross);
88657
89013
  const action = {
88658
89014
  type: "updateLeverage",
88659
89015
  asset: asset.asset_index,
@@ -89555,7 +89911,7 @@ var init_hyperliquid_client = __esm({
89555
89911
  });
89556
89912
  if (transportController.signal.aborted) throw transportController.signal.reason;
89557
89913
  responseStatus = received.status;
89558
- await recordHyperliquidExchangeResponse(apiUrl, received);
89914
+ await recordHyperliquidExchangeResponse(apiUrl, received, void 0, input.publicRequestPriority);
89559
89915
  const body = await received.json().catch(() => ({}));
89560
89916
  if (transportController.signal.aborted) throw transportController.signal.reason;
89561
89917
  return { response: received, payload: body };
@@ -89921,9 +90277,6 @@ async function pollCopyTradingRuntimeSource(profileId, options) {
89921
90277
  ...schedulerInstanceId ? { "x-client-runtime-instance": schedulerInstanceId } : {}
89922
90278
  }, profileId),
89923
90279
  body: JSON.stringify({
89924
- dry_run: Boolean(options?.dryRun),
89925
- force_refresh: Boolean(options?.forceRefresh),
89926
- ...options?.maxEvents ? { max_events: options.maxEvents } : {},
89927
90280
  ...options?.accountEvidence ? { account_evidence: options.accountEvidence } : {}
89928
90281
  }),
89929
90282
  credentials: "include",
@@ -90092,7 +90445,7 @@ async function getAiTradingStatus(cookie, profileId, options) {
90092
90445
  const message = await getErrorMessageFromResponse(response, "Failed to get AI Trader status", { fallbackDetail: true });
90093
90446
  throw new Error(message);
90094
90447
  }
90095
- return response.json();
90448
+ return recordStatusExchanges(await response.json());
90096
90449
  }, { cookie });
90097
90450
  }
90098
90451
  async function postClientRuntime(path, profileId, body, options) {
@@ -90668,7 +91021,7 @@ async function recordServerHostExecutionAudit(profileId, payload, signal, requir
90668
91021
  { ...authority.requestOptions, signal }
90669
91022
  );
90670
91023
  }
90671
- async function checkServerHostExecutionCapacity(profileId, plans, signal, requiredRuntimeSessionId, explicitRuntimeLeaseToken, explicitRuntimeDeviceId, explicitSchedulerInstanceId) {
91024
+ async function checkServerHostExecutionCapacity(profileId, plans, signal, requiredRuntimeSessionId, explicitRuntimeLeaseToken, explicitRuntimeDeviceId, explicitSchedulerInstanceId, cycleStartedAt) {
90672
91025
  const authority = resolveClientExchangeMutationAuthority(
90673
91026
  profileId,
90674
91027
  requiredRuntimeSessionId,
@@ -90681,7 +91034,9 @@ async function checkServerHostExecutionCapacity(profileId, plans, signal, requir
90681
91034
  authority.numericProfileId,
90682
91035
  JSON.stringify({
90683
91036
  ...clientExchangeMutationAuthorityBody(authority),
90684
- plans
91037
+ plans,
91038
+ cycle_started_at: cycleStartedAt || void 0
91039
+ // an order VTX sent since then refuses the batch
90685
91040
  }),
90686
91041
  { ...authority.requestOptions, signal }
90687
91042
  );
@@ -91325,6 +91680,7 @@ var init_api2 = __esm({
91325
91680
  init_google_auth_url();
91326
91681
  init_network_debug();
91327
91682
  init_monotonic_clock();
91683
+ init_bot_exchanges();
91328
91684
  init_local_breadcrumbs();
91329
91685
  init_abort();
91330
91686
  init_client_runtime_ownership_errors();
@@ -91337,6 +91693,7 @@ var init_api2 = __esm({
91337
91693
  init_client_host_commands();
91338
91694
  init_insights_access_center();
91339
91695
  init_updates();
91696
+ init_profile_emoji();
91340
91697
  init_server_runtime_lease();
91341
91698
  clientRuntimeSecretHeaders = (profileId) => {
91342
91699
  const headers = getProfileHeaders({}, profileId);
@@ -93534,6 +93891,7 @@ var init_browser_trading = __esm({
93534
93891
  estimatedPrice: input.estimatedPrice,
93535
93892
  slippage: input.slippage,
93536
93893
  reduceOnly: true,
93894
+ assets: input.assets,
93537
93895
  onExchangeOrderDispatched: input.onExchangeOrderDispatched
93538
93896
  });
93539
93897
  };
@@ -93568,15 +93926,15 @@ var init_hyperliquid_active_asset_contract = __esm({
93568
93926
  };
93569
93927
  normalizePair = (raw) => {
93570
93928
  if (Array.isArray(raw) && raw.length >= HYPERLIQUID_SIDE_PAIR_LENGTH) {
93571
- return [toNumber(raw[0], 0), toNumber(raw[1], 0)];
93929
+ return [toNumber2(raw[0], 0), toNumber2(raw[1], 0)];
93572
93930
  }
93573
93931
  if (raw && typeof raw === "object") {
93574
- const buy = toNumber(raw.buy ?? raw.long ?? raw.b, 0);
93575
- 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);
93576
93934
  return [buy, sell];
93577
93935
  }
93578
93936
  if (typeof raw === "string" || typeof raw === "number") {
93579
- const value = toNumber(raw, 0);
93937
+ const value = toNumber2(raw, 0);
93580
93938
  return [value, value];
93581
93939
  }
93582
93940
  return [0, 0];
@@ -93587,28 +93945,28 @@ var init_hyperliquid_active_asset_contract = __esm({
93587
93945
  const directSell = source.available_to_trade_sell;
93588
93946
  const hasDirectAvailable = directBuy !== void 0 || directSell !== void 0;
93589
93947
  const [pairBuy, pairSell] = normalizePair(source.availableToTrade);
93590
- const available_to_trade_buy = hasDirectAvailable ? toNumber(directBuy, pairBuy) : pairBuy;
93591
- 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;
93592
93950
  const directMaxBuy = source.max_trade_size_buy;
93593
93951
  const directMaxSell = source.max_trade_size_sell;
93594
93952
  const hasDirectMax = directMaxBuy !== void 0 || directMaxSell !== void 0;
93595
93953
  const [pairMaxBuy, pairMaxSell] = normalizePair(source.maxTradeSzs);
93596
- const max_trade_size_buy = hasDirectMax ? toNumber(directMaxBuy, pairMaxBuy) : pairMaxBuy;
93597
- 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;
93598
93956
  return {
93599
93957
  symbol: String(source.coin || symbol2),
93600
93958
  available_to_trade_buy,
93601
93959
  available_to_trade_sell,
93602
93960
  max_trade_size_buy,
93603
93961
  max_trade_size_sell,
93604
- mark_price: toNumber(source.markPx ?? source.mark_price, 0)
93962
+ mark_price: toNumber2(source.markPx ?? source.mark_price, 0)
93605
93963
  };
93606
93964
  };
93607
93965
  }
93608
93966
  });
93609
93967
 
93610
93968
  // lib/runtime/server-prompt-rescue-account-contract.ts
93611
- var toNumber3, firstNumber2, firstTruthy, spotContainers, extractCanonicalSpotMetrics, sumBalanceValueUsd, approximatelyEqual, balancesMirrorUnifiedAccountValue, computeEffectiveAccountValue, equityFormula, buildServerPromptRescueAccountSummary;
93969
+ var firstNumber2, equityFormula, buildServerPromptRescueAccountSummary;
93612
93970
  var init_server_prompt_rescue_account_contract = __esm({
93613
93971
  "lib/runtime/server-prompt-rescue-account-contract.ts"() {
93614
93972
  "use strict";
@@ -93617,10 +93975,7 @@ var init_server_prompt_rescue_account_contract = __esm({
93617
93975
  init_define_VTX_PI_MODEL_POLICY();
93618
93976
  init_hyperliquid_account_mode_contract();
93619
93977
  init_hyperliquid_account_contract();
93620
- toNumber3 = (value, fallback = 0) => {
93621
- const numeric2 = Number(value);
93622
- return Number.isFinite(numeric2) ? numeric2 : fallback;
93623
- };
93978
+ init_server_loop_account_value();
93624
93979
  firstNumber2 = (values, fallback = 0) => {
93625
93980
  for (const value of values) {
93626
93981
  if (value == null || value === "") continue;
@@ -93629,119 +93984,6 @@ var init_server_prompt_rescue_account_contract = __esm({
93629
93984
  }
93630
93985
  return fallback;
93631
93986
  };
93632
- firstTruthy = (values, fallback) => {
93633
- for (const value of values) {
93634
- if (value) return value;
93635
- }
93636
- return fallback;
93637
- };
93638
- spotContainers = (spotResponse) => {
93639
- if (!spotResponse || typeof spotResponse !== "object" || Array.isArray(spotResponse)) return [];
93640
- const response = spotResponse;
93641
- const containers = [response];
93642
- for (const key of ["spotState", "userState", "clearinghouseState", "state", "data"]) {
93643
- const child = response[key];
93644
- if (child && typeof child === "object" && !Array.isArray(child)) containers.push(child);
93645
- }
93646
- return containers;
93647
- };
93648
- extractCanonicalSpotMetrics = (spotResponse) => {
93649
- const response = spotResponse && typeof spotResponse === "object" && !Array.isArray(spotResponse) ? spotResponse : {};
93650
- const containers = spotContainers(response);
93651
- let accountValue = 0;
93652
- let totalMarginUsed = 0;
93653
- let withdrawable = 0;
93654
- for (const container of containers) {
93655
- const marginSummary = container.marginSummary && typeof container.marginSummary === "object" && !Array.isArray(container.marginSummary) ? container.marginSummary : {};
93656
- accountValue = Math.max(accountValue, toNumber3(marginSummary.accountValue));
93657
- totalMarginUsed = Math.max(totalMarginUsed, toNumber3(marginSummary.totalMarginUsed));
93658
- withdrawable = Math.max(withdrawable, toNumber3(container.withdrawable));
93659
- }
93660
- if (accountValue <= 0) {
93661
- for (const key of ["accountValue", "totalValue", "equity", "totalRawUsd", "usdValue", "usdcValue"]) {
93662
- accountValue = Math.max(accountValue, toNumber3(response[key]));
93663
- }
93664
- }
93665
- const balances = [];
93666
- const listKeys = ["balances", "tokenBalances", "spotBalances", "assets"];
93667
- for (const container of containers) {
93668
- for (const listKey of listKeys) {
93669
- const bucket = container[listKey];
93670
- if (!Array.isArray(bucket)) continue;
93671
- let stableTotal = 0;
93672
- let anyTotal = 0;
93673
- for (const rawEntry of bucket) {
93674
- if (!rawEntry || typeof rawEntry !== "object" || Array.isArray(rawEntry)) continue;
93675
- const entry = rawEntry;
93676
- const coin = String(firstTruthy([
93677
- entry.coin,
93678
- entry.token,
93679
- entry.asset,
93680
- entry.symbol
93681
- ], "")).trim().toUpperCase();
93682
- if (!coin) continue;
93683
- const total = toNumber3(firstTruthy([entry.total, entry.balance, entry.amount], "0"));
93684
- const hold = toNumber3(firstTruthy([entry.hold, entry.locked], "0"));
93685
- const available = Math.max(
93686
- 0,
93687
- toNumber3(firstTruthy([entry.available, entry.free, total - hold], "0"))
93688
- );
93689
- let valueUsd = toNumber3(firstTruthy([entry.usdValue, entry.usdcValue], "0"));
93690
- if (valueUsd <= 0 && STABLE_SPOT_SYMBOLS.has(coin)) {
93691
- valueUsd = available > 0 ? available : total;
93692
- }
93693
- balances.push({ coin, total, hold, available, value_usd: valueUsd });
93694
- const entryValue = valueUsd > 0 ? valueUsd : total;
93695
- if (entryValue > 0) {
93696
- anyTotal += entryValue;
93697
- if (STABLE_SPOT_SYMBOLS.has(coin)) stableTotal += entryValue;
93698
- }
93699
- }
93700
- if (accountValue <= 0) {
93701
- if (stableTotal > 0) accountValue = stableTotal;
93702
- else if (anyTotal > 0) accountValue = anyTotal;
93703
- }
93704
- }
93705
- if (balances.length > 0) break;
93706
- }
93707
- return { accountValue, totalMarginUsed, withdrawable, balances };
93708
- };
93709
- sumBalanceValueUsd = (balances) => balances.reduce((total, balance) => {
93710
- let valueUsd = toNumber3(balance.value_usd);
93711
- if (valueUsd <= 0 && STABLE_SPOT_SYMBOLS.has(String(balance.coin || "").trim().toUpperCase())) {
93712
- valueUsd = toNumber3(balance.total);
93713
- }
93714
- return total + Math.max(valueUsd, 0);
93715
- }, 0);
93716
- approximatelyEqual = (left, right, absoluteToleranceUsd, relativeTolerance) => {
93717
- const reference = Math.max(Math.abs(left), Math.abs(right), 1);
93718
- return Math.abs(left - right) <= Math.max(absoluteToleranceUsd, reference * relativeTolerance);
93719
- };
93720
- balancesMirrorUnifiedAccountValue = (input) => input.perpsEquity > 0 && input.spotEquity > 0 && input.balancesEquity > 0 && approximatelyEqual(
93721
- input.perpsEquity,
93722
- input.spotEquity,
93723
- input.absoluteToleranceUsd,
93724
- input.relativeTolerance
93725
- ) && approximatelyEqual(
93726
- input.spotEquity,
93727
- input.balancesEquity,
93728
- input.absoluteToleranceUsd,
93729
- input.relativeTolerance
93730
- );
93731
- computeEffectiveAccountValue = (input) => {
93732
- if (!input.unifiedLike) return input.perpsEquity;
93733
- if (input.balancesEquity > 0) {
93734
- if (input.mirrored) {
93735
- return Math.max(input.perpsEquity, input.spotEquity, input.balancesEquity);
93736
- }
93737
- return Math.max(
93738
- input.perpsEquity + input.balancesEquity,
93739
- input.spotEquity,
93740
- input.balancesEquity
93741
- );
93742
- }
93743
- return Math.max(input.perpsEquity, input.spotEquity);
93744
- };
93745
93987
  equityFormula = (input) => {
93746
93988
  if (!input.unifiedLike) return "perps_account_value";
93747
93989
  if (input.balancesEquity > 0) {
@@ -93756,11 +93998,11 @@ var init_server_prompt_rescue_account_contract = __esm({
93756
93998
  const perps = perpsResponse && typeof perpsResponse === "object" && !Array.isArray(perpsResponse) ? perpsResponse : {};
93757
93999
  const marginSummary = perps.marginSummary && typeof perps.marginSummary === "object" && !Array.isArray(perps.marginSummary) ? perps.marginSummary : {};
93758
94000
  const crossMarginSummary = perps.crossMarginSummary && typeof perps.crossMarginSummary === "object" && !Array.isArray(perps.crossMarginSummary) ? perps.crossMarginSummary : {};
93759
- const rawPerpsAccountValue = toNumber3(marginSummary.accountValue);
94001
+ const rawPerpsAccountValue = toNumber(marginSummary.accountValue);
93760
94002
  const perpsAccountValue = Math.max(0, rawPerpsAccountValue);
93761
- const crossMarginAccountValue = toNumber3(crossMarginSummary.accountValue);
93762
- let totalMarginUsed = toNumber3(marginSummary.totalMarginUsed);
93763
- let withdrawable = toNumber3(perps.withdrawable);
94003
+ const crossMarginAccountValue = toNumber(crossMarginSummary.accountValue);
94004
+ let totalMarginUsed = toNumber(marginSummary.totalMarginUsed);
94005
+ let withdrawable = toNumber(perps.withdrawable);
93764
94006
  const spot = accountMode === "disabled" ? { accountValue: 0, totalMarginUsed: 0, withdrawable: 0, balances: [] } : extractCanonicalSpotMetrics(spotResponse);
93765
94007
  const balances = spot.balances;
93766
94008
  const balancesEquity = sumBalanceValueUsd(balances);
@@ -93792,7 +94034,7 @@ var init_server_prompt_rescue_account_contract = __esm({
93792
94034
  mirrored
93793
94035
  };
93794
94036
  const accountValue = computeEffectiveAccountValue(formulaInput);
93795
- const maintenanceMargin = toNumber3(perps.crossMaintenanceMarginUsed);
94037
+ const maintenanceMargin = toNumber(perps.crossMaintenanceMarginUsed);
93796
94038
  const availableMargin = canonicalAvailableMargin(accountValue, totalMarginUsed);
93797
94039
  let totalNotional = 0;
93798
94040
  let totalUnrealizedPnl = 0;
@@ -93800,10 +94042,10 @@ var init_server_prompt_rescue_account_contract = __esm({
93800
94042
  for (const entry of positions) {
93801
94043
  const position = entry && typeof entry === "object" && !Array.isArray(entry) ? entry.position : null;
93802
94044
  if (!position || typeof position !== "object" || Array.isArray(position)) continue;
93803
- const size = toNumber3(position.szi);
93804
- const unrealizedPnl = toNumber3(position.unrealizedPnl);
94045
+ const size = toNumber(position.szi);
94046
+ const unrealizedPnl = toNumber(position.unrealizedPnl);
93805
94047
  totalUnrealizedPnl += unrealizedPnl;
93806
- totalNotional += Math.abs(size * toNumber3(position.entryPx) + unrealizedPnl);
94048
+ totalNotional += Math.abs(size * toNumber(position.entryPx) + unrealizedPnl);
93807
94049
  }
93808
94050
  return {
93809
94051
  account_value: accountValue,
@@ -93876,7 +94118,7 @@ var init_hyperliquid_fee_contract = __esm({
93876
94118
  });
93877
94119
 
93878
94120
  // lib/runtime/hyperliquid-account-state-adapter.ts
93879
- var USER_FILLS_CACHE_STORAGE_PREFIX, ACCOUNT_STATE_CACHE_STORAGE_PREFIX, browserUserFillsCache, browserUserFillsInFlight, browserAccountStateCache, browserAccountStateInFlight, toPositiveFinite, toFinite, firstFiniteNumber2, parseFundingUsdcFromInfoPosition2, buildUserFillsCacheKey, buildUserFillsStorageKey, buildAccountStateCacheKey, buildAccountStateStorageKey, hasActiveInfoRateLimitCooldown, requireNonNegativeConfigSeconds, requireAccountStateCacheConfig, requireUserFillsCacheConfig, normalizeFillSymbol, buildSymbolFilter, filterFillsBySymbols, readBrowserUserFillsCache, writeBrowserUserFillsCache, cloneBrowserAccountStateResult, withAccountStateEvidence, readBrowserAccountStateCache, writeBrowserAccountStateCache, isRateLimitError, createAbortError, waitForSharedBrowserRequest, waitForSharedBrowserUserFills, normalizeHyperliquidErrorDetail, parseInfoPositions, requireFinitePromptMetric, requirePromptClearinghouseState, requirePromptSpotState, normalizePerpDexName, listConfiguredPerpDexs, listPerpDexsForAccountState, prefixHip3PositionCoins, aggregateClearinghouseResponses, hasCompletePerpDexAccountMetrics, normalizeBrowserFillToTradeHistory, isPerpFill, settleAccountReads, fetchHyperliquidInfoRead, fetchHyperliquidInfoPayload, requireHyperliquidApiUrl, requireWalletAddress3, parseInfoPositionSnapshot, fetchBrowserAccountState2, fetchBrowserAccountStateUncached, fetchBrowserUserFills, fetchBrowserPositionSnapshot;
94121
+ var USER_FILLS_CACHE_STORAGE_PREFIX, ACCOUNT_STATE_CACHE_STORAGE_PREFIX, browserUserFillsCache, browserUserFillsPages, browserUserFillsInFlight, browserAccountStateCache, browserAccountStateInFlight, toPositiveFinite, toFinite, firstFiniteNumber2, parseFundingUsdcFromInfoPosition2, buildUserFillsCacheKey, buildUserFillsStorageKey, buildAccountStateCacheKey, buildAccountStateStorageKey, hasActiveInfoRateLimitCooldown, requireNonNegativeConfigSeconds, requireAccountStateCacheConfig, requireUserFillsCacheConfig, normalizeFillSymbol, buildSymbolFilter, filterFillsBySymbols, readBrowserUserFillsCache, writeBrowserUserFillsCache, cloneBrowserAccountStateResult, withAccountStateEvidence, readBrowserAccountStateCache, writeBrowserAccountStateCache, isRateLimitError, createAbortError, waitForSharedBrowserRequest, waitForSharedBrowserUserFills, normalizeHyperliquidErrorDetail, parseInfoPositions, requireFinitePromptMetric, requirePromptClearinghouseState, requirePromptSpotState, normalizePerpDexName, listConfiguredPerpDexs, listPerpDexsForAccountState, prefixHip3PositionCoins, aggregateClearinghouseResponses, hasCompletePerpDexAccountMetrics, normalizeBrowserFillToTradeHistory, isPerpFill, settleAccountReads, fetchHyperliquidInfoRead, fetchHyperliquidInfoPayload, requireHyperliquidApiUrl, requireWalletAddress3, parseInfoPositionSnapshot, fetchBrowserAccountState2, fetchBrowserAccountStateUncached, mergeNewerUserFills, fetchBrowserUserFills, fetchBrowserPositionSnapshot;
93880
94122
  var init_hyperliquid_account_state_adapter = __esm({
93881
94123
  "lib/runtime/hyperliquid-account-state-adapter.ts"() {
93882
94124
  "use strict";
@@ -93897,6 +94139,7 @@ var init_hyperliquid_account_state_adapter = __esm({
93897
94139
  USER_FILLS_CACHE_STORAGE_PREFIX = "vtx:hyperliquid:user-fills:v1:";
93898
94140
  ACCOUNT_STATE_CACHE_STORAGE_PREFIX = "vtx:hyperliquid:account-state:v1:";
93899
94141
  browserUserFillsCache = /* @__PURE__ */ new Map();
94142
+ browserUserFillsPages = /* @__PURE__ */ new Map();
93900
94143
  browserUserFillsInFlight = /* @__PURE__ */ new Map();
93901
94144
  browserAccountStateCache = /* @__PURE__ */ new Map();
93902
94145
  browserAccountStateInFlight = /* @__PURE__ */ new Map();
@@ -93949,7 +94192,7 @@ var init_hyperliquid_account_state_adapter = __esm({
93949
94192
  buildUserFillsStorageKey = (cacheKey) => {
93950
94193
  return `${USER_FILLS_CACHE_STORAGE_PREFIX}${cacheKey}`;
93951
94194
  };
93952
- buildAccountStateCacheKey = (apiUrl, walletAddress, symbol2, aggregatePerpDexs, scopeAccountSummaryToSelectedDex, dexNames, includeEffectiveTakerRate, includeExactAccountMode, includeActiveAssetData, feeSymbols) => {
94195
+ buildAccountStateCacheKey = (apiUrl, walletAddress, symbol2, aggregatePerpDexs, scopeAccountSummaryToSelectedDex, dexNames, includeEffectiveTakerRate, includeExactAccountMode, includeActiveAssetData, feeSymbols, serverLoopAccountValue2) => {
93953
94196
  return [
93954
94197
  apiUrl.replace(/\/$/, "").toLowerCase(),
93955
94198
  walletAddress.trim().toLowerCase(),
@@ -93959,6 +94202,8 @@ var init_hyperliquid_account_state_adapter = __esm({
93959
94202
  includeEffectiveTakerRate ? "with-effective-taker-rate" : "without-effective-taker-rate",
93960
94203
  includeExactAccountMode ? "with-exact-account-mode" : "without-exact-account-mode",
93961
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"] : [],
93962
94207
  ...dexNames.map(normalizePerpDexName).sort(),
93963
94208
  "fee-symbols",
93964
94209
  ...feeSymbols
@@ -94549,7 +94794,8 @@ var init_hyperliquid_account_state_adapter = __esm({
94549
94794
  includeEffectiveTakerRate,
94550
94795
  includeExactAccountMode,
94551
94796
  includeActiveAssetData,
94552
- [...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
94553
94799
  );
94554
94800
  const now = Date.now();
94555
94801
  const cached2 = readBrowserAccountStateCache(cacheKey);
@@ -94617,17 +94863,19 @@ var init_hyperliquid_account_state_adapter = __esm({
94617
94863
  staleIf429MaxAgeMs
94618
94864
  }) => {
94619
94865
  const metadataBodies = input.includeEffectiveTakerRate === true ? ["", ...dexNames].map((dex) => ({ type: "meta", ...dex ? { dex } : {} })) : [];
94866
+ const accountModeCache = input.publicRequestPriority === "ui" ? "display" : true;
94620
94867
  const reservation = await reserveHyperliquidPublicReads(apiUrl, [
94621
94868
  { type: "clearinghouseState", user: walletAddress },
94622
94869
  ...dexNames.map((dex) => ({ type: "clearinghouseState", user: walletAddress, dex })),
94623
94870
  { type: "spotClearinghouseState", user: walletAddress },
94624
94871
  ...input.includeActiveAssetData === false ? [] : [{ type: "activeAssetData", user: walletAddress, coin: symbol2 }],
94625
94872
  ...input.includeEffectiveTakerRate === true ? [{ type: "userFees", user: walletAddress }, ...metadataBodies] : [],
94626
- ...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 ? [
94627
94875
  { type: "userAbstraction", user: walletAddress },
94628
94876
  { type: "userDexAbstraction", user: walletAddress }
94629
94877
  ] : []
94630
- ], input.signal, { cacheAccountMode: true, cacheValidUntilMs: input.publicReadDeadlineMs });
94878
+ ], input.signal, { cacheAccountMode: accountModeCache, cacheValidUntilMs: input.publicReadDeadlineMs });
94631
94879
  const priorityScope = input.priorityScope ?? createHyperliquidPublicPriorityScope(input.publicRequestPriority);
94632
94880
  reservation.priorityScope = priorityScope;
94633
94881
  if (input.onPublicReadPendingChange) {
@@ -94657,8 +94905,8 @@ var init_hyperliquid_account_state_adapter = __esm({
94657
94905
  return { payload: null, fetchedAtMs: Date.now() };
94658
94906
  }).then((result) => ({ payload: result.payload, capturedAt: new Date(result.fetchedAtMs).toISOString() }))
94659
94907
  }))() : Promise.resolve(null);
94660
- const exactAccountModePromise = input.includeExactAccountMode === true ? (async () => {
94661
- 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 });
94662
94910
  const userAbstraction = abstractionRead.payload;
94663
94911
  let capturedAtMs = abstractionRead.fetchedAtMs;
94664
94912
  const preliminaryMode = extractCanonicalHyperliquidAccountMode(userAbstraction);
@@ -94667,7 +94915,7 @@ var init_hyperliquid_account_state_adapter = __esm({
94667
94915
  }
94668
94916
  let userDexAbstraction;
94669
94917
  if (preliminaryMode === "default" || preliminaryMode === "disabled") {
94670
- 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 });
94671
94919
  userDexAbstraction = dexRead.payload;
94672
94920
  capturedAtMs = Math.min(capturedAtMs, dexRead.fetchedAtMs);
94673
94921
  }
@@ -94678,7 +94926,8 @@ var init_hyperliquid_account_state_adapter = __esm({
94678
94926
  ),
94679
94927
  capturedAt: new Date(capturedAtMs).toISOString()
94680
94928
  };
94681
- })() : Promise.resolve(null);
94929
+ };
94930
+ const exactAccountModePromise = input.includeExactAccountMode === true ? readExactAccountMode() : Promise.resolve(null);
94682
94931
  await awaitAccountReads([userFeesPromise, exactAccountModePromise]);
94683
94932
  const metadataByDex = /* @__PURE__ */ new Map();
94684
94933
  if (input.includeEffectiveTakerRate === true) {
@@ -94787,12 +95036,31 @@ var init_hyperliquid_account_state_adapter = __esm({
94787
95036
  }
94788
95037
  const accountStateConfig = input.config.client_runtime_hyperliquid_account_state;
94789
95038
  const summaryPerpsResponse = exactAccountMode ? { ...accountSummaryPerpsResponse, accountMode: exactAccountMode.accountMode } : accountSummaryPerpsResponse;
94790
- const accountSummaryOptions = {
95039
+ const deviceSummaryOptions = {
94791
95040
  spotDominatesMinTotalUsd: accountStateConfig?.spot_dominates_min_total_usd,
94792
95041
  spotDominatesPerpsMultiplier: accountStateConfig?.spot_dominates_perps_multiplier,
94793
95042
  mirroredAccountValueAbsoluteToleranceUsd: accountStateConfig?.mirrored_account_value_absolute_tolerance_usd,
94794
95043
  mirroredAccountValueRelativeTolerance: accountStateConfig?.mirrored_account_value_relative_tolerance
94795
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
+ };
94796
95064
  const walletSummary = exactAccountMode && input.scopeAccountSummaryToSelectedDex !== true ? buildServerPromptRescueAccountSummary(
94797
95065
  perpsResponse,
94798
95066
  spotResponse,
@@ -94891,6 +95159,24 @@ var init_hyperliquid_account_state_adapter = __esm({
94891
95159
  await releaseHyperliquidPublicReadReservation(reservation);
94892
95160
  }
94893
95161
  };
95162
+ mergeNewerUserFills = (page, newer) => {
95163
+ const startTime = Number(page[0]?.time);
95164
+ if (!Number.isSafeInteger(startTime) || newer.length >= HYPERLIQUID_USER_FILLS_PROVIDER_PAGE_CAP) return null;
95165
+ const overlap = page.filter((fill) => Number(fill.time) === startTime).reverse();
95166
+ if (newer.length < overlap.length) return null;
95167
+ const added = [];
95168
+ for (const [index, fill] of newer.entries()) {
95169
+ if (!fill || typeof fill !== "object" || Array.isArray(fill)) return null;
95170
+ if (index < overlap.length) {
95171
+ if (JSON.stringify(fill) !== JSON.stringify(overlap[index])) return null;
95172
+ continue;
95173
+ }
95174
+ const time3 = Number(fill.time);
95175
+ if (!Number.isSafeInteger(time3) || time3 < startTime) return null;
95176
+ added.push(fill);
95177
+ }
95178
+ return [...added.reverse(), ...page].slice(0, HYPERLIQUID_USER_FILLS_PROVIDER_PAGE_CAP);
95179
+ };
94894
95180
  fetchBrowserUserFills = async (input) => {
94895
95181
  configureHyperliquidMarketSymbolCasing(input.config.client_runtime_hyperliquid_case_sensitive_symbols);
94896
95182
  const apiUrl = requireHyperliquidApiUrl(input.config);
@@ -94953,13 +95239,27 @@ var init_hyperliquid_account_state_adapter = __esm({
94953
95239
  let inFlight = existingFlight?.promise;
94954
95240
  if (!inFlight) {
94955
95241
  let freshRequest;
94956
- freshRequest = fetchHyperliquidInfoPayload(
94957
- apiUrl,
94958
- { type: "userFills", user: walletAddress },
94959
- void 0,
94960
- void 0,
94961
- priority
94962
- ).then((payload) => {
95242
+ const previousPage = browserUserFillsPages.get(cacheKey);
95243
+ freshRequest = (async () => {
95244
+ if (previousPage && previousPage.length > 0) {
95245
+ const newer = await fetchHyperliquidInfoPayload(
95246
+ apiUrl,
95247
+ { type: "userFillsByTime", user: walletAddress, startTime: Number(previousPage[0].time), aggregateByTime: false },
95248
+ void 0,
95249
+ void 0,
95250
+ priority
95251
+ );
95252
+ const page = Array.isArray(newer) ? mergeNewerUserFills(previousPage, newer) : null;
95253
+ if (page) return page;
95254
+ }
95255
+ return fetchHyperliquidInfoPayload(
95256
+ apiUrl,
95257
+ { type: "userFills", user: walletAddress },
95258
+ void 0,
95259
+ void 0,
95260
+ priority
95261
+ );
95262
+ })().then((payload) => {
94963
95263
  const providerRowCount2 = Array.isArray(payload) ? payload.length : 0;
94964
95264
  const rawFills2 = Array.isArray(payload) ? payload.filter(isPerpFill).map((fill) => ({ ...fill })) : [];
94965
95265
  const fillTimes = Array.isArray(payload) ? payload.map((fill) => Number(fill?.time)).filter((time3) => Number.isSafeInteger(time3) && time3 > 0) : [];
@@ -94969,6 +95269,11 @@ var init_hyperliquid_account_state_adapter = __esm({
94969
95269
  providerRowCount: providerRowCount2,
94970
95270
  oldestFillTimeMs: fillTimes.length > 0 ? Math.min(...fillTimes) : null
94971
95271
  };
95272
+ if (Array.isArray(payload) && payload.every((fill) => fill !== null && typeof fill === "object" && !Array.isArray(fill))) {
95273
+ browserUserFillsPages.set(cacheKey, payload);
95274
+ } else {
95275
+ browserUserFillsPages.delete(cacheKey);
95276
+ }
94972
95277
  writeBrowserUserFillsCache(cacheKey, entry);
94973
95278
  return entry;
94974
95279
  }).finally(() => {
@@ -95224,8 +95529,8 @@ var init_protective_evidence = __esm({
95224
95529
  const wallet = String(context.walletAddress ?? "").trim();
95225
95530
  const items = evidenceItems(context.requests ?? []);
95226
95531
  if (items.length === 0 || !wallet) return { reported: 0, nextEvidenceDueAtMs: listedDueAtMs };
95227
- const profileKey = String(context.profileId).trim();
95228
- const backoffUntil = evidenceBackoffUntil.get(profileKey) ?? 0;
95532
+ const profileKey2 = String(context.profileId).trim();
95533
+ const backoffUntil = evidenceBackoffUntil.get(profileKey2) ?? 0;
95229
95534
  if (Date.now() < backoffUntil) {
95230
95535
  return { reported: 0, nextEvidenceDueAtMs: backoffUntil, skipped: "backoff" };
95231
95536
  }
@@ -95268,15 +95573,15 @@ var init_protective_evidence = __esm({
95268
95573
  }
95269
95574
  if (failedCode) {
95270
95575
  const until = Date.now() + EVIDENCE_FAILURE_BACKOFF_MS;
95271
- evidenceBackoffUntil.set(profileKey, until);
95576
+ evidenceBackoffUntil.set(profileKey2, until);
95272
95577
  appendRuntimeDebugEvent({
95273
95578
  label: "client_protective_evidence_rejected",
95274
- note: `profile_id=${profileKey} code=${failedCode}`,
95579
+ note: `profile_id=${profileKey2} code=${failedCode}`,
95275
95580
  outcome: "error"
95276
95581
  });
95277
95582
  return { reported, nextEvidenceDueAtMs: until, failedCode, ...actions ? { actions } : {} };
95278
95583
  }
95279
- evidenceBackoffUntil.delete(profileKey);
95584
+ evidenceBackoffUntil.delete(profileKey2);
95280
95585
  return { reported, nextEvidenceDueAtMs, ...actions ? { actions } : {} };
95281
95586
  },
95282
95587
  () => ({ reported: 0, nextEvidenceDueAtMs: listedDueAtMs, skipped: "reporter_busy" })
@@ -95769,7 +96074,7 @@ var init_client_exchange_mutations = __esm({
95769
96074
  });
95770
96075
 
95771
96076
  // lib/runtime/execution-guard-contract.ts
95772
- var unitsFromPosition, signedUnitsFromPosition, signedUnitsFromEntryPosition, classifyExecutionIntent, resolveExecutionTarget, decisionOrderSizeAsset, flipExecutionLegs;
96077
+ var unitsFromPosition, signedUnitsFromPosition, signedUnitsFromEntryPosition, classifyExecutionIntent, reductionFirstOrder, usdAmount, orderMetadataRetryReason, orderCeilingRefusal, resolveExecutionTarget, decisionOrderSizeAsset, flipExecutionLegs, executedOrderPositionEvent;
95773
96078
  var init_execution_guard_contract = __esm({
95774
96079
  "lib/runtime/execution-guard-contract.ts"() {
95775
96080
  "use strict";
@@ -95965,6 +96270,32 @@ var init_execution_guard_contract = __esm({
95965
96270
  targetSignedUnits: -(units - Math.abs(snapshotSignedUnits))
95966
96271
  };
95967
96272
  };
96273
+ reductionFirstOrder = (plans) => {
96274
+ const reduces = plans.map((plan) => classifyExecutionIntent(plan.decision, plan.units, plan.signedUnits).reduceOnly);
96275
+ return plans.map((_, index) => index).sort((left, right) => Number(reduces[right]) - Number(reduces[left]));
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
+ };
95968
96299
  resolveExecutionTarget = (classified, liveSignedUnits, livePositionDirection) => {
95969
96300
  const liveUnits = Number.isFinite(liveSignedUnits) ? Math.trunc(liveSignedUnits) : 0;
95970
96301
  const exactLiveDirection = livePositionDirection == null ? liveUnits > 0 ? 1 : liveUnits < 0 ? -1 : 0 : livePositionDirection;
@@ -96039,11 +96370,24 @@ var init_execution_guard_contract = __esm({
96039
96370
  }
96040
96371
  ];
96041
96372
  };
96373
+ executedOrderPositionEvent = (intent, side, leg) => {
96374
+ if (side !== "buy" && side !== "sell") throw new Error("An executed order's side must be buy or sell");
96375
+ const sideDirection = side === "buy" ? "LONG" : "SHORT";
96376
+ const oppositeDirection = side === "buy" ? "SHORT" : "LONG";
96377
+ if (intent === "open" || intent === "add") return { positionEvent: intent, positionDirection: sideDirection };
96378
+ if (intent === "reduce" || intent === "close") return { positionEvent: intent, positionDirection: oppositeDirection };
96379
+ if (intent === "flip") {
96380
+ const [closeLeg, entryLeg] = flipExecutionLegs(side, "executed");
96381
+ const flipLeg = leg === entryLeg.leg ? entryLeg : closeLeg;
96382
+ return { positionEvent: flipLeg.positionEvent, positionDirection: flipLeg.positionDirection };
96383
+ }
96384
+ return { positionEvent: null, positionDirection: null };
96385
+ };
96042
96386
  }
96043
96387
  });
96044
96388
 
96045
96389
  // lib/runtime/copy-trading-evidence.ts
96046
- var ACCOUNT_MODE_CACHE_MS, dexList, normalizeRequest, openOrderRefs, EvidenceReadFailed, readClientCopyTradingAccountEvidence, accountEvidenceForUpload, readCopyOrderStatusEvidence, orderStatusEvidenceForAck;
96390
+ var ACCOUNT_MODE_CACHE_MS, dexList2, normalizeRequest, openOrderRefs, EvidenceReadFailed, readClientCopyTradingAccountEvidence, accountEvidenceForUpload, readCopyOrderStatusEvidence, orderStatusEvidenceForAck;
96047
96391
  var init_copy_trading_evidence = __esm({
96048
96392
  "lib/runtime/copy-trading-evidence.ts"() {
96049
96393
  "use strict";
@@ -96057,7 +96401,7 @@ var init_copy_trading_evidence = __esm({
96057
96401
  init_monotonic_clock();
96058
96402
  init_protective_evidence();
96059
96403
  ACCOUNT_MODE_CACHE_MS = runtime_policy_generated_default2.exchange.hyperliquid.client_public_read_budget.account_mode_ttl_seconds * MS_PER_SECOND;
96060
- dexList = (value) => {
96404
+ dexList2 = (value) => {
96061
96405
  if (!Array.isArray(value) || value.some((dex) => typeof dex !== "string")) return null;
96062
96406
  return [...new Set(value.map((dex) => dex.trim()))];
96063
96407
  };
@@ -96065,8 +96409,8 @@ var init_copy_trading_evidence = __esm({
96065
96409
  if (!request || typeof request !== "object") return null;
96066
96410
  const requestId = typeof request.request_id === "string" ? request.request_id.trim() : "";
96067
96411
  const walletAddress = typeof request.wallet_address === "string" ? request.wallet_address.trim() : "";
96068
- const dexes = dexList(request.dexes);
96069
- const openOrdersDexes = dexList(request.open_orders_dexes);
96412
+ const dexes = dexList2(request.dexes);
96413
+ const openOrdersDexes = dexList2(request.open_orders_dexes);
96070
96414
  const maxAgeSeconds = Number(request.max_age_seconds);
96071
96415
  if (!requestId || !walletAddress || !dexes || !openOrdersDexes || !Array.isArray(request.order_refs) || !Number.isFinite(maxAgeSeconds) || maxAgeSeconds <= 0) return null;
96072
96416
  const orderRefs = /* @__PURE__ */ new Map();
@@ -96501,6 +96845,27 @@ var init_protective_leg_evidence = __esm({
96501
96845
  }
96502
96846
  });
96503
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
+
96504
96869
  // lib/runtime/runtime-execution.ts
96505
96870
  function capCopiedToActual(copied, actual) {
96506
96871
  if (Math.abs(copied) <= COPY_TRADING_SIZE_EPSILON) return 0;
@@ -96536,7 +96901,7 @@ function copiedTargetNow(reconciliation, recordedTarget, actualPosition) {
96536
96901
  );
96537
96902
  return { copiedNow, targetNow, kept: copiedTargetBesideOwnPosition(targetNow, copiedNow, actualPosition) };
96538
96903
  }
96539
- 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;
96540
96905
  var init_runtime_execution = __esm({
96541
96906
  "lib/runtime/runtime-execution.ts"() {
96542
96907
  "use strict";
@@ -96563,6 +96928,7 @@ var init_runtime_execution = __esm({
96563
96928
  init_runtime_redaction();
96564
96929
  init_protective_leg_evidence();
96565
96930
  init_protective_stop_replacement();
96931
+ init_protective_entry_cover();
96566
96932
  init_error_surface_contract();
96567
96933
  init_runtime_handoff();
96568
96934
  clientProtectiveMutationAuthority = (request) => request.mutationAuthority === "manual_session" ? {} : {
@@ -96587,7 +96953,13 @@ var init_runtime_execution = __esm({
96587
96953
  const wallet = String(context.walletAddress || "").trim();
96588
96954
  if (!symbol2 || !wallet || !Number.isInteger(context.leverage) || context.leverage <= 0 || !Number.isFinite(context.currentPositionSize) || context.currentPositionSize === 0) return false;
96589
96955
  let active;
96956
+ let target;
96590
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
+ );
96591
96963
  active = await fetchBrowserHyperliquidInfoPayload(
96592
96964
  { config: input.config ?? null, signal: input.signal, publicRequestPriority: "trading_reconcile" },
96593
96965
  { type: "activeAssetData", user: wallet, coin: symbol2 },
@@ -96598,7 +96970,7 @@ var init_runtime_execution = __esm({
96598
96970
  return false;
96599
96971
  }
96600
96972
  const leverage = active?.leverage;
96601
- return leverage?.value === context.leverage && leverage?.type === (context.marginMode === "isolated" ? "isolated" : "cross");
96973
+ return leverage?.value === target.leverage && leverage?.type === (target.isCross ? "cross" : "isolated");
96602
96974
  };
96603
96975
  fetchClientRuntimeOpenOrders = async (request, publicRequestPriority = "trading_reconcile") => {
96604
96976
  const normalizedSymbol = normalizeHyperliquidMarketSymbol(
@@ -97038,7 +97410,9 @@ var init_runtime_execution = __esm({
97038
97410
  const phase = journal.phase == null ? "awaiting_member_outcome" : journal.phase;
97039
97411
  const filledSize = Number(journal.filledSize);
97040
97412
  const averagePrice = Number(journal.averagePrice);
97041
- 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) {
97042
97416
  protectiveGroupReadFailures.add(key);
97043
97417
  return [];
97044
97418
  }
@@ -97048,7 +97422,7 @@ var init_runtime_execution = __esm({
97048
97422
  const clientOrderId = String(member.clientOrderId ?? "").trim().toLowerCase();
97049
97423
  const triggerPrice = Number(member.triggerPrice);
97050
97424
  const size = Number(member.size);
97051
- 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)) {
97052
97426
  return [];
97053
97427
  }
97054
97428
  return [{
@@ -97057,7 +97431,8 @@ var init_runtime_execution = __esm({
97057
97431
  triggerPrice,
97058
97432
  size,
97059
97433
  isTrailing: member.isTrailing,
97060
- positionTpsl: member.positionTpsl
97434
+ positionTpsl: member.positionTpsl,
97435
+ ...typeof member.neverLandedAtMs === "number" ? { neverLandedAtMs: member.neverLandedAtMs } : {}
97061
97436
  }];
97062
97437
  });
97063
97438
  if (members.length !== journal.members.length || pendingEntry == null || legs.length > 0 && (members.length !== legs.length || members.some((member, index) => {
@@ -97072,6 +97447,10 @@ var init_runtime_execution = __esm({
97072
97447
  entryOrderId: journalEntryOrderId,
97073
97448
  filledSize,
97074
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 } : {},
97075
97454
  members
97076
97455
  };
97077
97456
  }
@@ -97832,21 +98211,27 @@ var init_runtime_execution = __esm({
97832
98211
  );
97833
98212
  return { group, cleanup, persistedGroupSet: persistenceFailed ? null : nextGroups };
97834
98213
  };
97835
- storedClientProtectiveCover = async (request, legs) => {
97836
- const cover = { sl: 0, tp: 0 };
97837
- if (legs.length === 0) return cover;
97838
- const symbol2 = request.executionContext.symbol.trim().toUpperCase();
97839
- const orders = await fetchClientRuntimeOpenOrders(request, "trading_reduce");
97840
- if (!Array.isArray(orders)) {
97841
- throw new Error("Malformed live protective-order snapshot.");
97842
- }
97843
- const liveOrderIds = new Set(orders.filter((order) => String(order.coin).trim().toUpperCase() === symbol2).map((order) => String(order.oid)));
97844
- for (const leg of legs) {
97845
- if (typeof leg.orderId === "string" || liveOrderIds.has(String(leg.orderId))) {
97846
- 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));
97847
98232
  }
97848
98233
  }
97849
- return cover;
98234
+ return protectiveEntryCover({ entryIsLong, storedLegs, liveOrderIds });
97850
98235
  };
97851
98236
  attachClientProtectivePlan = async (request, group, fill) => {
97852
98237
  const reports = [];
@@ -97944,10 +98329,7 @@ var init_runtime_execution = __esm({
97944
98329
  const liveExposure = Math.abs(livePositionSize);
97945
98330
  let storedCover;
97946
98331
  try {
97947
- storedCover = await storedClientProtectiveCover(
97948
- request,
97949
- existingGroups.flatMap((existing) => existing.legs)
97950
- );
98332
+ storedCover = await storedClientProtectiveCover(request, isLong, existingGroups);
97951
98333
  } catch (error48) {
97952
98334
  if (request.signal?.aborted) throw error48;
97953
98335
  reports.push({
@@ -97963,9 +98345,12 @@ var init_runtime_execution = __esm({
97963
98345
  return reports;
97964
98346
  }
97965
98347
  const allocatedCandidates = planned.flatMap((candidate) => {
97966
- const allocated = storedCover[candidate.kind];
97967
98348
  const size = roundAssetSize(
97968
- Math.min(fill.filledSize, Math.max(0, liveExposure - allocated)),
98349
+ protectiveEntryLegSize({
98350
+ filledSize: fill.filledSize,
98351
+ liveExposure,
98352
+ cover: storedCover[candidate.kind]
98353
+ }),
97969
98354
  request.executionContext.sizeDecimals
97970
98355
  );
97971
98356
  if (!Number.isFinite(size) || size <= 0) {
@@ -98073,6 +98458,9 @@ var init_runtime_execution = __esm({
98073
98458
  entryOrderId: fill.orderId,
98074
98459
  filledSize: fill.filledSize,
98075
98460
  averagePrice: fill.averagePrice,
98461
+ // One signed mutation carries every member (its first member's).
98462
+ mutationId: candidates[0].mutationId,
98463
+ createdAtMs: Date.now(),
98076
98464
  members: candidates.map((candidate) => ({
98077
98465
  kind: candidate.kind,
98078
98466
  clientOrderId: candidate.clientOrderId,
@@ -98585,6 +98973,82 @@ var init_runtime_execution = __esm({
98585
98973
  const endedAt = evidence.statusTimestampMs;
98586
98974
  return placedAt != null && endedAt != null && endedAt > placedAt;
98587
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
+ };
98588
99052
  recoverJournaledClientProtectiveAttachments = async (request, journaledGroups) => {
98589
99053
  const reports = [];
98590
99054
  const profileId = String(request.profileId).trim();
@@ -98606,24 +99070,64 @@ var init_runtime_execution = __esm({
98606
99070
  }
98607
99071
  })));
98608
99072
  }
98609
- 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;
98610
99076
  const plan = group.pendingEntry;
98611
- const journal = group.attachmentJournal;
99077
+ let journal = group.attachmentJournal;
98612
99078
  if (plan == null || journal == null || group.legs.length === 0) continue;
98613
99079
  const inspected = [];
98614
99080
  let unresolved = false;
99081
+ let ledgerVerdict = null;
99082
+ const newlyNeverLanded = /* @__PURE__ */ new Set();
98615
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
+ }
98616
99088
  let openOrder = liveOrders.find((order) => String(order.oid) === String(provisionalLeg.orderId)) ?? null;
98617
99089
  let canonicalLeg = provisionalLeg;
98618
99090
  if (openOrder == null) {
98619
99091
  try {
98620
- const evidence = await fetchBrowserOrderStatusEvidence({
99092
+ let evidence = await fetchBrowserOrderStatusEvidence({
98621
99093
  publicRequestPriority: "trading_reconcile",
98622
99094
  config: request.config ?? null,
98623
99095
  walletAddress,
98624
99096
  signal: request.signal,
98625
99097
  orderId: provisionalLeg.orderId
98626
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
+ }
98627
99131
  const resolvedOrderId = Number(evidence.orderId);
98628
99132
  if (!Number.isSafeInteger(resolvedOrderId) || resolvedOrderId <= 0) {
98629
99133
  throw new Error("Journaled protective order identity is unresolved.");
@@ -98691,6 +99195,28 @@ var init_runtime_execution = __esm({
98691
99195
  inspected.push({ leg: canonicalLeg, state: "open" });
98692
99196
  }
98693
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
+ }
98694
99220
  const hasFulfilled = inspected.some((entry) => entry.state === "fulfilled");
98695
99221
  const hasNonfulfilledTerminal = inspected.some((entry) => entry.state === "terminal");
98696
99222
  const openEntries = inspected.filter((entry) => entry.state === "open");
@@ -98935,6 +99461,47 @@ var init_runtime_execution = __esm({
98935
99461
  });
98936
99462
  continue;
98937
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
+ }
98938
99505
  let disposition;
98939
99506
  try {
98940
99507
  ({ disposition } = await resolveJournaledAttachmentContinuity(
@@ -98976,20 +99543,35 @@ var init_runtime_execution = __esm({
98976
99543
  }
98977
99544
  return reports;
98978
99545
  };
98979
- readPendingEntryMutation = async (request, plan) => {
99546
+ readClientOrderMutation = async (request, mutationId, clientOrderId) => {
98980
99547
  try {
98981
99548
  const mutation = await getClientRuntimeExchangeMutation(
98982
99549
  request.profileId,
98983
- plan.entryMutationId,
99550
+ mutationId,
98984
99551
  request.signal
98985
99552
  );
98986
99553
  if (mutation == null) return { kind: "absent" };
98987
- 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" };
98988
99555
  } catch (error48) {
98989
99556
  if (request.signal?.aborted) throw error48;
98990
99557
  return { kind: "unavailable" };
98991
99558
  }
98992
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
+ };
98993
99575
  requireClientRuntimeConfigSeconds = (config2, key) => {
98994
99576
  const value = Number(config2?.[key]);
98995
99577
  if (!Number.isFinite(value) || value < 0) {
@@ -99130,10 +99712,6 @@ var init_runtime_execution = __esm({
99130
99712
  });
99131
99713
  if (evidence.responseValid && evidence.responseStatus === "unknownOid") {
99132
99714
  const observedAtMs = Date.now();
99133
- const marginMs = requireClientRuntimeConfigSeconds(
99134
- request.config,
99135
- "client_pending_entry_never_landed_margin_seconds"
99136
- ) * MS_PER_SECOND;
99137
99715
  const firstSeenAtMs = plan.recovery?.unknownOidFirstSeenAtMs ?? observedAtMs;
99138
99716
  const recordFirstSeen = () => {
99139
99717
  if (plan.recovery?.unknownOidFirstSeenAtMs != null) return;
@@ -99148,16 +99726,12 @@ var init_runtime_execution = __esm({
99148
99726
  if (!Number.isSafeInteger(expiresAfterMs) || expiresAfterMs <= 0) {
99149
99727
  throw new Error("Pending entry is unknown to Hyperliquid and its signed expiry is unavailable.");
99150
99728
  }
99151
- provableAtMs = expiresAfterMs + marginMs;
99729
+ provableAtMs = clientOrderNeverLandsAfterMs(request.config, { kind: "found", expiresAfterMs });
99152
99730
  } else if (ledger.kind === "absent") {
99153
- const ageStartMs = plan.createdAtMs ?? firstSeenAtMs;
99154
- const signedLifetimeSeconds = Number(
99155
- request.config?.client_runtime_exchange_mutation?.expires_after_seconds
99156
- );
99157
- if (!Number.isInteger(signedLifetimeSeconds) || signedLifetimeSeconds <= 0) {
99158
- throw new Error("Missing required client runtime config: client_runtime_exchange_mutation.expires_after_seconds");
99159
- }
99160
- provableAtMs = ageStartMs + signedLifetimeSeconds * MS_PER_SECOND + marginMs;
99731
+ provableAtMs = clientOrderNeverLandsAfterMs(request.config, {
99732
+ kind: "absent",
99733
+ ageStartMs: plan.createdAtMs ?? firstSeenAtMs
99734
+ });
99161
99735
  } else {
99162
99736
  recordFirstSeen();
99163
99737
  throw new Error("Pending entry is unknown to Hyperliquid and the ledger cannot answer.");
@@ -100000,37 +100574,16 @@ var init_runtime_execution = __esm({
100000
100574
  }]
100001
100575
  });
100002
100576
  const observedAtMs = Date.now();
100003
- const marginMs = requireClientRuntimeConfigSeconds(
100004
- request.config,
100005
- "client_pending_entry_never_landed_margin_seconds"
100006
- ) * MS_PER_SECOND;
100007
- let ledgerKind;
100008
- let expiresAfterMs = Number.NaN;
100009
- try {
100010
- const mutation = await getClientRuntimeExchangeMutation(request.profileId, journal.mutationId, request.signal);
100011
- if (mutation == null) {
100012
- ledgerKind = "absent";
100013
- } else if (mutation.operation_kind === "order" && String(mutation.client_order_id ?? "").trim().toLowerCase() === String(leg.orderId)) {
100014
- ledgerKind = "found";
100015
- expiresAfterMs = Number(mutation.exchange_expires_after_ms);
100016
- } else {
100017
- ledgerKind = "unavailable";
100018
- }
100019
- } catch (error48) {
100020
- if (request.signal?.aborted) throw error48;
100021
- ledgerKind = "unavailable";
100022
- }
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;
100023
100579
  let provableAtMs;
100024
- if (ledgerKind === "found" && Number.isSafeInteger(expiresAfterMs) && expiresAfterMs > 0) {
100025
- provableAtMs = expiresAfterMs + marginMs;
100026
- } else if (ledgerKind === "absent") {
100027
- const signedLifetimeSeconds = Number(
100028
- request.config?.client_runtime_exchange_mutation?.expires_after_seconds
100029
- );
100030
- if (!Number.isInteger(signedLifetimeSeconds) || signedLifetimeSeconds <= 0) {
100031
- throw new Error("Missing required client runtime config: client_runtime_exchange_mutation.expires_after_seconds");
100032
- }
100033
- 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
+ });
100034
100587
  } else {
100035
100588
  return waiting("protective_stop_replacement_unresolved", "The stop re-place ledger cannot answer yet.");
100036
100589
  }
@@ -101129,7 +101682,7 @@ var init_runtime_execution = __esm({
101129
101682
  isLong: group.isLong,
101130
101683
  positionTpsl: leg.positionTpsl === true
101131
101684
  }] : []));
101132
- if (currentPositionSize === 0) {
101685
+ if (currentPositionSize === 0 || tracked.length === 0) {
101133
101686
  writeTrackedTrailingStops(profileId, symbol2, []);
101134
101687
  return [];
101135
101688
  }
@@ -101505,7 +102058,64 @@ var init_runtime_execution = __esm({
101505
102058
  const parsed = Number(position?.size ?? 0);
101506
102059
  return Number.isFinite(parsed) ? parsed : 0;
101507
102060
  };
101508
- 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") => {
101509
102119
  throwIfAborted2(input.signal);
101510
102120
  const snapshotPositionSize = Number.isFinite(input.executionContext.currentPositionSize) ? Number(input.executionContext.currentPositionSize) : 0;
101511
102121
  const decisionPrice = Number.isFinite(input.executionContext.lastPrice) ? Number(input.executionContext.lastPrice) : 0;
@@ -101517,7 +102127,7 @@ var init_runtime_execution = __esm({
101517
102127
  const decisionCapturedAtMs = Date.parse(String(input.executionContext.decisionSnapshotCapturedAt || ""));
101518
102128
  const maxAgeSeconds = Number(input.executionContext.executionFreshnessMaxAgeSeconds);
101519
102129
  const shouldRefreshExecutionSnapshot = Number.isFinite(decisionCapturedAtMs) && Number.isFinite(maxAgeSeconds) && maxAgeSeconds > 0 && (nowMs2 - decisionCapturedAtMs) / MS_PER_SECOND > maxAgeSeconds;
101520
- if (shouldRefreshExecutionSnapshot) {
102130
+ if (shouldRefreshExecutionSnapshot && orderPrice !== "fresh_mark") {
101521
102131
  try {
101522
102132
  const refreshed = await fetchBrowserAccountState2({
101523
102133
  publicRequestPriority: executionReadPriority(input),
@@ -101560,10 +102170,12 @@ var init_runtime_execution = __esm({
101560
102170
  symbol: input.executionContext.symbol,
101561
102171
  size: liveBrowserSnapshot.size
101562
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);
101563
102175
  return {
101564
102176
  currentPositionSize: Number.isFinite(parsedLiveSize) ? parsedLiveSize : snapshotPositionSize,
101565
102177
  currentPositionEntryPrice: liveBrowserSnapshot.entryPrice,
101566
- executionPrice: decisionPrice,
102178
+ executionPrice,
101567
102179
  executionSnapshotId: createRuntimeId(),
101568
102180
  executionSnapshotCapturedAt: (/* @__PURE__ */ new Date()).toISOString()
101569
102181
  };
@@ -101598,6 +102210,7 @@ var init_runtime_execution = __esm({
101598
102210
  });
101599
102211
  runtimeProtectionOwners = /* @__PURE__ */ new WeakMap();
101600
102212
  resolveRuntimeProtectionOwner = (request) => {
102213
+ if (request.executionMode === "server") return Promise.resolve("server");
101601
102214
  const cached2 = runtimeProtectionOwners.get(request);
101602
102215
  if (cached2) return cached2;
101603
102216
  const authority = runtimeProtectionAuthority(request);
@@ -101739,7 +102352,7 @@ var init_runtime_execution = __esm({
101739
102352
  () => withClientExecutionMutation(request, work),
101740
102353
  request.signal
101741
102354
  );
101742
- allocateServerExecutionCapacity = async (authority, plans) => {
102355
+ allocateServerExecutionCapacity = async (authority, plans, cycleStartedAt) => {
101743
102356
  if (plans.length === 0) return [];
101744
102357
  try {
101745
102358
  return await checkServerHostExecutionCapacity(
@@ -101749,11 +102362,12 @@ var init_runtime_execution = __esm({
101749
102362
  authority.sessionId,
101750
102363
  authority.runtimeLeaseToken,
101751
102364
  authority.runtimeDeviceId,
101752
- authority.schedulerInstanceId
102365
+ authority.schedulerInstanceId,
102366
+ cycleStartedAt
101753
102367
  );
101754
- } catch {
102368
+ } catch (error48) {
101755
102369
  throwIfAborted2(authority.signal);
101756
- return plans.map(() => "unavailable");
102370
+ return plans.map(() => ({ unavailable: error48 }));
101757
102371
  }
101758
102372
  };
101759
102373
  withClientProtectiveAdoptionMutation = (profileId, work, signal) => withClientExecutionMutation({ profileId: String(profileId).trim(), signal }, work);
@@ -101765,12 +102379,31 @@ var init_runtime_execution = __esm({
101765
102379
  throw withCommittedExecutionReports(error48, progress.committedReports);
101766
102380
  }
101767
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
+ };
101768
102403
  SERVER_AUDIT_RECORDED_ELSEWHERE = /* @__PURE__ */ new Set([
101769
102404
  "suppressed_duplicate_decision",
101770
102405
  "same_intent_cooldown",
101771
- "redis_unavailable",
101772
- "execution_capacity_refused",
101773
- "execution_capacity_unavailable"
102406
+ "execution_capacity_refused"
101774
102407
  ]);
101775
102408
  serverExecutionAuditOutcome = (result) => {
101776
102409
  if (result.status === "executed") {
@@ -101780,7 +102413,7 @@ var init_runtime_execution = __esm({
101780
102413
  return ["executed", "executed"];
101781
102414
  }
101782
102415
  if (result.status === "skipped") {
101783
- 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") {
101784
102417
  return ["noop", result.reasonCode];
101785
102418
  }
101786
102419
  if (result.reasonCode === "protective_reconciliation_unresolved") return ["blocked", result.reasonCode];
@@ -101900,7 +102533,7 @@ var init_runtime_execution = __esm({
101900
102533
  reasonCode: blockedByProtection ? "protective_reconciliation_unresolved" : "executed",
101901
102534
  orderId: flipClose.order_id == null ? null : String(flipClose.order_id)
101902
102535
  });
101903
- 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"];
101904
102537
  const entryAuditId = await recordAudit(null, {
101905
102538
  ...auditFields,
101906
102539
  status: entryStatus,
@@ -102361,7 +102994,7 @@ var init_runtime_execution = __esm({
102361
102994
  };
102362
102995
  }
102363
102996
  if (unsizedInput.executionMode === "server" && !unsizedInput.serverCapacityChecked && (unsizedInput.decision === "BUY" || unsizedInput.decision === "SELL") && requestedUnits > 0) {
102364
- const skipped = (reasonCode, message) => ({
102997
+ const skipped = (reasonCode, constraintReasonCode) => ({
102365
102998
  status: "skipped",
102366
102999
  intent: "hold",
102367
103000
  side: null,
@@ -102369,18 +103002,23 @@ var init_runtime_execution = __esm({
102369
103002
  requestedUnits,
102370
103003
  targetSignedUnits: 0,
102371
103004
  executedSizeAsset: 0,
102372
- executionReports: [],
102373
- 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}.`,
102374
103012
  reasonCode,
102375
103013
  executionSnapshotId: createRuntimeId(),
102376
103014
  executionSnapshotCapturedAt: (/* @__PURE__ */ new Date()).toISOString()
102377
103015
  });
102378
103016
  const capacity = unsizedInput.serverCapacityAllocation ?? (await allocateServerExecutionCapacity(unsizedInput, [
102379
103017
  { symbol: unsizedInput.executionContext.symbol, decision: unsizedInput.decision, units: requestedUnits }
102380
- ]))[0];
102381
- if (capacity === "unavailable") {
103018
+ ], unsizedInput.executionContext.decisionSnapshotCapturedAt))[0];
103019
+ if ("unavailable" in capacity) {
102382
103020
  throwIfAborted2(unsizedInput.signal);
102383
- return skipped("execution_capacity_unavailable", "Execution skipped: Failed to fetch positions before limit check.");
103021
+ throw capacity.unavailable instanceof Error ? capacity.unavailable : new Error("Positions could not be read before the limit check.");
102384
103022
  }
102385
103023
  if (!capacity.accepted || !(capacity.units > 0)) {
102386
103024
  appendRuntimeDebugEvent({
@@ -102388,13 +103026,19 @@ var init_runtime_execution = __esm({
102388
103026
  note: `symbol=${unsizedInput.executionContext.symbol} reason=${capacity.reason_code ?? "unknown"}`,
102389
103027
  outcome: "ok"
102390
103028
  });
102391
- return skipped("execution_capacity_refused", `Skipped: runtime constraint ${capacity.reason_code ?? "capacity"}.`);
103029
+ return skipped("execution_capacity_refused", capacity.reason_code ?? "capacity_reached");
102392
103030
  }
102393
- return executeClientRuntimeDecisionUnlocked({
103031
+ const acceptedUnits = Math.min(requestedUnits, Math.trunc(capacity.units));
103032
+ const result = await executeClientRuntimeDecisionUnlocked({
102394
103033
  ...unsizedInput,
102395
- units: Math.min(requestedUnits, Math.trunc(capacity.units)),
103034
+ units: acceptedUnits,
102396
103035
  serverCapacityChecked: true
102397
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;
102398
103042
  }
102399
103043
  const input = {
102400
103044
  ...unsizedInput,
@@ -102486,13 +103130,15 @@ var init_runtime_execution = __esm({
102486
103130
  executionSnapshotCapturedAt: (/* @__PURE__ */ new Date()).toISOString()
102487
103131
  };
102488
103132
  }
103133
+ const serverOrder = input.executionMode === "server";
102489
103134
  const {
102490
103135
  currentPositionSize,
102491
103136
  currentPositionEntryPrice,
102492
- executionPrice,
103137
+ executionPrice: resolvedExecutionPrice,
102493
103138
  executionSnapshotId,
102494
103139
  executionSnapshotCapturedAt
102495
- } = await resolveCurrentPositionSize(input);
103140
+ } = await resolveCurrentPositionSize(input, serverOrder ? "fresh_mark" : "decision");
103141
+ let executionPrice = resolvedExecutionPrice;
102496
103142
  throwIfAborted2(input.signal);
102497
103143
  const currentPosition = buildPositionSnapshot(input.executionContext.symbol, currentPositionSize);
102498
103144
  const decisionSnapshotId = String(input.executionContext.decisionSnapshotId ?? "").trim();
@@ -102503,6 +103149,15 @@ var init_runtime_execution = __esm({
102503
103149
  leg,
102504
103150
  attempt: 0
102505
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
+ };
102506
103161
  const liveSignedUnits = signedUnitsFromEntryPosition(
102507
103162
  currentPositionSize,
102508
103163
  currentPositionEntryPrice,
@@ -102553,7 +103208,12 @@ var init_runtime_execution = __esm({
102553
103208
  requestedUnits: classified.requestedUnits,
102554
103209
  targetSignedUnits: classified.targetSignedUnits,
102555
103210
  executedSizeAsset: 0,
102556
- 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
+ )],
102557
103217
  message: staleTargetConflict ? "Live state moved beyond the requested target; skipping stale decision" : "No-op: live position already matches target state",
102558
103218
  reasonCode: staleTargetConflict ? "stale_target_conflict" : "noop_already_at_target",
102559
103219
  executionSnapshotId,
@@ -102640,6 +103300,9 @@ var init_runtime_execution = __esm({
102640
103300
  input.runtimeDeviceId,
102641
103301
  input.schedulerInstanceId
102642
103302
  );
103303
+ if (!claim.allowed && claim.reason_code === "redis_unavailable") {
103304
+ throw Object.assign(new Error("Execution coordination was unavailable."), { reasonCode: "redis_unavailable" });
103305
+ }
102643
103306
  if (input.serverExecutionAudit && typeof claim.audit_id === "number") {
102644
103307
  input.serverExecutionAudit.auditId = claim.audit_id;
102645
103308
  }
@@ -102686,8 +103349,9 @@ var init_runtime_execution = __esm({
102686
103349
  if (classified.intent === "close") {
102687
103350
  throwIfAborted2(input.signal);
102688
103351
  const closeMutationId = await decisionLegMutationId("close");
102689
- const closeResponse = await executeClientClosePosition({
102690
- mutationId: closeMutationId,
103352
+ const closeResponse = await closeWithServerMetadataRetry("close", closeMutationId, (mutationId, estimatedPrice, assets) => executeClientClosePosition({
103353
+ mutationId,
103354
+ ...assets ? { assets } : {},
102691
103355
  profileId: input.profileId,
102692
103356
  runtimeSessionId: input.sessionId || "__missing_runtime_session__",
102693
103357
  runtimeLeaseToken: input.runtimeLeaseToken,
@@ -102700,9 +103364,9 @@ var init_runtime_execution = __esm({
102700
103364
  onExchangeOrderDispatched: () => input.onExchangeOrderDispatched?.("action"),
102701
103365
  symbol: input.executionContext.symbol,
102702
103366
  position: currentPosition,
102703
- estimatedPrice: executionPrice,
103367
+ estimatedPrice,
102704
103368
  slippage: input.executionContext.maxSlippageFraction
102705
- });
103369
+ }));
102706
103370
  const confirmedClose = extractCanonicalHyperliquidFilledOrderAcknowledgement(
102707
103371
  closeResponse
102708
103372
  );
@@ -102761,8 +103425,9 @@ var init_runtime_execution = __esm({
102761
103425
  if (targetResolution.closeOpposingPosition) {
102762
103426
  throwIfAborted2(input.signal);
102763
103427
  const flipCloseMutationId = await decisionLegMutationId("flip_close");
102764
- const closeResponse = await executeClientClosePosition({
102765
- mutationId: flipCloseMutationId,
103428
+ const closeResponse = await closeWithServerMetadataRetry("flip_close", flipCloseMutationId, (mutationId, estimatedPrice, assets) => executeClientClosePosition({
103429
+ mutationId,
103430
+ ...assets ? { assets } : {},
102766
103431
  profileId: input.profileId,
102767
103432
  runtimeSessionId: input.sessionId || "__missing_runtime_session__",
102768
103433
  runtimeLeaseToken: input.runtimeLeaseToken,
@@ -102775,9 +103440,9 @@ var init_runtime_execution = __esm({
102775
103440
  onExchangeOrderDispatched: () => input.onExchangeOrderDispatched?.("action"),
102776
103441
  symbol: input.executionContext.symbol,
102777
103442
  position: currentPosition,
102778
- estimatedPrice: executionPrice,
103443
+ estimatedPrice,
102779
103444
  slippage: input.executionContext.maxSlippageFraction
102780
- });
103445
+ }));
102781
103446
  const confirmedFlipClose = extractCanonicalHyperliquidFilledOrderAcknowledgement(
102782
103447
  closeResponse
102783
103448
  );
@@ -102896,6 +103561,7 @@ var init_runtime_execution = __esm({
102896
103561
  isCross: input.executionContext.marginMode !== "isolated"
102897
103562
  });
102898
103563
  throwIfAborted2(input.signal);
103564
+ if (serverOrder) executionPrice = await readServerOrderMarkPrice(input);
102899
103565
  }
102900
103566
  const actualUnits = targetResolution.orderUnits;
102901
103567
  const intendedSizeAsset = decisionOrderSizeAsset({
@@ -102906,7 +103572,7 @@ var init_runtime_execution = __esm({
102906
103572
  entryPrice: currentPositionEntryPrice,
102907
103573
  livePositionSize: currentPositionSize
102908
103574
  });
102909
- 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;
102910
103576
  appendRuntimeDebugEvent({
102911
103577
  label: "execution_size_computed",
102912
103578
  note: `symbol=${input.executionContext.symbol} actualUnits=${actualUnits} sizeAsset=${sizeAsset} price=${executionPrice}`
@@ -102914,7 +103580,7 @@ var init_runtime_execution = __esm({
102914
103580
  if (sizeAsset <= 0) {
102915
103581
  appendRuntimeDebugEvent({
102916
103582
  label: "execution_skipped_zero_size",
102917
- 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}`,
102918
103584
  outcome: "error"
102919
103585
  });
102920
103586
  return {
@@ -102926,13 +103592,27 @@ var init_runtime_execution = __esm({
102926
103592
  requestedUnits: classified.requestedUnits,
102927
103593
  targetSignedUnits: classified.targetSignedUnits,
102928
103594
  executedSizeAsset: 0,
102929
- 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 })],
102930
103598
  message: "Skipped: calculated size is zero",
102931
- reasonCode: "noop_already_at_target",
103599
+ reasonCode: "order_below_lot_size",
102932
103600
  executionSnapshotId,
102933
103601
  executionSnapshotCapturedAt
102934
103602
  };
102935
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
+ }
102936
103616
  const entryRequiresFlatAbsenceProof = Number.isFinite(currentPositionSize) && currentPositionSize === 0 || targetResolution.closeOpposingPosition;
102937
103617
  if (entryRequiresFlatAbsenceProof) {
102938
103618
  const finalProtectionObservation = await verifyNoLiveClientProtectiveTriggers(
@@ -103060,53 +103740,70 @@ var init_runtime_execution = __esm({
103060
103740
  let marketOrderResponse;
103061
103741
  let entryDispatchBoundaryPassed = false;
103062
103742
  let settledServerProtectedEntry = null;
103063
- try {
103064
- marketOrderResponse = await executeClientMarketOrder({
103065
- profileId: input.profileId,
103066
- runtimeSessionId: input.sessionId || "__missing_runtime_session__",
103067
- runtimeLeaseToken: input.runtimeLeaseToken,
103068
- runtimeDeviceId: input.runtimeDeviceId,
103069
- schedulerInstanceId: input.schedulerInstanceId,
103070
- walletAddress: input.executionContext.walletAddress,
103071
- config: input.config ?? null,
103072
- signal: input.signal,
103073
- signingKey: input.signingKey,
103074
- onExchangeOrderDispatched: () => {
103075
- if (persistedProtectiveGroupSet != null && pendingProtectiveCleanup != null && !replaceExactClientProtectiveGroupSet(
103076
- pendingProtectiveCleanup.profileId,
103077
- pendingProtectiveCleanup.symbol,
103078
- persistedProtectiveGroupSet,
103079
- persistedProtectiveGroupSet
103080
- )) {
103081
- throw createClientRuntimeWindowHandoffBeforePlanDispatchError(
103082
- pendingProtectiveCleanup
103083
- );
103084
- }
103085
- input.onExchangeOrderDispatched?.(
103086
- 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
103087
103765
  );
103088
- 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"
103089
103786
  },
103090
- symbol: input.executionContext.symbol,
103091
- side: classified.side,
103092
- size: sizeAsset,
103093
- estimatedPrice: executionPrice,
103094
- slippage: input.executionContext.maxSlippageFraction,
103095
- reduceOnly: classified.reduceOnly,
103096
- mutationId: entryMutationId,
103097
- clientOrderId: entryClientOrderId,
103098
- ...serverOwnedProtection ? {
103099
- // The server attaches the configured Auto SL/TP to this entry.
103100
- protection: {
103101
- source: "runtime_config",
103102
- requested_entry_size: sizeAsset,
103103
- is_long: classified.side === "buy"
103104
- },
103105
- onSettled: (mutation) => {
103106
- settledServerProtectedEntry = mutation;
103107
- }
103108
- } : {}
103109
- });
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
+ }
103110
103807
  } catch (entryDispatchError) {
103111
103808
  const handoffVeto = isClientRuntimeWindowHandoffBeforePlanDispatch(entryDispatchError);
103112
103809
  const handoffBeforeDispatch = handoffVeto || !entryDispatchBoundaryPassed && input.shouldCancelBeforeExchangeOrderDispatch?.() === true;
@@ -103163,7 +103860,7 @@ var init_runtime_execution = __esm({
103163
103860
  symbol: input.executionContext.symbol,
103164
103861
  action: classified.side.toUpperCase(),
103165
103862
  status: "executed",
103166
- execution_metadata: classified.intent === "flip" ? { ..._toExecutionMetadata(marketOrderResponse), decision_leg: "entry" } : _toExecutionMetadata(marketOrderResponse)
103863
+ execution_metadata: classified.intent === "flip" ? { ..._toExecutionMetadata(marketOrderResponse), decision_leg: "entry" } : { ..._toExecutionMetadata(marketOrderResponse), entry_began_flat: livePositionDirection === 0 }
103167
103864
  });
103168
103865
  const appendPostEntryProtectionFailure = (error48) => {
103169
103866
  const projection = projectExecutionErrorContract({
@@ -103330,10 +104027,11 @@ var init_runtime_execution = __esm({
103330
104027
  const kind = triggerInput.isTakeProfit ? "tp" : "sl";
103331
104028
  const alreadyProtected = (liveDirectionMatches ? (await storedClientProtectiveCover(
103332
104029
  input,
104030
+ isLong,
103333
104031
  readClientProtectiveGroups(
103334
104032
  String(input.profileId).trim(),
103335
104033
  input.executionContext.symbol
103336
- ).flatMap((group) => group.legs)
104034
+ )
103337
104035
  ))[kind] : 0) + activeLegs.filter((leg2) => leg2.kind === kind).reduce((total, leg2) => total + leg2.size, 0);
103338
104036
  const liveExposure = Math.abs(livePositionSize);
103339
104037
  const availableExposure = Math.max(0, liveExposure - alreadyProtected);
@@ -104502,6 +105200,7 @@ var init_provider_observability = __esm({
104502
105200
  }
104503
105201
  if (typeof raw.credential_ref === "string" && /^[a-f0-9]{64}$/.test(raw.credential_ref)) result.credential_ref = raw.credential_ref;
104504
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";
104505
105204
  if (typeof raw.quota_project_ref === "string" && /^[a-f0-9]{64}$/.test(raw.quota_project_ref) && raw.quota_project_source === "provider_quota_subject") {
104506
105205
  result.quota_project_ref = raw.quota_project_ref;
104507
105206
  result.quota_project_source = "provider_quota_subject";
@@ -107327,7 +108026,7 @@ var init_client_runtime_status_store = __esm({
107327
108026
  });
107328
108027
 
107329
108028
  // lib/runtime/perp-dex-scope.ts
107330
- var perpDexScopeForSymbols, profileEquityPerpDexScope;
108029
+ var perpDexScopeForSymbols, equityVenuesForSymbols, profileEquityVenues, profileExchanges, positionsOnVenues;
107331
108030
  var init_perp_dex_scope = __esm({
107332
108031
  "lib/runtime/perp-dex-scope.ts"() {
107333
108032
  "use strict";
@@ -107344,9 +108043,27 @@ var init_perp_dex_scope = __esm({
107344
108043
  }
107345
108044
  return dexes.size > 0 ? [...dexes].filter(Boolean) : void 0;
107346
108045
  };
107347
- profileEquityPerpDexScope = (tradingSymbols, defaultTradingSymbols) => perpDexScopeForSymbols(
107348
- (Array.isArray(tradingSymbols) && tradingSymbols.length > 0 ? tradingSymbols : defaultTradingSymbols ?? []).map((entry) => String(entry ?? "").trim()).filter(Boolean)
108046
+ equityVenuesForSymbols = (symbols) => {
108047
+ const venues = /* @__PURE__ */ new Set();
108048
+ for (const raw of symbols) {
108049
+ if (!String(raw ?? "").trim()) continue;
108050
+ if (!normalizeHyperliquidMarketSymbol(raw)) return null;
108051
+ venues.add(getHyperliquidMarketDex(raw));
108052
+ }
108053
+ return venues.size > 0 ? [...venues].sort() : null;
108054
+ };
108055
+ profileEquityVenues = (tradingSymbols, defaultTradingSymbols) => equityVenuesForSymbols(
108056
+ Array.isArray(tradingSymbols) && tradingSymbols.length > 0 ? tradingSymbols : defaultTradingSymbols ?? []
107349
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
+ };
108066
+ positionsOnVenues = (positions, venues) => venues ? positions.filter((position) => normalizeHyperliquidMarketSymbol(position.symbol) && venues.includes(getHyperliquidMarketDex(position.symbol))) : [...positions];
107350
108067
  }
107351
108068
  });
107352
108069
 
@@ -107415,6 +108132,13 @@ var init_client_killswitch = __esm({
107415
108132
  }
107416
108133
  const symbol2 = firstConfiguredSymbol(settings, input.config);
107417
108134
  const leverage = toPositiveFinite2(settings.leverage) ?? 1;
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
+ );
107418
108142
  const accountState = await fetchBrowserAccountState2({
107419
108143
  publicRequestPriority: "trading_reduce",
107420
108144
  config: input.config,
@@ -107423,9 +108147,7 @@ var init_client_killswitch = __esm({
107423
108147
  tickerPrice: 0,
107424
108148
  leverage,
107425
108149
  aggregatePerpDexs: true,
107426
- // Only the DEXes the server measures the killswitch on; a trigger's close
107427
- // re-reads every DEX before closing.
107428
- perpDexScope: profileEquityPerpDexScope(settings.trading_symbols, input.config.default_trading_symbols),
108150
+ perpDexScope: equityVenues?.filter(Boolean),
107429
108151
  forceRefresh: true,
107430
108152
  sessionId: input.sessionId,
107431
108153
  signal: input.signal
@@ -107458,7 +108180,9 @@ var init_client_killswitch = __esm({
107458
108180
  context,
107459
108181
  accountState,
107460
108182
  walletAddress,
107461
- symbol: symbol2
108183
+ symbol: symbol2,
108184
+ equityVenues,
108185
+ closeVenues
107462
108186
  };
107463
108187
  }
107464
108188
  if (!context.snapshot_trusted || context.status === "untrusted") {
@@ -107469,7 +108193,9 @@ var init_client_killswitch = __esm({
107469
108193
  context,
107470
108194
  accountState,
107471
108195
  walletAddress,
107472
- symbol: symbol2
108196
+ symbol: symbol2,
108197
+ equityVenues,
108198
+ closeVenues
107473
108199
  };
107474
108200
  }
107475
108201
  const peakEquity = toPositiveFinite2(context.peak_equity);
@@ -107481,7 +108207,9 @@ var init_client_killswitch = __esm({
107481
108207
  context,
107482
108208
  accountState,
107483
108209
  walletAddress,
107484
- symbol: symbol2
108210
+ symbol: symbol2,
108211
+ equityVenues,
108212
+ closeVenues
107485
108213
  };
107486
108214
  }
107487
108215
  const drawdownPercent = calculateClientKillswitchDrawdownPercent(
@@ -107496,11 +108224,13 @@ var init_client_killswitch = __esm({
107496
108224
  context,
107497
108225
  accountState,
107498
108226
  walletAddress,
107499
- symbol: symbol2
108227
+ symbol: symbol2,
108228
+ equityVenues,
108229
+ closeVenues
107500
108230
  };
107501
108231
  };
107502
108232
  closeClientKillswitchPositions = async (input) => {
107503
- const positions = input.positions.filter((position) => {
108233
+ const positions = positionsOnVenues(input.positions, input.venues).filter((position) => {
107504
108234
  const size = Number(position.size);
107505
108235
  return Number.isFinite(size) && size !== 0;
107506
108236
  });
@@ -107635,13 +108365,13 @@ var init_history_evidence = __esm({
107635
108365
  runClientHistoryAsks = async (context) => {
107636
108366
  let asks = normalizeHistoryAsks(context.asks);
107637
108367
  const wallet = String(context.walletAddress ?? "").trim();
107638
- const profileKey = String(context.profileId).trim();
107639
- if (asks.length === 0 || !wallet || !profileKey) return { reported: 0, rounds: 0, nextAsks: asks };
107640
- if (Date.now() < (historyBackoffUntil.get(profileKey) ?? 0)) {
108368
+ const profileKey2 = String(context.profileId).trim();
108369
+ if (asks.length === 0 || !wallet || !profileKey2) return { reported: 0, rounds: 0, nextAsks: asks };
108370
+ if (Date.now() < (historyBackoffUntil.get(profileKey2) ?? 0)) {
107641
108371
  return { reported: 0, rounds: 0, nextAsks: asks, skipped: "backoff" };
107642
108372
  }
107643
- if (runningProfiles.has(profileKey)) return { reported: 0, rounds: 0, nextAsks: asks, skipped: "busy" };
107644
- runningProfiles.add(profileKey);
108373
+ if (runningProfiles.has(profileKey2)) return { reported: 0, rounds: 0, nextAsks: asks, skipped: "busy" };
108374
+ runningProfiles.add(profileKey2);
107645
108375
  let reported = 0;
107646
108376
  let rounds = 0;
107647
108377
  const maxRounds = Math.max(1, Math.floor(context.maxRounds ?? HISTORY_ROUNDS_PER_BEAT));
@@ -107666,24 +108396,24 @@ var init_history_evidence = __esm({
107666
108396
  reported += Number(answer?.accepted ?? 0);
107667
108397
  asks = normalizeHistoryAsks(answer?.history_asks);
107668
108398
  }
107669
- historyBackoffUntil.delete(profileKey);
108399
+ historyBackoffUntil.delete(profileKey2);
107670
108400
  appendRuntimeDebugEvent({
107671
108401
  label: "client_history_evidence_reported",
107672
- note: `profile_id=${profileKey} rounds=${rounds} accepted=${reported} next=${asks.map((ask) => ask.stream).join(",") || "none"}`
108402
+ note: `profile_id=${profileKey2} rounds=${rounds} accepted=${reported} next=${asks.map((ask) => ask.stream).join(",") || "none"}`
107673
108403
  });
107674
108404
  return { reported, rounds, nextAsks: asks };
107675
108405
  } catch (error48) {
107676
108406
  if (context.signal?.aborted) return { reported, rounds, nextAsks: asks };
107677
108407
  const failedCode = errorCode3(error48) || "history_evidence_read_failed";
107678
- historyBackoffUntil.set(profileKey, Date.now() + HISTORY_RETRY_MS);
108408
+ historyBackoffUntil.set(profileKey2, Date.now() + HISTORY_RETRY_MS);
107679
108409
  appendRuntimeDebugEvent({
107680
108410
  label: "client_history_evidence_failed",
107681
- note: `profile_id=${profileKey} rounds=${rounds} code=${failedCode}`,
108411
+ note: `profile_id=${profileKey2} rounds=${rounds} code=${failedCode}`,
107682
108412
  outcome: "error"
107683
108413
  });
107684
108414
  return { reported, rounds, nextAsks: asks, failedCode };
107685
108415
  } finally {
107686
- runningProfiles.delete(profileKey);
108416
+ runningProfiles.delete(profileKey2);
107687
108417
  }
107688
108418
  };
107689
108419
  }
@@ -107729,11 +108459,11 @@ var init_portfolio_evidence = __esm({
107729
108459
  errorCode4 = (error48) => String(error48?.code ?? "").trim();
107730
108460
  runClientPortfolioReport = async (context) => {
107731
108461
  const wallet = String(context.walletAddress ?? "").trim();
107732
- const profileKey = String(context.profileId).trim();
107733
- if (context.due !== true || !wallet || !profileKey) return { reported: false };
107734
- if (Date.now() < (portfolioBackoffUntil.get(profileKey) ?? 0)) return { reported: false, skipped: "backoff" };
107735
- if (runningProfiles2.has(profileKey)) return { reported: false, skipped: "busy" };
107736
- runningProfiles2.add(profileKey);
108462
+ const profileKey2 = String(context.profileId).trim();
108463
+ if (context.due !== true || !wallet || !profileKey2) return { reported: false };
108464
+ if (Date.now() < (portfolioBackoffUntil.get(profileKey2) ?? 0)) return { reported: false, skipped: "backoff" };
108465
+ if (runningProfiles2.has(profileKey2)) return { reported: false, skipped: "busy" };
108466
+ runningProfiles2.add(profileKey2);
107737
108467
  try {
107738
108468
  const startedAtMonotonicMs = monotonicNowMs();
107739
108469
  const body = await fetchBrowserHyperliquidInfoText(
@@ -107749,25 +108479,25 @@ var init_portfolio_evidence = __esm({
107749
108479
  observed_age_ms: monotonicAgeMs(startedAtMonotonicMs),
107750
108480
  body
107751
108481
  });
107752
- portfolioBackoffUntil.delete(profileKey);
108482
+ portfolioBackoffUntil.delete(profileKey2);
107753
108483
  const reported = Number(answer?.accepted ?? 0) > 0;
107754
108484
  appendRuntimeDebugEvent({
107755
108485
  label: "client_portfolio_evidence_reported",
107756
- note: `profile_id=${profileKey} accepted=${String(reported)} published=${String(Boolean(answer?.published))} ignored=${answer?.ignored ?? "none"}`
108486
+ note: `profile_id=${profileKey2} accepted=${String(reported)} published=${String(Boolean(answer?.published))} ignored=${answer?.ignored ?? "none"}`
107757
108487
  });
107758
108488
  return { reported, published: Boolean(answer?.published) };
107759
108489
  } catch (error48) {
107760
108490
  if (context.signal?.aborted) return { reported: false };
107761
108491
  const failedCode = errorCode4(error48) || "portfolio_evidence_read_failed";
107762
- portfolioBackoffUntil.set(profileKey, Date.now() + PORTFOLIO_RETRY_MS);
108492
+ portfolioBackoffUntil.set(profileKey2, Date.now() + PORTFOLIO_RETRY_MS);
107763
108493
  appendRuntimeDebugEvent({
107764
108494
  label: "client_portfolio_evidence_failed",
107765
- note: `profile_id=${profileKey} code=${failedCode}`,
108495
+ note: `profile_id=${profileKey2} code=${failedCode}`,
107766
108496
  outcome: "error"
107767
108497
  });
107768
108498
  return { reported: false, failedCode };
107769
108499
  } finally {
107770
- runningProfiles2.delete(profileKey);
108500
+ runningProfiles2.delete(profileKey2);
107771
108501
  }
107772
108502
  };
107773
108503
  }
@@ -109292,8 +110022,14 @@ var init_native_provider_budget = __esm({
109292
110022
  init_define_VTX_GROK_POLICY();
109293
110023
  init_define_VTX_PI_MODEL_POLICY();
109294
110024
  NativeModelTimeoutError = class extends Error {
109295
- 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) {
109296
110031
  super("Native model request timed out.");
110032
+ this.attemptCapExpired = attemptCapExpired;
109297
110033
  this.runtimeNativeFailureKind = "timeout";
109298
110034
  this.name = "NativeModelTimeoutError";
109299
110035
  }
@@ -109453,6 +110189,14 @@ function applyNativeRequestParameters(requestBody, parameters, selectedValues, a
109453
110189
  }
109454
110190
  return next;
109455
110191
  }
110192
+ function hasUserSelectedNativeRequestParameters(parameters, selectedValues, apiSurface) {
110193
+ if (!selectedValues) return false;
110194
+ return (parameters || []).some((parameter) => {
110195
+ if (parameter.api_surface !== apiSurface || parameter.app_managed || !parameter.user_visible) return false;
110196
+ const value = selectedValues[nativeParameterIdentity(parameter)];
110197
+ return value !== null && value !== void 0 && value !== "";
110198
+ });
110199
+ }
109456
110200
  function filterNativeRequestParameterValues(parameters, values, options = {}) {
109457
110201
  const selectedValues = values || {};
109458
110202
  const filtered = {};
@@ -109527,7 +110271,7 @@ var init_native_request_parameters = __esm({
109527
110271
  });
109528
110272
 
109529
110273
  // lib/runtime/provider-client.ts
109530
- var mapOpenAiCompatibleNativeRequestPath, isRetryableProviderFailureForFallback, extractRuntimeProviderFailureStatusCode, isModelSpecificProviderFailure, isKeySpecificOrTransientProviderFailure, providerDispatchClockMs, beginProviderDispatch, providerDispatchLatencyMs, attachProviderDispatchFailure, attachProviderFailureTrace, toRuntimeExecutionMode, buildNoneReasoningPayload, normalizeLevelValue, buildRuntimeReasoningPayload, resolveProviderReasoningParameters, requestedReasoningParameters, usesReasoningCompletionTokens, shouldRequestReasoningTrace, normalizeProviderToken, runtimeProviderForByokProvider, findByokProviderForRuntime, findNativeRequestParametersForModel, modelHasNativeRequestApiSurface, setDottedRequestValue, normalizeProviderMaxTokens, applyRuntimeRequestContract, normalizeProvider2, requireProviderEndpoint, SSE_DATA_FIELD_PREFIX2, estimateTokenCount, normalizeUsageCount, buildOpenAiUsagePayload, buildAnthropicUsagePayload, buildGoogleUsagePayload, normalizeProviderUsageMetrics, providerResponseSignals, fetchProvider, readProviderPayload, emitRuntimeDelta, readProviderTextStream, extractOpenAiCompatibleDeltaText, readOpenAiCompatibleTextStream, rawProviderTextForDebug, extractProviderErrorDetail, buildCanonicalProviderFailureMessage, toProviderNetworkDebugError, REASONING_ONLY_CONTENT_TYPES, extractOpenAiContentPartText, extractOpenAiReasoningPartText, extractOpenAiMessageContent, extractOpenAiMessageReasoningContent, extractOpenAiCompatibleText, normalizeRuntimeChatHistory, calculateProviderCost, callOpenAiCompatible, extractOpenAiResponsesText, extractOpenAiResponsesReasoning, callOpenAiResponses, extractAnthropicMessageText, extractAnthropicReasoningContent, callAnthropic, isVertexExpressKey, googlePublicModelIdRegexes, shouldUseGooglePublicEndpointForModel, normalizeGoogleModelId, shouldRetryGoogleVertexRequestPublicly, GOOGLE_VERTEX_PUBLIC_RETRY_NOTE, buildGoogleRequest, isGoogleReasoningPart, extractGoogleMessageText, extractGoogleReasoningContent, extractGoogleSafetyMetadata, GOOGLE_BLOCKED_FINISH_REASONS, googleProviderBlockReason, callGoogle, resolveRuntimeProvider, defaultInvocationContext, defaultProviderTransport, invocationFailureCode, buildBrowserInvocation, resolveProviderSecretKey, resolveNativeProviderCredentialSlots, resolveProviderSecretKeySlots, requireOpenAiCompatibleRuntimeBaseUrl, runtimeSubscriptionPlan, runtimeKeySlotSupportsModel, invokeRuntimeProviderAttempt, runtimeProviderInvoker, invokeRuntimeProvider;
110274
+ var mapOpenAiCompatibleNativeRequestPath, isRetryableProviderFailureForFallback, extractRuntimeProviderFailureStatusCode, isModelSpecificProviderFailure, emptyProviderContentError, isEmptyProviderContentFailure, emptyReplyForInternalAttempt, isEmptyProviderMessageFailure, isRetryableProviderAttemptFailure, providerRejectedRequestError, OPTIONAL_CONTRACT_PARAMETER_TOKENS, OPTIONAL_CONTRACT_REJECTION_TOKENS, OPTIONAL_CONTRACT_GRAMMAR_TOKENS, isOptionalContractParameterRejection, OPTIONAL_CONTRACT_REQUEST_KEYS, OPTIONAL_CONTRACT_EXTRA_BODY_KEYS, resolveEmptyContentRetryPolicy, isKeySpecificOrTransientProviderFailure, providerDispatchClockMs, beginProviderDispatch, providerDispatchLatencyMs, attachProviderDispatchFailure, attachProviderFailureTrace, toRuntimeExecutionMode, buildNoneReasoningPayload, normalizeLevelValue, buildRuntimeReasoningPayload, resolveProviderReasoningParameters, requestedReasoningParameters, usesReasoningCompletionTokens, shouldRequestReasoningTrace, normalizeProviderToken, runtimeProviderForByokProvider, findByokProviderForRuntime, findNativeRequestParametersForModel, modelHasNativeRequestApiSurface, asRequestRecord, setDottedRequestValue, normalizeProviderMaxTokens, applyRuntimeRequestContract, normalizeProvider2, requireProviderEndpoint, SSE_DATA_FIELD_PREFIX2, estimateTokenCount, normalizeUsageCount, buildOpenAiUsagePayload, buildAnthropicUsagePayload, buildGoogleUsagePayload, normalizeProviderUsageMetrics, providerResponseSignals, fetchProvider, readProviderPayload, emitRuntimeDelta, readProviderTextStream, extractOpenAiCompatibleDeltaText, readOpenAiCompatibleTextStream, rawProviderTextForDebug, extractProviderErrorDetail, buildCanonicalProviderFailureMessage, toProviderNetworkDebugError, REASONING_ONLY_CONTENT_TYPES, extractOpenAiContentPartText, extractOpenAiReasoningPartText, extractOpenAiMessageContent, extractOpenAiMessageReasoningContent, extractOpenAiCompatibleText, normalizeRuntimeChatHistory, calculateProviderCost, callOpenAiCompatible, extractOpenAiResponsesText, extractOpenAiResponsesReasoning, callOpenAiResponses, extractAnthropicMessageText, extractAnthropicReasoningContent, callAnthropic, isVertexExpressKey, googlePublicModelIdRegexes, shouldUseGooglePublicEndpointForModel, normalizeGoogleModelId, shouldRetryGoogleVertexRequestPublicly, GOOGLE_VERTEX_PUBLIC_RETRY_NOTE, buildGoogleRequest, isGoogleReasoningPart, extractGoogleMessageText, extractGoogleReasoningContent, extractGoogleSafetyMetadata, GOOGLE_BLOCKED_FINISH_REASONS, googleProviderBlockReason, callGoogle, resolveRuntimeProvider, defaultInvocationContext, defaultProviderTransport, invocationFailureCode, buildBrowserInvocation, resolveProviderSecretKey, resolveNativeProviderCredentialSlots, resolveProviderSecretKeySlots, requireOpenAiCompatibleRuntimeBaseUrl, runtimeSubscriptionPlan, runtimeKeySlotSupportsModel, invokeRuntimeProviderAttempt, runtimeProviderInvoker, invokeRuntimeProvider;
109531
110275
  var init_provider_client = __esm({
109532
110276
  "lib/runtime/provider-client.ts"() {
109533
110277
  "use strict";
@@ -109582,6 +110326,58 @@ var init_provider_client = __esm({
109582
110326
  "no route to model"
109583
110327
  ].some((token) => normalized.includes(token));
109584
110328
  };
110329
+ emptyProviderContentError = (message, reply) => Object.assign(new Error(message), {
110330
+ runtimeEmptyProviderContent: true,
110331
+ // Kept for the in-place retry's own row only (Venice): a model's final
110332
+ // empty reply is recorded with no result and never priced, as in Server Mode.
110333
+ ...reply ? { runtimeEmptyProviderReply: reply.result, runtimeEmptyProviderMessage: reply.emptyMessage } : {}
110334
+ });
110335
+ isEmptyProviderContentFailure = (error48) => error48?.runtimeEmptyProviderContent === true;
110336
+ emptyReplyForInternalAttempt = (error48) => {
110337
+ const reply = error48?.runtimeEmptyProviderReply;
110338
+ return reply ? { ...reply, reasoningContent: null } : null;
110339
+ };
110340
+ isEmptyProviderMessageFailure = (error48) => error48?.runtimeEmptyProviderMessage === true;
110341
+ isRetryableProviderAttemptFailure = (failure2) => failure2.emptyContent || failure2.nativeFailureKind !== void 0 || failure2.statusCode === HTTP_STATUS.REQUEST_TIMEOUT || isRetryableProviderFailureForFallback(failure2.detail);
110342
+ providerRejectedRequestError = (message, detail) => Object.assign(new Error(message), { runtimeProviderRejectionDetail: String(detail || message) });
110343
+ OPTIONAL_CONTRACT_PARAMETER_TOKENS = [
110344
+ "response_format",
110345
+ "venice_parameters",
110346
+ "strip_thinking_response",
110347
+ "disable_thinking",
110348
+ "reasoning_effort",
110349
+ "thinking_budget",
110350
+ "thinking_level",
110351
+ "extra_body"
110352
+ ];
110353
+ OPTIONAL_CONTRACT_REJECTION_TOKENS = [
110354
+ "unexpected keyword argument",
110355
+ "unknown parameter",
110356
+ "unsupported parameter",
110357
+ "not supported",
110358
+ "invalid parameter",
110359
+ "extra fields not permitted",
110360
+ "not permitted"
110361
+ ];
110362
+ OPTIONAL_CONTRACT_GRAMMAR_TOKENS = ["failed to transform json schema into a grammar", "json_schema_converter"];
110363
+ isOptionalContractParameterRejection = (error48) => {
110364
+ const detail = error48?.runtimeProviderRejectionDetail;
110365
+ if (typeof detail !== "string" || !detail) return false;
110366
+ const normalized = detail.toLowerCase();
110367
+ if (OPTIONAL_CONTRACT_GRAMMAR_TOKENS.some((token) => normalized.includes(token))) return true;
110368
+ return OPTIONAL_CONTRACT_PARAMETER_TOKENS.some((token) => normalized.includes(token)) && OPTIONAL_CONTRACT_REJECTION_TOKENS.some((token) => normalized.includes(token));
110369
+ };
110370
+ OPTIONAL_CONTRACT_REQUEST_KEYS = ["response_format", "reasoning_effort", "reasoning_format"];
110371
+ OPTIONAL_CONTRACT_EXTRA_BODY_KEYS = ["thinking_level", "thinking_budget", "reasoning", "include_reasoning", "venice_parameters"];
110372
+ resolveEmptyContentRetryPolicy = (config2) => {
110373
+ const policy2 = config2.empty_content_retry;
110374
+ if (policy2 === void 0 || policy2 === null) return null;
110375
+ const values = [policy2.max_retries, policy2.delay_seconds, policy2.jitter_min_seconds, policy2.jitter_max_seconds];
110376
+ if (values.some((value) => typeof value !== "number" || !Number.isFinite(value) || value < 0) || !Number.isInteger(policy2.max_retries) || policy2.jitter_max_seconds < policy2.jitter_min_seconds) {
110377
+ throw new Error("Missing or invalid config key: empty_content_retry");
110378
+ }
110379
+ return policy2;
110380
+ };
109585
110381
  isKeySpecificOrTransientProviderFailure = (detail) => {
109586
110382
  const normalized = String(detail || "").toLowerCase();
109587
110383
  return isRetryableProviderFailureForFallback(detail) || normalized.includes("http 401") || normalized.includes("http 403") || normalized.includes("(401)") || normalized.includes("(403)") || normalized.includes("unauthorized") || normalized.includes("forbidden") || normalized.includes("permission") || normalized.includes("quota");
@@ -109605,7 +110401,10 @@ var init_provider_client = __esm({
109605
110401
  }
109606
110402
  sanitizedError.runtimeProviderStatusCode = response?.status ?? null;
109607
110403
  sanitizedError.runtimeProviderRequestId = providerRequestId(response);
109608
- sanitizedError.runtimeProviderDiagnostics = marker?.providerDiagnostics ?? {};
110404
+ sanitizedError.runtimeProviderDiagnostics = {
110405
+ ...marker?.providerDiagnostics ?? {},
110406
+ ...error48 instanceof NativeModelTimeoutError && error48.attemptCapExpired ? { timeout_bound: "attempt_cap" } : {}
110407
+ };
109609
110408
  if (marker?.googleQuotaFailure) sanitizedError.runtimeGoogleQuotaFailure = true;
109610
110409
  sanitizedError.runtimeRequestInputTokens = marker?.requestInputTokens ?? null;
109611
110410
  if (marker) {
@@ -109917,6 +110716,7 @@ var init_provider_client = __esm({
109917
110716
  modelHasNativeRequestApiSurface = (config2, provider, model, apiSurface) => findNativeRequestParametersForModel(config2, provider, model).some(
109918
110717
  (parameter) => parameter.api_surface === apiSurface
109919
110718
  );
110719
+ asRequestRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
109920
110720
  setDottedRequestValue = (target, path, value) => {
109921
110721
  const segments = path.split(".").map((segment) => segment.trim()).filter(Boolean);
109922
110722
  if (segments.length === 0) return;
@@ -110187,7 +110987,7 @@ var init_provider_client = __esm({
110187
110987
  const { payload, rawText: rawText2 } = await readProviderPayload(response);
110188
110988
  onPayload?.(payload);
110189
110989
  const detail = extractProviderErrorDetail(payload, rawText2);
110190
- throw new Error(buildCanonicalProviderFailureMessage({ response, detail, runtimeMode }));
110990
+ throw providerRejectedRequestError(buildCanonicalProviderFailureMessage({ response, detail, runtimeMode }), detail);
110191
110991
  }
110192
110992
  let content = "";
110193
110993
  let reasoningContent = "";
@@ -110246,7 +111046,7 @@ var init_provider_client = __esm({
110246
111046
  });
110247
111047
  const finalContent = content.trim();
110248
111048
  if (!finalContent) {
110249
- throw new Error("Provider response did not include any message content.");
111049
+ throw emptyProviderContentError("Provider response did not include any message content.");
110250
111050
  }
110251
111051
  return {
110252
111052
  rawText,
@@ -110435,12 +111235,9 @@ var init_provider_client = __esm({
110435
111235
  }).filter((call) => Boolean(call));
110436
111236
  if (!response.ok) {
110437
111237
  const detail = extractProviderErrorDetail(payload, rawText);
110438
- throw new Error(buildCanonicalProviderFailureMessage({ response, detail, runtimeMode }));
111238
+ throw providerRejectedRequestError(buildCanonicalProviderFailureMessage({ response, detail, runtimeMode }), detail);
110439
111239
  }
110440
- if (!content && toolCalls.length === 0) {
110441
- throw new Error("Provider response did not include any message content.");
110442
- }
110443
- return {
111240
+ const result = {
110444
111241
  content: content || "",
110445
111242
  reasoningContent,
110446
111243
  toolCalls,
@@ -110459,6 +111256,13 @@ var init_provider_client = __esm({
110459
111256
  refusalStatus: typeof message?.refusal === "string" && message.refusal.trim() ? "refused" : "none",
110460
111257
  reasoningTraceSource: reasoningContent ? "provider_native" : "none"
110461
111258
  };
111259
+ if (!content && toolCalls.length === 0) {
111260
+ throw emptyProviderContentError("Provider response did not include any message content.", {
111261
+ result,
111262
+ emptyMessage: Array.isArray(payload?.choices) && payload.choices.length > 0
111263
+ });
111264
+ }
111265
+ return result;
110462
111266
  };
110463
111267
  normalizeRuntimeChatHistory = (messages) => {
110464
111268
  if (!Array.isArray(messages)) {
@@ -110557,6 +111361,7 @@ var init_provider_client = __esm({
110557
111361
  });
110558
111362
  let response = null;
110559
111363
  let dispatchMarker = null;
111364
+ const internalDispatchAttempts = [];
110560
111365
  try {
110561
111366
  const reasoningParams = resolveProviderReasoningParameters(provider, reasoningPayload);
110562
111367
  const useReasoningCompletionTokens = usesReasoningCompletionTokens(provider, reasoningParams);
@@ -110690,50 +111495,131 @@ var init_provider_client = __esm({
110690
111495
  if (useRelay && configuredPlans?.length && !relayPlan) {
110691
111496
  throw new Error(`The selected ${provider} endpoint does not match a configured plan.`);
110692
111497
  }
110693
- dispatchMarker = beginProviderDispatch(finalRequestBody);
110694
- response = useRelay ? await relayNativeProviderRequest(provider, String(apiKey || "").trim(), finalRequestBody, {
110695
- profileId: profileId == null ? void 0 : Number(profileId),
110696
- signal,
110697
- planId: relayPlan?.id,
110698
- traceId: trace.id
110699
- }) : await fetchProvider(requestUrl, {
110700
- method: "POST",
110701
- headers: requestHeaders,
110702
- body: JSON.stringify(finalRequestBody),
110703
- signal
110704
- });
110705
- const payload = typeof onDelta === "function" ? await readOpenAiCompatibleTextStream(response, runtimeMode, onDelta, (rawPayload) => {
110706
- if (dispatchMarker) Object.assign(dispatchMarker.effectiveReasoningParameters, extractProviderReasoningParameters(rawPayload));
110707
- }).then(({ payload: streamPayload, rawText }) => {
110708
- trace.attachResponse({
110709
- status: response?.status ?? null,
110710
- statusText: response?.statusText ?? "",
110711
- body: null,
110712
- rawText: rawProviderTextForDebug(null, rawText)
111498
+ const dispatch = async (body) => {
111499
+ if (body !== finalRequestBody) trace.attachRequest({ url: requestUrl, method: "POST", headers: requestHeaders, body });
111500
+ response = null;
111501
+ const marker = beginProviderDispatch(body);
111502
+ dispatchMarker = marker;
111503
+ const dispatched = useRelay ? await relayNativeProviderRequest(provider, String(apiKey || "").trim(), body, {
111504
+ profileId: profileId == null ? void 0 : Number(profileId),
111505
+ signal,
111506
+ planId: relayPlan?.id,
111507
+ traceId: trace.id
111508
+ }) : await fetchProvider(requestUrl, {
111509
+ method: "POST",
111510
+ headers: requestHeaders,
111511
+ body: JSON.stringify(body),
111512
+ signal
110713
111513
  });
110714
- return streamPayload;
110715
- }) : await extractOpenAiCompatibleText(response, runtimeMode, (payloadJson, rawText) => {
110716
- dispatchMarker.effectiveReasoningParameters = extractProviderReasoningParameters(payloadJson);
110717
- trace.attachResponse({
110718
- status: response?.status ?? null,
110719
- statusText: response?.statusText ?? "",
110720
- body: payloadJson,
110721
- rawText: rawProviderTextForDebug(payloadJson, rawText)
111514
+ response = dispatched;
111515
+ const payload = typeof onDelta === "function" ? await readOpenAiCompatibleTextStream(dispatched, runtimeMode, onDelta, (rawPayload) => {
111516
+ Object.assign(marker.effectiveReasoningParameters, extractProviderReasoningParameters(rawPayload));
111517
+ }).then(({ payload: streamPayload, rawText }) => {
111518
+ trace.attachResponse({
111519
+ status: dispatched.status,
111520
+ statusText: dispatched.statusText ?? "",
111521
+ body: null,
111522
+ rawText: rawProviderTextForDebug(null, rawText)
111523
+ });
111524
+ return streamPayload;
111525
+ }) : await extractOpenAiCompatibleText(dispatched, runtimeMode, (payloadJson, rawText) => {
111526
+ marker.effectiveReasoningParameters = extractProviderReasoningParameters(payloadJson);
111527
+ trace.attachResponse({
111528
+ status: dispatched.status,
111529
+ statusText: dispatched.statusText ?? "",
111530
+ body: payloadJson,
111531
+ rawText: rawProviderTextForDebug(payloadJson, rawText)
111532
+ });
111533
+ });
111534
+ return {
111535
+ ...payload,
111536
+ sentReasoningParameters: marker.sentReasoningParameters,
111537
+ effectiveReasoningParameters: marker.effectiveReasoningParameters,
111538
+ requestInputTokens: marker.requestInputTokens,
111539
+ providerDiagnostics: marker.providerDiagnostics,
111540
+ providerStatusCode: dispatched.status,
111541
+ dispatchStartedAt: marker.startedAt,
111542
+ dispatchLatencyMs: providerDispatchLatencyMs(marker)
111543
+ };
111544
+ };
111545
+ const attemptDispatch = async (body) => {
111546
+ try {
111547
+ return { ok: true, payload: await dispatch(body) };
111548
+ } catch (error48) {
111549
+ return { ok: false, error: error48 };
111550
+ }
111551
+ };
111552
+ const recordInternalRetry = (error48) => {
111553
+ if (!dispatchMarker) return;
111554
+ internalDispatchAttempts.push({
111555
+ sentReasoningParameters: dispatchMarker.sentReasoningParameters,
111556
+ effectiveReasoningParameters: dispatchMarker.effectiveReasoningParameters,
111557
+ startedAt: dispatchMarker.startedAt,
111558
+ latencyMs: providerDispatchLatencyMs(dispatchMarker),
111559
+ transport: "openai_compatible_chat_completions",
111560
+ requestInputTokens: dispatchMarker.requestInputTokens,
111561
+ providerDiagnostics: dispatchMarker.providerDiagnostics,
111562
+ providerRequestId: providerRequestId(response),
111563
+ errorDetail: getSanitizedRuntimeErrorMessage(error48) || "Provider compatibility dispatch failed.",
111564
+ // An empty reply is an unknown outcome with no status, as in Server Mode.
111565
+ statusCode: isEmptyProviderContentFailure(error48) ? null : response?.status ?? null,
111566
+ retryable: isEmptyProviderContentFailure(error48),
111567
+ response: emptyReplyForInternalAttempt(error48)
110722
111568
  });
110723
- });
110724
- trace.completeSuccess(response.status);
110725
- return {
110726
- ...payload,
110727
- sentReasoningParameters: dispatchMarker.sentReasoningParameters,
110728
- effectiveReasoningParameters: dispatchMarker.effectiveReasoningParameters,
110729
- requestInputTokens: dispatchMarker.requestInputTokens,
110730
- providerDiagnostics: dispatchMarker.providerDiagnostics,
110731
- providerStatusCode: response.status,
110732
- dispatchStartedAt: dispatchMarker.startedAt,
110733
- dispatchLatencyMs: providerDispatchLatencyMs(dispatchMarker)
110734
111569
  };
111570
+ let dispatchedBody = finalRequestBody;
111571
+ let outcome = await attemptDispatch(dispatchedBody);
111572
+ if (!outcome.ok && !signal?.aborted && isOptionalContractParameterRejection(outcome.error)) {
111573
+ const withoutExtraBody = Object.fromEntries(
111574
+ Object.entries(requestBody).filter(([key]) => !OPTIONAL_CONTRACT_EXTRA_BODY_KEYS.includes(key))
111575
+ );
111576
+ const fallbackBody = applyNativeRequestParameters(
111577
+ withoutExtraBody,
111578
+ (nativeRequestParameters ?? []).filter((parameter) => parameter.request_path !== "extra_body" && !parameter.request_path.startsWith("extra_body.")),
111579
+ nativeRequestParameterValues,
111580
+ "openai_compatible_chat_completions",
111581
+ { includeAppManaged: true, mapRequestPath: mapOpenAiCompatibleNativeRequestPath }
111582
+ );
111583
+ for (const key of OPTIONAL_CONTRACT_REQUEST_KEYS) delete fallbackBody[key];
111584
+ const hadOptionalContractArguments = Object.keys(finalRequestBody).some((key) => !(key in fallbackBody));
111585
+ if (hadOptionalContractArguments && !hasUserSelectedNativeRequestParameters(
111586
+ nativeRequestParameters,
111587
+ nativeRequestParameterValues,
111588
+ "openai_compatible_chat_completions"
111589
+ )) {
111590
+ recordInternalRetry(outcome.error);
111591
+ appendRuntimeDebugEvent({
111592
+ label: "optional_contract_arguments_rejected_retry",
111593
+ note: `provider=${provider} model=${model}`,
111594
+ outcome: "error"
111595
+ });
111596
+ dispatchedBody = fallbackBody;
111597
+ outcome = await attemptDispatch(dispatchedBody);
111598
+ }
111599
+ }
111600
+ if (!outcome.ok && provider === "venice" && typeof onDelta !== "function" && !signal?.aborted && isEmptyProviderMessageFailure(outcome.error)) {
111601
+ recordInternalRetry(outcome.error);
111602
+ appendRuntimeDebugEvent({
111603
+ label: "venice_empty_content_thinking_disabled_retry",
111604
+ note: `model=${model}`,
111605
+ outcome: "error"
111606
+ });
111607
+ dispatchedBody = {
111608
+ ...dispatchedBody,
111609
+ venice_parameters: {
111610
+ ...asRequestRecord(dispatchedBody.venice_parameters),
111611
+ strip_thinking_response: true,
111612
+ disable_thinking: true
111613
+ }
111614
+ };
111615
+ outcome = await attemptDispatch(dispatchedBody);
111616
+ }
111617
+ if (!outcome.ok) throw outcome.error;
111618
+ trace.completeSuccess(outcome.payload.providerStatusCode ?? null);
111619
+ return { ...outcome.payload, internalDispatchAttempts };
110735
111620
  } catch (error48) {
110736
111621
  const sanitizedError = attachProviderDispatchFailure(error48, dispatchMarker, response);
111622
+ sanitizedError.runtimeInternalDispatchAttempts = internalDispatchAttempts;
110737
111623
  trace.completeError(toProviderNetworkDebugError(sanitizedError), response?.status ?? null);
110738
111624
  throw attachProviderFailureTrace(sanitizedError, trace.id);
110739
111625
  }
@@ -110835,7 +111721,7 @@ var init_provider_client = __esm({
110835
111721
  }
110836
111722
  const text = extractOpenAiResponsesText(payload);
110837
111723
  if (!text) {
110838
- throw new Error("OpenAI Responses API did not include any text content.");
111724
+ throw emptyProviderContentError("OpenAI Responses API did not include any text content.");
110839
111725
  }
110840
111726
  trace.completeSuccess(response.status);
110841
111727
  return {
@@ -110982,7 +111868,7 @@ var init_provider_client = __esm({
110982
111868
  }
110983
111869
  const text = extractAnthropicMessageText(payload);
110984
111870
  if (!text) {
110985
- throw new Error("Anthropic response did not include any text content.");
111871
+ throw emptyProviderContentError("Anthropic response did not include any text content.");
110986
111872
  }
110987
111873
  const reasoningContent = extractAnthropicReasoningContent(payload);
110988
111874
  const anthropicUsage = buildAnthropicUsagePayload(payload?.usage);
@@ -111362,7 +112248,7 @@ var init_provider_client = __esm({
111362
112248
  blockedError.runtimeProviderResult = providerResult;
111363
112249
  throw blockedError;
111364
112250
  }
111365
- throw new Error("Google response did not include any text content.");
112251
+ throw emptyProviderContentError("Google response did not include any text content.");
111366
112252
  }
111367
112253
  trace.completeSuccess(response.status);
111368
112254
  return providerResult;
@@ -111670,6 +112556,8 @@ var init_provider_client = __esm({
111670
112556
  });
111671
112557
  const providerKeySlots = resolveProviderSecretKeySlots(provider, secrets);
111672
112558
  let providerKeySlotIndex = Math.max(0, input.providerKeySlotIndex ?? 0);
112559
+ const keySweepStartSlotIndex = input.keySweepStartSlotIndex ?? providerKeySlotIndex;
112560
+ const emptyContentRetryPolicy = resolveEmptyContentRetryPolicy(config2);
111673
112561
  if (input.allowFallback !== false) {
111674
112562
  const eligibleSlot = providerKeySlots.findIndex((_, index) => index >= providerKeySlotIndex && runtimeKeySlotSupportsModel(config2, secrets, provider, index, model));
111675
112563
  if (eligibleSlot >= 0) providerKeySlotIndex = eligibleSlot;
@@ -111756,6 +112644,7 @@ var init_provider_client = __esm({
111756
112644
  requestInputTokens: attempt.requestInputTokens,
111757
112645
  providerDiagnostics: attempt.providerDiagnostics,
111758
112646
  providerRequestId: attempt.providerRequestId,
112647
+ response: attempt.response ?? null,
111759
112648
  retryable: attempt.retryable ?? false,
111760
112649
  fallbackFrom: chain.at(-1) ?? null
111761
112650
  }));
@@ -111791,7 +112680,8 @@ var init_provider_client = __esm({
111791
112680
  if (egress && (timeoutMs <= 0 || !googleEgressHasBudget(egress))) throw new NativeModelTimeoutError();
111792
112681
  signal?.addEventListener("abort", cancelAttempt, { once: true });
111793
112682
  if (signal?.aborted) cancelAttempt();
111794
- 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;
111795
112685
  try {
111796
112686
  response = await callGoogle(
111797
112687
  remoteApiKey,
@@ -112033,7 +112923,7 @@ var init_provider_client = __esm({
112033
112923
  registerTraderProviderCallFinished(schedulerResourceKey, schedulerOwnerId, failedAtMs - startedAtMs);
112034
112924
  const detail = getSanitizedRuntimeErrorMessage(error48) || String(error48 || "unknown provider error");
112035
112925
  const nativeFailureKind = error48?.runtimeNativeFailureKind;
112036
- const statusCode = extractRuntimeProviderFailureStatusCode(error48);
112926
+ const statusCode = isEmptyProviderContentFailure(error48) ? null : extractRuntimeProviderFailureStatusCode(error48);
112037
112927
  const rawInternalDispatchAttempts = error48?.runtimeInternalDispatchAttempts;
112038
112928
  const observedInvocationAttempts2 = await withInternalDispatchAttempts(
112039
112929
  rawInternalDispatchAttempts
@@ -112094,7 +112984,12 @@ var init_provider_client = __esm({
112094
112984
  errorDetail: detail,
112095
112985
  statusCode,
112096
112986
  failureCode: nativeFailureKind === "transport" ? "transport_error" : nativeFailureKind === "timeout" ? "timeout" : signal?.aborted || isAbortLikeError(error48) ? "cancelled" : void 0,
112097
- retryable: isRetryableProviderFailureForFallback(detail),
112987
+ retryable: isRetryableProviderAttemptFailure({
112988
+ detail,
112989
+ statusCode,
112990
+ nativeFailureKind,
112991
+ emptyContent: isEmptyProviderContentFailure(error48)
112992
+ }),
112098
112993
  providerCost: failedCostInfo?.costStatus === "unavailable" ? null : failedCostInfo?.cost,
112099
112994
  userCost: failedCostInfo?.costStatus === "unavailable" ? null : failedCostInfo?.costUser,
112100
112995
  costStatus: failedCostInfo?.costStatus ?? "unavailable",
@@ -112132,7 +113027,9 @@ var init_provider_client = __esm({
112132
113027
  });
112133
113028
  }
112134
113029
  }
112135
- if ((!egress || googleEgressHasBudget(egress)) && !signal?.aborted && input.allowFallback !== false && !emittedDelta && (isKeySpecificOrTransientProviderFailure(detail) || isModelSpecificProviderFailure(detail) || retryableRouteFailure)) {
113030
+ const emptyContentFailure = isEmptyProviderContentFailure(error48);
113031
+ const keySpecificOrTransientFailure = isKeySpecificOrTransientProviderFailure(detail) || statusCode === HTTP_STATUS.REQUEST_TIMEOUT || nativeFailureKind === "transport" || emptyContentFailure;
113032
+ if ((!egress || googleEgressHasBudget(egress)) && !signal?.aborted && input.allowFallback !== false && !emittedDelta && (keySpecificOrTransientFailure || isModelSpecificProviderFailure(detail) || retryableRouteFailure)) {
112136
113033
  const nextProviderKeySlotIndex = providerKeySlots.findIndex((_, index) => index > providerKeySlotIndex && runtimeKeySlotSupportsModel(config2, secrets, provider, index, model) && (!isModelSpecificProviderFailure(detail) || resolveNativeProviderCredentialSlots(provider, secrets)[index]?.baseUrl !== resolveNativeProviderCredentialSlots(provider, secrets)[providerKeySlotIndex]?.baseUrl));
112137
113034
  if (provider !== "local" && nextProviderKeySlotIndex >= 0) {
112138
113035
  const diagnostics = normalizeProviderDiagnostics(error48?.runtimeProviderDiagnostics);
@@ -112168,6 +113065,38 @@ var init_provider_client = __esm({
112168
113065
  return await invokeRuntimeProviderAttempt({
112169
113066
  ...input,
112170
113067
  providerKeySlotIndex: nextProviderKeySlotIndex,
113068
+ keySweepStartSlotIndex,
113069
+ googleEgressRoute: void 0,
113070
+ googleEgressTriedRoutes: [],
113071
+ nativeRecoverySafe,
113072
+ invocationAttemptChain: invocationAttempts2
113073
+ });
113074
+ }
113075
+ }
113076
+ if (emptyContentFailure && (!egress || googleEgressHasBudget(egress)) && !signal?.aborted && input.allowFallback !== false && !emittedDelta) {
113077
+ const retryPolicy = emptyContentRetryPolicy;
113078
+ const retryCount = input.emptyContentRetryCount ?? 0;
113079
+ const retryDelayMs = retryPolicy === null ? 0 : (retryPolicy.delay_seconds + retryPolicy.jitter_min_seconds + Math.random() * (retryPolicy.jitter_max_seconds - retryPolicy.jitter_min_seconds)) * MS_PER_SECOND;
113080
+ const remainingMs = input.nativeRequestDeadlineMs === void 0 ? Number.POSITIVE_INFINITY : input.nativeRequestDeadlineMs - Date.now();
113081
+ if (retryPolicy !== null && retryCount < retryPolicy.max_retries && retryDelayMs < remainingMs) {
113082
+ try {
113083
+ await waitForProviderRetry(retryDelayMs, signal);
113084
+ } catch (cancelled) {
113085
+ cancelled.runtimeInvocationAttempts = invocationAttempts2;
113086
+ cancelled.runtimePartialOutput = emittedDelta;
113087
+ cancelled.runtimeNativeRecoverySafe = nativeRecoverySafe;
113088
+ throw cancelled;
113089
+ }
113090
+ appendRuntimeDebugEvent({
113091
+ label: "provider_empty_content_retry",
113092
+ note: `provider=${provider} model=${model} retry=${retryCount + 1}/${retryPolicy.max_retries}`,
113093
+ outcome: "error"
113094
+ });
113095
+ return await invokeRuntimeProviderAttempt({
113096
+ ...input,
113097
+ providerKeySlotIndex: keySweepStartSlotIndex,
113098
+ keySweepStartSlotIndex,
113099
+ emptyContentRetryCount: retryCount + 1,
112171
113100
  googleEgressRoute: void 0,
112172
113101
  googleEgressTriedRoutes: [],
112173
113102
  nativeRecoverySafe,
@@ -113597,6 +114526,7 @@ __export(local_analysis_exports, {
113597
114526
  ClientRuntimeAgentInstructionEmpty: () => ClientRuntimeAgentInstructionEmpty,
113598
114527
  ClientRuntimeAiSchedulePaused: () => ClientRuntimeAiSchedulePaused,
113599
114528
  ClientRuntimeAiScheduleStillActive: () => ClientRuntimeAiScheduleStillActive,
114529
+ SERVER_UNREADABLE_REPLY_HOLD_REASONING: () => SERVER_UNREADABLE_REPLY_HOLD_REASONING,
113600
114530
  ServerDispatchAccountStateStale: () => ServerDispatchAccountStateStale,
113601
114531
  aiOrderSlippageFraction: () => aiOrderSlippageFraction,
113602
114532
  buildLocalRuntimePromptArtifacts: () => buildLocalRuntimePromptArtifacts,
@@ -113609,7 +114539,6 @@ __export(local_analysis_exports, {
113609
114539
  isClientRuntimeAiScheduleStillActive: () => isClientRuntimeAiScheduleStillActive,
113610
114540
  isServerDispatchAccountStateStale: () => isServerDispatchAccountStateStale,
113611
114541
  perpDexScopeForSymbols: () => perpDexScopeForSymbols,
113612
- profileEquityPerpDexScope: () => profileEquityPerpDexScope,
113613
114542
  resolveEffectivePromptRuntimeProvenance: () => resolveEffectivePromptRuntimeProvenance,
113614
114543
  resolveExternalInferenceRuntimeTimeoutSeconds: () => resolveExternalInferenceRuntimeTimeoutSeconds,
113615
114544
  resolveLocalRuntimeSecretProvider: () => resolveLocalRuntimeSecretProvider,
@@ -113618,7 +114547,7 @@ __export(local_analysis_exports, {
113618
114547
  runLocalRuntimeCycle: () => runLocalRuntimeCycle,
113619
114548
  summarizeReviewFailureExplanation: () => summarizeReviewFailureExplanation
113620
114549
  });
113621
- 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, 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, 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, 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;
113622
114551
  var init_local_analysis = __esm({
113623
114552
  "lib/runtime/local-analysis.ts"() {
113624
114553
  "use strict";
@@ -113793,6 +114722,10 @@ var init_local_analysis = __esm({
113793
114722
  };
113794
114723
  isServerDispatchAccountStateStale = (value) => value instanceof Error && value.name === "ServerDispatchAccountStateStale";
113795
114724
  isClientRuntimeAiSchedulePaused = (value) => value instanceof ClientRuntimeAiSchedulePaused;
114725
+ acceptancePositionCaps = (executionMode, caps) => executionMode === "server" ? { remaining_global_units: null, remaining_exchange_units: null, remaining_asset_units: null } : caps;
114726
+ accountSnapshotCapturedAt = (executionMode, accountStateFetchedAtMs) => new Date(
114727
+ (executionMode === "server" ? accountStateFetchedAtMs : null) ?? Date.now()
114728
+ ).toISOString();
113796
114729
  buildClaimedAgentRuntimeCycleResult = async (input) => {
113797
114730
  const { config: config2, settings, instruction, runtimeInput, signal } = input;
113798
114731
  const binding = runtimeInput.runtimeContractBinding;
@@ -113832,6 +114765,8 @@ var init_local_analysis = __esm({
113832
114765
  perpDexScope: perpDexScopeForSymbols(symbols),
113833
114766
  feeSymbols: symbols,
113834
114767
  includeEffectiveTakerRate: true,
114768
+ // A Server bot's account is valued as the Python Server loop valued it.
114769
+ serverLoopAccountValue: runtimeInput.executionMode === "server",
113835
114770
  sessionId: String(runtimeInput.sessionId || "").trim(),
113836
114771
  signal
113837
114772
  });
@@ -113989,9 +114924,11 @@ var init_local_analysis = __esm({
113989
114924
  runtime_disabled: settings.main_model_enabled === false,
113990
114925
  kill_switch_active: false,
113991
114926
  max_trades_per_prompt: remainingPromptUnits,
113992
- remaining_exchange_units: Math.max(0, maxTradesPerExchange - (exchangeUnitsUsed.get(getHyperliquidMarketDex(entry.symbol)) ?? 0)),
113993
- remaining_global_units: remainingGlobalUnits,
113994
- remaining_asset_units: remainingAssetUnits,
114927
+ ...acceptancePositionCaps(runtimeInput.executionMode, {
114928
+ remaining_exchange_units: Math.max(0, maxTradesPerExchange - (exchangeUnitsUsed.get(getHyperliquidMarketDex(entry.symbol)) ?? 0)),
114929
+ remaining_global_units: remainingGlobalUnits,
114930
+ remaining_asset_units: remainingAssetUnits
114931
+ }),
113995
114932
  current_symbol_signed_units: currentSignedUnits,
113996
114933
  model_allowed: true,
113997
114934
  provider_allowed: true
@@ -114004,7 +114941,8 @@ var init_local_analysis = __esm({
114004
114941
  decision: "HOLD",
114005
114942
  units: 0,
114006
114943
  reasoning: `Skipped by client runtime constraints: ${accepted.reason_code}`,
114007
- executionContext
114944
+ executionContext,
114945
+ ...entry.decision === "BUY" || entry.decision === "SELL" ? { unsentOrder: { decision: entry.decision, units: entry.units, constraintReasonCode: accepted.reason_code } } : {}
114008
114946
  };
114009
114947
  }
114010
114948
  throw new Error(buildRuntimeConstraintRejectionMessage({
@@ -114113,7 +115051,7 @@ var init_local_analysis = __esm({
114113
115051
  clientExchangeSnapshot: buildClientExchangeSnapshot({
114114
115052
  walletAddress,
114115
115053
  symbol: symbol2,
114116
- capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
115054
+ capturedAt: accountSnapshotCapturedAt(runtimeInput.executionMode, accountState.evidence?.fetchedAtMs),
114117
115055
  markPrice: primaryPrice,
114118
115056
  accountSummary: accountState.accountSummary,
114119
115057
  positions: accountState.positions,
@@ -114455,6 +115393,12 @@ var init_local_analysis = __esm({
114455
115393
  };
114456
115394
  formatDecisionSymbolTrace = (symbols) => symbols.length > 0 ? symbols.map((entry) => `${entry.symbol}:${entry.decision}/${entry.units}`).join(",") : "none";
114457
115395
  formatActionableDecisionSymbols = (symbols) => formatDecisionSymbolTrace(symbols.filter((entry) => entry.decision !== "HOLD" && entry.units > 0));
115396
+ decisionRecordsBySymbol = (plans) => Object.fromEntries(plans.map((plan) => [plan.symbol, {
115397
+ decision: plan.decision,
115398
+ reasoning: plan.reasoning,
115399
+ units: plan.units,
115400
+ tradability: plan.tradability
115401
+ }]));
114458
115402
  normalizePromptSymbols = (symbols) => {
114459
115403
  const seen = /* @__PURE__ */ new Set();
114460
115404
  const normalized = [];
@@ -114571,6 +115515,7 @@ var init_local_analysis = __esm({
114571
115515
  }
114572
115516
  );
114573
115517
  };
115518
+ SERVER_UNREADABLE_REPLY_HOLD_REASONING = "Configured symbol was omitted from the model response. Defaulted to HOLD.";
114574
115519
  buildMissingDecisionHold = (symbol2, reasoning = `No valid model decision was returned for configured symbol ${symbol2}.`) => ({
114575
115520
  symbol: symbol2,
114576
115521
  decision: "HOLD",
@@ -115689,10 +116634,19 @@ ${reviewOutputContract}`;
115689
116634
  });
115690
116635
  return { c: summarized };
115691
116636
  };
116637
+ CANDLE_CLOSE_TICKER_TIMEFRAME = "5m";
116638
+ candleCloseTicker = (symbol2, candlesByTimeframe) => {
116639
+ const preferred = candlesByTimeframe[CANDLE_CLOSE_TICKER_TIMEFRAME] ?? [];
116640
+ const reference = preferred.length > 0 ? preferred : Object.values(candlesByTimeframe).find((rows) => rows.length > 0) ?? [];
116641
+ const latest = reference.reduce((current, candle) => current === null || toEpochSeconds(candle.timestamp) > toEpochSeconds(current.timestamp) ? candle : current, null);
116642
+ const close = toPositiveFinite3(latest?.close);
116643
+ return close === null ? null : { symbol: symbol2, price: close, timestamp: "", source: "recent_candle_close" };
116644
+ };
115692
116645
  buildPromptCandlesPayload = (input) => {
115693
116646
  const payload = {};
115694
116647
  for (const symbol2 of input.symbols) {
115695
- const asOfTimestamp = toEpochSeconds(input.tickersBySymbol[symbol2]?.timestamp) || Math.floor(Date.now() / MS_PER_SECOND);
116648
+ const symbolTicker = input.tickersBySymbol[symbol2];
116649
+ const asOfTimestamp = (symbolTicker?.is_fresh === true ? toEpochSeconds(symbolTicker.timestamp) : 0) || Math.floor(Date.now() / MS_PER_SECOND);
115696
116650
  const symbolData = {
115697
116651
  data: {}
115698
116652
  };
@@ -117129,7 +118083,7 @@ ${behaviorJson}
117129
118083
  );
117130
118084
  }
117131
118085
  };
117132
- 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) => {
117133
118087
  let attempt = 0;
117134
118088
  while (true) {
117135
118089
  if (waitForLiveAccountState) {
@@ -117179,7 +118133,7 @@ ${behaviorJson}
117179
118133
  const liveEquity = Number.isFinite(Number(liveEquityRaw)) ? Number(liveEquityRaw) : 0;
117180
118134
  const liveUnrealizedPnlRaw = getTotalUnrealizedPnl ? getTotalUnrealizedPnl() : null;
117181
118135
  const liveUnrealizedPnl = liveUnrealizedPnlRaw !== null && liveUnrealizedPnlRaw !== void 0 && Number.isFinite(Number(liveUnrealizedPnlRaw)) ? Number(liveUnrealizedPnlRaw) : null;
117182
- const parityIncluded = liveEquity > 0;
118136
+ const parityIncluded = liveEquity > 0 || runsWithoutEquity;
117183
118137
  const parityPreparedAtMs = Date.now();
117184
118138
  const accountStateResolvedAtMs = getAccountStateResolvedAtMs ? getAccountStateResolvedAtMs() : null;
117185
118139
  const accountStateAgeMs = typeof accountStateResolvedAtMs === "number" ? Math.max(0, parityPreparedAtMs - accountStateResolvedAtMs) : null;
@@ -117637,10 +118591,6 @@ ${behaviorJson}
117637
118591
  );
117638
118592
  }
117639
118593
  let requestTimeoutSeconds = clampNumber(settings.timeout_seconds, config2.default_timeout_seconds);
117640
- let requestTimeoutMs = Math.max(CYCLE_TIMEOUT_FLOOR_MS, Math.round(requestTimeoutSeconds * MS_PER_SECOND));
117641
- if (requestTimeoutMs !== defaultTimeoutMs) {
117642
- armCycleDeadline(requestTimeoutMs, "Runtime request timeout reached.");
117643
- }
117644
118594
  const {
117645
118595
  symbols,
117646
118596
  timeframes,
@@ -117767,6 +118717,10 @@ ${behaviorJson}
117767
118717
  // A Server bot's cycle reads the account authoritatively, as the Python
117768
118718
  // Server loop does: never a cached or rate-limit-stale observation.
117769
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",
117770
118724
  sessionId,
117771
118725
  signal: timeoutController.signal
117772
118726
  }).catch(async (error48) => {
@@ -117877,7 +118831,8 @@ ${behaviorJson}
117877
118831
  },
117878
118832
  initialPromptMetadata,
117879
118833
  () => latestPositions,
117880
- () => _latestPerpDexAccounts
118834
+ () => _latestPerpDexAccounts,
118835
+ input.executionMode === "server"
117881
118836
  ).then((contracts) => {
117882
118837
  appendRuntimeTimingEvent("prompt_contract_loaded", promptContractStartedAtMs);
117883
118838
  return contracts;
@@ -117890,8 +118845,13 @@ ${behaviorJson}
117890
118845
  const marketDataStartedAtMs = Date.now();
117891
118846
  const candlesTickerPromise = Promise.all(
117892
118847
  symbols.map(async (marketSymbol) => {
118848
+ let tickerError = null;
117893
118849
  const [loadedTicker, loadedCandles] = await Promise.all([
117894
- getLiveTicker(marketSymbol, "hyperliquid", timeoutController.signal),
118850
+ getLiveTicker(marketSymbol, "hyperliquid", timeoutController.signal).catch((error48) => {
118851
+ if (timeoutController.signal.aborted || isAbortLikeError(error48)) throw error48;
118852
+ tickerError = error48;
118853
+ return null;
118854
+ }),
117895
118855
  Promise.all(
117896
118856
  sortedTimeframes.map(async (marketTimeframe) => [
117897
118857
  marketTimeframe,
@@ -117912,11 +118872,17 @@ ${behaviorJson}
117912
118872
  ])
117913
118873
  )
117914
118874
  ]);
117915
- return {
117916
- symbol: marketSymbol,
117917
- ticker: loadedTicker,
117918
- candles: Object.fromEntries(loadedCandles)
117919
- };
118875
+ const candles = Object.fromEntries(loadedCandles);
118876
+ const ticker2 = loadedTicker?.is_fresh === true && toPositiveFinite3(loadedTicker.price) !== null ? loadedTicker : candleCloseTicker(marketSymbol, candles) ?? loadedTicker;
118877
+ if (ticker2 === null) throw tickerError;
118878
+ if (loadedTicker === null) {
118879
+ appendRuntimeDebugEvent({
118880
+ label: "live_ticker_unavailable",
118881
+ note: `symbol=${marketSymbol} price_source=recent_candle_close detail=${tickerError instanceof Error ? tickerError.message : String(tickerError)}`,
118882
+ outcome: "error"
118883
+ });
118884
+ }
118885
+ return { symbol: marketSymbol, ticker: ticker2, candles };
117920
118886
  })
117921
118887
  ).then((result) => {
117922
118888
  const primaryTicker = result.find((entry) => entry.symbol === localFallbackSymbol)?.ticker ?? result[0]?.ticker;
@@ -118049,7 +119015,7 @@ ${behaviorJson}
118049
119015
  const clientExchangeSnapshot = buildClientExchangeSnapshot({
118050
119016
  walletAddress,
118051
119017
  symbol: symbol2,
118052
- capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
119018
+ capturedAt: accountSnapshotCapturedAt(input.executionMode, browserAccountState.evidence?.fetchedAtMs),
118053
119019
  markPrice: toPositiveFinite3(availableToTrade.mark_price) ?? toPositiveFinite3(ticker.price),
118054
119020
  accountSummary,
118055
119021
  positions,
@@ -118083,8 +119049,8 @@ ${behaviorJson}
118083
119049
  const maxTradesPerExchange = Math.round(clampNumber(promptKnobs.max_trades_per_exchange, maxTradesGlobal));
118084
119050
  const metadataTradeSize = clampNumber(promptKnobs.trade_size, config2.default_ai_trade_amount);
118085
119051
  const metadataLeverage = clampNumber(promptKnobs.leverage, config2.default_leverage);
118086
- const metricsWindowHours = Math.round(clampNumber(promptKnobs.metrics_window_hours, 0));
118087
- const metricsSecondaryWindowHours = Math.round(clampNumber(promptKnobs.metrics_secondary_window_hours, 0));
119052
+ const metricsWindowHours = clampNumber(promptKnobs.metrics_window_hours, 0);
119053
+ const metricsSecondaryWindowHours = clampNumber(promptKnobs.metrics_secondary_window_hours, 0);
118088
119054
  const promptSymbols = Array.isArray(promptKnobs.active_symbols) && promptKnobs.active_symbols.length > 0 ? promptKnobs.active_symbols.map((item) => String(item || "").trim()).filter(Boolean) : symbols;
118089
119055
  const promptTimeframes = Array.isArray(promptKnobs.active_timeframes) && promptKnobs.active_timeframes.length > 0 ? sortTradingTimeframes(promptKnobs.active_timeframes.map((item) => String(item || "").trim()).filter(Boolean)) : sortedTimeframes;
118090
119056
  const executionFreshnessMaxAgeSeconds = requirePositiveIntegerField(
@@ -118261,7 +119227,7 @@ ${behaviorJson}
118261
119227
  throw new Error(message);
118262
119228
  }
118263
119229
  } catch (error48) {
118264
- if (!(error48 instanceof Error) || !serverProviderNotConfigured || !deviceProviderModelEligible || normalizeModelFallbacks(settings.model_fallbacks).main.length === 0) throw error48;
119230
+ if (!(error48 instanceof Error) || normalizeModelFallbacks(settings.model_fallbacks).main.length === 0) throw error48;
118265
119231
  primaryAvailabilityError = Object.assign(error48, { modelFallbackSafe: true });
118266
119232
  }
118267
119233
  const localAcceptanceConstraints = {
@@ -118733,8 +119699,10 @@ ${stringifyPromptJson(candlesPayload)}
118733
119699
  config2,
118734
119700
  requestTimeoutSeconds
118735
119701
  );
118736
- requestTimeoutMs = Math.max(CYCLE_TIMEOUT_FLOOR_MS, Math.round(requestTimeoutSeconds * MS_PER_SECOND));
118737
- armCycleDeadline(requestTimeoutMs, "Runtime request timeout reached.");
119702
+ armCycleDeadline(
119703
+ Math.max(CYCLE_TIMEOUT_FLOOR_MS, Math.round(requestTimeoutSeconds * MS_PER_SECOND)),
119704
+ "Runtime request timeout reached."
119705
+ );
118738
119706
  appendRuntimeDebugEvent({
118739
119707
  label: "external_inference_timeout_extended",
118740
119708
  note: `lane=main seconds=${requestTimeoutSeconds}`
@@ -118824,7 +119792,12 @@ ${stringifyPromptJson(candlesPayload)}
118824
119792
  systemPrompt,
118825
119793
  userPrompt,
118826
119794
  temperature: entryParameters?.temperature ?? temperature,
118827
- maxTokens: entryParameters?.max_tokens ?? maxTokens,
119795
+ // Every Main model gets at least the configured output budget, as in
119796
+ // the Server loop (ai_trading_service.py _execute_llm_request).
119797
+ maxTokens: Math.max(
119798
+ entryParameters?.max_tokens ?? maxTokens,
119799
+ requirePositiveIntegerField(config2.max_tokens_min, "max_tokens_min")
119800
+ ),
118828
119801
  reasoningPayload: modelIndex === 0 ? reasoningPayload : buildRuntimeReasoningPayload(controls, extractRuntimeReasoningSelection({ runtime_reasoning: entryParameters?.runtime_reasoning }, controls.control_type, controls.control_type === "toggle" ? controls.toggle_behavior : "disable_reasoning")),
118829
119802
  nativeRequestParameters: entryConfig?.native_request_parameters,
118830
119803
  nativeRequestParameterValues: modelIndex === 0 ? nativeRequestParameterValues : filterNativeRequestParameterValues(entryConfig?.native_request_parameters, entryParameters?.native_request_parameter_values),
@@ -118891,18 +119864,31 @@ ${stringifyPromptJson(candlesPayload)}
118891
119864
  `provider=${provider} requested_model=${authoritativeModel} response_model=${providerResponse.model} llm_latency_s=${providerResponse.latency} snippet=${responseSnippet || "(empty)"}`
118892
119865
  );
118893
119866
  let primaryDecisionContent = providerResponse.content;
119867
+ let mainReplyUnreadable = false;
118894
119868
  if (!allPromptSymbolsUnavailable && !isExternalRuntimeProviderResult(providerResponse)) {
118895
119869
  const validationErrors = currentModelOutputValidationErrors(providerResponse.content, promptSymbols);
118896
- if (validationErrors.length > 0) {
119870
+ if (validationErrors.length > 0 && input.executionMode !== "server") {
118897
119871
  throw modelOutputValidationError("Main", providerResponse.invocations, validationErrors, promptSymbols);
118898
119872
  }
118899
- 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
+ }
118900
119884
  }
118901
- const primaryParseOutcome = classifyDecisionParseOutcome(
118902
- providerResponse.content,
118903
- symbol2,
118904
- promptSymbols
118905
- );
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);
118906
119892
  invocationAttempts = applyInvocationParseOutcome(
118907
119893
  providerResponse.invocations,
118908
119894
  {
@@ -118966,6 +119952,7 @@ ${stringifyPromptJson(candlesPayload)}
118966
119952
  let finalTradability = selectedPrimaryPlan?.tradability ?? parsed.tradability;
118967
119953
  let reviewTradability = null;
118968
119954
  let finalAnalysis = primaryDecisionContent;
119955
+ let reviewedCycle = null;
118969
119956
  let finalModel = primaryDisplayModel;
118970
119957
  let finalProvider = providerResponse.provider;
118971
119958
  let finalSystemPrompt = systemPrompt;
@@ -119017,7 +120004,7 @@ ${stringifyPromptJson(candlesPayload)}
119017
120004
  return entry.decision === "BUY" || entry.decision === "SELL" ? total + Math.max(0, Math.trunc(entry.units)) : total;
119018
120005
  }, 0);
119019
120006
  const reviewMaxTrades = Math.max(0, maxTradesPerPrompt - unreviewedPrimaryUnits);
119020
- const shouldReview = !allPromptSymbolsUnavailable && reviewEnabled && reviewCandidatePlans.length > 0;
120007
+ const shouldReview = !allPromptSymbolsUnavailable && reviewEnabled && !mainReplyUnreadable && reviewCandidatePlans.length > 0;
119021
120008
  if (shouldReview) {
119022
120009
  let reviewModel = requireNonEmptyStringField(promptMetadata.review_model, "review_model");
119023
120010
  const requestedReviewModel = reviewModel;
@@ -119272,7 +120259,11 @@ ${reviewOutputContract}`;
119272
120259
  finalReasoning = selectedReviewedPlan?.reasoning ?? reviewed.reasoning;
119273
120260
  reviewTradability = selectedReviewedPlan?.tradability ?? reviewed.tradability;
119274
120261
  finalTradability = reviewTradability;
119275
- finalAnalysis = reviewDecisionContent;
120262
+ finalAnalysis = finalDecisionPlans.length > 1 ? JSON.stringify(decisionRecordsBySymbol(finalDecisionPlans)) : reviewDecisionContent;
120263
+ reviewedCycle = {
120264
+ originalModel: primaryDisplayModel,
120265
+ originalDecisions: decisionRecordsBySymbol(primaryDecisionPlans)
120266
+ };
119276
120267
  const reviewDisplayModel = isExternalRuntimeProviderResult(reviewResponse) ? String(reviewResponse.model || reviewModel).trim() || reviewModel : projectInvocationStageModelLabel({
119277
120268
  requestedModel: requestedReviewModel,
119278
120269
  displayModel: String(reviewResponse.model || reviewModel).trim() || reviewModel,
@@ -119314,6 +120305,9 @@ ${reviewOutputContract}`;
119314
120305
  if (error48 instanceof CriticalBehaviorStateError || detail.includes(BEHAVIOR_STATE_UNAVAILABLE_ERROR) || detail.includes("Critical behavior context could not be constructed")) {
119315
120306
  throw new CriticalBehaviorStateError(error48);
119316
120307
  }
120308
+ if (input.executionMode === "server" && error48?.code === "settings_superseded") {
120309
+ throw error48;
120310
+ }
119317
120311
  invocationAttempts = mergeInvocationAttemptChains(
119318
120312
  invocationAttempts,
119319
120313
  Array.isArray(error48?.runtimeInvocationAttempts) ? error48.runtimeInvocationAttempts : []
@@ -119324,6 +120318,7 @@ ${reviewOutputContract}`;
119324
120318
  ...entry,
119325
120319
  ...reviewedSymbolKeys.has(normalizeRuntimeSymbol(entry.symbol)) ? { decision: "HOLD", units: 0, reasoning: finalReasoning } : {}
119326
120320
  }));
120321
+ if (finalDecisionPlans.length > 1) finalAnalysis = JSON.stringify(decisionRecordsBySymbol(finalDecisionPlans));
119327
120322
  const failedSelectedPlan = finalDecisionPlans.find((entry) => normalizeRuntimeSymbol(entry.symbol) === normalizeRuntimeSymbol(symbol2)) ?? finalDecisionPlans[0];
119328
120323
  finalDecision = failedSelectedPlan?.decision ?? "HOLD";
119329
120324
  finalUnits = failedSelectedPlan?.units ?? 0;
@@ -119380,7 +120375,7 @@ ${reviewOutputContract}`;
119380
120375
  Math.round(Number(settings.tradability_increase_minimum ?? config2.default_tradability_increase_minimum))
119381
120376
  )
119382
120377
  );
119383
- const acceptedExecutionPlans = finalDecisionPlans.map((entry) => {
120378
+ const acceptExecutionPlan = (entry) => {
119384
120379
  const planSymbol = normalizeRuntimeSymbol(entry.symbol);
119385
120380
  const isPrimaryPlanSymbol = planSymbol === normalizeRuntimeSymbol(symbol2);
119386
120381
  const planSignedUnits = computePlanSignedUnits(entry.symbol);
@@ -119421,9 +120416,11 @@ ${reviewOutputContract}`;
119421
120416
  const planConstraints = {
119422
120417
  ...localAcceptanceConstraints,
119423
120418
  max_trades_per_prompt: remainingPromptUnits,
119424
- remaining_global_units: remainingGlobalUnits,
119425
- remaining_exchange_units: Math.max(0, maxTradesPerExchange - (exchangeUnitsUsed.get(getHyperliquidMarketDex(entry.symbol)) ?? 0)),
119426
- remaining_asset_units: remainingAssetUnits,
120419
+ ...acceptancePositionCaps(input.executionMode, {
120420
+ remaining_global_units: remainingGlobalUnits,
120421
+ remaining_exchange_units: Math.max(0, maxTradesPerExchange - (exchangeUnitsUsed.get(getHyperliquidMarketDex(entry.symbol)) ?? 0)),
120422
+ remaining_asset_units: remainingAssetUnits
120423
+ }),
119427
120424
  current_symbol_signed_units: planSignedUnits
119428
120425
  };
119429
120426
  const planAcceptance = evaluateRuntimeDecisionAcceptance({
@@ -119450,7 +120447,14 @@ ${reviewOutputContract}`;
119450
120447
  units: 0,
119451
120448
  tradability: entry.tradability,
119452
120449
  reasoning: `Skipped by client runtime constraints: ${planAcceptance.reason_code || "capacity_reached"}`,
119453
- 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
+ } : {}
119454
120458
  };
119455
120459
  }
119456
120460
  throw new Error(buildRuntimeConstraintRejectionMessage({
@@ -119496,7 +120500,16 @@ ${reviewOutputContract}`;
119496
120500
  reasoning: entry.reasoning,
119497
120501
  executionContext: buildExecutionContextForSymbol(entry.symbol)
119498
120502
  };
119499
- });
120503
+ };
120504
+ const acceptedBySlot = /* @__PURE__ */ new Map();
120505
+ for (const slot of reductionFirstOrder(finalDecisionPlans.map((entry) => ({
120506
+ decision: entry.decision,
120507
+ units: entry.units,
120508
+ signedUnits: computePlanSignedUnits(entry.symbol)
120509
+ })))) {
120510
+ acceptedBySlot.set(slot, acceptExecutionPlan(finalDecisionPlans[slot]));
120511
+ }
120512
+ const acceptedExecutionPlans = finalDecisionPlans.map((_, slot) => acceptedBySlot.get(slot));
119500
120513
  const selectedAcceptedPlan = acceptedExecutionPlans.find((entry) => normalizeRuntimeSymbol(entry.symbol) === normalizeRuntimeSymbol(symbol2)) ?? acceptedExecutionPlans[0];
119501
120514
  const acceptance = {
119502
120515
  accepted: true,
@@ -119658,6 +120671,7 @@ ${reviewOutputContract}`;
119658
120671
  completedAt: (/* @__PURE__ */ new Date()).toISOString(),
119659
120672
  settingsFallbackUsed,
119660
120673
  settingsSnapshot: settingsSnapshotWithContext,
120674
+ reviewedCycle,
119661
120675
  clientExchangeSnapshot,
119662
120676
  executionContext: selectedAcceptedPlan?.executionContext ?? buildExecutionContextForSymbol(symbol2),
119663
120677
  executionPlans: acceptedExecutionPlans
@@ -119759,6 +120773,7 @@ var init_engine = __esm({
119759
120773
  init_hyperliquid_account_state_adapter();
119760
120774
  init_hyperliquid_market_symbol();
119761
120775
  init_client_killswitch();
120776
+ init_perp_dex_scope();
119762
120777
  init_api2();
119763
120778
  init_history_evidence();
119764
120779
  init_portfolio_evidence();
@@ -120153,24 +121168,16 @@ var init_engine = __esm({
120153
121168
  withServerPositionEvents = (result) => result.executionReports.map((report) => {
120154
121169
  const action = String(report.action ?? "").toUpperCase();
120155
121170
  if (report.status !== "executed" || !["BUY", "SELL", "FLIP_OPEN"].includes(action)) return report;
120156
- const bySide = (side) => side === "BUY" ? "LONG" : "SHORT";
120157
- let event = null;
120158
- let direction = null;
120159
- if (result.intent === "open" || result.intent === "add") {
120160
- event = result.intent;
120161
- direction = bySide(action);
120162
- } else if (result.intent === "reduce") {
120163
- event = "reduce";
120164
- direction = action === "BUY" ? "SHORT" : "LONG";
120165
- } else if (result.intent === "close") {
120166
- event = "close";
120167
- direction = action === "SELL" ? "LONG" : "SHORT";
120168
- } else if (result.intent === "flip" && (result.side === "buy" || result.side === "sell")) {
120169
- const [closeLeg, entryLeg] = flipExecutionLegs(result.side, "executed");
120170
- const leg = report.execution_metadata?.decision_leg === "entry" || action === "FLIP_OPEN" ? entryLeg : closeLeg;
120171
- event = leg.positionEvent;
120172
- direction = leg.positionDirection;
120173
- }
121171
+ const side = result.intent === "flip" || action === "FLIP_OPEN" ? result.side : action === "BUY" ? "buy" : "sell";
121172
+ if (side !== "buy" && side !== "sell") return report;
121173
+ const leg = report.execution_metadata?.decision_leg === "entry" || action === "FLIP_OPEN" ? "entry" : "flip_close";
121174
+ const { positionEvent: intentEvent, positionDirection: direction } = executedOrderPositionEvent(
121175
+ String(result.intent ?? ""),
121176
+ side,
121177
+ leg
121178
+ );
121179
+ const beganFlat = report.execution_metadata?.entry_began_flat;
121180
+ const event = (result.intent === "open" || result.intent === "add") && typeof beganFlat === "boolean" ? beganFlat ? "open" : "add" : result.intent === "close" && result.reasonCode === "close_fill_unresolved" ? "reduce" : intentEvent;
120174
121181
  if (!event || !direction) return report;
120175
121182
  return { ...report, execution_metadata: { ...report.execution_metadata, position_event: event, position_direction: direction } };
120176
121183
  });
@@ -120457,6 +121464,8 @@ var init_engine = __esm({
120457
121464
  this._settleUnreportedModelCalls = null;
120458
121465
  // How many of an error's model calls its last error report carried.
120459
121466
  this._lastErrorReportCalls = null;
121467
+ // The retry wait the API returned for this runtime's latest error report.
121468
+ this._reportedProviderRetryAfterSeconds = null;
120460
121469
  this._activeRuntimeContractIdentity = null;
120461
121470
  this._contractRebindInFlight = false;
120462
121471
  this._contractRebindExhausted = false;
@@ -120645,6 +121654,12 @@ var init_engine = __esm({
120645
121654
  await this._trailingMaintenancePromise;
120646
121655
  await this._pendingProtectionRecoveryPromise;
120647
121656
  await waitForBrowserExchangeMutationSettlement(profileId);
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
+ );
120648
121663
  const { positions } = await fetchBrowserAccountState2({
120649
121664
  publicRequestPriority: "trading_reduce",
120650
121665
  config: paused.config,
@@ -120653,6 +121668,8 @@ var init_engine = __esm({
120653
121668
  tickerPrice: 0,
120654
121669
  leverage: 1,
120655
121670
  aggregatePerpDexs: true,
121671
+ // Only the bot's exchanges: positions elsewhere are not the bot's to close.
121672
+ perpDexScope: stopCloseVenues?.filter(Boolean),
120656
121673
  forceRefresh: true,
120657
121674
  sessionId: this._sessionId ?? void 0
120658
121675
  });
@@ -120665,7 +121682,8 @@ var init_engine = __esm({
120665
121682
  positions,
120666
121683
  config: paused.config,
120667
121684
  signingKey,
120668
- timeoutSeconds
121685
+ timeoutSeconds,
121686
+ venues: stopCloseVenues
120669
121687
  });
120670
121688
  if (summary.positionCloseFailures > 0) {
120671
121689
  throw new Error(`${summary.positionCloseFailures} position(s) could not be closed`);
@@ -123321,7 +124339,17 @@ var init_engine = __esm({
123321
124339
  // A Server bot's row records what started its cycle, as the
123322
124340
  // Python Server loop's does (a Client row never has, and the key
123323
124341
  // is part of a row's Insights settings epoch).
123324
- settingsSnapshot: this._expectedExecutionMode === "server" ? { ...result.settingsSnapshot, analysis_trigger_origin: ignoreAiSchedule ? "manual" : "scheduled" } : result.settingsSnapshot,
124342
+ settingsSnapshot: {
124343
+ ...result.settingsSnapshot,
124344
+ ...this._expectedExecutionMode === "server" ? { analysis_trigger_origin: ignoreAiSchedule ? "manual" : "scheduled" } : {},
124345
+ // A cycle Review changed keeps the Main model and its own
124346
+ // decisions, as the Server loop's row does; the decision route
124347
+ // also records them as per-symbol rows.
124348
+ ...result.reviewedCycle ? {
124349
+ original_model: result.reviewedCycle.originalModel,
124350
+ original_decisions: result.reviewedCycle.originalDecisions
124351
+ } : {}
124352
+ },
123325
124353
  clientExchangeSnapshot: result.clientExchangeSnapshot ?? null,
123326
124354
  // The server refuses a report with more attempts than one cycle can make.
123327
124355
  invocations: boundRuntimeReportAttempts(
@@ -123411,6 +124439,7 @@ var init_engine = __esm({
123411
124439
  }
123412
124440
  const executionResults = [];
123413
124441
  const executionFailures = [];
124442
+ const executionFailureCauses = [];
123414
124443
  const executionLeaseToken = () => {
123415
124444
  const lease = getPersistedClientRuntimeServerLease(profileId);
123416
124445
  return lease?.runtimeSessionId === sessionId && lease.deviceId === deviceId && lease.mode === "trader" ? lease.runtimeLeaseToken : null;
@@ -123429,7 +124458,7 @@ var init_engine = __esm({
123429
124458
  symbol: plan.executionContext.symbol,
123430
124459
  decision,
123431
124460
  units: Math.trunc(Number(plan.units))
123432
- })));
124461
+ })), capacityPlans[0]?.plan.executionContext.decisionSnapshotCapturedAt);
123433
124462
  capacityPlans.forEach(({ planIndex }, index) => serverCapacityByPlan.set(planIndex, allocations[index]));
123434
124463
  }
123435
124464
  const runPlan = async (plan, planIndex) => {
@@ -123570,6 +124599,7 @@ var init_engine = __esm({
123570
124599
  symbol: plan.executionContext.symbol,
123571
124600
  projection: projectedFailure
123572
124601
  });
124602
+ executionFailureCauses.push(executionError);
123573
124603
  }
123574
124604
  appendRuntimeDebugEvent({
123575
124605
  label: "execution_plan_failed",
@@ -123620,6 +124650,24 @@ var init_engine = __esm({
123620
124650
  }
123621
124651
  }
123622
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
+ }
123623
124671
  return { control: "continue", result: executionResult };
123624
124672
  };
123625
124673
  const recordPlanResult = (executionResult) => {
@@ -123633,23 +124681,43 @@ var init_engine = __esm({
123633
124681
  }
123634
124682
  };
123635
124683
  const cycleSupersededWithoutExecution = () => !this._executionFinalizationRequired && (analysisAbortController.signal.aborted || this._isStopping || this._analysisRequestId !== requestId);
123636
- for (let planIndex = 0; planIndex < executionPlans.length; planIndex += 1) {
123637
- if (planIndex > 0 && this._windowHandoffRequested) {
124684
+ const advisorySignedUnits = (context) => {
124685
+ try {
124686
+ return signedUnitsFromEntryPosition(
124687
+ context.currentPositionSize,
124688
+ context.currentPositionEntryPrice,
124689
+ context.unitSizeUsdc
124690
+ );
124691
+ } catch {
124692
+ return 0;
124693
+ }
124694
+ };
124695
+ const dispatchOrder = reductionFirstOrder(executionPlans.map((plan) => ({
124696
+ decision: plan.decision,
124697
+ units: plan.units,
124698
+ signedUnits: advisorySignedUnits(plan.executionContext)
124699
+ })));
124700
+ const dispatchedPlanIndexes = [];
124701
+ for (const [dispatched, planIndex] of dispatchOrder.entries()) {
124702
+ if (dispatched > 0 && this._windowHandoffRequested) {
123638
124703
  break;
123639
124704
  }
123640
124705
  const outcome = await runPlan(executionPlans[planIndex], planIndex);
123641
124706
  if (outcome.control === "return") {
123642
124707
  return;
123643
124708
  }
124709
+ if (outcome.result) {
124710
+ recordPlanResult(outcome.result);
124711
+ dispatchedPlanIndexes.push(planIndex);
124712
+ }
123644
124713
  if (outcome.control === "break") {
123645
- if (outcome.result) recordPlanResult(outcome.result);
123646
124714
  break;
123647
124715
  }
123648
- recordPlanResult(outcome.result);
123649
124716
  if (cycleSupersededWithoutExecution()) {
123650
124717
  return;
123651
124718
  }
123652
124719
  }
124720
+ executionResults.splice(0, executionResults.length, ...executionResults.map((executionResult, position) => ({ executionResult, planIndex: dispatchedPlanIndexes[position] })).sort((left, right) => left.planIndex - right.planIndex).map(({ executionResult }) => executionResult));
123653
124721
  const executionReports = executionResults.flatMap((executionResult) => Array.isArray(executionResult.executionReports) ? this._expectedExecutionMode === "server" ? withServerPositionEvents(executionResult) : executionResult.executionReports : []);
123654
124722
  const executedOrderReports = executionReports.filter((report) => report.status === "executed" && String(report.order_id || "").trim().length > 0);
123655
124723
  const handoffCleanups = executionResults.flatMap((executionResult) => executionResult.handoffCleanup ? [executionResult.handoffCleanup] : []);
@@ -123802,16 +124870,18 @@ var init_engine = __esm({
123802
124870
  cycleReason = "execution_failed";
123803
124871
  cycleFailureStage = "execution";
123804
124872
  const primaryFailure = selectPrimaryExecutionFailure(executionFailures);
123805
- if (!primaryFailure) return;
123806
- await this.reportError(primaryFailure.projection.message, {
123807
- fatal: false,
123808
- model: result.model,
123809
- modelSource: result.model_source ?? result.provider,
123810
- executionSymbol: primaryFailure.symbol,
123811
- executionReasonCode: primaryFailure.projection.reason_code,
123812
- executionStage: primaryFailure.projection.execution_stage,
123813
- dispatchOutcome: primaryFailure.projection.dispatch_outcome
123814
- });
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
+ }
123815
124885
  return;
123816
124886
  }
123817
124887
  }
@@ -123948,9 +125018,8 @@ var init_engine = __esm({
123948
125018
  });
123949
125019
  return;
123950
125020
  }
123951
- if (hasEventBoundProviderFailureEvidence(error48) && this._expectedExecutionMode === "server") {
123952
- const backoffSeconds = Number((await this.getExecutionConfig(profileId).catch(() => null))?.provider_failure_backoff_seconds);
123953
- if (Number.isFinite(backoffSeconds) && backoffSeconds > 0) providerRetryDelayMs = backoffSeconds * MS_PER_SECOND;
125021
+ if (this._expectedExecutionMode === "server" && this._reportedProviderRetryAfterSeconds !== null) {
125022
+ providerRetryDelayMs = this._reportedProviderRetryAfterSeconds * MS_PER_SECOND;
123954
125023
  }
123955
125024
  if (hasEventBoundProviderFailureEvidence(error48)) {
123956
125025
  this.scheduleProviderFailureDiagnosticsTelemetry({
@@ -124044,7 +125113,7 @@ var init_engine = __esm({
124044
125113
  primary_analysis_disabled: this._primaryAnalysisDisabled,
124045
125114
  agent_poll_retry_ms: agentPollDelayMs
124046
125115
  });
124047
- const providerRetryWake = providerRetryDelayMs !== null && aiSchedulePauseMs === null && agentPollDelayMs === null && (this._nextRunAtMs == null || this._nextRunAtMs > Date.now() + providerRetryDelayMs) ? providerRetryDelayMs : null;
125116
+ const providerRetryWake = providerRetryDelayMs !== null && aiSchedulePauseMs === null && agentPollDelayMs === null ? providerRetryDelayMs : null;
124048
125117
  if (providerRetryWake !== null) this._nextRunAtMs = Date.now() + providerRetryWake;
124049
125118
  const windowEndsAtMs = this._aiScheduleWindowEndsAtMs;
124050
125119
  const nextWorkAtMs = this._primaryAnalysisDisabled && this._loopIntervalMs != null ? Date.now() + this._loopIntervalMs : this._nextRunAtMs;
@@ -124271,6 +125340,7 @@ var init_engine = __esm({
124271
125340
  }
124272
125341
  }
124273
125342
  async reportError(reason, options) {
125343
+ this._reportedProviderRetryAfterSeconds = null;
124274
125344
  if (this._isStopping) {
124275
125345
  this._lastError = null;
124276
125346
  return null;
@@ -124349,6 +125419,8 @@ var init_engine = __esm({
124349
125419
  }
124350
125420
  );
124351
125421
  const accepted = this._setRuntimeStatus(response.runtime, "error_report");
125422
+ const retryAfterSeconds = Number(response.provider_retry_after_seconds);
125423
+ this._reportedProviderRetryAfterSeconds = accepted && response.provider_retry_after_seconds != null && Number.isFinite(retryAfterSeconds) && retryAfterSeconds >= 0 ? retryAfterSeconds : null;
124352
125424
  this._lastError = persistedError;
124353
125425
  this._notifyListeners();
124354
125426
  return accepted ? response.runtime ?? null : null;
@@ -124888,7 +125960,7 @@ var init_engine = __esm({
124888
125960
  positionCloseFailures: 0
124889
125961
  };
124890
125962
  if (context.close_positions) {
124891
- const stalePositions = evaluation.accountState?.positions ?? [];
125963
+ const stalePositions = positionsOnVenues(evaluation.accountState?.positions ?? [], evaluation.closeVenues);
124892
125964
  try {
124893
125965
  const signingKey = String(
124894
125966
  this._deviceSecrets?.hyperliquidSigningKey || ""
@@ -124917,6 +125989,8 @@ var init_engine = __esm({
124917
125989
  tickerPrice: 0,
124918
125990
  leverage: 1,
124919
125991
  aggregatePerpDexs: true,
125992
+ // The bot's exchanges: positions elsewhere are not the bot's to close.
125993
+ perpDexScope: evaluation.closeVenues?.filter(Boolean),
124920
125994
  forceRefresh: true,
124921
125995
  sessionId: this._sessionId ?? void 0,
124922
125996
  signal: refreshController.signal
@@ -124939,7 +126013,8 @@ var init_engine = __esm({
124939
126013
  positions: freshPositions,
124940
126014
  config: config2,
124941
126015
  signingKey,
124942
- timeoutSeconds: closeTimeoutSeconds
126016
+ timeoutSeconds: closeTimeoutSeconds,
126017
+ venues: evaluation.closeVenues
124943
126018
  });
124944
126019
  } else {
124945
126020
  closeSummary = {