@vtxmacro/cli 2026.10.18 → 2026.10.20
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/exo-harness.ts +8 -0
- package/bin/vtx-mcp.js +9 -1
- package/bin/vtx-service-bootstrap.js +9 -1
- package/bin/vtx-service-launcher.js +8 -0
- package/bin/vtx.js +1220 -474
- package/package.json +1 -1
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.
|
|
116
|
+
agent_cli_release_default = { package_name: "@vtxmacro/cli", package_version: "2026.10.20", 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
|
},
|
|
@@ -1292,6 +1297,9 @@ var init_runtime_policy_generated = __esm({
|
|
|
1292
1297
|
websocket: {
|
|
1293
1298
|
ping_interval_seconds: 20,
|
|
1294
1299
|
account_open_timeout_seconds: 10
|
|
1300
|
+
},
|
|
1301
|
+
perp_dexs: {
|
|
1302
|
+
default_dex_label: "Hyperliquid"
|
|
1295
1303
|
}
|
|
1296
1304
|
},
|
|
1297
1305
|
cache: {
|
|
@@ -1457,7 +1465,7 @@ var init_runtime_policy_generated = __esm({
|
|
|
1457
1465
|
});
|
|
1458
1466
|
|
|
1459
1467
|
// lib/constants.ts
|
|
1460
|
-
var MS_PER_SECOND, SECONDS_PER_MINUTE, MINUTES_PER_HOUR, HOURS_PER_DAY, DAYS_PER_WEEK, MS_PER_MINUTE, SECONDS_PER_HOUR, SECONDS_PER_DAY, SECONDS_PER_WEEK, MINUTES_PER_DAY, MINUTES_PER_WEEK, MS_PER_HOUR, MS_PER_DAY, READ_STAMP_TIE_MS, READ_STAMP_STEP_BACK_MS, CLOCK_FIELD_DIGITS, BACKOFF_GROWTH_FACTOR, BYTES_PER_KIB, BYTES_PER_MIB, BITS_PER_BYTE, BYTE_MASK, OWNER_ONLY_FILE_MODE, OWNER_ONLY_DIRECTORY_MODE, GROUP_OTHER_PERMISSION_BITS, DECIMAL_RADIX, HEX_RADIX, BASE36_RADIX, BYTE_HEX_DIGITS, UINT32_HEX_DIGITS, RANDOM_FRACTION_PREFIX_LENGTH, PERCENT_SCALE, MIDPOINT_DIVISOR, SQUARE_EXPONENT, FNV1A_32_OFFSET_BASIS, FNV1A_32_PRIME, JSON_INDENT_SPACES, INT32_MIN, INT32_MAX, SET_TIMEOUT_MAX_DELAY_MS, POSITION_SIZE_EPSILON, CANDLE_TIMEFRAME_SECONDS, HTTP_STATUS, HTTP_STATUS_MIN, HTTP_STATUS_MAX, HTTP_CLIENT_ERROR_MIN, HTTP_SERVER_ERROR_MIN, AI_COST_ESTIMATE_PERIOD_DAYS, SECONDS_PER_AI_COST_ESTIMATE_PERIOD, DATE_FIELD_DIGITS, EXTERNAL_INFERENCE_LIMITS, NODE_ARGV_COMMAND_ARGS_START, EXIT_CODE_TEMPFAIL, SHA256_INITIAL_STATE, SHA256_ROUND_CONSTANTS, SHA256, UINT64_HIGH_WORD_DIVISOR, CANONICAL_BASE64URL, INFERENCE_ENVELOPE_CRYPTO, EXTERNAL_INFERENCE_SCHEMA_BOUNDS, JSON_RPC_ERROR_CODES, INFERENCE_MCP_SCHEMA_PROBE_MAX_DEPTH, INFERENCE_HOST_PROCESS_LOCK_RECORD_SCHEMA_VERSION, INFERENCE_HOST_RECLAIM_GUARD_CREATE_PASSES, LINUX_PROC_STAT_COMM_TERMINATOR_CHARS, INFERENCE_HOST_RANDOM_BYTES, INFERENCE_OAUTH_TOKEN_MAX_LENGTH, INFERENCE_CREDENTIAL_WINDOWS_NOT_FOUND_EXIT_CODE, MACOS_SECURITY_ITEM_NOT_FOUND_EXIT_CODE, INFERENCE_CREDENTIAL_LABEL_ACCOUNT_KEY_CHARS, INFERENCE_HOST_STABLE_OPERATION_ID_HASH_CHARS, INFERENCE_HOST_DRAIN_PRIORITY, INFERENCE_JOB_CLAIM_SCHEMA_VERSION, INFERENCE_HOST_WINDOWS_TASK_IDENTITY_MAX_CHARS, INFERENCE_HOST_OWNER_ONLY_EXECUTABLE_MODE, WINDOWS_TASKKILL_PROCESS_NOT_FOUND_EXIT_CODE, INFERENCE_HOST_CLI_MAX_SERVICE_POSITIONALS, INFERENCE_HOST_CLI_MAX_COMMAND_POSITIONALS, INFERENCE_HOST_DISPLAY_NAME_MAX_CHARS, INFERENCE_HOST_REVOCATION_CHECKPOINT_MAX_CHARS, INFERENCE_HOST_MODEL_ID_MAX_CHARS, CODEX_RECOVERY_RECEIPT_MAX_CHARS, CODEX_HOSTED_ATTEMPT_PATH_SEGMENTS, CODEX_GUARDIAN_PROCESS_TOKEN_BYTES, CODEX_RATE_LIMIT_EXHAUSTED_PERCENT, INFERENCE_HOST_PROXY_TOKEN_BYTES, GROK_TOOL_SERVER_TOKEN_BYTES, GROK_NATIVE_SESSION_GROUP_NAME_MAX_CHARS, GROK_POLICY_TRANSPORT_MAX_BYTES, EXO_POLICY_MAX_TOOL_ROUNDS, EXO_POLICY_MAX_MODELS, EXO_POLICY_MODEL_NAME_MAX_CHARS, EXO_RUNTIME_VERSION_COMMIT_CHARS, PI_QUALIFIED_MODEL_ID_MAX_CHARS, PI_STRUCTURED_OUTPUT_MAX_DEPTH, PI_STRUCTURED_OUTPUT_MAX_PROPERTIES, INFERENCE_HOST_API_KEY_MIN_CHARS, INFERENCE_HOST_API_KEY_MAX_BYTES, INFERENCE_HOST_API_KEY_IDENTITY_HEX_CHARS, DEEPSEEK_HARNESS_NODE_LTS_MAJOR, DEEPSEEK_HARNESS_NODE_LTS_MIN_MINOR, DEEPSEEK_HARNESS_NODE_CURRENT_MAJOR, PROMPT_FIXED_DIGITS, PROMPT_SIGNIFICANT_DIGITS, PROMPT_NUMBER_MAX_DIGITS, PROMPT_PRICE_INTEGER_THRESHOLD, PROMPT_MARGIN_UTILIZATION_DECIMALS, PROMPT_SYMBOL_MAX_CHARS, PROMPT_PARTIAL_UNIT_ROUND_UP_FRACTION, HALF_UP_ROUNDING_OFFSET, PROMPT_ENTRY_PRICE_MATCH_ABS_TOLERANCE, PROMPT_ENTRY_PRICE_MATCH_REL_TOLERANCE, DECISION_OUTPUT_EXAMPLE_TRADABILITY, INDICATOR_RSI_PERIOD, INDICATOR_ATR_PERIOD, INDICATOR_MACD_FAST_PERIOD, INDICATOR_MACD_SLOW_PERIOD, INDICATOR_MACD_SIGNAL_PERIOD, INDICATOR_BOLLINGER_PERIOD, INDICATOR_BOLLINGER_STD_DEV, INDICATOR_OSCILLATOR_MAX, EMA_SMOOTHING_NUMERATOR, PROMPT_EMA_PERIODS, JSON_UNICODE_ESCAPE_PREFIX_LENGTH, JSON_UNICODE_ESCAPE_HEX_DIGITS, JSON_CONTROL_CHARACTER_MAX, RUNTIME_DEBUG_SNIPPET_CHARS, RUNTIME_DEBUG_PROMPT_SNIPPET_CHARS, RUNTIME_DEBUG_TOKEN_PREFIX_CHARS, RUNTIME_DEBUG_USD_DECIMALS, REVIEW_FAILURE_DETAIL_MAX_CHARS, RUNTIME_LATENCY_SECONDS_DECIMALS, AI_SCHEDULE_CLOCK_PARTS, ESTIMATED_CHARS_PER_TOKEN, PROVIDER_ERROR_RAW_TEXT_MAX_CHARS, AI_CALL_COST_DECIMALS, PROVIDER_DIAGNOSTIC_LIMITS, AI_INVOCATION_CONTRACT_VERSION, AI_INVOCATION_TELEMETRY_LIMITS, PROVIDER_USAGE_DETAIL_LIMITS, HYPERLIQUID_EXCHANGE_SPECIFICATION, HYPERLIQUID_TPSL_BATCH_MIN_ORDERS, HYPERLIQUID_USER_FILLS_PROVIDER_PAGE_CAP, HYPERLIQUID_ROW_WEIGHTED_INFO_REQUESTS, HYPERLIQUID_INFO_ROWS_PER_EXTRA_WEIGHT, HYPERLIQUID_META_AND_ASSET_CTXS_PARTS, HYPERLIQUID_SIDE_PAIR_LENGTH, HYPERLIQUID_SIGNED_SIZE_MATCH_EXTRA_DECIMALS, HYPERLIQUID_OPEN_ORDERS_MAX_NESTING_DEPTH, ACCOUNT_PAYLOAD_MODE_SEARCH_MAX_DEPTH, HYPERLIQUID_ACCOUNT_ROUNDING_DECIMALS, HYPERLIQUID_UNREALIZED_PNL_ZERO_TOLERANCE, HYPERLIQUID_MAX_DEPLOYER_FEE_SCALE, HYPERLIQUID_DEPLOYER_FEE_SCALE_MULTIPLIER, HYPERLIQUID_GROWTH_MODE_FEE_FACTOR, HYPERLIQUID_ALIGNED_QUOTE_NON_DEPLOYER_FEE_FACTOR, HYPERLIQUID_CLOSE_SIZE_RELATIVE_TOLERANCE, HYPERLIQUID_POSITION_SIZE_MATCH_ABS_TOLERANCE, HYPERLIQUID_POSITION_SIZE_MATCH_RELATIVE_TOLERANCE, HYPERLIQUID_LOT_FLOOR_NOISE_DECIMALS, HYPERLIQUID_RECOVERY_BACKOFF_MAX_EXPONENT, HYPERLIQUID_RECOVERY_CONCURRENCY_GROWTH_FACTOR, UUID_BYTES, UUID_HEX_GROUP_ENDS, MSGPACK, CLIENT_RUNTIME_DEFAULT_RETRY_SECONDS, CLIENT_RUNTIME_PROVIDER_ATTEMPT_SUMMARY_MAX_CHARS, CLIENT_RUNTIME_HL_REQUEST_TYPE_MAX_CHARS, CLIENT_RUNTIME_DRAWDOWN_DEBUG_DECIMALS, CLIENT_PROTECTIVE_GROUP_VERSION, CLIENT_PROTECTIVE_TPSL_PAIR_LEGS, CLIENT_PROTECTIVE_FILL_MATCH_ABS_TOLERANCE, CLIENT_PROTECTIVE_FILL_MATCH_REL_TOLERANCE, CLIENT_CLOSE_FILL_EPSILON_ULPS, COPY_TRADING_SIZE_EPSILON, COPY_TRADING_RELATIVE_SIZE_TOLERANCE, COPY_TRADING_NOTIONAL_CAP_TOLERANCE_USD, CLIENT_ACCOUNT_PNL_NONZERO_MIN_USD, RUNTIME_PORTFOLIO_PERIOD_ENTRY_LENGTH, CLIENT_EXCHANGE_RECONCILIATION_MAX_DELAY_MS, RFC1918_172_BLOCK_SECOND_OCTET, AGENT_CLI_TAKEOVER_REQUIRED_EXIT_CODE, EXIT_CODE_INTERRUPTED, EXIT_CODE_SIGNAL_BASE, BYOK_PROVIDER_DISPLAY_ORDER_STEP, TOKENS_PER_MILLION, RENDER_DEBUG_ID_RANDOM_CHARS;
|
|
1468
|
+
var MS_PER_SECOND, SECONDS_PER_MINUTE, MINUTES_PER_HOUR, HOURS_PER_DAY, DAYS_PER_WEEK, MS_PER_MINUTE, SECONDS_PER_HOUR, SECONDS_PER_DAY, SECONDS_PER_WEEK, MINUTES_PER_DAY, MINUTES_PER_WEEK, MS_PER_HOUR, MS_PER_DAY, READ_STAMP_TIE_MS, READ_STAMP_STEP_BACK_MS, CLOCK_FIELD_DIGITS, BACKOFF_GROWTH_FACTOR, BYTES_PER_KIB, BYTES_PER_MIB, BITS_PER_BYTE, BYTE_MASK, OWNER_ONLY_FILE_MODE, OWNER_ONLY_DIRECTORY_MODE, GROUP_OTHER_PERMISSION_BITS, DECIMAL_RADIX, HEX_RADIX, BASE36_RADIX, BYTE_HEX_DIGITS, UINT32_HEX_DIGITS, RANDOM_FRACTION_PREFIX_LENGTH, PERCENT_SCALE, MIDPOINT_DIVISOR, SQUARE_EXPONENT, FNV1A_32_OFFSET_BASIS, FNV1A_32_PRIME, JSON_INDENT_SPACES, INT32_MIN, INT32_MAX, SET_TIMEOUT_MAX_DELAY_MS, POSITION_SIZE_EPSILON, CANDLE_TIMEFRAME_SECONDS, HTTP_STATUS, HTTP_STATUS_MIN, HTTP_STATUS_MAX, HTTP_CLIENT_ERROR_MIN, HTTP_SERVER_ERROR_MIN, USD_DISPLAY_DECIMALS, AI_COST_ESTIMATE_PERIOD_DAYS, SECONDS_PER_AI_COST_ESTIMATE_PERIOD, DATE_FIELD_DIGITS, EXTERNAL_INFERENCE_LIMITS, NODE_ARGV_COMMAND_ARGS_START, EXIT_CODE_TEMPFAIL, SHA256_INITIAL_STATE, SHA256_ROUND_CONSTANTS, SHA256, UINT64_HIGH_WORD_DIVISOR, CANONICAL_BASE64URL, INFERENCE_ENVELOPE_CRYPTO, EXTERNAL_INFERENCE_SCHEMA_BOUNDS, JSON_RPC_ERROR_CODES, INFERENCE_MCP_SCHEMA_PROBE_MAX_DEPTH, INFERENCE_HOST_PROCESS_LOCK_RECORD_SCHEMA_VERSION, INFERENCE_HOST_RECLAIM_GUARD_CREATE_PASSES, LINUX_PROC_STAT_COMM_TERMINATOR_CHARS, INFERENCE_HOST_RANDOM_BYTES, INFERENCE_OAUTH_TOKEN_MAX_LENGTH, INFERENCE_CREDENTIAL_WINDOWS_NOT_FOUND_EXIT_CODE, MACOS_SECURITY_ITEM_NOT_FOUND_EXIT_CODE, INFERENCE_CREDENTIAL_LABEL_ACCOUNT_KEY_CHARS, INFERENCE_HOST_STABLE_OPERATION_ID_HASH_CHARS, INFERENCE_HOST_DRAIN_PRIORITY, INFERENCE_JOB_CLAIM_SCHEMA_VERSION, INFERENCE_HOST_WINDOWS_TASK_IDENTITY_MAX_CHARS, INFERENCE_HOST_OWNER_ONLY_EXECUTABLE_MODE, WINDOWS_TASKKILL_PROCESS_NOT_FOUND_EXIT_CODE, INFERENCE_HOST_CLI_MAX_SERVICE_POSITIONALS, INFERENCE_HOST_CLI_MAX_COMMAND_POSITIONALS, INFERENCE_HOST_DISPLAY_NAME_MAX_CHARS, INFERENCE_HOST_REVOCATION_CHECKPOINT_MAX_CHARS, INFERENCE_HOST_MODEL_ID_MAX_CHARS, CODEX_RECOVERY_RECEIPT_MAX_CHARS, CODEX_HOSTED_ATTEMPT_PATH_SEGMENTS, CODEX_GUARDIAN_PROCESS_TOKEN_BYTES, CODEX_RATE_LIMIT_EXHAUSTED_PERCENT, INFERENCE_HOST_PROXY_TOKEN_BYTES, GROK_TOOL_SERVER_TOKEN_BYTES, GROK_NATIVE_SESSION_GROUP_NAME_MAX_CHARS, GROK_POLICY_TRANSPORT_MAX_BYTES, EXO_POLICY_MAX_TOOL_ROUNDS, EXO_POLICY_MAX_MODELS, EXO_POLICY_MODEL_NAME_MAX_CHARS, EXO_RUNTIME_VERSION_COMMIT_CHARS, PI_QUALIFIED_MODEL_ID_MAX_CHARS, PI_STRUCTURED_OUTPUT_MAX_DEPTH, PI_STRUCTURED_OUTPUT_MAX_PROPERTIES, INFERENCE_HOST_API_KEY_MIN_CHARS, INFERENCE_HOST_API_KEY_MAX_BYTES, INFERENCE_HOST_API_KEY_IDENTITY_HEX_CHARS, DEEPSEEK_HARNESS_NODE_LTS_MAJOR, DEEPSEEK_HARNESS_NODE_LTS_MIN_MINOR, DEEPSEEK_HARNESS_NODE_CURRENT_MAJOR, PROMPT_FIXED_DIGITS, PROMPT_SIGNIFICANT_DIGITS, PROMPT_NUMBER_MAX_DIGITS, PROMPT_PRICE_INTEGER_THRESHOLD, PROMPT_MARGIN_UTILIZATION_DECIMALS, PROMPT_SYMBOL_MAX_CHARS, PROMPT_PARTIAL_UNIT_ROUND_UP_FRACTION, HALF_UP_ROUNDING_OFFSET, PROMPT_ENTRY_PRICE_MATCH_ABS_TOLERANCE, PROMPT_ENTRY_PRICE_MATCH_REL_TOLERANCE, DECISION_OUTPUT_EXAMPLE_TRADABILITY, INDICATOR_RSI_PERIOD, INDICATOR_ATR_PERIOD, INDICATOR_MACD_FAST_PERIOD, INDICATOR_MACD_SLOW_PERIOD, INDICATOR_MACD_SIGNAL_PERIOD, INDICATOR_BOLLINGER_PERIOD, INDICATOR_BOLLINGER_STD_DEV, INDICATOR_OSCILLATOR_MAX, EMA_SMOOTHING_NUMERATOR, PROMPT_EMA_PERIODS, JSON_UNICODE_ESCAPE_PREFIX_LENGTH, JSON_UNICODE_ESCAPE_HEX_DIGITS, JSON_CONTROL_CHARACTER_MAX, RUNTIME_DEBUG_SNIPPET_CHARS, RUNTIME_DEBUG_PROMPT_SNIPPET_CHARS, RUNTIME_DEBUG_TOKEN_PREFIX_CHARS, RUNTIME_DEBUG_USD_DECIMALS, REVIEW_FAILURE_DETAIL_MAX_CHARS, RUNTIME_LATENCY_SECONDS_DECIMALS, AI_SCHEDULE_CLOCK_PARTS, ESTIMATED_CHARS_PER_TOKEN, PROVIDER_ERROR_RAW_TEXT_MAX_CHARS, AI_CALL_COST_DECIMALS, PROVIDER_DIAGNOSTIC_LIMITS, AI_INVOCATION_CONTRACT_VERSION, AI_INVOCATION_TELEMETRY_LIMITS, PROVIDER_USAGE_DETAIL_LIMITS, HYPERLIQUID_EXCHANGE_SPECIFICATION, HYPERLIQUID_TPSL_BATCH_MIN_ORDERS, HYPERLIQUID_USER_FILLS_PROVIDER_PAGE_CAP, HYPERLIQUID_ROW_WEIGHTED_INFO_REQUESTS, HYPERLIQUID_INFO_ROWS_PER_EXTRA_WEIGHT, HYPERLIQUID_META_AND_ASSET_CTXS_PARTS, HYPERLIQUID_SIDE_PAIR_LENGTH, HYPERLIQUID_SIGNED_SIZE_MATCH_EXTRA_DECIMALS, HYPERLIQUID_OPEN_ORDERS_MAX_NESTING_DEPTH, ACCOUNT_PAYLOAD_MODE_SEARCH_MAX_DEPTH, HYPERLIQUID_ACCOUNT_ROUNDING_DECIMALS, HYPERLIQUID_UNREALIZED_PNL_ZERO_TOLERANCE, HYPERLIQUID_MAX_DEPLOYER_FEE_SCALE, HYPERLIQUID_DEPLOYER_FEE_SCALE_MULTIPLIER, HYPERLIQUID_GROWTH_MODE_FEE_FACTOR, HYPERLIQUID_ALIGNED_QUOTE_NON_DEPLOYER_FEE_FACTOR, HYPERLIQUID_CLOSE_SIZE_RELATIVE_TOLERANCE, HYPERLIQUID_POSITION_SIZE_MATCH_ABS_TOLERANCE, HYPERLIQUID_POSITION_SIZE_MATCH_RELATIVE_TOLERANCE, HYPERLIQUID_LOT_FLOOR_NOISE_DECIMALS, HYPERLIQUID_RECOVERY_BACKOFF_MAX_EXPONENT, HYPERLIQUID_RECOVERY_CONCURRENCY_GROWTH_FACTOR, UUID_BYTES, UUID_HEX_GROUP_ENDS, MSGPACK, CLIENT_RUNTIME_DEFAULT_RETRY_SECONDS, CLIENT_RUNTIME_PROVIDER_ATTEMPT_SUMMARY_MAX_CHARS, CLIENT_RUNTIME_HL_REQUEST_TYPE_MAX_CHARS, CLIENT_RUNTIME_DRAWDOWN_DEBUG_DECIMALS, CLIENT_PROTECTIVE_GROUP_VERSION, CLIENT_PROTECTIVE_TPSL_PAIR_LEGS, CLIENT_PROTECTIVE_FILL_MATCH_ABS_TOLERANCE, CLIENT_PROTECTIVE_FILL_MATCH_REL_TOLERANCE, CLIENT_CLOSE_FILL_EPSILON_ULPS, COPY_TRADING_SIZE_EPSILON, COPY_TRADING_RELATIVE_SIZE_TOLERANCE, COPY_TRADING_NOTIONAL_CAP_TOLERANCE_USD, CLIENT_ACCOUNT_PNL_NONZERO_MIN_USD, RUNTIME_PORTFOLIO_PERIOD_ENTRY_LENGTH, CLIENT_EXCHANGE_RECONCILIATION_MAX_DELAY_MS, RFC1918_172_BLOCK_SECOND_OCTET, AGENT_CLI_TAKEOVER_REQUIRED_EXIT_CODE, EXIT_CODE_INTERRUPTED, EXIT_CODE_SIGNAL_BASE, BYOK_PROVIDER_DISPLAY_ORDER_STEP, TOKENS_PER_MILLION, RENDER_DEBUG_ID_RANDOM_CHARS;
|
|
1461
1469
|
var init_constants = __esm({
|
|
1462
1470
|
"lib/constants.ts"() {
|
|
1463
1471
|
"use strict";
|
|
@@ -1550,6 +1558,7 @@ var init_constants = __esm({
|
|
|
1550
1558
|
HTTP_STATUS_MAX = 599;
|
|
1551
1559
|
HTTP_CLIENT_ERROR_MIN = 400;
|
|
1552
1560
|
HTTP_SERVER_ERROR_MIN = 500;
|
|
1561
|
+
USD_DISPLAY_DECIMALS = 2;
|
|
1553
1562
|
AI_COST_ESTIMATE_PERIOD_DAYS = 30;
|
|
1554
1563
|
SECONDS_PER_AI_COST_ESTIMATE_PERIOD = SECONDS_PER_DAY * AI_COST_ESTIMATE_PERIOD_DAYS;
|
|
1555
1564
|
DATE_FIELD_DIGITS = 2;
|
|
@@ -20766,6 +20775,10 @@ var init_runtime_policy_generated2 = __esm({
|
|
|
20766
20775
|
},
|
|
20767
20776
|
defaults: {
|
|
20768
20777
|
server_ai_max_slippage: 5
|
|
20778
|
+
},
|
|
20779
|
+
risk: {
|
|
20780
|
+
max_order_notional: 5e3,
|
|
20781
|
+
max_position_notional: 1e4
|
|
20769
20782
|
}
|
|
20770
20783
|
},
|
|
20771
20784
|
agent_cli: {
|
|
@@ -21018,6 +21031,7 @@ var init_runtime_policy_generated2 = __esm({
|
|
|
21018
21031
|
metadata_ttl_seconds: 300,
|
|
21019
21032
|
user_fees_ttl_seconds: 300,
|
|
21020
21033
|
account_mode_ttl_seconds: 30,
|
|
21034
|
+
ui_account_mode_ttl_seconds: 300,
|
|
21021
21035
|
default_request_weight: 20,
|
|
21022
21036
|
cache_max_entries: 512
|
|
21023
21037
|
},
|
|
@@ -21097,6 +21111,9 @@ var init_runtime_policy_generated2 = __esm({
|
|
|
21097
21111
|
websocket: {
|
|
21098
21112
|
ping_interval_seconds: 20,
|
|
21099
21113
|
account_open_timeout_seconds: 10
|
|
21114
|
+
},
|
|
21115
|
+
perp_dexs: {
|
|
21116
|
+
default_dex_label: "Hyperliquid"
|
|
21100
21117
|
}
|
|
21101
21118
|
},
|
|
21102
21119
|
cache: {
|
|
@@ -54314,7 +54331,7 @@ var init_hyperliquid_market_symbol = __esm({
|
|
|
54314
54331
|
});
|
|
54315
54332
|
|
|
54316
54333
|
// lib/runtime/bot-exchanges.ts
|
|
54317
|
-
var exchangesByProfile, profileKey, dexList, recordBotExchanges, recordStatusExchanges;
|
|
54334
|
+
var exchangesByProfile, exchangesVersion, exchangeListeners, exchangesChanged, profileKey, dexList, recordBotExchanges, recordStatusExchanges;
|
|
54318
54335
|
var init_bot_exchanges = __esm({
|
|
54319
54336
|
"lib/runtime/bot-exchanges.ts"() {
|
|
54320
54337
|
"use strict";
|
|
@@ -54323,6 +54340,12 @@ var init_bot_exchanges = __esm({
|
|
|
54323
54340
|
init_define_VTX_PI_MODEL_POLICY();
|
|
54324
54341
|
init_hyperliquid_market_symbol();
|
|
54325
54342
|
exchangesByProfile = /* @__PURE__ */ new Map();
|
|
54343
|
+
exchangesVersion = 0;
|
|
54344
|
+
exchangeListeners = /* @__PURE__ */ new Set();
|
|
54345
|
+
exchangesChanged = () => {
|
|
54346
|
+
exchangesVersion += 1;
|
|
54347
|
+
exchangeListeners.forEach((listener) => listener());
|
|
54348
|
+
};
|
|
54326
54349
|
profileKey = (profileId) => {
|
|
54327
54350
|
const id2 = Number(profileId);
|
|
54328
54351
|
return Number.isInteger(id2) && id2 > 0 ? id2 : null;
|
|
@@ -54333,11 +54356,14 @@ var init_bot_exchanges = __esm({
|
|
|
54333
54356
|
if (id2 === null) return;
|
|
54334
54357
|
const equity = dexList(equityVenues);
|
|
54335
54358
|
const read = readVenues === void 0 ? equity : dexList(readVenues);
|
|
54359
|
+
const previous = exchangesByProfile.get(id2);
|
|
54336
54360
|
if (!equity || !read) {
|
|
54337
|
-
exchangesByProfile.delete(id2);
|
|
54361
|
+
if (exchangesByProfile.delete(id2)) exchangesChanged();
|
|
54338
54362
|
return;
|
|
54339
54363
|
}
|
|
54364
|
+
if (previous && previous.equity.join() === equity.join() && previous.read.join() === read.join()) return;
|
|
54340
54365
|
exchangesByProfile.set(id2, { equity, read });
|
|
54366
|
+
exchangesChanged();
|
|
54341
54367
|
};
|
|
54342
54368
|
recordStatusExchanges = (status) => {
|
|
54343
54369
|
const fields = status;
|
|
@@ -54773,7 +54799,7 @@ async function getLiveTicker(symbol2 = "PI_XBTUSD", exchange = "kraken", signal)
|
|
|
54773
54799
|
}
|
|
54774
54800
|
async function getExecutionAssetMetadata(exchange, symbol2, options) {
|
|
54775
54801
|
const params = new URLSearchParams();
|
|
54776
|
-
if (options?.
|
|
54802
|
+
if (options?.forceCatalogRefresh) params.set("force_catalog_refresh", "true");
|
|
54777
54803
|
if (options?.publicRequestPriority) params.set("public_request_priority", options.publicRequestPriority);
|
|
54778
54804
|
const query = params.size > 0 ? `?${params.toString()}` : "";
|
|
54779
54805
|
const url2 = `${getApiUrl()}/trading/execution-metadata/${encodeURIComponent(exchange)}/${encodeURIComponent(symbol2)}${query}`;
|
|
@@ -55253,8 +55279,225 @@ var init_hyperliquid_account_mode_contract = __esm({
|
|
|
55253
55279
|
}
|
|
55254
55280
|
});
|
|
55255
55281
|
|
|
55282
|
+
// lib/runtime/server-loop-account-value.ts
|
|
55283
|
+
var STABLE_SPOT_SYMBOLS, toNumber, firstTruthy, spotContainers, extractCanonicalSpotMetrics, stableOrPricedValueUsd, sumBalanceValueUsd, sumBalanceHoldUsd, approximatelyEqual, balancesMirrorUnifiedAccountValue, computeEffectiveAccountValue, requireThreshold, serverLoopAccountValue;
|
|
55284
|
+
var init_server_loop_account_value = __esm({
|
|
55285
|
+
"lib/runtime/server-loop-account-value.ts"() {
|
|
55286
|
+
"use strict";
|
|
55287
|
+
init_define_VTX_EXO_POLICY();
|
|
55288
|
+
init_define_VTX_GROK_POLICY();
|
|
55289
|
+
init_define_VTX_PI_MODEL_POLICY();
|
|
55290
|
+
init_hyperliquid_account_mode_contract();
|
|
55291
|
+
STABLE_SPOT_SYMBOLS = /* @__PURE__ */ new Set(["USDC", "USD", "USDT"]);
|
|
55292
|
+
toNumber = (value, fallback = 0) => {
|
|
55293
|
+
const numeric2 = Number(value);
|
|
55294
|
+
return Number.isFinite(numeric2) ? numeric2 : fallback;
|
|
55295
|
+
};
|
|
55296
|
+
firstTruthy = (values, fallback) => {
|
|
55297
|
+
for (const value of values) {
|
|
55298
|
+
if (value) return value;
|
|
55299
|
+
}
|
|
55300
|
+
return fallback;
|
|
55301
|
+
};
|
|
55302
|
+
spotContainers = (spotResponse) => {
|
|
55303
|
+
if (!spotResponse || typeof spotResponse !== "object" || Array.isArray(spotResponse)) return [];
|
|
55304
|
+
const response = spotResponse;
|
|
55305
|
+
const containers = [response];
|
|
55306
|
+
for (const key of ["spotState", "userState", "clearinghouseState", "state", "data"]) {
|
|
55307
|
+
const child = response[key];
|
|
55308
|
+
if (child && typeof child === "object" && !Array.isArray(child)) containers.push(child);
|
|
55309
|
+
}
|
|
55310
|
+
return containers;
|
|
55311
|
+
};
|
|
55312
|
+
extractCanonicalSpotMetrics = (spotResponse) => {
|
|
55313
|
+
const response = spotResponse && typeof spotResponse === "object" && !Array.isArray(spotResponse) ? spotResponse : {};
|
|
55314
|
+
const containers = spotContainers(response);
|
|
55315
|
+
let accountValue = 0;
|
|
55316
|
+
let totalMarginUsed = 0;
|
|
55317
|
+
let withdrawable = 0;
|
|
55318
|
+
for (const container of containers) {
|
|
55319
|
+
const marginSummary = container.marginSummary && typeof container.marginSummary === "object" && !Array.isArray(container.marginSummary) ? container.marginSummary : {};
|
|
55320
|
+
accountValue = Math.max(accountValue, toNumber(marginSummary.accountValue));
|
|
55321
|
+
totalMarginUsed = Math.max(totalMarginUsed, toNumber(marginSummary.totalMarginUsed));
|
|
55322
|
+
withdrawable = Math.max(withdrawable, toNumber(container.withdrawable));
|
|
55323
|
+
}
|
|
55324
|
+
if (accountValue <= 0) {
|
|
55325
|
+
for (const key of ["accountValue", "totalValue", "equity", "totalRawUsd", "usdValue", "usdcValue"]) {
|
|
55326
|
+
accountValue = Math.max(accountValue, toNumber(response[key]));
|
|
55327
|
+
}
|
|
55328
|
+
}
|
|
55329
|
+
const balances = [];
|
|
55330
|
+
const listKeys = ["balances", "tokenBalances", "spotBalances", "assets"];
|
|
55331
|
+
for (const container of containers) {
|
|
55332
|
+
for (const listKey of listKeys) {
|
|
55333
|
+
const bucket = container[listKey];
|
|
55334
|
+
if (!Array.isArray(bucket)) continue;
|
|
55335
|
+
let stableTotal = 0;
|
|
55336
|
+
let anyTotal = 0;
|
|
55337
|
+
for (const rawEntry of bucket) {
|
|
55338
|
+
if (!rawEntry || typeof rawEntry !== "object" || Array.isArray(rawEntry)) continue;
|
|
55339
|
+
const entry = rawEntry;
|
|
55340
|
+
const coin = String(firstTruthy([
|
|
55341
|
+
entry.coin,
|
|
55342
|
+
entry.token,
|
|
55343
|
+
entry.asset,
|
|
55344
|
+
entry.symbol
|
|
55345
|
+
], "")).trim().toUpperCase();
|
|
55346
|
+
if (!coin) continue;
|
|
55347
|
+
const total = toNumber(firstTruthy([entry.total, entry.balance, entry.amount], "0"));
|
|
55348
|
+
const hold = toNumber(firstTruthy([entry.hold, entry.locked], "0"));
|
|
55349
|
+
const available = Math.max(
|
|
55350
|
+
0,
|
|
55351
|
+
toNumber(firstTruthy([entry.available, entry.free, total - hold], "0"))
|
|
55352
|
+
);
|
|
55353
|
+
let valueUsd = toNumber(firstTruthy([entry.usdValue, entry.usdcValue], "0"));
|
|
55354
|
+
if (valueUsd <= 0 && STABLE_SPOT_SYMBOLS.has(coin)) {
|
|
55355
|
+
valueUsd = available > 0 ? available : total;
|
|
55356
|
+
}
|
|
55357
|
+
balances.push({ coin, total, hold, available, value_usd: valueUsd });
|
|
55358
|
+
const entryValue = valueUsd > 0 ? valueUsd : total;
|
|
55359
|
+
if (entryValue > 0) {
|
|
55360
|
+
anyTotal += entryValue;
|
|
55361
|
+
if (STABLE_SPOT_SYMBOLS.has(coin)) stableTotal += entryValue;
|
|
55362
|
+
}
|
|
55363
|
+
}
|
|
55364
|
+
if (accountValue <= 0) {
|
|
55365
|
+
if (stableTotal > 0) accountValue = stableTotal;
|
|
55366
|
+
else if (anyTotal > 0) accountValue = anyTotal;
|
|
55367
|
+
}
|
|
55368
|
+
}
|
|
55369
|
+
if (balances.length > 0) break;
|
|
55370
|
+
}
|
|
55371
|
+
return { accountValue, totalMarginUsed, withdrawable, balances };
|
|
55372
|
+
};
|
|
55373
|
+
stableOrPricedValueUsd = (balance) => {
|
|
55374
|
+
const valueUsd = toNumber(balance.value_usd);
|
|
55375
|
+
if (valueUsd <= 0 && STABLE_SPOT_SYMBOLS.has(String(balance.coin || "").trim().toUpperCase())) {
|
|
55376
|
+
return toNumber(balance.total);
|
|
55377
|
+
}
|
|
55378
|
+
return valueUsd;
|
|
55379
|
+
};
|
|
55380
|
+
sumBalanceValueUsd = (balances) => balances.reduce(
|
|
55381
|
+
(total, balance) => total + Math.max(stableOrPricedValueUsd(balance), 0),
|
|
55382
|
+
0
|
|
55383
|
+
);
|
|
55384
|
+
sumBalanceHoldUsd = (balances) => balances.reduce((total, balance) => {
|
|
55385
|
+
const valueUsd = stableOrPricedValueUsd(balance);
|
|
55386
|
+
const amount = toNumber(balance.total);
|
|
55387
|
+
if (valueUsd <= 0 || amount <= 0) return total;
|
|
55388
|
+
return total + Math.max(0, valueUsd * (toNumber(balance.hold) / amount));
|
|
55389
|
+
}, 0);
|
|
55390
|
+
approximatelyEqual = (left, right, absoluteToleranceUsd, relativeTolerance) => {
|
|
55391
|
+
const reference = Math.max(Math.abs(left), Math.abs(right), 1);
|
|
55392
|
+
return Math.abs(left - right) <= Math.max(absoluteToleranceUsd, reference * relativeTolerance);
|
|
55393
|
+
};
|
|
55394
|
+
balancesMirrorUnifiedAccountValue = (input) => input.perpsEquity > 0 && input.spotEquity > 0 && input.balancesEquity > 0 && approximatelyEqual(
|
|
55395
|
+
input.perpsEquity,
|
|
55396
|
+
input.spotEquity,
|
|
55397
|
+
input.absoluteToleranceUsd,
|
|
55398
|
+
input.relativeTolerance
|
|
55399
|
+
) && approximatelyEqual(
|
|
55400
|
+
input.spotEquity,
|
|
55401
|
+
input.balancesEquity,
|
|
55402
|
+
input.absoluteToleranceUsd,
|
|
55403
|
+
input.relativeTolerance
|
|
55404
|
+
);
|
|
55405
|
+
computeEffectiveAccountValue = (input) => {
|
|
55406
|
+
if (!input.unifiedLike) return input.perpsEquity;
|
|
55407
|
+
if (input.balancesEquity > 0) {
|
|
55408
|
+
if (input.mirrored) {
|
|
55409
|
+
return Math.max(input.perpsEquity, input.spotEquity, input.balancesEquity);
|
|
55410
|
+
}
|
|
55411
|
+
return Math.max(
|
|
55412
|
+
input.perpsEquity + input.balancesEquity,
|
|
55413
|
+
input.spotEquity,
|
|
55414
|
+
input.balancesEquity
|
|
55415
|
+
);
|
|
55416
|
+
}
|
|
55417
|
+
return Math.max(input.perpsEquity, input.spotEquity);
|
|
55418
|
+
};
|
|
55419
|
+
requireThreshold = (value, key) => {
|
|
55420
|
+
const numeric2 = typeof value === "number" ? value : Number.NaN;
|
|
55421
|
+
if (!Number.isFinite(numeric2) || numeric2 < 0) {
|
|
55422
|
+
throw new Error(`Missing required Hyperliquid account-state configuration: ${key}`);
|
|
55423
|
+
}
|
|
55424
|
+
return numeric2;
|
|
55425
|
+
};
|
|
55426
|
+
serverLoopAccountValue = (input) => {
|
|
55427
|
+
const { classification } = input;
|
|
55428
|
+
const spotDominatesMinTotalUsd = requireThreshold(
|
|
55429
|
+
input.spotDominatesMinTotalUsd,
|
|
55430
|
+
"client_runtime_hyperliquid_account_state.spot_dominates_min_total_usd"
|
|
55431
|
+
);
|
|
55432
|
+
const spotDominatesPerpsMultiplier = requireThreshold(
|
|
55433
|
+
input.spotDominatesPerpsMultiplier,
|
|
55434
|
+
"client_runtime_hyperliquid_account_state.spot_dominates_perps_multiplier"
|
|
55435
|
+
);
|
|
55436
|
+
const spotAvailableToTradeRatioThreshold = requireThreshold(
|
|
55437
|
+
classification.spotAvailableToTradeRatioThreshold,
|
|
55438
|
+
"client_runtime_hyperliquid_account_state.spot_available_to_trade_ratio_threshold"
|
|
55439
|
+
);
|
|
55440
|
+
const spotMeaningfulHoldUsd = requireThreshold(
|
|
55441
|
+
classification.spotMeaningfulHoldUsd,
|
|
55442
|
+
"client_runtime_hyperliquid_account_state.spot_meaningful_hold_usd"
|
|
55443
|
+
);
|
|
55444
|
+
const spotVeryStrongTotalUsd = requireThreshold(
|
|
55445
|
+
classification.spotVeryStrongTotalUsd,
|
|
55446
|
+
"client_runtime_hyperliquid_account_state.spot_very_strong_total_usd"
|
|
55447
|
+
);
|
|
55448
|
+
const spotVeryStrongPerpsEquityThresholdUsd = requireThreshold(
|
|
55449
|
+
classification.spotVeryStrongPerpsEquityThresholdUsd,
|
|
55450
|
+
"client_runtime_hyperliquid_account_state.spot_very_strong_perps_equity_threshold_usd"
|
|
55451
|
+
);
|
|
55452
|
+
const absoluteToleranceUsd = requireThreshold(
|
|
55453
|
+
input.mirroredAccountValueAbsoluteToleranceUsd,
|
|
55454
|
+
"client_runtime_hyperliquid_account_state.mirrored_account_value_absolute_tolerance_usd"
|
|
55455
|
+
);
|
|
55456
|
+
const relativeTolerance = requireThreshold(
|
|
55457
|
+
input.mirroredAccountValueRelativeTolerance,
|
|
55458
|
+
"client_runtime_hyperliquid_account_state.mirrored_account_value_relative_tolerance"
|
|
55459
|
+
);
|
|
55460
|
+
const perps = input.perpsResponse && typeof input.perpsResponse === "object" && !Array.isArray(input.perpsResponse) ? input.perpsResponse : {};
|
|
55461
|
+
const rawPerpsAccountValue = toNumber(perps.marginSummary?.accountValue);
|
|
55462
|
+
const perpsEquity = Math.max(rawPerpsAccountValue, 0);
|
|
55463
|
+
const spot = extractCanonicalSpotMetrics(input.spotResponse);
|
|
55464
|
+
const spotEquity = Math.max(spot.accountValue, 0);
|
|
55465
|
+
const balancesEquity = sumBalanceValueUsd(spot.balances);
|
|
55466
|
+
const accountMode = classification.exactAccountMode ?? input.accountMode;
|
|
55467
|
+
let unifiedLike = isUnifiedAccountMode(accountMode);
|
|
55468
|
+
const defaultMode = String(accountMode ?? "").trim() === "" || normalizeCanonicalHyperliquidAccountMode(accountMode) === "default";
|
|
55469
|
+
if (!unifiedLike && defaultMode) {
|
|
55470
|
+
const [availableBuy, availableSell] = classification.availableToTrade ?? [0, 0];
|
|
55471
|
+
const equityBase = rawPerpsAccountValue > 0 ? rawPerpsAccountValue : spotEquity;
|
|
55472
|
+
const spotRatio = equityBase > 0 ? spot.accountValue / equityBase : 0;
|
|
55473
|
+
const tradableWithSpotCollateral = classification.availableToTrade !== null && balancesEquity >= spotDominatesMinTotalUsd && Math.max(availableBuy, availableSell) > 0 && spotRatio >= spotAvailableToTradeRatioThreshold;
|
|
55474
|
+
const spotDominates = balancesEquity >= spotDominatesMinTotalUsd && (perpsEquity <= 0 || balancesEquity >= perpsEquity * spotDominatesPerpsMultiplier);
|
|
55475
|
+
const meaningfulHold = sumBalanceHoldUsd(spot.balances) >= spotMeaningfulHoldUsd;
|
|
55476
|
+
const veryStrongSpot = balancesEquity >= spotVeryStrongTotalUsd && perpsEquity <= spotVeryStrongPerpsEquityThresholdUsd;
|
|
55477
|
+
unifiedLike = tradableWithSpotCollateral || spot.balances.length > 0 && spotDominates && (meaningfulHold || veryStrongSpot);
|
|
55478
|
+
}
|
|
55479
|
+
return {
|
|
55480
|
+
accountValue: computeEffectiveAccountValue({
|
|
55481
|
+
perpsEquity,
|
|
55482
|
+
spotEquity,
|
|
55483
|
+
balancesEquity,
|
|
55484
|
+
unifiedLike,
|
|
55485
|
+
mirrored: balancesMirrorUnifiedAccountValue({
|
|
55486
|
+
perpsEquity,
|
|
55487
|
+
spotEquity,
|
|
55488
|
+
balancesEquity,
|
|
55489
|
+
absoluteToleranceUsd,
|
|
55490
|
+
relativeTolerance
|
|
55491
|
+
})
|
|
55492
|
+
}),
|
|
55493
|
+
valuedAsUnified: unifiedLike
|
|
55494
|
+
};
|
|
55495
|
+
};
|
|
55496
|
+
}
|
|
55497
|
+
});
|
|
55498
|
+
|
|
55256
55499
|
// lib/runtime/hyperliquid-account-contract.ts
|
|
55257
|
-
var
|
|
55500
|
+
var toNumber2, firstNumber, roundTo, canonicalAvailableMargin, spotBalanceValueUsd, normalizeSpotBalancesFromInfoResponse, sumBalanceHoldUsd2, sumPositionUnrealizedPnl, resolveTotalUnrealizedPnl, approximatelyEqualAccountValues, accountValueThresholds, serverLoopValuation, serverLoopValuationCountsSpot, buildAccountSummaryFromInfoResponses;
|
|
55258
55501
|
var init_hyperliquid_account_contract = __esm({
|
|
55259
55502
|
"lib/runtime/hyperliquid-account-contract.ts"() {
|
|
55260
55503
|
"use strict";
|
|
@@ -55263,7 +55506,8 @@ var init_hyperliquid_account_contract = __esm({
|
|
|
55263
55506
|
init_define_VTX_PI_MODEL_POLICY();
|
|
55264
55507
|
init_hyperliquid_account_mode_contract();
|
|
55265
55508
|
init_constants();
|
|
55266
|
-
|
|
55509
|
+
init_server_loop_account_value();
|
|
55510
|
+
toNumber2 = (value, fallback = 0) => {
|
|
55267
55511
|
const numeric2 = Number(value);
|
|
55268
55512
|
return Number.isFinite(numeric2) ? numeric2 : fallback;
|
|
55269
55513
|
};
|
|
@@ -55281,7 +55525,6 @@ var init_hyperliquid_account_contract = __esm({
|
|
|
55281
55525
|
};
|
|
55282
55526
|
roundTo = (value, digits = HYPERLIQUID_ACCOUNT_ROUNDING_DECIMALS) => Number(value.toFixed(digits));
|
|
55283
55527
|
canonicalAvailableMargin = (accountValue, totalMarginUsed) => Math.max(0, accountValue - totalMarginUsed);
|
|
55284
|
-
STABLE_SPOT_SYMBOLS = /* @__PURE__ */ new Set(["USDC", "USD", "USDT"]);
|
|
55285
55528
|
spotBalanceValueUsd = (balance, coin, total) => {
|
|
55286
55529
|
const explicit = firstNumber([balance?.value_usd, balance?.usdValue, balance?.usdcValue], Number.NaN);
|
|
55287
55530
|
if (Number.isFinite(explicit)) {
|
|
@@ -55304,8 +55547,8 @@ var init_hyperliquid_account_contract = __esm({
|
|
|
55304
55547
|
const balances = Array.isArray(firstWithBalances?.balances) ? firstWithBalances.balances : [];
|
|
55305
55548
|
return balances.map((balance) => {
|
|
55306
55549
|
const coin = String(balance?.coin ?? "").toUpperCase();
|
|
55307
|
-
const total =
|
|
55308
|
-
const hold =
|
|
55550
|
+
const total = toNumber2(balance?.total, 0);
|
|
55551
|
+
const hold = toNumber2(balance?.hold, 0);
|
|
55309
55552
|
const available = roundTo(Math.max(0, total - hold));
|
|
55310
55553
|
const value_usd = spotBalanceValueUsd(balance, coin, total);
|
|
55311
55554
|
return {
|
|
@@ -55317,10 +55560,10 @@ var init_hyperliquid_account_contract = __esm({
|
|
|
55317
55560
|
};
|
|
55318
55561
|
}).filter((balance) => balance.coin.length > 0);
|
|
55319
55562
|
};
|
|
55320
|
-
|
|
55321
|
-
const hold =
|
|
55322
|
-
const total =
|
|
55323
|
-
const valueUsd =
|
|
55563
|
+
sumBalanceHoldUsd2 = (balances) => balances.reduce((acc, balance) => {
|
|
55564
|
+
const hold = toNumber2(balance.hold, 0);
|
|
55565
|
+
const total = toNumber2(balance.total, 0);
|
|
55566
|
+
const valueUsd = toNumber2(balance.value_usd, 0);
|
|
55324
55567
|
if (hold <= 0 || total <= 0 || valueUsd <= 0) {
|
|
55325
55568
|
return acc;
|
|
55326
55569
|
}
|
|
@@ -55329,12 +55572,12 @@ var init_hyperliquid_account_contract = __esm({
|
|
|
55329
55572
|
sumPositionUnrealizedPnl = (perpsResponse) => {
|
|
55330
55573
|
const assetPositions = Array.isArray(perpsResponse?.assetPositions) ? perpsResponse.assetPositions : [];
|
|
55331
55574
|
return assetPositions.reduce((total, entry) => {
|
|
55332
|
-
const unrealizedPnl =
|
|
55575
|
+
const unrealizedPnl = toNumber2(entry?.position?.unrealizedPnl, 0);
|
|
55333
55576
|
return total + unrealizedPnl;
|
|
55334
55577
|
}, 0);
|
|
55335
55578
|
};
|
|
55336
55579
|
resolveTotalUnrealizedPnl = (perpsResponse) => {
|
|
55337
|
-
const topLevel =
|
|
55580
|
+
const topLevel = toNumber2(perpsResponse?.totalUnrealizedPnl, 0);
|
|
55338
55581
|
const positionTotal = sumPositionUnrealizedPnl(perpsResponse);
|
|
55339
55582
|
if (Math.abs(topLevel) < HYPERLIQUID_UNREALIZED_PNL_ZERO_TOLERANCE && Math.abs(positionTotal) >= HYPERLIQUID_UNREALIZED_PNL_ZERO_TOLERANCE) {
|
|
55340
55583
|
return positionTotal;
|
|
@@ -55348,33 +55591,49 @@ var init_hyperliquid_account_contract = __esm({
|
|
|
55348
55591
|
reference * relativeTolerance
|
|
55349
55592
|
);
|
|
55350
55593
|
};
|
|
55594
|
+
accountValueThresholds = (options) => ({
|
|
55595
|
+
spotDominatesMinTotalUsd: Number(options.spotDominatesMinTotalUsd ?? options.spot_dominates_min_total_usd),
|
|
55596
|
+
spotDominatesPerpsMultiplier: Number(options.spotDominatesPerpsMultiplier ?? options.spot_dominates_perps_multiplier),
|
|
55597
|
+
mirroredAccountValueAbsoluteToleranceUsd: Number(
|
|
55598
|
+
options.mirroredAccountValueAbsoluteToleranceUsd ?? options.mirrored_account_value_absolute_tolerance_usd
|
|
55599
|
+
),
|
|
55600
|
+
mirroredAccountValueRelativeTolerance: Number(
|
|
55601
|
+
options.mirroredAccountValueRelativeTolerance ?? options.mirrored_account_value_relative_tolerance
|
|
55602
|
+
)
|
|
55603
|
+
});
|
|
55604
|
+
serverLoopValuation = (perpsResponse, spotResponse, options) => options.serverLoopClassification ? serverLoopAccountValue({
|
|
55605
|
+
perpsResponse,
|
|
55606
|
+
spotResponse,
|
|
55607
|
+
accountMode: extractAccountModeFromPayload(perpsResponse),
|
|
55608
|
+
classification: options.serverLoopClassification,
|
|
55609
|
+
...accountValueThresholds(options)
|
|
55610
|
+
}) : null;
|
|
55611
|
+
serverLoopValuationCountsSpot = (perpsResponse, spotResponse, options) => serverLoopValuation(perpsResponse, spotResponse, options)?.valuedAsUnified === true;
|
|
55351
55612
|
buildAccountSummaryFromInfoResponses = (perpsResponse, spotResponse, options = {}) => {
|
|
55352
55613
|
const marginSummary = perpsResponse?.marginSummary ?? {};
|
|
55353
|
-
const perpsAccountValue =
|
|
55354
|
-
const total_margin_used =
|
|
55355
|
-
const totalNtlPos =
|
|
55356
|
-
const withdrawable =
|
|
55614
|
+
const perpsAccountValue = toNumber2(marginSummary?.accountValue, 0);
|
|
55615
|
+
const total_margin_used = toNumber2(marginSummary?.totalMarginUsed, 0);
|
|
55616
|
+
const totalNtlPos = toNumber2(marginSummary?.totalNtlPos, 0);
|
|
55617
|
+
const withdrawable = toNumber2(perpsResponse?.withdrawable, 0);
|
|
55357
55618
|
const maintenance_margin = firstNumber([
|
|
55358
55619
|
perpsResponse?.crossMaintenanceMarginUsed,
|
|
55359
55620
|
marginSummary?.crossMaintenanceMarginUsed,
|
|
55360
55621
|
marginSummary?.totalMaintenanceMargin
|
|
55361
55622
|
], 0);
|
|
55362
55623
|
const balances = normalizeSpotBalancesFromInfoResponse(spotResponse);
|
|
55363
|
-
const spotPortfolioValue = balances.reduce((acc, balance) => acc +
|
|
55364
|
-
const balancesHoldUsd =
|
|
55624
|
+
const spotPortfolioValue = balances.reduce((acc, balance) => acc + toNumber2(balance.value_usd, 0), 0);
|
|
55625
|
+
const balancesHoldUsd = sumBalanceHoldUsd2(balances);
|
|
55365
55626
|
const account_mode = extractAccountModeFromPayload(perpsResponse);
|
|
55366
55627
|
const crossMarginSummary = perpsResponse?.crossMarginSummary && typeof perpsResponse.crossMarginSummary === "object" ? perpsResponse.crossMarginSummary : null;
|
|
55367
|
-
const crossMarginAccountValue = crossMarginSummary ?
|
|
55628
|
+
const crossMarginAccountValue = crossMarginSummary ? toNumber2(crossMarginSummary.accountValue, 0) : 0;
|
|
55368
55629
|
const normalizedMode = String(account_mode || "").trim().toLowerCase().replace(/[_\s-]/g, "");
|
|
55369
55630
|
const isAmbiguousDefaultMode = normalizedMode.length === 0 || normalizedMode === "default";
|
|
55370
|
-
const
|
|
55371
|
-
|
|
55372
|
-
|
|
55373
|
-
|
|
55374
|
-
|
|
55375
|
-
|
|
55376
|
-
options.mirroredAccountValueRelativeTolerance ?? options.mirrored_account_value_relative_tolerance
|
|
55377
|
-
);
|
|
55631
|
+
const {
|
|
55632
|
+
spotDominatesMinTotalUsd,
|
|
55633
|
+
spotDominatesPerpsMultiplier,
|
|
55634
|
+
mirroredAccountValueAbsoluteToleranceUsd,
|
|
55635
|
+
mirroredAccountValueRelativeTolerance
|
|
55636
|
+
} = accountValueThresholds(options);
|
|
55378
55637
|
const hasSpotDominanceThresholds = Number.isFinite(spotDominatesMinTotalUsd) && spotDominatesMinTotalUsd >= 0 && Number.isFinite(spotDominatesPerpsMultiplier) && spotDominatesPerpsMultiplier >= 0;
|
|
55379
55638
|
const hasMirroredAccountValueTolerances = Number.isFinite(mirroredAccountValueAbsoluteToleranceUsd) && mirroredAccountValueAbsoluteToleranceUsd >= 0 && Number.isFinite(mirroredAccountValueRelativeTolerance) && mirroredAccountValueRelativeTolerance >= 0;
|
|
55380
55639
|
const spotDominatesPerps = hasSpotDominanceThresholds && spotPortfolioValue >= spotDominatesMinTotalUsd && (perpsAccountValue <= 0 || spotPortfolioValue >= perpsAccountValue * spotDominatesPerpsMultiplier);
|
|
@@ -55385,7 +55644,8 @@ var init_hyperliquid_account_contract = __esm({
|
|
|
55385
55644
|
mirroredAccountValueAbsoluteToleranceUsd,
|
|
55386
55645
|
mirroredAccountValueRelativeTolerance
|
|
55387
55646
|
);
|
|
55388
|
-
const
|
|
55647
|
+
const deviceAccountValue = isUnifiedAccountMode(account_mode) && crossMarginSummary !== null && crossMarginAccountValue > 0 ? crossMarginAccountValue + spotPortfolioValue : ambiguousDefaultLooksUnified && !ambiguousDefaultSpotAlreadyIncludesPerps ? perpsAccountValue + spotPortfolioValue : Math.max(perpsAccountValue, spotPortfolioValue);
|
|
55648
|
+
const account_value = serverLoopValuation(perpsResponse, spotResponse, options)?.accountValue ?? deviceAccountValue;
|
|
55389
55649
|
return {
|
|
55390
55650
|
account_value,
|
|
55391
55651
|
total_margin_used,
|
|
@@ -55403,7 +55663,7 @@ var init_hyperliquid_account_contract = __esm({
|
|
|
55403
55663
|
});
|
|
55404
55664
|
|
|
55405
55665
|
// lib/runtime/order-identity.ts
|
|
55406
|
-
var clientOrderIdForMutation, clientDecisionMutationId;
|
|
55666
|
+
var clientOrderIdForMutation, mutationIdForClientOrderId, clientDecisionMutationId;
|
|
55407
55667
|
var init_order_identity = __esm({
|
|
55408
55668
|
"lib/runtime/order-identity.ts"() {
|
|
55409
55669
|
"use strict";
|
|
@@ -55412,6 +55672,12 @@ var init_order_identity = __esm({
|
|
|
55412
55672
|
init_define_VTX_PI_MODEL_POLICY();
|
|
55413
55673
|
init_constants();
|
|
55414
55674
|
clientOrderIdForMutation = (mutationId) => `0x${String(mutationId).trim().toLowerCase().replaceAll("-", "")}`;
|
|
55675
|
+
mutationIdForClientOrderId = (clientOrderId) => {
|
|
55676
|
+
const cloid = String(clientOrderId).trim().toLowerCase();
|
|
55677
|
+
if (!/^0x[0-9a-f]{32}$/.test(cloid)) return null;
|
|
55678
|
+
const hex4 = cloid.slice("0x".length);
|
|
55679
|
+
return UUID_HEX_GROUP_ENDS.map((end, index) => hex4.slice(index === 0 ? 0 : UUID_HEX_GROUP_ENDS[index - 1], end)).join("-");
|
|
55680
|
+
};
|
|
55415
55681
|
clientDecisionMutationId = async (input) => {
|
|
55416
55682
|
const key = [
|
|
55417
55683
|
"client-decision:v1",
|
|
@@ -55642,7 +55908,14 @@ var init_hyperliquid_public_read = __esm({
|
|
|
55642
55908
|
const ticket = crypto.randomUUID();
|
|
55643
55909
|
const deadline = Math.min(deadlineMs ?? Infinity, Date.now() + recoveryPolicy.recovery_queue_wait_seconds * MS_PER_SECOND);
|
|
55644
55910
|
if (hostTransport) {
|
|
55645
|
-
const permit = await hostTransport.admission.acquire({
|
|
55911
|
+
const permit = await hostTransport.admission.acquire({
|
|
55912
|
+
requestType,
|
|
55913
|
+
weight,
|
|
55914
|
+
priority: priority.value,
|
|
55915
|
+
currentPriority: () => priority.value,
|
|
55916
|
+
deadlineMs: deadline,
|
|
55917
|
+
signal
|
|
55918
|
+
});
|
|
55646
55919
|
return { ...permit, endpoint: apiUrl, fleet: true };
|
|
55647
55920
|
}
|
|
55648
55921
|
let admitted = false;
|
|
@@ -55808,7 +56081,7 @@ var init_hyperliquid_public_read = __esm({
|
|
|
55808
56081
|
};
|
|
55809
56082
|
cacheTtlMs = (body, options) => {
|
|
55810
56083
|
const requestType = String(body.type);
|
|
55811
|
-
return (["meta", "spotMeta", "perpDexs"].includes(requestType) ? policy.metadata_ttl_seconds : requestType === "userFees" ? policy.user_fees_ttl_seconds : options.cacheAccountMode && ["userAbstraction", "userDexAbstraction"].includes(requestType) ? policy.account_mode_ttl_seconds : 0) * MS_PER_SECOND;
|
|
56084
|
+
return (["meta", "spotMeta", "perpDexs"].includes(requestType) ? policy.metadata_ttl_seconds : requestType === "userFees" ? policy.user_fees_ttl_seconds : options.cacheAccountMode && ["userAbstraction", "userDexAbstraction"].includes(requestType) ? options.cacheAccountMode === "display" ? policy.ui_account_mode_ttl_seconds : policy.account_mode_ttl_seconds : 0) * MS_PER_SECOND;
|
|
55812
56085
|
};
|
|
55813
56086
|
eligibleCache = (apiUrl, body, options) => {
|
|
55814
56087
|
const ttl = cacheTtlMs(body, options);
|
|
@@ -57453,7 +57726,7 @@ function getNumber(value, name) {
|
|
|
57453
57726
|
}
|
|
57454
57727
|
assertArgument(false, "invalid numeric value", name || "value", value);
|
|
57455
57728
|
}
|
|
57456
|
-
function
|
|
57729
|
+
function toNumber3(value) {
|
|
57457
57730
|
return getNumber(toBigInt(value));
|
|
57458
57731
|
}
|
|
57459
57732
|
function toBeHex(_value, _width) {
|
|
@@ -59875,7 +60148,7 @@ var init_abstract_coder = __esm({
|
|
|
59875
60148
|
return toBigInt(this.readBytes(WordSize));
|
|
59876
60149
|
}
|
|
59877
60150
|
readIndex() {
|
|
59878
|
-
return
|
|
60151
|
+
return toNumber3(this.readBytes(WordSize));
|
|
59879
60152
|
}
|
|
59880
60153
|
};
|
|
59881
60154
|
}
|
|
@@ -86312,7 +86585,7 @@ __export(ethers_exports, {
|
|
|
86312
86585
|
toBeArray: () => toBeArray,
|
|
86313
86586
|
toBeHex: () => toBeHex,
|
|
86314
86587
|
toBigInt: () => toBigInt,
|
|
86315
|
-
toNumber: () =>
|
|
86588
|
+
toNumber: () => toNumber3,
|
|
86316
86589
|
toQuantity: () => toQuantity,
|
|
86317
86590
|
toTwos: () => toTwos,
|
|
86318
86591
|
toUtf8Bytes: () => toUtf8Bytes,
|
|
@@ -86530,7 +86803,7 @@ __export(lib_exports, {
|
|
|
86530
86803
|
toBeArray: () => toBeArray,
|
|
86531
86804
|
toBeHex: () => toBeHex,
|
|
86532
86805
|
toBigInt: () => toBigInt,
|
|
86533
|
-
toNumber: () =>
|
|
86806
|
+
toNumber: () => toNumber3,
|
|
86534
86807
|
toQuantity: () => toQuantity,
|
|
86535
86808
|
toTwos: () => toTwos,
|
|
86536
86809
|
toUtf8Bytes: () => toUtf8Bytes,
|
|
@@ -87442,7 +87715,7 @@ var init_hyperliquid_signer = __esm({
|
|
|
87442
87715
|
});
|
|
87443
87716
|
|
|
87444
87717
|
// lib/runtime/hyperliquid-client.ts
|
|
87445
|
-
var HyperliquidExchangeRejectionError, durableMutationAuthorityArgs, assertFreshPreparedExecutionContext, normalizeSymbol, HYPERLIQUID_NONCE_STORAGE_KEY, HYPERLIQUID_NONCE_LOCK_NAME, lastGeneratedNonce, readBrowserStoredHyperliquidNonce, writeBrowserStoredHyperliquidNonce, browserNonceCoordinator, allocateHyperliquidNonce, hostNonceAllocator, allocateActionNonce, generateHyperliquidNonce, normalizeDecimalString, HYPERLIQUID_PRICE_SIGNIFICANT_FIGURES, HYPERLIQUID_INTEGER_PRICE_MINIMUM, shortestDecimalParts, formatHyperliquidPerpPriceGrid, formatHyperliquidTriggerPriceWire, hyperliquidOrderPriceRounding, formatHyperliquidOrderPriceWire, countSignificantDigits, countDecimalPlaces, validateHyperliquidPerpPriceWire, validateHyperliquidSizeWire, formatSizeWire, inferApiUrl, inferIsTestnet, postHyperliquidInfoRead, postHyperliquidInfo, fetchBrowserHyperliquidInfoPayload, fetchBrowserHyperliquidInfoRead, fetchBrowserHyperliquidInfoText, coerceMarketMaxLeverage, toFiniteNumber, OPEN_ORDER_NUMERIC_STRING, OPEN_ORDER_ID_STRING, parseCanonicalOpenOrderId, parseOpenOrderFiniteNumber, parseOpenOrderPositiveNumber, parseOpenOrderPresentationNumber, readOpenOrderField, firstFiniteNumber, parseFundingUsdcFromInfoPosition, isExchangeIsolatedOnly, computeHip3AssetId, getPerpDexIndexMap, buildAssetInfosFromMetaResponse, requireWalletAddress, assertPositiveInteger, assertPositiveNumber, normalizeOrderSide, normalizeHyperliquidClientOrderId, resolveAssets, findResolvedAsset, normalizeExecutionAssetMetadata, resolveHyperliquidAsset, resolveHyperliquidAssetIndex, decimalUnits, quantizeHyperliquidOrderSizeValue, hyperliquidSignedSizeMatchesRequestedSize, finitePositive, readDevicePrivateExecutionContext, quantizeHyperliquidOrderSize, fetchBrowserAvailableAssets, fetchBrowserAllMids, fetchBrowserSymbolMidPrice, fetchBrowserOpenOrders, parseCanonicalHyperliquidOrderStatusEvidence, fetchBrowserOrderStatusEvidence, fetchBrowserUserRole, fetchBrowserAccountState, fetchBrowserPosition, buildHyperliquidOrderWire, buildHyperliquidTriggerOrderWire, signHyperliquidPayload, signHyperliquidPreparedAction, buildHyperliquidCancelPayload, buildHyperliquidUpdateLeveragePayload, buildHyperliquidMarketOrderPayload, buildHyperliquidLimitOrderPayload, buildHyperliquidTriggerOrderPayload, buildHyperliquidOrderBatchPayload, buildHyperliquidModifyOrderPayload, extractHyperliquidExchangeError, resolveHyperliquidTriggerAcknowledgements, isDefinitiveHyperliquidExchangeResponse, extractDefinitiveHyperliquidOrderId, CANONICAL_POSITIVE_DECIMAL_PATTERN, extractCanonicalHyperliquidOrderStateAcknowledgement, extractCanonicalHyperliquidOrderStateAcknowledgements, extractCanonicalHyperliquidFilledOrderAcknowledgement, extractDefinitiveHyperliquidOrderMemberResults, buildHyperliquidOrderDiagnostics, loadClientExecutionReferenceEvidence, sha256Hex, extractSignedPayloadClientOrderId, extractSignedPayloadMutationCorrelation, assertDurableMutationMatchesSignedAction, exchangeRejectionReason, exchangeActionPriority, submitHyperliquidExchangePayload;
|
|
87718
|
+
var HyperliquidExchangeRejectionError, durableMutationAuthorityArgs, assertFreshPreparedExecutionContext, normalizeSymbol, HYPERLIQUID_NONCE_STORAGE_KEY, HYPERLIQUID_NONCE_LOCK_NAME, lastGeneratedNonce, readBrowserStoredHyperliquidNonce, writeBrowserStoredHyperliquidNonce, browserNonceCoordinator, allocateHyperliquidNonce, hostNonceAllocator, allocateActionNonce, generateHyperliquidNonce, normalizeDecimalString, HYPERLIQUID_PRICE_SIGNIFICANT_FIGURES, HYPERLIQUID_INTEGER_PRICE_MINIMUM, shortestDecimalParts, formatHyperliquidPerpPriceGrid, formatHyperliquidTriggerPriceWire, hyperliquidOrderPriceRounding, formatHyperliquidOrderPriceWire, countSignificantDigits, countDecimalPlaces, validateHyperliquidPerpPriceWire, validateHyperliquidSizeWire, formatSizeWire, inferApiUrl, inferIsTestnet, postHyperliquidInfoRead, postHyperliquidInfo, fetchBrowserHyperliquidInfoPayload, fetchBrowserHyperliquidInfoRead, fetchBrowserHyperliquidInfoText, coerceMarketMaxLeverage, toFiniteNumber, OPEN_ORDER_NUMERIC_STRING, OPEN_ORDER_ID_STRING, parseCanonicalOpenOrderId, parseOpenOrderFiniteNumber, parseOpenOrderPositiveNumber, parseOpenOrderPresentationNumber, readOpenOrderField, firstFiniteNumber, parseFundingUsdcFromInfoPosition, isExchangeIsolatedOnly, resolveLeverageTarget, computeHip3AssetId, getPerpDexIndexMap, buildAssetInfosFromMetaResponse, requireWalletAddress, assertPositiveInteger, assertPositiveNumber, normalizeOrderSide, normalizeHyperliquidClientOrderId, resolveAssets, findResolvedAsset, normalizeExecutionAssetMetadata, resolveHyperliquidAsset, resolveHyperliquidAssetIndex, decimalUnits, quantizeHyperliquidOrderSizeValue, hyperliquidSignedSizeMatchesRequestedSize, finitePositive, readDevicePrivateExecutionContext, quantizeHyperliquidOrderSize, fetchBrowserAvailableAssets, fetchBrowserAllMids, fetchBrowserSymbolMidPrice, fetchBrowserOpenOrders, parseCanonicalHyperliquidOrderStatusEvidence, fetchBrowserOrderStatusEvidence, fetchBrowserUserRole, fetchBrowserAccountState, fetchBrowserPosition, buildHyperliquidOrderWire, buildHyperliquidTriggerOrderWire, signHyperliquidPayload, signHyperliquidPreparedAction, buildHyperliquidCancelPayload, buildHyperliquidUpdateLeveragePayload, buildHyperliquidMarketOrderPayload, buildHyperliquidLimitOrderPayload, buildHyperliquidTriggerOrderPayload, buildHyperliquidOrderBatchPayload, buildHyperliquidModifyOrderPayload, extractHyperliquidExchangeError, resolveHyperliquidTriggerAcknowledgements, isDefinitiveHyperliquidExchangeResponse, extractDefinitiveHyperliquidOrderId, CANONICAL_POSITIVE_DECIMAL_PATTERN, extractCanonicalHyperliquidOrderStateAcknowledgement, extractCanonicalHyperliquidOrderStateAcknowledgements, extractCanonicalHyperliquidFilledOrderAcknowledgement, extractDefinitiveHyperliquidOrderMemberResults, buildHyperliquidOrderDiagnostics, loadClientExecutionReferenceEvidence, sha256Hex, extractSignedPayloadClientOrderId, extractSignedPayloadMutationCorrelation, assertDurableMutationMatchesSignedAction, exchangeRejectionReason, exchangeActionPriority, submitHyperliquidExchangePayload;
|
|
87446
87719
|
var init_hyperliquid_client = __esm({
|
|
87447
87720
|
"lib/runtime/hyperliquid-client.ts"() {
|
|
87448
87721
|
"use strict";
|
|
@@ -87819,6 +88092,10 @@ var init_hyperliquid_client = __esm({
|
|
|
87819
88092
|
return null;
|
|
87820
88093
|
};
|
|
87821
88094
|
isExchangeIsolatedOnly = (asset) => asset.only_isolated === true || ["nocross", "strictisolated"].includes(String(asset.margin_mode || "").trim().toLowerCase());
|
|
88095
|
+
resolveLeverageTarget = (asset, leverage, isCross) => ({
|
|
88096
|
+
leverage: Math.max(1, Math.min(asset.max_leverage, Math.trunc(leverage))),
|
|
88097
|
+
isCross: isExchangeIsolatedOnly(asset) ? false : isCross !== false
|
|
88098
|
+
});
|
|
87822
88099
|
computeHip3AssetId = (perpDexIndex, indexInMeta) => HYPERLIQUID_EXCHANGE_SPECIFICATION.hip3_asset_id_base + Math.trunc(perpDexIndex) * HYPERLIQUID_EXCHANGE_SPECIFICATION.hip3_asset_id_dex_stride + Math.trunc(indexInMeta);
|
|
87823
88100
|
getPerpDexIndexMap = (payload) => {
|
|
87824
88101
|
if (!Array.isArray(payload)) {
|
|
@@ -87972,6 +88249,12 @@ var init_hyperliquid_client = __esm({
|
|
|
87972
88249
|
if (!symbol2) {
|
|
87973
88250
|
throw new Error("Missing Hyperliquid symbol.");
|
|
87974
88251
|
}
|
|
88252
|
+
if (input.refreshCatalog) {
|
|
88253
|
+
return normalizeExecutionAssetMetadata(symbol2, await getExecutionAssetMetadata("hyperliquid", symbol2, {
|
|
88254
|
+
forceCatalogRefresh: true,
|
|
88255
|
+
...input.publicRequestPriority === "trading_reduce" ? { publicRequestPriority: "trading_reduce" } : {}
|
|
88256
|
+
}));
|
|
88257
|
+
}
|
|
87975
88258
|
if (Array.isArray(input.assets) && input.assets.length > 0) {
|
|
87976
88259
|
const explicitAsset = findResolvedAsset(symbol2, input.assets);
|
|
87977
88260
|
if (explicitAsset) {
|
|
@@ -88099,20 +88382,14 @@ var init_hyperliquid_client = __esm({
|
|
|
88099
88382
|
if (!symbol2) {
|
|
88100
88383
|
throw new Error("Missing Hyperliquid symbol.");
|
|
88101
88384
|
}
|
|
88102
|
-
const
|
|
88103
|
-
input.includePrivateContext && String(input.walletAddress ?? "").trim()
|
|
88104
|
-
);
|
|
88105
|
-
const devicePrivateContext = deviceReadsPrivateContext ? readDevicePrivateExecutionContext({
|
|
88385
|
+
const devicePrivateContext = input.includePrivateContext ? readDevicePrivateExecutionContext({
|
|
88106
88386
|
...input,
|
|
88107
|
-
|
|
88387
|
+
// Refused before any request when the wallet is missing.
|
|
88388
|
+
walletAddress: requireWalletAddress(String(input.walletAddress ?? "")),
|
|
88108
88389
|
symbol: symbol2
|
|
88109
88390
|
}) : null;
|
|
88110
88391
|
devicePrivateContext?.catch(() => void 0);
|
|
88111
|
-
const metadata = input.
|
|
88112
|
-
includePrivateContext: true,
|
|
88113
|
-
...input.publicRequestPriority === "trading_reduce" ? { publicRequestPriority: "trading_reduce" } : {},
|
|
88114
|
-
profileId: Number.isFinite(Number(input.profileId)) ? Number(input.profileId) : void 0
|
|
88115
|
-
}) : input.publicRequestPriority === "trading_reduce" ? await getExecutionAssetMetadata("hyperliquid", symbol2, { publicRequestPriority: "trading_reduce" }) : await getExecutionAssetMetadata("hyperliquid", symbol2);
|
|
88392
|
+
const metadata = input.publicRequestPriority === "trading_reduce" ? await getExecutionAssetMetadata("hyperliquid", symbol2, { publicRequestPriority: "trading_reduce" }) : await getExecutionAssetMetadata("hyperliquid", symbol2);
|
|
88116
88393
|
const deviceContext = devicePrivateContext ? await devicePrivateContext : null;
|
|
88117
88394
|
const executionContextReceivedAtMonotonicMs = globalThis.performance.now();
|
|
88118
88395
|
const resolved = normalizeExecutionAssetMetadata(symbol2, metadata);
|
|
@@ -88152,11 +88429,6 @@ var init_hyperliquid_client = __esm({
|
|
|
88152
88429
|
executionPositionSize: deviceContext.executionPositionSize,
|
|
88153
88430
|
executionContextAtMs: deviceContext.executionContextAtMs,
|
|
88154
88431
|
executionContextReceivedAtMonotonicMs
|
|
88155
|
-
} : input.includePrivateContext ? {
|
|
88156
|
-
executionMarkPrice: Number.isFinite(Number(metadata.execution_mark_price)) && Number(metadata.execution_mark_price) > 0 ? Number(metadata.execution_mark_price) : null,
|
|
88157
|
-
executionPositionSize: Number.isFinite(Number(metadata.execution_position_size)) ? Number(metadata.execution_position_size) : null,
|
|
88158
|
-
executionContextAtMs: Number.isFinite(Number(metadata.execution_context_at_ms)) && Number(metadata.execution_context_at_ms) > 0 ? Number(metadata.execution_context_at_ms) : null,
|
|
88159
|
-
executionContextReceivedAtMonotonicMs
|
|
88160
88432
|
} : {}
|
|
88161
88433
|
};
|
|
88162
88434
|
};
|
|
@@ -88731,8 +89003,7 @@ var init_hyperliquid_client = __esm({
|
|
|
88731
89003
|
const { signHyperliquidAction: signHyperliquidAction2 } = await Promise.resolve().then(() => (init_hyperliquid_signer(), hyperliquid_signer_exports));
|
|
88732
89004
|
const nonce = input.nonce ?? await allocateActionNonce(input, apiUrl);
|
|
88733
89005
|
const expiresAfter = input.expiresAfterSeconds == null ? null : nonce + input.expiresAfterSeconds * MS_PER_SECOND;
|
|
88734
|
-
const leverage =
|
|
88735
|
-
const isCross = isExchangeIsolatedOnly(asset) ? false : input.isCross !== false;
|
|
89006
|
+
const { leverage, isCross } = resolveLeverageTarget(asset, input.leverage, input.isCross);
|
|
88736
89007
|
const action = {
|
|
88737
89008
|
type: "updateLeverage",
|
|
88738
89009
|
asset: asset.asset_index,
|
|
@@ -90000,9 +90271,6 @@ async function pollCopyTradingRuntimeSource(profileId, options) {
|
|
|
90000
90271
|
...schedulerInstanceId ? { "x-client-runtime-instance": schedulerInstanceId } : {}
|
|
90001
90272
|
}, profileId),
|
|
90002
90273
|
body: JSON.stringify({
|
|
90003
|
-
dry_run: Boolean(options?.dryRun),
|
|
90004
|
-
force_refresh: Boolean(options?.forceRefresh),
|
|
90005
|
-
...options?.maxEvents ? { max_events: options.maxEvents } : {},
|
|
90006
90274
|
...options?.accountEvidence ? { account_evidence: options.accountEvidence } : {}
|
|
90007
90275
|
}),
|
|
90008
90276
|
credentials: "include",
|
|
@@ -93617,6 +93885,7 @@ var init_browser_trading = __esm({
|
|
|
93617
93885
|
estimatedPrice: input.estimatedPrice,
|
|
93618
93886
|
slippage: input.slippage,
|
|
93619
93887
|
reduceOnly: true,
|
|
93888
|
+
assets: input.assets,
|
|
93620
93889
|
onExchangeOrderDispatched: input.onExchangeOrderDispatched
|
|
93621
93890
|
});
|
|
93622
93891
|
};
|
|
@@ -93651,15 +93920,15 @@ var init_hyperliquid_active_asset_contract = __esm({
|
|
|
93651
93920
|
};
|
|
93652
93921
|
normalizePair = (raw) => {
|
|
93653
93922
|
if (Array.isArray(raw) && raw.length >= HYPERLIQUID_SIDE_PAIR_LENGTH) {
|
|
93654
|
-
return [
|
|
93923
|
+
return [toNumber2(raw[0], 0), toNumber2(raw[1], 0)];
|
|
93655
93924
|
}
|
|
93656
93925
|
if (raw && typeof raw === "object") {
|
|
93657
|
-
const buy =
|
|
93658
|
-
const sell =
|
|
93926
|
+
const buy = toNumber2(raw.buy ?? raw.long ?? raw.b, 0);
|
|
93927
|
+
const sell = toNumber2(raw.sell ?? raw.short ?? raw.s, 0);
|
|
93659
93928
|
return [buy, sell];
|
|
93660
93929
|
}
|
|
93661
93930
|
if (typeof raw === "string" || typeof raw === "number") {
|
|
93662
|
-
const value =
|
|
93931
|
+
const value = toNumber2(raw, 0);
|
|
93663
93932
|
return [value, value];
|
|
93664
93933
|
}
|
|
93665
93934
|
return [0, 0];
|
|
@@ -93670,28 +93939,28 @@ var init_hyperliquid_active_asset_contract = __esm({
|
|
|
93670
93939
|
const directSell = source.available_to_trade_sell;
|
|
93671
93940
|
const hasDirectAvailable = directBuy !== void 0 || directSell !== void 0;
|
|
93672
93941
|
const [pairBuy, pairSell] = normalizePair(source.availableToTrade);
|
|
93673
|
-
const available_to_trade_buy = hasDirectAvailable ?
|
|
93674
|
-
const available_to_trade_sell = hasDirectAvailable ?
|
|
93942
|
+
const available_to_trade_buy = hasDirectAvailable ? toNumber2(directBuy, pairBuy) : pairBuy;
|
|
93943
|
+
const available_to_trade_sell = hasDirectAvailable ? toNumber2(directSell, pairSell) : pairSell;
|
|
93675
93944
|
const directMaxBuy = source.max_trade_size_buy;
|
|
93676
93945
|
const directMaxSell = source.max_trade_size_sell;
|
|
93677
93946
|
const hasDirectMax = directMaxBuy !== void 0 || directMaxSell !== void 0;
|
|
93678
93947
|
const [pairMaxBuy, pairMaxSell] = normalizePair(source.maxTradeSzs);
|
|
93679
|
-
const max_trade_size_buy = hasDirectMax ?
|
|
93680
|
-
const max_trade_size_sell = hasDirectMax ?
|
|
93948
|
+
const max_trade_size_buy = hasDirectMax ? toNumber2(directMaxBuy, pairMaxBuy) : pairMaxBuy;
|
|
93949
|
+
const max_trade_size_sell = hasDirectMax ? toNumber2(directMaxSell, pairMaxSell) : pairMaxSell;
|
|
93681
93950
|
return {
|
|
93682
93951
|
symbol: String(source.coin || symbol2),
|
|
93683
93952
|
available_to_trade_buy,
|
|
93684
93953
|
available_to_trade_sell,
|
|
93685
93954
|
max_trade_size_buy,
|
|
93686
93955
|
max_trade_size_sell,
|
|
93687
|
-
mark_price:
|
|
93956
|
+
mark_price: toNumber2(source.markPx ?? source.mark_price, 0)
|
|
93688
93957
|
};
|
|
93689
93958
|
};
|
|
93690
93959
|
}
|
|
93691
93960
|
});
|
|
93692
93961
|
|
|
93693
93962
|
// lib/runtime/server-prompt-rescue-account-contract.ts
|
|
93694
|
-
var
|
|
93963
|
+
var firstNumber2, equityFormula, buildServerPromptRescueAccountSummary;
|
|
93695
93964
|
var init_server_prompt_rescue_account_contract = __esm({
|
|
93696
93965
|
"lib/runtime/server-prompt-rescue-account-contract.ts"() {
|
|
93697
93966
|
"use strict";
|
|
@@ -93700,10 +93969,7 @@ var init_server_prompt_rescue_account_contract = __esm({
|
|
|
93700
93969
|
init_define_VTX_PI_MODEL_POLICY();
|
|
93701
93970
|
init_hyperliquid_account_mode_contract();
|
|
93702
93971
|
init_hyperliquid_account_contract();
|
|
93703
|
-
|
|
93704
|
-
const numeric2 = Number(value);
|
|
93705
|
-
return Number.isFinite(numeric2) ? numeric2 : fallback;
|
|
93706
|
-
};
|
|
93972
|
+
init_server_loop_account_value();
|
|
93707
93973
|
firstNumber2 = (values, fallback = 0) => {
|
|
93708
93974
|
for (const value of values) {
|
|
93709
93975
|
if (value == null || value === "") continue;
|
|
@@ -93712,119 +93978,6 @@ var init_server_prompt_rescue_account_contract = __esm({
|
|
|
93712
93978
|
}
|
|
93713
93979
|
return fallback;
|
|
93714
93980
|
};
|
|
93715
|
-
firstTruthy = (values, fallback) => {
|
|
93716
|
-
for (const value of values) {
|
|
93717
|
-
if (value) return value;
|
|
93718
|
-
}
|
|
93719
|
-
return fallback;
|
|
93720
|
-
};
|
|
93721
|
-
spotContainers = (spotResponse) => {
|
|
93722
|
-
if (!spotResponse || typeof spotResponse !== "object" || Array.isArray(spotResponse)) return [];
|
|
93723
|
-
const response = spotResponse;
|
|
93724
|
-
const containers = [response];
|
|
93725
|
-
for (const key of ["spotState", "userState", "clearinghouseState", "state", "data"]) {
|
|
93726
|
-
const child = response[key];
|
|
93727
|
-
if (child && typeof child === "object" && !Array.isArray(child)) containers.push(child);
|
|
93728
|
-
}
|
|
93729
|
-
return containers;
|
|
93730
|
-
};
|
|
93731
|
-
extractCanonicalSpotMetrics = (spotResponse) => {
|
|
93732
|
-
const response = spotResponse && typeof spotResponse === "object" && !Array.isArray(spotResponse) ? spotResponse : {};
|
|
93733
|
-
const containers = spotContainers(response);
|
|
93734
|
-
let accountValue = 0;
|
|
93735
|
-
let totalMarginUsed = 0;
|
|
93736
|
-
let withdrawable = 0;
|
|
93737
|
-
for (const container of containers) {
|
|
93738
|
-
const marginSummary = container.marginSummary && typeof container.marginSummary === "object" && !Array.isArray(container.marginSummary) ? container.marginSummary : {};
|
|
93739
|
-
accountValue = Math.max(accountValue, toNumber3(marginSummary.accountValue));
|
|
93740
|
-
totalMarginUsed = Math.max(totalMarginUsed, toNumber3(marginSummary.totalMarginUsed));
|
|
93741
|
-
withdrawable = Math.max(withdrawable, toNumber3(container.withdrawable));
|
|
93742
|
-
}
|
|
93743
|
-
if (accountValue <= 0) {
|
|
93744
|
-
for (const key of ["accountValue", "totalValue", "equity", "totalRawUsd", "usdValue", "usdcValue"]) {
|
|
93745
|
-
accountValue = Math.max(accountValue, toNumber3(response[key]));
|
|
93746
|
-
}
|
|
93747
|
-
}
|
|
93748
|
-
const balances = [];
|
|
93749
|
-
const listKeys = ["balances", "tokenBalances", "spotBalances", "assets"];
|
|
93750
|
-
for (const container of containers) {
|
|
93751
|
-
for (const listKey of listKeys) {
|
|
93752
|
-
const bucket = container[listKey];
|
|
93753
|
-
if (!Array.isArray(bucket)) continue;
|
|
93754
|
-
let stableTotal = 0;
|
|
93755
|
-
let anyTotal = 0;
|
|
93756
|
-
for (const rawEntry of bucket) {
|
|
93757
|
-
if (!rawEntry || typeof rawEntry !== "object" || Array.isArray(rawEntry)) continue;
|
|
93758
|
-
const entry = rawEntry;
|
|
93759
|
-
const coin = String(firstTruthy([
|
|
93760
|
-
entry.coin,
|
|
93761
|
-
entry.token,
|
|
93762
|
-
entry.asset,
|
|
93763
|
-
entry.symbol
|
|
93764
|
-
], "")).trim().toUpperCase();
|
|
93765
|
-
if (!coin) continue;
|
|
93766
|
-
const total = toNumber3(firstTruthy([entry.total, entry.balance, entry.amount], "0"));
|
|
93767
|
-
const hold = toNumber3(firstTruthy([entry.hold, entry.locked], "0"));
|
|
93768
|
-
const available = Math.max(
|
|
93769
|
-
0,
|
|
93770
|
-
toNumber3(firstTruthy([entry.available, entry.free, total - hold], "0"))
|
|
93771
|
-
);
|
|
93772
|
-
let valueUsd = toNumber3(firstTruthy([entry.usdValue, entry.usdcValue], "0"));
|
|
93773
|
-
if (valueUsd <= 0 && STABLE_SPOT_SYMBOLS.has(coin)) {
|
|
93774
|
-
valueUsd = available > 0 ? available : total;
|
|
93775
|
-
}
|
|
93776
|
-
balances.push({ coin, total, hold, available, value_usd: valueUsd });
|
|
93777
|
-
const entryValue = valueUsd > 0 ? valueUsd : total;
|
|
93778
|
-
if (entryValue > 0) {
|
|
93779
|
-
anyTotal += entryValue;
|
|
93780
|
-
if (STABLE_SPOT_SYMBOLS.has(coin)) stableTotal += entryValue;
|
|
93781
|
-
}
|
|
93782
|
-
}
|
|
93783
|
-
if (accountValue <= 0) {
|
|
93784
|
-
if (stableTotal > 0) accountValue = stableTotal;
|
|
93785
|
-
else if (anyTotal > 0) accountValue = anyTotal;
|
|
93786
|
-
}
|
|
93787
|
-
}
|
|
93788
|
-
if (balances.length > 0) break;
|
|
93789
|
-
}
|
|
93790
|
-
return { accountValue, totalMarginUsed, withdrawable, balances };
|
|
93791
|
-
};
|
|
93792
|
-
sumBalanceValueUsd = (balances) => balances.reduce((total, balance) => {
|
|
93793
|
-
let valueUsd = toNumber3(balance.value_usd);
|
|
93794
|
-
if (valueUsd <= 0 && STABLE_SPOT_SYMBOLS.has(String(balance.coin || "").trim().toUpperCase())) {
|
|
93795
|
-
valueUsd = toNumber3(balance.total);
|
|
93796
|
-
}
|
|
93797
|
-
return total + Math.max(valueUsd, 0);
|
|
93798
|
-
}, 0);
|
|
93799
|
-
approximatelyEqual = (left, right, absoluteToleranceUsd, relativeTolerance) => {
|
|
93800
|
-
const reference = Math.max(Math.abs(left), Math.abs(right), 1);
|
|
93801
|
-
return Math.abs(left - right) <= Math.max(absoluteToleranceUsd, reference * relativeTolerance);
|
|
93802
|
-
};
|
|
93803
|
-
balancesMirrorUnifiedAccountValue = (input) => input.perpsEquity > 0 && input.spotEquity > 0 && input.balancesEquity > 0 && approximatelyEqual(
|
|
93804
|
-
input.perpsEquity,
|
|
93805
|
-
input.spotEquity,
|
|
93806
|
-
input.absoluteToleranceUsd,
|
|
93807
|
-
input.relativeTolerance
|
|
93808
|
-
) && approximatelyEqual(
|
|
93809
|
-
input.spotEquity,
|
|
93810
|
-
input.balancesEquity,
|
|
93811
|
-
input.absoluteToleranceUsd,
|
|
93812
|
-
input.relativeTolerance
|
|
93813
|
-
);
|
|
93814
|
-
computeEffectiveAccountValue = (input) => {
|
|
93815
|
-
if (!input.unifiedLike) return input.perpsEquity;
|
|
93816
|
-
if (input.balancesEquity > 0) {
|
|
93817
|
-
if (input.mirrored) {
|
|
93818
|
-
return Math.max(input.perpsEquity, input.spotEquity, input.balancesEquity);
|
|
93819
|
-
}
|
|
93820
|
-
return Math.max(
|
|
93821
|
-
input.perpsEquity + input.balancesEquity,
|
|
93822
|
-
input.spotEquity,
|
|
93823
|
-
input.balancesEquity
|
|
93824
|
-
);
|
|
93825
|
-
}
|
|
93826
|
-
return Math.max(input.perpsEquity, input.spotEquity);
|
|
93827
|
-
};
|
|
93828
93981
|
equityFormula = (input) => {
|
|
93829
93982
|
if (!input.unifiedLike) return "perps_account_value";
|
|
93830
93983
|
if (input.balancesEquity > 0) {
|
|
@@ -93839,11 +93992,11 @@ var init_server_prompt_rescue_account_contract = __esm({
|
|
|
93839
93992
|
const perps = perpsResponse && typeof perpsResponse === "object" && !Array.isArray(perpsResponse) ? perpsResponse : {};
|
|
93840
93993
|
const marginSummary = perps.marginSummary && typeof perps.marginSummary === "object" && !Array.isArray(perps.marginSummary) ? perps.marginSummary : {};
|
|
93841
93994
|
const crossMarginSummary = perps.crossMarginSummary && typeof perps.crossMarginSummary === "object" && !Array.isArray(perps.crossMarginSummary) ? perps.crossMarginSummary : {};
|
|
93842
|
-
const rawPerpsAccountValue =
|
|
93995
|
+
const rawPerpsAccountValue = toNumber(marginSummary.accountValue);
|
|
93843
93996
|
const perpsAccountValue = Math.max(0, rawPerpsAccountValue);
|
|
93844
|
-
const crossMarginAccountValue =
|
|
93845
|
-
let totalMarginUsed =
|
|
93846
|
-
let withdrawable =
|
|
93997
|
+
const crossMarginAccountValue = toNumber(crossMarginSummary.accountValue);
|
|
93998
|
+
let totalMarginUsed = toNumber(marginSummary.totalMarginUsed);
|
|
93999
|
+
let withdrawable = toNumber(perps.withdrawable);
|
|
93847
94000
|
const spot = accountMode === "disabled" ? { accountValue: 0, totalMarginUsed: 0, withdrawable: 0, balances: [] } : extractCanonicalSpotMetrics(spotResponse);
|
|
93848
94001
|
const balances = spot.balances;
|
|
93849
94002
|
const balancesEquity = sumBalanceValueUsd(balances);
|
|
@@ -93875,7 +94028,7 @@ var init_server_prompt_rescue_account_contract = __esm({
|
|
|
93875
94028
|
mirrored
|
|
93876
94029
|
};
|
|
93877
94030
|
const accountValue = computeEffectiveAccountValue(formulaInput);
|
|
93878
|
-
const maintenanceMargin =
|
|
94031
|
+
const maintenanceMargin = toNumber(perps.crossMaintenanceMarginUsed);
|
|
93879
94032
|
const availableMargin = canonicalAvailableMargin(accountValue, totalMarginUsed);
|
|
93880
94033
|
let totalNotional = 0;
|
|
93881
94034
|
let totalUnrealizedPnl = 0;
|
|
@@ -93883,10 +94036,10 @@ var init_server_prompt_rescue_account_contract = __esm({
|
|
|
93883
94036
|
for (const entry of positions) {
|
|
93884
94037
|
const position = entry && typeof entry === "object" && !Array.isArray(entry) ? entry.position : null;
|
|
93885
94038
|
if (!position || typeof position !== "object" || Array.isArray(position)) continue;
|
|
93886
|
-
const size =
|
|
93887
|
-
const unrealizedPnl =
|
|
94039
|
+
const size = toNumber(position.szi);
|
|
94040
|
+
const unrealizedPnl = toNumber(position.unrealizedPnl);
|
|
93888
94041
|
totalUnrealizedPnl += unrealizedPnl;
|
|
93889
|
-
totalNotional += Math.abs(size *
|
|
94042
|
+
totalNotional += Math.abs(size * toNumber(position.entryPx) + unrealizedPnl);
|
|
93890
94043
|
}
|
|
93891
94044
|
return {
|
|
93892
94045
|
account_value: accountValue,
|
|
@@ -94033,7 +94186,7 @@ var init_hyperliquid_account_state_adapter = __esm({
|
|
|
94033
94186
|
buildUserFillsStorageKey = (cacheKey) => {
|
|
94034
94187
|
return `${USER_FILLS_CACHE_STORAGE_PREFIX}${cacheKey}`;
|
|
94035
94188
|
};
|
|
94036
|
-
buildAccountStateCacheKey = (apiUrl, walletAddress, symbol2, aggregatePerpDexs, scopeAccountSummaryToSelectedDex, dexNames, includeEffectiveTakerRate, includeExactAccountMode, includeActiveAssetData, feeSymbols) => {
|
|
94189
|
+
buildAccountStateCacheKey = (apiUrl, walletAddress, symbol2, aggregatePerpDexs, scopeAccountSummaryToSelectedDex, dexNames, includeEffectiveTakerRate, includeExactAccountMode, includeActiveAssetData, feeSymbols, serverLoopAccountValue2) => {
|
|
94037
94190
|
return [
|
|
94038
94191
|
apiUrl.replace(/\/$/, "").toLowerCase(),
|
|
94039
94192
|
walletAddress.trim().toLowerCase(),
|
|
@@ -94043,6 +94196,8 @@ var init_hyperliquid_account_state_adapter = __esm({
|
|
|
94043
94196
|
includeEffectiveTakerRate ? "with-effective-taker-rate" : "without-effective-taker-rate",
|
|
94044
94197
|
includeExactAccountMode ? "with-exact-account-mode" : "without-exact-account-mode",
|
|
94045
94198
|
includeActiveAssetData ? "with-active-asset" : "without-active-asset",
|
|
94199
|
+
// A device read's key is unchanged; a Server-loop valuation never shares it.
|
|
94200
|
+
...serverLoopAccountValue2 ? ["server-loop-account-value"] : [],
|
|
94046
94201
|
...dexNames.map(normalizePerpDexName).sort(),
|
|
94047
94202
|
"fee-symbols",
|
|
94048
94203
|
...feeSymbols
|
|
@@ -94633,7 +94788,8 @@ var init_hyperliquid_account_state_adapter = __esm({
|
|
|
94633
94788
|
includeEffectiveTakerRate,
|
|
94634
94789
|
includeExactAccountMode,
|
|
94635
94790
|
includeActiveAssetData,
|
|
94636
|
-
[...new Set((input.feeSymbols ?? [symbol2]).map(normalizeHyperliquidMarketSymbol).filter(Boolean))].sort()
|
|
94791
|
+
[...new Set((input.feeSymbols ?? [symbol2]).map(normalizeHyperliquidMarketSymbol).filter(Boolean))].sort(),
|
|
94792
|
+
input.serverLoopAccountValue === true
|
|
94637
94793
|
);
|
|
94638
94794
|
const now = Date.now();
|
|
94639
94795
|
const cached2 = readBrowserAccountStateCache(cacheKey);
|
|
@@ -94701,17 +94857,19 @@ var init_hyperliquid_account_state_adapter = __esm({
|
|
|
94701
94857
|
staleIf429MaxAgeMs
|
|
94702
94858
|
}) => {
|
|
94703
94859
|
const metadataBodies = input.includeEffectiveTakerRate === true ? ["", ...dexNames].map((dex) => ({ type: "meta", ...dex ? { dex } : {} })) : [];
|
|
94860
|
+
const accountModeCache = input.publicRequestPriority === "ui" ? "display" : true;
|
|
94704
94861
|
const reservation = await reserveHyperliquidPublicReads(apiUrl, [
|
|
94705
94862
|
{ type: "clearinghouseState", user: walletAddress },
|
|
94706
94863
|
...dexNames.map((dex) => ({ type: "clearinghouseState", user: walletAddress, dex })),
|
|
94707
94864
|
{ type: "spotClearinghouseState", user: walletAddress },
|
|
94708
94865
|
...input.includeActiveAssetData === false ? [] : [{ type: "activeAssetData", user: walletAddress, coin: symbol2 }],
|
|
94709
94866
|
...input.includeEffectiveTakerRate === true ? [{ type: "userFees", user: walletAddress }, ...metadataBodies] : [],
|
|
94710
|
-
|
|
94867
|
+
// A Server-loop valuation may need the mode too; a reservation claims no weight.
|
|
94868
|
+
...input.includeExactAccountMode === true || input.serverLoopAccountValue === true ? [
|
|
94711
94869
|
{ type: "userAbstraction", user: walletAddress },
|
|
94712
94870
|
{ type: "userDexAbstraction", user: walletAddress }
|
|
94713
94871
|
] : []
|
|
94714
|
-
], input.signal, { cacheAccountMode:
|
|
94872
|
+
], input.signal, { cacheAccountMode: accountModeCache, cacheValidUntilMs: input.publicReadDeadlineMs });
|
|
94715
94873
|
const priorityScope = input.priorityScope ?? createHyperliquidPublicPriorityScope(input.publicRequestPriority);
|
|
94716
94874
|
reservation.priorityScope = priorityScope;
|
|
94717
94875
|
if (input.onPublicReadPendingChange) {
|
|
@@ -94741,8 +94899,8 @@ var init_hyperliquid_account_state_adapter = __esm({
|
|
|
94741
94899
|
return { payload: null, fetchedAtMs: Date.now() };
|
|
94742
94900
|
}).then((result) => ({ payload: result.payload, capturedAt: new Date(result.fetchedAtMs).toISOString() }))
|
|
94743
94901
|
}))() : Promise.resolve(null);
|
|
94744
|
-
const
|
|
94745
|
-
const abstractionRead = await readHyperliquidPublicInfo(apiUrl, { type: "userAbstraction", user: walletAddress }, { signal: input.signal, reservation, cacheAccountMode:
|
|
94902
|
+
const readExactAccountMode = async () => {
|
|
94903
|
+
const abstractionRead = await readHyperliquidPublicInfo(apiUrl, { type: "userAbstraction", user: walletAddress }, { signal: input.signal, reservation, cacheAccountMode: accountModeCache, priorityScope });
|
|
94746
94904
|
const userAbstraction = abstractionRead.payload;
|
|
94747
94905
|
let capturedAtMs = abstractionRead.fetchedAtMs;
|
|
94748
94906
|
const preliminaryMode = extractCanonicalHyperliquidAccountMode(userAbstraction);
|
|
@@ -94751,7 +94909,7 @@ var init_hyperliquid_account_state_adapter = __esm({
|
|
|
94751
94909
|
}
|
|
94752
94910
|
let userDexAbstraction;
|
|
94753
94911
|
if (preliminaryMode === "default" || preliminaryMode === "disabled") {
|
|
94754
|
-
const dexRead = await readHyperliquidPublicInfo(apiUrl, { type: "userDexAbstraction", user: walletAddress }, { signal: input.signal, reservation, cacheAccountMode:
|
|
94912
|
+
const dexRead = await readHyperliquidPublicInfo(apiUrl, { type: "userDexAbstraction", user: walletAddress }, { signal: input.signal, reservation, cacheAccountMode: accountModeCache, priorityScope });
|
|
94755
94913
|
userDexAbstraction = dexRead.payload;
|
|
94756
94914
|
capturedAtMs = Math.min(capturedAtMs, dexRead.fetchedAtMs);
|
|
94757
94915
|
}
|
|
@@ -94762,7 +94920,8 @@ var init_hyperliquid_account_state_adapter = __esm({
|
|
|
94762
94920
|
),
|
|
94763
94921
|
capturedAt: new Date(capturedAtMs).toISOString()
|
|
94764
94922
|
};
|
|
94765
|
-
}
|
|
94923
|
+
};
|
|
94924
|
+
const exactAccountModePromise = input.includeExactAccountMode === true ? readExactAccountMode() : Promise.resolve(null);
|
|
94766
94925
|
await awaitAccountReads([userFeesPromise, exactAccountModePromise]);
|
|
94767
94926
|
const metadataByDex = /* @__PURE__ */ new Map();
|
|
94768
94927
|
if (input.includeEffectiveTakerRate === true) {
|
|
@@ -94871,12 +95030,31 @@ var init_hyperliquid_account_state_adapter = __esm({
|
|
|
94871
95030
|
}
|
|
94872
95031
|
const accountStateConfig = input.config.client_runtime_hyperliquid_account_state;
|
|
94873
95032
|
const summaryPerpsResponse = exactAccountMode ? { ...accountSummaryPerpsResponse, accountMode: exactAccountMode.accountMode } : accountSummaryPerpsResponse;
|
|
94874
|
-
const
|
|
95033
|
+
const deviceSummaryOptions = {
|
|
94875
95034
|
spotDominatesMinTotalUsd: accountStateConfig?.spot_dominates_min_total_usd,
|
|
94876
95035
|
spotDominatesPerpsMultiplier: accountStateConfig?.spot_dominates_perps_multiplier,
|
|
94877
95036
|
mirroredAccountValueAbsoluteToleranceUsd: accountStateConfig?.mirrored_account_value_absolute_tolerance_usd,
|
|
94878
95037
|
mirroredAccountValueRelativeTolerance: accountStateConfig?.mirrored_account_value_relative_tolerance
|
|
94879
95038
|
};
|
|
95039
|
+
let serverLoopClassification = input.serverLoopAccountValue === true ? {
|
|
95040
|
+
spotAvailableToTradeRatioThreshold: accountStateConfig?.spot_available_to_trade_ratio_threshold,
|
|
95041
|
+
spotMeaningfulHoldUsd: accountStateConfig?.spot_meaningful_hold_usd,
|
|
95042
|
+
spotVeryStrongTotalUsd: accountStateConfig?.spot_very_strong_total_usd,
|
|
95043
|
+
spotVeryStrongPerpsEquityThresholdUsd: accountStateConfig?.spot_very_strong_perps_equity_threshold_usd,
|
|
95044
|
+
// The Python loop probes BTC's activeAssetData. This read's own probe
|
|
95045
|
+
// answers for the same collateral only on the default Perps DEX.
|
|
95046
|
+
availableToTrade: activeAssetResult?.payload != null && !selectedDex ? ((probe) => [probe.available_to_trade_buy, probe.available_to_trade_sell])(
|
|
95047
|
+
normalizeActiveAssetData(activeAssetResult.payload, symbol2)
|
|
95048
|
+
) : null
|
|
95049
|
+
} : null;
|
|
95050
|
+
if (serverLoopClassification && !exactAccountMode && input.scopeAccountSummaryToSelectedDex !== true && serverLoopValuationCountsSpot(accountSummaryPerpsResponse, spotResponse, { ...deviceSummaryOptions, serverLoopClassification })) {
|
|
95051
|
+
const [serverLoopExactAccountMode] = await awaitAccountReads([readExactAccountMode()]);
|
|
95052
|
+
serverLoopClassification = { ...serverLoopClassification, exactAccountMode: serverLoopExactAccountMode.accountMode };
|
|
95053
|
+
}
|
|
95054
|
+
const accountSummaryOptions = {
|
|
95055
|
+
...deviceSummaryOptions,
|
|
95056
|
+
...serverLoopClassification ? { serverLoopClassification } : {}
|
|
95057
|
+
};
|
|
94880
95058
|
const walletSummary = exactAccountMode && input.scopeAccountSummaryToSelectedDex !== true ? buildServerPromptRescueAccountSummary(
|
|
94881
95059
|
perpsResponse,
|
|
94882
95060
|
spotResponse,
|
|
@@ -95890,7 +96068,7 @@ var init_client_exchange_mutations = __esm({
|
|
|
95890
96068
|
});
|
|
95891
96069
|
|
|
95892
96070
|
// lib/runtime/execution-guard-contract.ts
|
|
95893
|
-
var unitsFromPosition, signedUnitsFromPosition, signedUnitsFromEntryPosition, classifyExecutionIntent, reductionFirstOrder, resolveExecutionTarget, decisionOrderSizeAsset, flipExecutionLegs, executedOrderPositionEvent;
|
|
96071
|
+
var unitsFromPosition, signedUnitsFromPosition, signedUnitsFromEntryPosition, classifyExecutionIntent, reductionFirstOrder, usdAmount, orderMetadataRetryReason, orderCeilingRefusal, resolveExecutionTarget, decisionOrderSizeAsset, flipExecutionLegs, executedOrderPositionEvent;
|
|
95894
96072
|
var init_execution_guard_contract = __esm({
|
|
95895
96073
|
"lib/runtime/execution-guard-contract.ts"() {
|
|
95896
96074
|
"use strict";
|
|
@@ -96090,6 +96268,28 @@ var init_execution_guard_contract = __esm({
|
|
|
96090
96268
|
const reduces = plans.map((plan) => classifyExecutionIntent(plan.decision, plan.units, plan.signedUnits).reduceOnly);
|
|
96091
96269
|
return plans.map((_, index) => index).sort((left, right) => Number(reduces[right]) - Number(reduces[left]));
|
|
96092
96270
|
};
|
|
96271
|
+
usdAmount = (value) => `$${value.toLocaleString("en-US", {
|
|
96272
|
+
minimumFractionDigits: USD_DISPLAY_DECIMALS,
|
|
96273
|
+
maximumFractionDigits: USD_DISPLAY_DECIMALS
|
|
96274
|
+
})}`;
|
|
96275
|
+
orderMetadataRetryReason = (rejection) => {
|
|
96276
|
+
const message = String(rejection ?? "").toLowerCase();
|
|
96277
|
+
if (message.includes("invalid size")) return "invalid_size";
|
|
96278
|
+
if (message.includes("reference price") && message.includes("95% away")) return "reference_price";
|
|
96279
|
+
return null;
|
|
96280
|
+
};
|
|
96281
|
+
orderCeilingRefusal = (input) => {
|
|
96282
|
+
const orderNotional = input.size * input.price;
|
|
96283
|
+
if (orderNotional > input.maxOrderNotional) {
|
|
96284
|
+
return `Order notional ${usdAmount(orderNotional)} exceeds limit ${usdAmount(input.maxOrderNotional)}`;
|
|
96285
|
+
}
|
|
96286
|
+
const resultingSize = input.side === "buy" ? input.currentPositionSize + input.size : input.currentPositionSize - input.size;
|
|
96287
|
+
const resultingNotional = Math.abs(resultingSize) * input.price;
|
|
96288
|
+
if (resultingNotional > input.maxPositionNotional) {
|
|
96289
|
+
return `Resulting position notional ${usdAmount(resultingNotional)} exceeds limit ${usdAmount(input.maxPositionNotional)}`;
|
|
96290
|
+
}
|
|
96291
|
+
return null;
|
|
96292
|
+
};
|
|
96093
96293
|
resolveExecutionTarget = (classified, liveSignedUnits, livePositionDirection) => {
|
|
96094
96294
|
const liveUnits = Number.isFinite(liveSignedUnits) ? Math.trunc(liveSignedUnits) : 0;
|
|
96095
96295
|
const exactLiveDirection = livePositionDirection == null ? liveUnits > 0 ? 1 : liveUnits < 0 ? -1 : 0 : livePositionDirection;
|
|
@@ -96639,6 +96839,27 @@ var init_protective_leg_evidence = __esm({
|
|
|
96639
96839
|
}
|
|
96640
96840
|
});
|
|
96641
96841
|
|
|
96842
|
+
// lib/runtime/protective-entry-cover.ts
|
|
96843
|
+
var protectiveEntryCover, protectiveEntryLegSize;
|
|
96844
|
+
var init_protective_entry_cover = __esm({
|
|
96845
|
+
"lib/runtime/protective-entry-cover.ts"() {
|
|
96846
|
+
"use strict";
|
|
96847
|
+
init_define_VTX_EXO_POLICY();
|
|
96848
|
+
init_define_VTX_GROK_POLICY();
|
|
96849
|
+
init_define_VTX_PI_MODEL_POLICY();
|
|
96850
|
+
protectiveEntryCover = (input) => {
|
|
96851
|
+
const cover = { sl: 0, tp: 0 };
|
|
96852
|
+
for (const leg of input.storedLegs) {
|
|
96853
|
+
if (leg.isLong !== input.entryIsLong) continue;
|
|
96854
|
+
const rests = leg.orderId == null ? leg.canStillExist : input.liveOrderIds.has(String(leg.orderId));
|
|
96855
|
+
if (rests) cover[leg.kind] += leg.size;
|
|
96856
|
+
}
|
|
96857
|
+
return cover;
|
|
96858
|
+
};
|
|
96859
|
+
protectiveEntryLegSize = (input) => Math.min(input.filledSize, Math.max(0, input.liveExposure - input.cover));
|
|
96860
|
+
}
|
|
96861
|
+
});
|
|
96862
|
+
|
|
96642
96863
|
// lib/runtime/runtime-execution.ts
|
|
96643
96864
|
function capCopiedToActual(copied, actual) {
|
|
96644
96865
|
if (Math.abs(copied) <= COPY_TRADING_SIZE_EPSILON) return 0;
|
|
@@ -96674,7 +96895,7 @@ function copiedTargetNow(reconciliation, recordedTarget, actualPosition) {
|
|
|
96674
96895
|
);
|
|
96675
96896
|
return { copiedNow, targetNow, kept: copiedTargetBesideOwnPosition(targetNow, copiedNow, actualPosition) };
|
|
96676
96897
|
}
|
|
96677
|
-
var clientProtectiveMutationAuthority, executionReadPriority, serverEntryLeverageAlreadyHeld, fetchClientRuntimeOpenOrders, _extractOrderResponseStates, createRuntimeId, _extractFilledSize, _extractOrderId, _toExecutionMetadata, _extractClientMutationId, _stableMutationIdentity, trailingStopMemory, protectiveGroupMemory, protectiveGroupReadFailures, windowHandoffCleanupAttempts, clientRuntimeProtectionStorage, resolveClientRuntimeProtectionStorage, setClientRuntimeProtectionStorage, trailingStopStorageKey, readTrackedTrailingStops, writeTrackedTrailingStops, rememberTrailingStop, protectiveGroupStorageKey, LOST_LEG_EVIDENCE_MAX_AGE_MS, EPISODE_END_FILL_LOOKBACK_MS, withClientProtectivePlanSetLock, readClientProtectiveGroups, writeClientProtectiveGroups, hasClientProtectiveGroupReadFailure, readFreshClientProtectiveGroups, stableProtectionSnapshot, exactClientProtectiveGroupSnapshot, exactClientProtectiveGroupSetSnapshot, storableClientProtectiveGroup, replaceExactClientProtectiveGroup, replaceExactClientProtectiveGroupSet, isClientRuntimeLeaseOwnershipError, hasClientRuntimeProtectionState, clearClientRuntimeVetoedProtectiveIntent, rethrowWindowHandoffAfterProtectiveReplacementVeto, canPersistClientProtectiveGroups, removeTrackedTrailingStop, replaceTrackedTrailingStop, replaceProtectiveLeg, replacementJournalEntryOrderId, buildProtectiveReplacementJournalGroup, isProtectiveReplacementJournalGroup, reserveProtectiveLegReplacement, ensureProtectiveReplacementJournalCompanion, buildVetoedProtectiveReplacementCleanup, assertExactProtectiveReplacementDispatchAuthority, transitionProtectiveReplacementAcknowledgement, transitionTerminalProtectiveReplacement, pendingProtectiveReplacementReport, isConfiguredProtectionRequested, protectiveAction, executedProtectiveReport, isExactClientPositionTpslPair, deviceOwnsClientProtectiveLegKind, isAdoptionNarrowedPositionTpslLeg, hasAmbiguousClientPositionTpslAuthority, protectiveStableShapeMatches, observedProtectiveGroupingMatches, protectiveLiveShapeMatches, protectiveTerminalShapeMatches, cancelClientProtectiveLeg, buildPendingProtectivePlan, persistPendingClientProtectiveGroup, storedClientProtectiveCover, attachClientProtectivePlan, resolveJournaledAttachmentContinuity, protectiveMemberRested, recoverJournaledClientProtectiveAttachments, readPendingEntryMutation, requireClientRuntimeConfigSeconds, replacePendingEntryRecovery, recoverPendingClientProtectiveGroups, recoverPendingProtectiveReplacements, liveProtectiveOrderShape, observedStandaloneProtectiveGroup, migrateTrackedTrailingStopsToStandalone, reconcileClientProtectiveGroups, cancelAllClientProtectiveGroups, tightenClientTrailingStops, throwIfAborted2, sleep2, isDefinitiveEntryRejection, resolveExchangeSizeDecimals, roundAssetSize, resolvePositionSize, resolveCurrentPositionSize, buildPositionSnapshot, signedRemainingExposureAfterConfirmedReduction, runtimeProtectionAuthority, runtimeProtectionOwners, resolveRuntimeProtectionOwner, drainServerProtectionForRuntime, drainServerProtectionIfOwned, verifyNoLiveClientProtectiveTriggers, clientExecutionMutations, CLIENT_EXECUTION_QUEUE_TIMEOUT_MESSAGE, withClientExecutionMutation, withClientProtectivePlanSetMutation, allocateServerExecutionCapacity, withClientProtectiveAdoptionMutation, executeClientRuntimeDecisionLocked, SERVER_AUDIT_RECORDED_ELSEWHERE, serverExecutionAuditOutcome, decisionLegOf, withExecutionAuditId, executeClientRuntimeDecision, waitForFlipCloseFreshness, maintainClientRuntimeTrailingStops, listPendingClientProtectiveSymbols, listStoredClientProtectiveSymbols, hasUnresolvedClientProtectiveIdentity, resolveClientProtectiveIdentitiesForAdoption, exportClientProtectiveGroupsForAdoption, adoptionGroupKey, applyClientProtectiveAdoptionOutcomes, hasStoredClientProtectiveGroupsForWallet, hasPendingClientProtectiveGroups, recoverManualClientProtectiveGroups, clientRuntimeDecisionSizesOrders, COMMITTED_EXECUTION_REPORTS, getCommittedExecutionReports, withCommittedExecutionReports, executeClientRuntimeDecisionUnlocked, executeClientCopyTradingIntent, _copyCancelOrderId, executeClientCopyTradingOrderAction;
|
|
96898
|
+
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, COMMITTED_DECISION_ORDER, getCommittedExecutionReports, getCommittedDecisionOrder, withCommittedExecutionReports, executeClientRuntimeDecisionUnlocked, executeClientCopyTradingIntent, _copyCancelOrderId, executeClientCopyTradingOrderAction;
|
|
96678
96899
|
var init_runtime_execution = __esm({
|
|
96679
96900
|
"lib/runtime/runtime-execution.ts"() {
|
|
96680
96901
|
"use strict";
|
|
@@ -96701,6 +96922,7 @@ var init_runtime_execution = __esm({
|
|
|
96701
96922
|
init_runtime_redaction();
|
|
96702
96923
|
init_protective_leg_evidence();
|
|
96703
96924
|
init_protective_stop_replacement();
|
|
96925
|
+
init_protective_entry_cover();
|
|
96704
96926
|
init_error_surface_contract();
|
|
96705
96927
|
init_runtime_handoff();
|
|
96706
96928
|
clientProtectiveMutationAuthority = (request) => request.mutationAuthority === "manual_session" ? {} : {
|
|
@@ -96725,7 +96947,13 @@ var init_runtime_execution = __esm({
|
|
|
96725
96947
|
const wallet = String(context.walletAddress || "").trim();
|
|
96726
96948
|
if (!symbol2 || !wallet || !Number.isInteger(context.leverage) || context.leverage <= 0 || !Number.isFinite(context.currentPositionSize) || context.currentPositionSize === 0) return false;
|
|
96727
96949
|
let active;
|
|
96950
|
+
let target;
|
|
96728
96951
|
try {
|
|
96952
|
+
target = resolveLeverageTarget(
|
|
96953
|
+
await resolveHyperliquidAsset({ symbol: symbol2, config: input.config ?? null, publicRequestPriority: "trading_reconcile" }),
|
|
96954
|
+
context.leverage,
|
|
96955
|
+
context.marginMode !== "isolated"
|
|
96956
|
+
);
|
|
96729
96957
|
active = await fetchBrowserHyperliquidInfoPayload(
|
|
96730
96958
|
{ config: input.config ?? null, signal: input.signal, publicRequestPriority: "trading_reconcile" },
|
|
96731
96959
|
{ type: "activeAssetData", user: wallet, coin: symbol2 },
|
|
@@ -96736,7 +96964,7 @@ var init_runtime_execution = __esm({
|
|
|
96736
96964
|
return false;
|
|
96737
96965
|
}
|
|
96738
96966
|
const leverage = active?.leverage;
|
|
96739
|
-
return leverage?.value ===
|
|
96967
|
+
return leverage?.value === target.leverage && leverage?.type === (target.isCross ? "cross" : "isolated");
|
|
96740
96968
|
};
|
|
96741
96969
|
fetchClientRuntimeOpenOrders = async (request, publicRequestPriority = "trading_reconcile") => {
|
|
96742
96970
|
const normalizedSymbol = normalizeHyperliquidMarketSymbol(
|
|
@@ -97176,7 +97404,9 @@ var init_runtime_execution = __esm({
|
|
|
97176
97404
|
const phase = journal.phase == null ? "awaiting_member_outcome" : journal.phase;
|
|
97177
97405
|
const filledSize = Number(journal.filledSize);
|
|
97178
97406
|
const averagePrice = Number(journal.averagePrice);
|
|
97179
|
-
|
|
97407
|
+
const invalidJournalTime = (value) => value != null && (typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0);
|
|
97408
|
+
const journalMutationId = journal.mutationId == null ? void 0 : String(journal.mutationId).trim().toLowerCase();
|
|
97409
|
+
if (phase !== "awaiting_member_outcome" && phase !== "cancel_survivors" && phase !== "cancel_stale_members" || journalMutationId !== void 0 && !/^[0-9a-f]{8}(?:-[0-9a-f]{4}){3}-[0-9a-f]{12}$/.test(journalMutationId) || invalidJournalTime(journal.createdAtMs) || invalidJournalTime(journal.unknownOidFirstSeenAtMs) || invalidJournalTime(journal.unknownOidObservedAtMs) || !/^[1-9]\d*$/.test(journalEntryOrderId) || !Number.isFinite(filledSize) || filledSize <= 0 || !Number.isFinite(averagePrice) || averagePrice <= 0 || !Array.isArray(journal.members) || journal.members.length < 1 || journal.members.length > CLIENT_PROTECTIVE_TPSL_PAIR_LEGS) {
|
|
97180
97410
|
protectiveGroupReadFailures.add(key);
|
|
97181
97411
|
return [];
|
|
97182
97412
|
}
|
|
@@ -97186,7 +97416,7 @@ var init_runtime_execution = __esm({
|
|
|
97186
97416
|
const clientOrderId = String(member.clientOrderId ?? "").trim().toLowerCase();
|
|
97187
97417
|
const triggerPrice = Number(member.triggerPrice);
|
|
97188
97418
|
const size = Number(member.size);
|
|
97189
|
-
if (member.kind !== "sl" && member.kind !== "tp" || !/^0x[0-9a-f]{32}$/.test(clientOrderId) || !Number.isFinite(triggerPrice) || triggerPrice <= 0 || !Number.isFinite(size) || size <= 0 || typeof member.isTrailing !== "boolean" || typeof member.positionTpsl !== "boolean") {
|
|
97419
|
+
if (member.kind !== "sl" && member.kind !== "tp" || !/^0x[0-9a-f]{32}$/.test(clientOrderId) || !Number.isFinite(triggerPrice) || triggerPrice <= 0 || !Number.isFinite(size) || size <= 0 || typeof member.isTrailing !== "boolean" || typeof member.positionTpsl !== "boolean" || invalidJournalTime(member.neverLandedAtMs)) {
|
|
97190
97420
|
return [];
|
|
97191
97421
|
}
|
|
97192
97422
|
return [{
|
|
@@ -97195,7 +97425,8 @@ var init_runtime_execution = __esm({
|
|
|
97195
97425
|
triggerPrice,
|
|
97196
97426
|
size,
|
|
97197
97427
|
isTrailing: member.isTrailing,
|
|
97198
|
-
positionTpsl: member.positionTpsl
|
|
97428
|
+
positionTpsl: member.positionTpsl,
|
|
97429
|
+
...typeof member.neverLandedAtMs === "number" ? { neverLandedAtMs: member.neverLandedAtMs } : {}
|
|
97199
97430
|
}];
|
|
97200
97431
|
});
|
|
97201
97432
|
if (members.length !== journal.members.length || pendingEntry == null || legs.length > 0 && (members.length !== legs.length || members.some((member, index) => {
|
|
@@ -97210,6 +97441,10 @@ var init_runtime_execution = __esm({
|
|
|
97210
97441
|
entryOrderId: journalEntryOrderId,
|
|
97211
97442
|
filledSize,
|
|
97212
97443
|
averagePrice,
|
|
97444
|
+
...journalMutationId !== void 0 ? { mutationId: journalMutationId } : {},
|
|
97445
|
+
...typeof journal.createdAtMs === "number" ? { createdAtMs: journal.createdAtMs } : {},
|
|
97446
|
+
...typeof journal.unknownOidFirstSeenAtMs === "number" ? { unknownOidFirstSeenAtMs: journal.unknownOidFirstSeenAtMs } : {},
|
|
97447
|
+
...typeof journal.unknownOidObservedAtMs === "number" ? { unknownOidObservedAtMs: journal.unknownOidObservedAtMs } : {},
|
|
97213
97448
|
members
|
|
97214
97449
|
};
|
|
97215
97450
|
}
|
|
@@ -97970,21 +98205,27 @@ var init_runtime_execution = __esm({
|
|
|
97970
98205
|
);
|
|
97971
98206
|
return { group, cleanup, persistedGroupSet: persistenceFailed ? null : nextGroups };
|
|
97972
98207
|
};
|
|
97973
|
-
|
|
97974
|
-
|
|
97975
|
-
|
|
97976
|
-
|
|
97977
|
-
|
|
97978
|
-
|
|
97979
|
-
|
|
97980
|
-
|
|
97981
|
-
|
|
97982
|
-
|
|
97983
|
-
|
|
97984
|
-
|
|
98208
|
+
attachmentMemberNeverLanded = (group, leg) => group.attachmentJournal?.members.some((member) => member.clientOrderId === leg.orderId && member.neverLandedAtMs != null) === true;
|
|
98209
|
+
storedClientProtectiveCover = async (request, entryIsLong, groups) => {
|
|
98210
|
+
const storedLegs = groups.filter((group) => group.isLong === entryIsLong).flatMap((group) => group.legs.map((leg) => ({
|
|
98211
|
+
isLong: group.isLong,
|
|
98212
|
+
kind: leg.kind,
|
|
98213
|
+
size: leg.size,
|
|
98214
|
+
orderId: typeof leg.orderId === "number" ? leg.orderId : null,
|
|
98215
|
+
canStillExist: !attachmentMemberNeverLanded(group, leg)
|
|
98216
|
+
})));
|
|
98217
|
+
const liveOrderIds = /* @__PURE__ */ new Set();
|
|
98218
|
+
if (storedLegs.length > 0) {
|
|
98219
|
+
const symbol2 = request.executionContext.symbol.trim().toUpperCase();
|
|
98220
|
+
const orders = await fetchClientRuntimeOpenOrders(request, "trading_reduce");
|
|
98221
|
+
if (!Array.isArray(orders)) {
|
|
98222
|
+
throw new Error("Malformed live protective-order snapshot.");
|
|
98223
|
+
}
|
|
98224
|
+
for (const order of orders) {
|
|
98225
|
+
if (String(order.coin).trim().toUpperCase() === symbol2) liveOrderIds.add(String(order.oid));
|
|
97985
98226
|
}
|
|
97986
98227
|
}
|
|
97987
|
-
return
|
|
98228
|
+
return protectiveEntryCover({ entryIsLong, storedLegs, liveOrderIds });
|
|
97988
98229
|
};
|
|
97989
98230
|
attachClientProtectivePlan = async (request, group, fill) => {
|
|
97990
98231
|
const reports = [];
|
|
@@ -98082,10 +98323,7 @@ var init_runtime_execution = __esm({
|
|
|
98082
98323
|
const liveExposure = Math.abs(livePositionSize);
|
|
98083
98324
|
let storedCover;
|
|
98084
98325
|
try {
|
|
98085
|
-
storedCover = await storedClientProtectiveCover(
|
|
98086
|
-
request,
|
|
98087
|
-
existingGroups.flatMap((existing) => existing.legs)
|
|
98088
|
-
);
|
|
98326
|
+
storedCover = await storedClientProtectiveCover(request, isLong, existingGroups);
|
|
98089
98327
|
} catch (error48) {
|
|
98090
98328
|
if (request.signal?.aborted) throw error48;
|
|
98091
98329
|
reports.push({
|
|
@@ -98101,9 +98339,12 @@ var init_runtime_execution = __esm({
|
|
|
98101
98339
|
return reports;
|
|
98102
98340
|
}
|
|
98103
98341
|
const allocatedCandidates = planned.flatMap((candidate) => {
|
|
98104
|
-
const allocated = storedCover[candidate.kind];
|
|
98105
98342
|
const size = roundAssetSize(
|
|
98106
|
-
|
|
98343
|
+
protectiveEntryLegSize({
|
|
98344
|
+
filledSize: fill.filledSize,
|
|
98345
|
+
liveExposure,
|
|
98346
|
+
cover: storedCover[candidate.kind]
|
|
98347
|
+
}),
|
|
98107
98348
|
request.executionContext.sizeDecimals
|
|
98108
98349
|
);
|
|
98109
98350
|
if (!Number.isFinite(size) || size <= 0) {
|
|
@@ -98211,6 +98452,9 @@ var init_runtime_execution = __esm({
|
|
|
98211
98452
|
entryOrderId: fill.orderId,
|
|
98212
98453
|
filledSize: fill.filledSize,
|
|
98213
98454
|
averagePrice: fill.averagePrice,
|
|
98455
|
+
// One signed mutation carries every member (its first member's).
|
|
98456
|
+
mutationId: candidates[0].mutationId,
|
|
98457
|
+
createdAtMs: Date.now(),
|
|
98214
98458
|
members: candidates.map((candidate) => ({
|
|
98215
98459
|
kind: candidate.kind,
|
|
98216
98460
|
clientOrderId: candidate.clientOrderId,
|
|
@@ -98723,6 +98967,82 @@ var init_runtime_execution = __esm({
|
|
|
98723
98967
|
const endedAt = evidence.statusTimestampMs;
|
|
98724
98968
|
return placedAt != null && endedAt != null && endedAt > placedAt;
|
|
98725
98969
|
};
|
|
98970
|
+
ledgerOrderIdsByClientOrderId = (mutation) => {
|
|
98971
|
+
const orderIds = /* @__PURE__ */ new Map();
|
|
98972
|
+
const add = (clientOrderId, exchangeOrderId) => {
|
|
98973
|
+
const cloid = String(clientOrderId ?? "").trim().toLowerCase();
|
|
98974
|
+
const orderId = String(exchangeOrderId ?? "").trim();
|
|
98975
|
+
if (/^0x[0-9a-f]{32}$/.test(cloid) && /^[1-9]\d*$/.test(orderId) && Number.isSafeInteger(Number(orderId))) {
|
|
98976
|
+
orderIds.set(cloid, Number(orderId));
|
|
98977
|
+
}
|
|
98978
|
+
};
|
|
98979
|
+
add(mutation.client_order_id, mutation.exchange_order_id);
|
|
98980
|
+
for (const member of mutation.order_members ?? []) {
|
|
98981
|
+
add(member.client_order_id, member.exchange_order_id);
|
|
98982
|
+
}
|
|
98983
|
+
return orderIds;
|
|
98984
|
+
};
|
|
98985
|
+
journaledAttachmentNeverLanded = async (request, group) => {
|
|
98986
|
+
const journal = group.attachmentJournal;
|
|
98987
|
+
let ledgerOrderIds = /* @__PURE__ */ new Map();
|
|
98988
|
+
if (journal == null) return { group, proven: false, ledgerOrderIds };
|
|
98989
|
+
const observedAtMs = Date.now();
|
|
98990
|
+
const firstSeenAtMs = journal.unknownOidFirstSeenAtMs ?? observedAtMs;
|
|
98991
|
+
const waiting = (unknownOidObservedAtMs) => {
|
|
98992
|
+
if (journal.unknownOidFirstSeenAtMs != null && unknownOidObservedAtMs === void 0) {
|
|
98993
|
+
return { group, proven: false, ledgerOrderIds };
|
|
98994
|
+
}
|
|
98995
|
+
const recorded = {
|
|
98996
|
+
...group,
|
|
98997
|
+
attachmentJournal: {
|
|
98998
|
+
...journal,
|
|
98999
|
+
unknownOidFirstSeenAtMs: firstSeenAtMs,
|
|
99000
|
+
...unknownOidObservedAtMs !== void 0 ? { unknownOidObservedAtMs } : {}
|
|
99001
|
+
}
|
|
99002
|
+
};
|
|
99003
|
+
if (!replaceExactClientProtectiveGroup(
|
|
99004
|
+
String(request.profileId).trim(),
|
|
99005
|
+
request.executionContext.symbol,
|
|
99006
|
+
group,
|
|
99007
|
+
recorded
|
|
99008
|
+
)) {
|
|
99009
|
+
throw new Error("Journaled attachment recovery state could not be saved durably.");
|
|
99010
|
+
}
|
|
99011
|
+
return { group: recorded, proven: false, ledgerOrderIds };
|
|
99012
|
+
};
|
|
99013
|
+
const mutationId = journal.mutationId ?? mutationIdForClientOrderId(journal.members[0]?.clientOrderId ?? "");
|
|
99014
|
+
let provableAtMs;
|
|
99015
|
+
if (mutationId == null) {
|
|
99016
|
+
provableAtMs = clientOrderNeverLandsAfterMs(request.config, { kind: "absent", ageStartMs: firstSeenAtMs });
|
|
99017
|
+
} else {
|
|
99018
|
+
const ledger = await readClientOrderMutation(
|
|
99019
|
+
request,
|
|
99020
|
+
mutationId,
|
|
99021
|
+
clientOrderIdForMutation(mutationId)
|
|
99022
|
+
);
|
|
99023
|
+
if (ledger.kind === "found") {
|
|
99024
|
+
ledgerOrderIds = ledgerOrderIdsByClientOrderId(ledger.mutation);
|
|
99025
|
+
if (String(ledger.mutation.exchange_order_id ?? "").trim().length > 0) {
|
|
99026
|
+
return { group, proven: false, ledgerOrderIds };
|
|
99027
|
+
}
|
|
99028
|
+
const expiresAfterMs = Number(ledger.mutation.exchange_expires_after_ms);
|
|
99029
|
+
if (!Number.isSafeInteger(expiresAfterMs) || expiresAfterMs <= 0) return waiting();
|
|
99030
|
+
provableAtMs = clientOrderNeverLandsAfterMs(request.config, { kind: "found", expiresAfterMs });
|
|
99031
|
+
} else if (ledger.kind === "absent") {
|
|
99032
|
+
provableAtMs = clientOrderNeverLandsAfterMs(request.config, {
|
|
99033
|
+
kind: "absent",
|
|
99034
|
+
ageStartMs: journal.createdAtMs ?? firstSeenAtMs
|
|
99035
|
+
});
|
|
99036
|
+
} else {
|
|
99037
|
+
return waiting();
|
|
99038
|
+
}
|
|
99039
|
+
}
|
|
99040
|
+
if (observedAtMs < provableAtMs) return waiting();
|
|
99041
|
+
if (journal.unknownOidObservedAtMs == null || journal.unknownOidObservedAtMs < provableAtMs) {
|
|
99042
|
+
return waiting(observedAtMs);
|
|
99043
|
+
}
|
|
99044
|
+
return { group, proven: true, ledgerOrderIds };
|
|
99045
|
+
};
|
|
98726
99046
|
recoverJournaledClientProtectiveAttachments = async (request, journaledGroups) => {
|
|
98727
99047
|
const reports = [];
|
|
98728
99048
|
const profileId = String(request.profileId).trim();
|
|
@@ -98744,24 +99064,64 @@ var init_runtime_execution = __esm({
|
|
|
98744
99064
|
}
|
|
98745
99065
|
})));
|
|
98746
99066
|
}
|
|
98747
|
-
|
|
99067
|
+
const boundOrderIds = new Set(readClientProtectiveGroups(profileId, symbol2).flatMap((stored) => stored.legs.flatMap((leg) => typeof leg.orderId === "number" ? [String(leg.orderId)] : [])));
|
|
99068
|
+
for (const journaledGroup of journaledGroups) {
|
|
99069
|
+
let group = journaledGroup;
|
|
98748
99070
|
const plan = group.pendingEntry;
|
|
98749
|
-
|
|
99071
|
+
let journal = group.attachmentJournal;
|
|
98750
99072
|
if (plan == null || journal == null || group.legs.length === 0) continue;
|
|
98751
99073
|
const inspected = [];
|
|
98752
99074
|
let unresolved = false;
|
|
99075
|
+
let ledgerVerdict = null;
|
|
99076
|
+
const newlyNeverLanded = /* @__PURE__ */ new Set();
|
|
98753
99077
|
for (const provisionalLeg of group.legs) {
|
|
99078
|
+
if (attachmentMemberNeverLanded(group, provisionalLeg)) {
|
|
99079
|
+
inspected.push({ leg: provisionalLeg, state: "terminal", rested: false, neverLanded: true });
|
|
99080
|
+
continue;
|
|
99081
|
+
}
|
|
98754
99082
|
let openOrder = liveOrders.find((order) => String(order.oid) === String(provisionalLeg.orderId)) ?? null;
|
|
98755
99083
|
let canonicalLeg = provisionalLeg;
|
|
98756
99084
|
if (openOrder == null) {
|
|
98757
99085
|
try {
|
|
98758
|
-
|
|
99086
|
+
let evidence = await fetchBrowserOrderStatusEvidence({
|
|
98759
99087
|
publicRequestPriority: "trading_reconcile",
|
|
98760
99088
|
config: request.config ?? null,
|
|
98761
99089
|
walletAddress,
|
|
98762
99090
|
signal: request.signal,
|
|
98763
99091
|
orderId: provisionalLeg.orderId
|
|
98764
99092
|
});
|
|
99093
|
+
if (typeof provisionalLeg.orderId === "string" && evidence.responseValid && evidence.responseStatus === "unknownOid") {
|
|
99094
|
+
if (ledgerVerdict == null) {
|
|
99095
|
+
ledgerVerdict = await journaledAttachmentNeverLanded(request, group);
|
|
99096
|
+
group = ledgerVerdict.group;
|
|
99097
|
+
journal = group.attachmentJournal ?? journal;
|
|
99098
|
+
}
|
|
99099
|
+
const ledgerOrderId = ledgerVerdict.ledgerOrderIds.get(provisionalLeg.orderId);
|
|
99100
|
+
if (ledgerOrderId != null) {
|
|
99101
|
+
evidence = await fetchBrowserOrderStatusEvidence({
|
|
99102
|
+
publicRequestPriority: "trading_reconcile",
|
|
99103
|
+
config: request.config ?? null,
|
|
99104
|
+
walletAddress,
|
|
99105
|
+
signal: request.signal,
|
|
99106
|
+
orderId: ledgerOrderId
|
|
99107
|
+
});
|
|
99108
|
+
if (!evidence.responseValid || !evidence.orderMatches) {
|
|
99109
|
+
throw new Error("Journaled protective order identity is unresolved.");
|
|
99110
|
+
}
|
|
99111
|
+
} else {
|
|
99112
|
+
const mayRestUnseen = liveOrders.some((order) => !boundOrderIds.has(String(order.oid)) && protectiveLiveShapeMatches({
|
|
99113
|
+
shape: liveProtectiveOrderShape(order),
|
|
99114
|
+
symbol: symbol2,
|
|
99115
|
+
isLong: group.isLong,
|
|
99116
|
+
leg: provisionalLeg
|
|
99117
|
+
}));
|
|
99118
|
+
if (ledgerVerdict.proven && !mayRestUnseen) {
|
|
99119
|
+
newlyNeverLanded.add(provisionalLeg.orderId);
|
|
99120
|
+
inspected.push({ leg: provisionalLeg, state: "terminal", rested: false, neverLanded: true });
|
|
99121
|
+
continue;
|
|
99122
|
+
}
|
|
99123
|
+
}
|
|
99124
|
+
}
|
|
98765
99125
|
const resolvedOrderId = Number(evidence.orderId);
|
|
98766
99126
|
if (!Number.isSafeInteger(resolvedOrderId) || resolvedOrderId <= 0) {
|
|
98767
99127
|
throw new Error("Journaled protective order identity is unresolved.");
|
|
@@ -98829,6 +99189,28 @@ var init_runtime_execution = __esm({
|
|
|
98829
99189
|
inspected.push({ leg: canonicalLeg, state: "open" });
|
|
98830
99190
|
}
|
|
98831
99191
|
if (unresolved || inspected.length !== group.legs.length) continue;
|
|
99192
|
+
if (newlyNeverLanded.size > 0) {
|
|
99193
|
+
const neverLandedAtMs = Date.now();
|
|
99194
|
+
const proven = {
|
|
99195
|
+
...group,
|
|
99196
|
+
attachmentJournal: {
|
|
99197
|
+
...journal,
|
|
99198
|
+
members: journal.members.map((member) => newlyNeverLanded.has(member.clientOrderId) ? { ...member, neverLandedAtMs } : member)
|
|
99199
|
+
}
|
|
99200
|
+
};
|
|
99201
|
+
if (!replaceExactClientProtectiveGroup(profileId, symbol2, group, proven)) {
|
|
99202
|
+
reports.push({
|
|
99203
|
+
order_id: journal.entryOrderId,
|
|
99204
|
+
symbol: symbol2,
|
|
99205
|
+
action: "PROTECTIVE_RECONCILIATION",
|
|
99206
|
+
status: "failed",
|
|
99207
|
+
execution_metadata: { reason_code: "protective_lifecycle_persistence_failed" }
|
|
99208
|
+
});
|
|
99209
|
+
continue;
|
|
99210
|
+
}
|
|
99211
|
+
group = proven;
|
|
99212
|
+
journal = proven.attachmentJournal ?? journal;
|
|
99213
|
+
}
|
|
98832
99214
|
const hasFulfilled = inspected.some((entry) => entry.state === "fulfilled");
|
|
98833
99215
|
const hasNonfulfilledTerminal = inspected.some((entry) => entry.state === "terminal");
|
|
98834
99216
|
const openEntries = inspected.filter((entry) => entry.state === "open");
|
|
@@ -99073,6 +99455,47 @@ var init_runtime_execution = __esm({
|
|
|
99073
99455
|
});
|
|
99074
99456
|
continue;
|
|
99075
99457
|
}
|
|
99458
|
+
if (inspected.every((entry) => entry.neverLanded === true)) {
|
|
99459
|
+
let livePositionSize = Number.NaN;
|
|
99460
|
+
let positionError = null;
|
|
99461
|
+
try {
|
|
99462
|
+
livePositionSize = Number((await fetchBrowserPositionSnapshot(
|
|
99463
|
+
request.config ?? {},
|
|
99464
|
+
walletAddress,
|
|
99465
|
+
symbol2,
|
|
99466
|
+
request.signal,
|
|
99467
|
+
"trading_reconcile"
|
|
99468
|
+
)).size);
|
|
99469
|
+
} catch (error48) {
|
|
99470
|
+
if (request.signal?.aborted) throw error48;
|
|
99471
|
+
positionError = error48;
|
|
99472
|
+
}
|
|
99473
|
+
if (!Number.isFinite(livePositionSize)) {
|
|
99474
|
+
reports.push({
|
|
99475
|
+
order_id: journal.entryOrderId,
|
|
99476
|
+
symbol: symbol2,
|
|
99477
|
+
action: "PROTECTIVE_RECONCILIATION",
|
|
99478
|
+
status: "failed",
|
|
99479
|
+
execution_metadata: {
|
|
99480
|
+
reason_code: "protective_attachment_continuity_unresolved",
|
|
99481
|
+
error: getSanitizedRuntimeErrorMessage(positionError) || "Unable to verify live position exposure."
|
|
99482
|
+
}
|
|
99483
|
+
});
|
|
99484
|
+
continue;
|
|
99485
|
+
}
|
|
99486
|
+
if (!(group.isLong ? livePositionSize > 0 : livePositionSize < 0)) {
|
|
99487
|
+
if (!replaceExactClientProtectiveGroup(profileId, symbol2, group, null)) {
|
|
99488
|
+
reports.push({
|
|
99489
|
+
order_id: journal.entryOrderId,
|
|
99490
|
+
symbol: symbol2,
|
|
99491
|
+
action: "PROTECTIVE_RECONCILIATION",
|
|
99492
|
+
status: "failed",
|
|
99493
|
+
execution_metadata: { reason_code: "protective_lifecycle_persistence_failed" }
|
|
99494
|
+
});
|
|
99495
|
+
}
|
|
99496
|
+
continue;
|
|
99497
|
+
}
|
|
99498
|
+
}
|
|
99076
99499
|
let disposition;
|
|
99077
99500
|
try {
|
|
99078
99501
|
({ disposition } = await resolveJournaledAttachmentContinuity(
|
|
@@ -99114,20 +99537,35 @@ var init_runtime_execution = __esm({
|
|
|
99114
99537
|
}
|
|
99115
99538
|
return reports;
|
|
99116
99539
|
};
|
|
99117
|
-
|
|
99540
|
+
readClientOrderMutation = async (request, mutationId, clientOrderId) => {
|
|
99118
99541
|
try {
|
|
99119
99542
|
const mutation = await getClientRuntimeExchangeMutation(
|
|
99120
99543
|
request.profileId,
|
|
99121
|
-
|
|
99544
|
+
mutationId,
|
|
99122
99545
|
request.signal
|
|
99123
99546
|
);
|
|
99124
99547
|
if (mutation == null) return { kind: "absent" };
|
|
99125
|
-
return mutation.operation_kind === "order" && String(mutation.client_order_id ?? "").trim().toLowerCase() ===
|
|
99548
|
+
return mutation.operation_kind === "order" && String(mutation.client_order_id ?? "").trim().toLowerCase() === clientOrderId ? { kind: "found", mutation } : { kind: "unavailable" };
|
|
99126
99549
|
} catch (error48) {
|
|
99127
99550
|
if (request.signal?.aborted) throw error48;
|
|
99128
99551
|
return { kind: "unavailable" };
|
|
99129
99552
|
}
|
|
99130
99553
|
};
|
|
99554
|
+
readPendingEntryMutation = (request, plan) => readClientOrderMutation(request, plan.entryMutationId, plan.entryClientOrderId);
|
|
99555
|
+
clientOrderNeverLandsAfterMs = (config2, ledger) => {
|
|
99556
|
+
const marginMs = requireClientRuntimeConfigSeconds(
|
|
99557
|
+
config2,
|
|
99558
|
+
"client_pending_entry_never_landed_margin_seconds"
|
|
99559
|
+
) * MS_PER_SECOND;
|
|
99560
|
+
if (ledger.kind === "found") return ledger.expiresAfterMs + marginMs;
|
|
99561
|
+
const signedLifetimeSeconds = Number(
|
|
99562
|
+
config2?.client_runtime_exchange_mutation?.expires_after_seconds
|
|
99563
|
+
);
|
|
99564
|
+
if (!Number.isInteger(signedLifetimeSeconds) || signedLifetimeSeconds <= 0) {
|
|
99565
|
+
throw new Error("Missing required client runtime config: client_runtime_exchange_mutation.expires_after_seconds");
|
|
99566
|
+
}
|
|
99567
|
+
return ledger.ageStartMs + signedLifetimeSeconds * MS_PER_SECOND + marginMs;
|
|
99568
|
+
};
|
|
99131
99569
|
requireClientRuntimeConfigSeconds = (config2, key) => {
|
|
99132
99570
|
const value = Number(config2?.[key]);
|
|
99133
99571
|
if (!Number.isFinite(value) || value < 0) {
|
|
@@ -99268,10 +99706,6 @@ var init_runtime_execution = __esm({
|
|
|
99268
99706
|
});
|
|
99269
99707
|
if (evidence.responseValid && evidence.responseStatus === "unknownOid") {
|
|
99270
99708
|
const observedAtMs = Date.now();
|
|
99271
|
-
const marginMs = requireClientRuntimeConfigSeconds(
|
|
99272
|
-
request.config,
|
|
99273
|
-
"client_pending_entry_never_landed_margin_seconds"
|
|
99274
|
-
) * MS_PER_SECOND;
|
|
99275
99709
|
const firstSeenAtMs = plan.recovery?.unknownOidFirstSeenAtMs ?? observedAtMs;
|
|
99276
99710
|
const recordFirstSeen = () => {
|
|
99277
99711
|
if (plan.recovery?.unknownOidFirstSeenAtMs != null) return;
|
|
@@ -99286,16 +99720,12 @@ var init_runtime_execution = __esm({
|
|
|
99286
99720
|
if (!Number.isSafeInteger(expiresAfterMs) || expiresAfterMs <= 0) {
|
|
99287
99721
|
throw new Error("Pending entry is unknown to Hyperliquid and its signed expiry is unavailable.");
|
|
99288
99722
|
}
|
|
99289
|
-
provableAtMs = expiresAfterMs
|
|
99723
|
+
provableAtMs = clientOrderNeverLandsAfterMs(request.config, { kind: "found", expiresAfterMs });
|
|
99290
99724
|
} else if (ledger.kind === "absent") {
|
|
99291
|
-
|
|
99292
|
-
|
|
99293
|
-
|
|
99294
|
-
);
|
|
99295
|
-
if (!Number.isInteger(signedLifetimeSeconds) || signedLifetimeSeconds <= 0) {
|
|
99296
|
-
throw new Error("Missing required client runtime config: client_runtime_exchange_mutation.expires_after_seconds");
|
|
99297
|
-
}
|
|
99298
|
-
provableAtMs = ageStartMs + signedLifetimeSeconds * MS_PER_SECOND + marginMs;
|
|
99725
|
+
provableAtMs = clientOrderNeverLandsAfterMs(request.config, {
|
|
99726
|
+
kind: "absent",
|
|
99727
|
+
ageStartMs: plan.createdAtMs ?? firstSeenAtMs
|
|
99728
|
+
});
|
|
99299
99729
|
} else {
|
|
99300
99730
|
recordFirstSeen();
|
|
99301
99731
|
throw new Error("Pending entry is unknown to Hyperliquid and the ledger cannot answer.");
|
|
@@ -100138,37 +100568,16 @@ var init_runtime_execution = __esm({
|
|
|
100138
100568
|
}]
|
|
100139
100569
|
});
|
|
100140
100570
|
const observedAtMs = Date.now();
|
|
100141
|
-
const
|
|
100142
|
-
|
|
100143
|
-
"client_pending_entry_never_landed_margin_seconds"
|
|
100144
|
-
) * MS_PER_SECOND;
|
|
100145
|
-
let ledgerKind;
|
|
100146
|
-
let expiresAfterMs = Number.NaN;
|
|
100147
|
-
try {
|
|
100148
|
-
const mutation = await getClientRuntimeExchangeMutation(request.profileId, journal.mutationId, request.signal);
|
|
100149
|
-
if (mutation == null) {
|
|
100150
|
-
ledgerKind = "absent";
|
|
100151
|
-
} else if (mutation.operation_kind === "order" && String(mutation.client_order_id ?? "").trim().toLowerCase() === String(leg.orderId)) {
|
|
100152
|
-
ledgerKind = "found";
|
|
100153
|
-
expiresAfterMs = Number(mutation.exchange_expires_after_ms);
|
|
100154
|
-
} else {
|
|
100155
|
-
ledgerKind = "unavailable";
|
|
100156
|
-
}
|
|
100157
|
-
} catch (error48) {
|
|
100158
|
-
if (request.signal?.aborted) throw error48;
|
|
100159
|
-
ledgerKind = "unavailable";
|
|
100160
|
-
}
|
|
100571
|
+
const ledger = await readClientOrderMutation(request, journal.mutationId, String(leg.orderId));
|
|
100572
|
+
const expiresAfterMs = ledger.kind === "found" ? Number(ledger.mutation.exchange_expires_after_ms) : Number.NaN;
|
|
100161
100573
|
let provableAtMs;
|
|
100162
|
-
if (
|
|
100163
|
-
provableAtMs = expiresAfterMs
|
|
100164
|
-
} else if (
|
|
100165
|
-
|
|
100166
|
-
|
|
100167
|
-
|
|
100168
|
-
|
|
100169
|
-
throw new Error("Missing required client runtime config: client_runtime_exchange_mutation.expires_after_seconds");
|
|
100170
|
-
}
|
|
100171
|
-
provableAtMs = journal.createdAtMs + signedLifetimeSeconds * MS_PER_SECOND + marginMs;
|
|
100574
|
+
if (ledger.kind === "found" && Number.isSafeInteger(expiresAfterMs) && expiresAfterMs > 0) {
|
|
100575
|
+
provableAtMs = clientOrderNeverLandsAfterMs(request.config, { kind: "found", expiresAfterMs });
|
|
100576
|
+
} else if (ledger.kind === "absent") {
|
|
100577
|
+
provableAtMs = clientOrderNeverLandsAfterMs(request.config, {
|
|
100578
|
+
kind: "absent",
|
|
100579
|
+
ageStartMs: journal.createdAtMs
|
|
100580
|
+
});
|
|
100172
100581
|
} else {
|
|
100173
100582
|
return waiting("protective_stop_replacement_unresolved", "The stop re-place ledger cannot answer yet.");
|
|
100174
100583
|
}
|
|
@@ -101643,7 +102052,64 @@ var init_runtime_execution = __esm({
|
|
|
101643
102052
|
const parsed = Number(position?.size ?? 0);
|
|
101644
102053
|
return Number.isFinite(parsed) ? parsed : 0;
|
|
101645
102054
|
};
|
|
101646
|
-
|
|
102055
|
+
readServerOrderMarkPrice = async (input) => {
|
|
102056
|
+
const symbol2 = normalizeHyperliquidMarketSymbol(input.executionContext.symbol);
|
|
102057
|
+
const active = await fetchBrowserHyperliquidInfoPayload(
|
|
102058
|
+
{ config: input.config ?? null, signal: input.signal, publicRequestPriority: executionReadPriority(input) },
|
|
102059
|
+
{ type: "activeAssetData", user: String(input.executionContext.walletAddress || "").trim(), coin: symbol2 },
|
|
102060
|
+
"hyperliquid.activeAssetData"
|
|
102061
|
+
);
|
|
102062
|
+
const markPrice = Number(active?.markPx);
|
|
102063
|
+
if (!Number.isFinite(markPrice) || !(markPrice > 0)) {
|
|
102064
|
+
throw new Error(`Missing Hyperliquid mark price for ${input.executionContext.symbol}.`);
|
|
102065
|
+
}
|
|
102066
|
+
return markPrice;
|
|
102067
|
+
};
|
|
102068
|
+
serverOrderMetadataRetry = async (input, rejection, leg, rejectedMutationId) => {
|
|
102069
|
+
const decisionSnapshotId = String(input.executionContext.decisionSnapshotId ?? "").trim();
|
|
102070
|
+
if (input.executionMode !== "server" || !decisionSnapshotId || !isDefinitiveEntryRejection(rejection, rejectedMutationId)) return null;
|
|
102071
|
+
const reason = orderMetadataRetryReason(rejection.message);
|
|
102072
|
+
if (reason === null) return null;
|
|
102073
|
+
throwIfAborted2(input.signal);
|
|
102074
|
+
try {
|
|
102075
|
+
const asset = await resolveHyperliquidAsset({
|
|
102076
|
+
symbol: input.executionContext.symbol,
|
|
102077
|
+
config: input.config ?? void 0,
|
|
102078
|
+
publicRequestPriority: executionReadPriority(input),
|
|
102079
|
+
refreshCatalog: true
|
|
102080
|
+
});
|
|
102081
|
+
if (!Number.isInteger(asset.sz_decimals) || asset.sz_decimals < 0) return null;
|
|
102082
|
+
const markPrice = reason === "reference_price" ? await readServerOrderMarkPrice(input) : null;
|
|
102083
|
+
appendRuntimeDebugEvent({
|
|
102084
|
+
label: "execution_order_metadata_retry",
|
|
102085
|
+
note: `symbol=${input.executionContext.symbol} leg=${leg} reason=${reason}`
|
|
102086
|
+
});
|
|
102087
|
+
return {
|
|
102088
|
+
mutationId: await clientDecisionMutationId({
|
|
102089
|
+
profileId: input.profileId,
|
|
102090
|
+
decisionSnapshotId,
|
|
102091
|
+
symbol: input.executionContext.symbol,
|
|
102092
|
+
leg,
|
|
102093
|
+
attempt: 1
|
|
102094
|
+
}),
|
|
102095
|
+
assets: [{
|
|
102096
|
+
symbol: input.executionContext.symbol,
|
|
102097
|
+
asset_id: asset.asset_index,
|
|
102098
|
+
asset_index: asset.asset_index,
|
|
102099
|
+
max_leverage: asset.max_leverage,
|
|
102100
|
+
sz_decimals: asset.sz_decimals,
|
|
102101
|
+
margin_mode: asset.margin_mode ?? null,
|
|
102102
|
+
only_isolated: asset.only_isolated === true
|
|
102103
|
+
}],
|
|
102104
|
+
sizeDecimals: asset.sz_decimals,
|
|
102105
|
+
markPrice
|
|
102106
|
+
};
|
|
102107
|
+
} catch {
|
|
102108
|
+
throwIfAborted2(input.signal);
|
|
102109
|
+
return null;
|
|
102110
|
+
}
|
|
102111
|
+
};
|
|
102112
|
+
resolveCurrentPositionSize = async (input, orderPrice = "decision") => {
|
|
101647
102113
|
throwIfAborted2(input.signal);
|
|
101648
102114
|
const snapshotPositionSize = Number.isFinite(input.executionContext.currentPositionSize) ? Number(input.executionContext.currentPositionSize) : 0;
|
|
101649
102115
|
const decisionPrice = Number.isFinite(input.executionContext.lastPrice) ? Number(input.executionContext.lastPrice) : 0;
|
|
@@ -101655,7 +102121,7 @@ var init_runtime_execution = __esm({
|
|
|
101655
102121
|
const decisionCapturedAtMs = Date.parse(String(input.executionContext.decisionSnapshotCapturedAt || ""));
|
|
101656
102122
|
const maxAgeSeconds = Number(input.executionContext.executionFreshnessMaxAgeSeconds);
|
|
101657
102123
|
const shouldRefreshExecutionSnapshot = Number.isFinite(decisionCapturedAtMs) && Number.isFinite(maxAgeSeconds) && maxAgeSeconds > 0 && (nowMs2 - decisionCapturedAtMs) / MS_PER_SECOND > maxAgeSeconds;
|
|
101658
|
-
if (shouldRefreshExecutionSnapshot) {
|
|
102124
|
+
if (shouldRefreshExecutionSnapshot && orderPrice !== "fresh_mark") {
|
|
101659
102125
|
try {
|
|
101660
102126
|
const refreshed = await fetchBrowserAccountState2({
|
|
101661
102127
|
publicRequestPriority: executionReadPriority(input),
|
|
@@ -101698,10 +102164,12 @@ var init_runtime_execution = __esm({
|
|
|
101698
102164
|
symbol: input.executionContext.symbol,
|
|
101699
102165
|
size: liveBrowserSnapshot.size
|
|
101700
102166
|
});
|
|
102167
|
+
const liveMarkPrice = Number(liveBrowserSnapshot.markPrice);
|
|
102168
|
+
const executionPrice = orderPrice !== "fresh_mark" ? decisionPrice : parsedLiveSize !== 0 && Number.isFinite(liveMarkPrice) && liveMarkPrice > 0 ? liveMarkPrice : await readServerOrderMarkPrice(input);
|
|
101701
102169
|
return {
|
|
101702
102170
|
currentPositionSize: Number.isFinite(parsedLiveSize) ? parsedLiveSize : snapshotPositionSize,
|
|
101703
102171
|
currentPositionEntryPrice: liveBrowserSnapshot.entryPrice,
|
|
101704
|
-
executionPrice
|
|
102172
|
+
executionPrice,
|
|
101705
102173
|
executionSnapshotId: createRuntimeId(),
|
|
101706
102174
|
executionSnapshotCapturedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
101707
102175
|
};
|
|
@@ -101902,9 +102370,30 @@ var init_runtime_execution = __esm({
|
|
|
101902
102370
|
try {
|
|
101903
102371
|
return await executeClientRuntimeDecisionUnlocked(input, progress);
|
|
101904
102372
|
} catch (error48) {
|
|
101905
|
-
throw withCommittedExecutionReports(error48, progress.committedReports);
|
|
102373
|
+
throw withCommittedExecutionReports(error48, progress.committedReports, progress.committedOrder ?? null);
|
|
102374
|
+
}
|
|
102375
|
+
});
|
|
102376
|
+
unsentDecisionOrderReport = (input, reasonCode, metadata = {}) => ({
|
|
102377
|
+
order_id: null,
|
|
102378
|
+
symbol: input.executionContext.symbol,
|
|
102379
|
+
action: String(input.decision).toUpperCase(),
|
|
102380
|
+
status: "blocked",
|
|
102381
|
+
execution_metadata: {
|
|
102382
|
+
reason_code: reasonCode,
|
|
102383
|
+
...metadata,
|
|
102384
|
+
...input.cycleId ? { cycle_id: input.cycleId } : {},
|
|
102385
|
+
...input.executionContext.decisionSnapshotId ? { decision_snapshot_id: input.executionContext.decisionSnapshotId } : {}
|
|
101906
102386
|
}
|
|
101907
102387
|
});
|
|
102388
|
+
withCapacityTrim = (result, trim) => {
|
|
102389
|
+
const decisionOrders = result.executionReports.filter((report) => report.status === "executed" && (report.action === "BUY" || report.action === "SELL") && (result.intent !== "flip" || report.execution_metadata?.decision_leg === "entry"));
|
|
102390
|
+
const trimmed = decisionOrders[decisionOrders.length - 1];
|
|
102391
|
+
if (!trimmed) return result;
|
|
102392
|
+
return {
|
|
102393
|
+
...result,
|
|
102394
|
+
executionReports: result.executionReports.map((report) => report === trimmed ? { ...report, execution_metadata: { ...report.execution_metadata, ...trim } } : report)
|
|
102395
|
+
};
|
|
102396
|
+
};
|
|
101908
102397
|
SERVER_AUDIT_RECORDED_ELSEWHERE = /* @__PURE__ */ new Set([
|
|
101909
102398
|
"suppressed_duplicate_decision",
|
|
101910
102399
|
"same_intent_cooldown",
|
|
@@ -101918,7 +102407,7 @@ var init_runtime_execution = __esm({
|
|
|
101918
102407
|
return ["executed", "executed"];
|
|
101919
102408
|
}
|
|
101920
102409
|
if (result.status === "skipped") {
|
|
101921
|
-
if (result.reasonCode === "noop_already_at_target" || result.reasonCode === "stale_target_conflict") {
|
|
102410
|
+
if (result.reasonCode === "noop_already_at_target" || result.reasonCode === "stale_target_conflict" || result.reasonCode === "order_below_lot_size") {
|
|
101922
102411
|
return ["noop", result.reasonCode];
|
|
101923
102412
|
}
|
|
101924
102413
|
if (result.reasonCode === "protective_reconciliation_unresolved") return ["blocked", result.reasonCode];
|
|
@@ -101938,6 +102427,7 @@ var init_runtime_execution = __esm({
|
|
|
101938
102427
|
if (input.executionMode !== "server") return executeClientRuntimeDecisionLocked(input);
|
|
101939
102428
|
const audit = input.serverExecutionAudit ?? { auditId: null };
|
|
101940
102429
|
let entryDispatched = false;
|
|
102430
|
+
let exitDispatched = false;
|
|
101941
102431
|
const recordAudit = async (auditId2, fields, signal = input.signal) => {
|
|
101942
102432
|
try {
|
|
101943
102433
|
const recorded = await recordServerHostExecutionAudit(
|
|
@@ -101974,13 +102464,15 @@ var init_runtime_execution = __esm({
|
|
|
101974
102464
|
onExchangeOrderDispatched: (kind) => {
|
|
101975
102465
|
input.onExchangeOrderDispatched?.(kind);
|
|
101976
102466
|
if (kind === "entry") entryDispatched = true;
|
|
102467
|
+
if (kind === "exit") exitDispatched = true;
|
|
101977
102468
|
}
|
|
101978
102469
|
});
|
|
101979
102470
|
} catch (error48) {
|
|
101980
102471
|
const committedClose = getCommittedExecutionReports(error48).find((report) => report.status === "executed" && decisionLegOf(report) === "flip_close");
|
|
101981
102472
|
if (audit.auditId !== null && (!input.signal?.aborted || committedClose) && (input.decision === "BUY" || input.decision === "SELL")) {
|
|
101982
102473
|
const reason = String(error48?.reasonCode ?? "");
|
|
101983
|
-
const
|
|
102474
|
+
const orderMayHaveGoneOut = entryDispatched || exitDispatched && !committedClose;
|
|
102475
|
+
const [status2, reasonCode2] = reason === "outcome_unknown" || !reason && orderMayHaveGoneOut ? ["outcome_unknown", "outcome_unknown"] : ["error", reason === "exchange_rejected" ? "exchange_rejected" : "execution_error"];
|
|
101984
102476
|
const side = input.decision === "BUY" ? "buy" : "sell";
|
|
101985
102477
|
if (committedClose) {
|
|
101986
102478
|
await recordAudit(audit.auditId, {
|
|
@@ -102038,7 +102530,7 @@ var init_runtime_execution = __esm({
|
|
|
102038
102530
|
reasonCode: blockedByProtection ? "protective_reconciliation_unresolved" : "executed",
|
|
102039
102531
|
orderId: flipClose.order_id == null ? null : String(flipClose.order_id)
|
|
102040
102532
|
});
|
|
102041
|
-
const [entryStatus, entryReason] = entryReport ? ["executed", "executed"] : blockedByProtection ? ["blocked", "protective_reconciliation_unresolved"] : result.reasonCode === "noop_already_at_target" ? ["noop",
|
|
102533
|
+
const [entryStatus, entryReason] = entryReport ? ["executed", "executed"] : blockedByProtection ? ["blocked", "protective_reconciliation_unresolved"] : result.reasonCode === "noop_already_at_target" || result.reasonCode === "order_below_lot_size" ? ["noop", result.reasonCode] : ["blocked", "local_safety_block"];
|
|
102042
102534
|
const entryAuditId = await recordAudit(null, {
|
|
102043
102535
|
...auditFields,
|
|
102044
102536
|
status: entryStatus,
|
|
@@ -102457,12 +102949,18 @@ var init_runtime_execution = __esm({
|
|
|
102457
102949
|
return !input.skipTrailingMaintenance && context.tpSlEnabled === true && context.stopLossEnabled !== false && context.stopLossType === "trailing" && positionSize !== 0;
|
|
102458
102950
|
};
|
|
102459
102951
|
COMMITTED_EXECUTION_REPORTS = /* @__PURE__ */ Symbol("committedExecutionReports");
|
|
102952
|
+
COMMITTED_DECISION_ORDER = /* @__PURE__ */ Symbol("committedDecisionOrder");
|
|
102460
102953
|
getCommittedExecutionReports = (error48) => {
|
|
102461
102954
|
if (!error48 || typeof error48 !== "object") return [];
|
|
102462
102955
|
const reports = error48[COMMITTED_EXECUTION_REPORTS];
|
|
102463
102956
|
return Array.isArray(reports) ? reports : [];
|
|
102464
102957
|
};
|
|
102465
|
-
|
|
102958
|
+
getCommittedDecisionOrder = (error48) => {
|
|
102959
|
+
if (!error48 || typeof error48 !== "object") return null;
|
|
102960
|
+
const order = error48[COMMITTED_DECISION_ORDER];
|
|
102961
|
+
return order && typeof order === "object" ? order : null;
|
|
102962
|
+
};
|
|
102963
|
+
withCommittedExecutionReports = (error48, reports, order = null) => {
|
|
102466
102964
|
if (!reports || !reports.some((report) => report.status === "executed")) return error48;
|
|
102467
102965
|
const carrier = error48 && typeof error48 === "object" ? error48 : new Error(String(error48 ?? "Unknown runtime execution error."), { cause: error48 });
|
|
102468
102966
|
Object.defineProperty(carrier, COMMITTED_EXECUTION_REPORTS, {
|
|
@@ -102470,6 +102968,11 @@ var init_runtime_execution = __esm({
|
|
|
102470
102968
|
enumerable: false,
|
|
102471
102969
|
configurable: true
|
|
102472
102970
|
});
|
|
102971
|
+
Object.defineProperty(carrier, COMMITTED_DECISION_ORDER, {
|
|
102972
|
+
value: order,
|
|
102973
|
+
enumerable: false,
|
|
102974
|
+
configurable: true
|
|
102975
|
+
});
|
|
102473
102976
|
return carrier;
|
|
102474
102977
|
};
|
|
102475
102978
|
executeClientRuntimeDecisionUnlocked = async (unsizedInput, progress = { committedReports: null }) => {
|
|
@@ -102499,7 +103002,7 @@ var init_runtime_execution = __esm({
|
|
|
102499
103002
|
};
|
|
102500
103003
|
}
|
|
102501
103004
|
if (unsizedInput.executionMode === "server" && !unsizedInput.serverCapacityChecked && (unsizedInput.decision === "BUY" || unsizedInput.decision === "SELL") && requestedUnits > 0) {
|
|
102502
|
-
const skipped = (reasonCode,
|
|
103005
|
+
const skipped = (reasonCode, constraintReasonCode) => ({
|
|
102503
103006
|
status: "skipped",
|
|
102504
103007
|
intent: "hold",
|
|
102505
103008
|
side: null,
|
|
@@ -102507,8 +103010,13 @@ var init_runtime_execution = __esm({
|
|
|
102507
103010
|
requestedUnits,
|
|
102508
103011
|
targetSignedUnits: 0,
|
|
102509
103012
|
executedSizeAsset: 0,
|
|
102510
|
-
|
|
102511
|
-
|
|
103013
|
+
// The decision keeps its order; this record says it was not placed and
|
|
103014
|
+
// which limit refused it.
|
|
103015
|
+
executionReports: [unsentDecisionOrderReport(unsizedInput, reasonCode, {
|
|
103016
|
+
constraint_reason_code: constraintReasonCode,
|
|
103017
|
+
requested_units: requestedUnits
|
|
103018
|
+
})],
|
|
103019
|
+
message: `Skipped: runtime constraint ${constraintReasonCode}.`,
|
|
102512
103020
|
reasonCode,
|
|
102513
103021
|
executionSnapshotId: createRuntimeId(),
|
|
102514
103022
|
executionSnapshotCapturedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
@@ -102526,13 +103034,19 @@ var init_runtime_execution = __esm({
|
|
|
102526
103034
|
note: `symbol=${unsizedInput.executionContext.symbol} reason=${capacity.reason_code ?? "unknown"}`,
|
|
102527
103035
|
outcome: "ok"
|
|
102528
103036
|
});
|
|
102529
|
-
return skipped("execution_capacity_refused",
|
|
103037
|
+
return skipped("execution_capacity_refused", capacity.reason_code ?? "capacity_reached");
|
|
102530
103038
|
}
|
|
102531
|
-
|
|
103039
|
+
const acceptedUnits = Math.min(requestedUnits, Math.trunc(capacity.units));
|
|
103040
|
+
const result = await executeClientRuntimeDecisionUnlocked({
|
|
102532
103041
|
...unsizedInput,
|
|
102533
|
-
units:
|
|
103042
|
+
units: acceptedUnits,
|
|
102534
103043
|
serverCapacityChecked: true
|
|
102535
103044
|
}, progress);
|
|
103045
|
+
return acceptedUnits < requestedUnits ? withCapacityTrim(result, {
|
|
103046
|
+
requested_units: requestedUnits,
|
|
103047
|
+
accepted_units: acceptedUnits,
|
|
103048
|
+
constraint_reason_code: capacity.reason_code ?? "units_capped"
|
|
103049
|
+
}) : result;
|
|
102536
103050
|
}
|
|
102537
103051
|
const input = {
|
|
102538
103052
|
...unsizedInput,
|
|
@@ -102624,13 +103138,15 @@ var init_runtime_execution = __esm({
|
|
|
102624
103138
|
executionSnapshotCapturedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
102625
103139
|
};
|
|
102626
103140
|
}
|
|
103141
|
+
const serverOrder = input.executionMode === "server";
|
|
102627
103142
|
const {
|
|
102628
103143
|
currentPositionSize,
|
|
102629
103144
|
currentPositionEntryPrice,
|
|
102630
|
-
executionPrice,
|
|
103145
|
+
executionPrice: resolvedExecutionPrice,
|
|
102631
103146
|
executionSnapshotId,
|
|
102632
103147
|
executionSnapshotCapturedAt
|
|
102633
|
-
} = await resolveCurrentPositionSize(input);
|
|
103148
|
+
} = await resolveCurrentPositionSize(input, serverOrder ? "fresh_mark" : "decision");
|
|
103149
|
+
let executionPrice = resolvedExecutionPrice;
|
|
102634
103150
|
throwIfAborted2(input.signal);
|
|
102635
103151
|
const currentPosition = buildPositionSnapshot(input.executionContext.symbol, currentPositionSize);
|
|
102636
103152
|
const decisionSnapshotId = String(input.executionContext.decisionSnapshotId ?? "").trim();
|
|
@@ -102641,6 +103157,15 @@ var init_runtime_execution = __esm({
|
|
|
102641
103157
|
leg,
|
|
102642
103158
|
attempt: 0
|
|
102643
103159
|
}) : Promise.resolve(void 0);
|
|
103160
|
+
const closeWithServerMetadataRetry = async (leg, mutationId, send) => {
|
|
103161
|
+
try {
|
|
103162
|
+
return await send(mutationId, executionPrice);
|
|
103163
|
+
} catch (rejection) {
|
|
103164
|
+
const retry = await serverOrderMetadataRetry(input, rejection, leg, mutationId);
|
|
103165
|
+
if (retry === null) throw rejection;
|
|
103166
|
+
return send(retry.mutationId, retry.markPrice ?? executionPrice, retry.assets);
|
|
103167
|
+
}
|
|
103168
|
+
};
|
|
102644
103169
|
const liveSignedUnits = signedUnitsFromEntryPosition(
|
|
102645
103170
|
currentPositionSize,
|
|
102646
103171
|
currentPositionEntryPrice,
|
|
@@ -102691,7 +103216,12 @@ var init_runtime_execution = __esm({
|
|
|
102691
103216
|
requestedUnits: classified.requestedUnits,
|
|
102692
103217
|
targetSignedUnits: classified.targetSignedUnits,
|
|
102693
103218
|
executedSizeAsset: 0,
|
|
102694
|
-
|
|
103219
|
+
// A Server bot's skip is its execution audit row; a Client bot's is this record.
|
|
103220
|
+
executionReports: input.executionMode === "server" ? reconciliationReports : [...reconciliationReports, unsentDecisionOrderReport(
|
|
103221
|
+
input,
|
|
103222
|
+
staleTargetConflict ? "stale_target_conflict" : "noop_already_at_target",
|
|
103223
|
+
{ intent: classified.intent }
|
|
103224
|
+
)],
|
|
102695
103225
|
message: staleTargetConflict ? "Live state moved beyond the requested target; skipping stale decision" : "No-op: live position already matches target state",
|
|
102696
103226
|
reasonCode: staleTargetConflict ? "stale_target_conflict" : "noop_already_at_target",
|
|
102697
103227
|
executionSnapshotId,
|
|
@@ -102827,8 +103357,9 @@ var init_runtime_execution = __esm({
|
|
|
102827
103357
|
if (classified.intent === "close") {
|
|
102828
103358
|
throwIfAborted2(input.signal);
|
|
102829
103359
|
const closeMutationId = await decisionLegMutationId("close");
|
|
102830
|
-
const closeResponse = await executeClientClosePosition({
|
|
102831
|
-
mutationId
|
|
103360
|
+
const closeResponse = await closeWithServerMetadataRetry("close", closeMutationId, (mutationId, estimatedPrice, assets) => executeClientClosePosition({
|
|
103361
|
+
mutationId,
|
|
103362
|
+
...assets ? { assets } : {},
|
|
102832
103363
|
profileId: input.profileId,
|
|
102833
103364
|
runtimeSessionId: input.sessionId || "__missing_runtime_session__",
|
|
102834
103365
|
runtimeLeaseToken: input.runtimeLeaseToken,
|
|
@@ -102838,20 +103369,42 @@ var init_runtime_execution = __esm({
|
|
|
102838
103369
|
config: input.config ?? null,
|
|
102839
103370
|
signal: input.signal,
|
|
102840
103371
|
signingKey: input.signingKey,
|
|
102841
|
-
onExchangeOrderDispatched: () => input.onExchangeOrderDispatched?.("
|
|
103372
|
+
onExchangeOrderDispatched: () => input.onExchangeOrderDispatched?.("exit"),
|
|
102842
103373
|
symbol: input.executionContext.symbol,
|
|
102843
103374
|
position: currentPosition,
|
|
102844
|
-
estimatedPrice
|
|
103375
|
+
estimatedPrice,
|
|
102845
103376
|
slippage: input.executionContext.maxSlippageFraction
|
|
102846
|
-
});
|
|
103377
|
+
}));
|
|
102847
103378
|
const confirmedClose = extractCanonicalHyperliquidFilledOrderAcknowledgement(
|
|
102848
103379
|
closeResponse
|
|
102849
103380
|
);
|
|
102850
103381
|
const expectedCloseSize = Math.abs(currentPositionSize);
|
|
102851
103382
|
const closeTolerance = Math.max(expectedCloseSize, 1) * Number.EPSILON * CLIENT_CLOSE_FILL_EPSILON_ULPS;
|
|
102852
103383
|
const closeFillConfirmed = confirmedClose != null && Math.abs(confirmedClose.filledSize - expectedCloseSize) <= closeTolerance;
|
|
103384
|
+
const closeReport = {
|
|
103385
|
+
order_id: _extractOrderId(closeResponse),
|
|
103386
|
+
client_mutation_id: _extractClientMutationId(closeResponse),
|
|
103387
|
+
symbol: input.executionContext.symbol,
|
|
103388
|
+
action: classified.side.toUpperCase(),
|
|
103389
|
+
status: "executed",
|
|
103390
|
+
execution_metadata: _toExecutionMetadata(closeResponse)
|
|
103391
|
+
};
|
|
103392
|
+
const committedCloseReports = [...reconciliationReports, closeReport];
|
|
103393
|
+
progress.committedReports = committedCloseReports;
|
|
103394
|
+
const recordPostCloseReports = (reports) => {
|
|
103395
|
+
reconciliationReports.push(...reports);
|
|
103396
|
+
committedCloseReports.push(...reports);
|
|
103397
|
+
};
|
|
103398
|
+
progress.committedOrder = {
|
|
103399
|
+
intent: classified.intent,
|
|
103400
|
+
side: classified.side,
|
|
103401
|
+
reduceOnly: classified.reduceOnly,
|
|
103402
|
+
requestedUnits: classified.requestedUnits,
|
|
103403
|
+
targetSignedUnits: classified.targetSignedUnits,
|
|
103404
|
+
executedSizeAsset: confirmedClose?.filledSize ?? 0
|
|
103405
|
+
};
|
|
102853
103406
|
if (closeFillConfirmed) {
|
|
102854
|
-
|
|
103407
|
+
recordPostCloseReports(await cancelAllClientProtectiveGroups(
|
|
102855
103408
|
input,
|
|
102856
103409
|
"position_closed"
|
|
102857
103410
|
));
|
|
@@ -102862,7 +103415,7 @@ var init_runtime_execution = __esm({
|
|
|
102862
103415
|
[]
|
|
102863
103416
|
);
|
|
102864
103417
|
} else if (hasTrackedProtection) {
|
|
102865
|
-
|
|
103418
|
+
recordPostCloseReports(await reconcileClientProtectiveGroups(
|
|
102866
103419
|
input,
|
|
102867
103420
|
confirmedClose == null ? void 0 : signedRemainingExposureAfterConfirmedReduction(
|
|
102868
103421
|
currentPositionSize,
|
|
@@ -102878,17 +103431,7 @@ var init_runtime_execution = __esm({
|
|
|
102878
103431
|
requestedUnits: classified.requestedUnits,
|
|
102879
103432
|
targetSignedUnits: classified.targetSignedUnits,
|
|
102880
103433
|
executedSizeAsset: confirmedClose?.filledSize ?? 0,
|
|
102881
|
-
executionReports: [
|
|
102882
|
-
...reconciliationReports,
|
|
102883
|
-
{
|
|
102884
|
-
order_id: _extractOrderId(closeResponse),
|
|
102885
|
-
client_mutation_id: _extractClientMutationId(closeResponse),
|
|
102886
|
-
symbol: input.executionContext.symbol,
|
|
102887
|
-
action: classified.side.toUpperCase(),
|
|
102888
|
-
status: "executed",
|
|
102889
|
-
execution_metadata: _toExecutionMetadata(closeResponse)
|
|
102890
|
-
}
|
|
102891
|
-
],
|
|
103434
|
+
executionReports: [...reconciliationReports, closeReport],
|
|
102892
103435
|
message: closeFillConfirmed ? "Closed position" : "The close order did not confirm the full position size; retained trailing protection for any remaining exposure.",
|
|
102893
103436
|
...closeFillConfirmed ? {} : { reasonCode: "close_fill_unresolved" },
|
|
102894
103437
|
executionSnapshotId,
|
|
@@ -102902,8 +103445,9 @@ var init_runtime_execution = __esm({
|
|
|
102902
103445
|
if (targetResolution.closeOpposingPosition) {
|
|
102903
103446
|
throwIfAborted2(input.signal);
|
|
102904
103447
|
const flipCloseMutationId = await decisionLegMutationId("flip_close");
|
|
102905
|
-
const closeResponse = await executeClientClosePosition({
|
|
102906
|
-
mutationId
|
|
103448
|
+
const closeResponse = await closeWithServerMetadataRetry("flip_close", flipCloseMutationId, (mutationId, estimatedPrice, assets) => executeClientClosePosition({
|
|
103449
|
+
mutationId,
|
|
103450
|
+
...assets ? { assets } : {},
|
|
102907
103451
|
profileId: input.profileId,
|
|
102908
103452
|
runtimeSessionId: input.sessionId || "__missing_runtime_session__",
|
|
102909
103453
|
runtimeLeaseToken: input.runtimeLeaseToken,
|
|
@@ -102913,12 +103457,12 @@ var init_runtime_execution = __esm({
|
|
|
102913
103457
|
config: input.config ?? null,
|
|
102914
103458
|
signal: input.signal,
|
|
102915
103459
|
signingKey: input.signingKey,
|
|
102916
|
-
onExchangeOrderDispatched: () => input.onExchangeOrderDispatched?.("
|
|
103460
|
+
onExchangeOrderDispatched: () => input.onExchangeOrderDispatched?.("exit"),
|
|
102917
103461
|
symbol: input.executionContext.symbol,
|
|
102918
103462
|
position: currentPosition,
|
|
102919
|
-
estimatedPrice
|
|
103463
|
+
estimatedPrice,
|
|
102920
103464
|
slippage: input.executionContext.maxSlippageFraction
|
|
102921
|
-
});
|
|
103465
|
+
}));
|
|
102922
103466
|
const confirmedFlipClose = extractCanonicalHyperliquidFilledOrderAcknowledgement(
|
|
102923
103467
|
closeResponse
|
|
102924
103468
|
);
|
|
@@ -103037,6 +103581,7 @@ var init_runtime_execution = __esm({
|
|
|
103037
103581
|
isCross: input.executionContext.marginMode !== "isolated"
|
|
103038
103582
|
});
|
|
103039
103583
|
throwIfAborted2(input.signal);
|
|
103584
|
+
if (serverOrder) executionPrice = await readServerOrderMarkPrice(input);
|
|
103040
103585
|
}
|
|
103041
103586
|
const actualUnits = targetResolution.orderUnits;
|
|
103042
103587
|
const intendedSizeAsset = decisionOrderSizeAsset({
|
|
@@ -103047,7 +103592,7 @@ var init_runtime_execution = __esm({
|
|
|
103047
103592
|
entryPrice: currentPositionEntryPrice,
|
|
103048
103593
|
livePositionSize: currentPositionSize
|
|
103049
103594
|
});
|
|
103050
|
-
|
|
103595
|
+
let sizeAsset = Number.isFinite(intendedSizeAsset) && intendedSizeAsset > 0 ? quantizeHyperliquidOrderSizeValue(intendedSizeAsset, input.executionContext.sizeDecimals, "nearest") : 0;
|
|
103051
103596
|
appendRuntimeDebugEvent({
|
|
103052
103597
|
label: "execution_size_computed",
|
|
103053
103598
|
note: `symbol=${input.executionContext.symbol} actualUnits=${actualUnits} sizeAsset=${sizeAsset} price=${executionPrice}`
|
|
@@ -103055,7 +103600,7 @@ var init_runtime_execution = __esm({
|
|
|
103055
103600
|
if (sizeAsset <= 0) {
|
|
103056
103601
|
appendRuntimeDebugEvent({
|
|
103057
103602
|
label: "execution_skipped_zero_size",
|
|
103058
|
-
note: `reason=
|
|
103603
|
+
note: `reason=order_below_lot_size actualUnits=${actualUnits} unitSize=${input.executionContext.unitSizeUsdc} intendedSize=${intendedSizeAsset} decimals=${input.executionContext.sizeDecimals}`,
|
|
103059
103604
|
outcome: "error"
|
|
103060
103605
|
});
|
|
103061
103606
|
return {
|
|
@@ -103067,13 +103612,27 @@ var init_runtime_execution = __esm({
|
|
|
103067
103612
|
requestedUnits: classified.requestedUnits,
|
|
103068
103613
|
targetSignedUnits: classified.targetSignedUnits,
|
|
103069
103614
|
executedSizeAsset: 0,
|
|
103070
|
-
|
|
103615
|
+
// Too small to place is not "already at target": it has its own reason,
|
|
103616
|
+
// on a Server bot's audit row and on a Client bot's record.
|
|
103617
|
+
executionReports: input.executionMode === "server" ? executionReports : [...executionReports, unsentDecisionOrderReport(input, "order_below_lot_size", { intent: classified.intent })],
|
|
103071
103618
|
message: "Skipped: calculated size is zero",
|
|
103072
|
-
reasonCode: "
|
|
103619
|
+
reasonCode: "order_below_lot_size",
|
|
103073
103620
|
executionSnapshotId,
|
|
103074
103621
|
executionSnapshotCapturedAt
|
|
103075
103622
|
};
|
|
103076
103623
|
}
|
|
103624
|
+
if (input.executionMode === "server") {
|
|
103625
|
+
const ceilingRefusal = orderCeilingRefusal({
|
|
103626
|
+
side: classified.side,
|
|
103627
|
+
size: sizeAsset,
|
|
103628
|
+
price: executionPrice,
|
|
103629
|
+
// A flip's close has filled by now: its new position starts from flat.
|
|
103630
|
+
currentPositionSize: targetResolution.closeOpposingPosition ? 0 : currentPositionSize,
|
|
103631
|
+
maxOrderNotional: runtime_policy_generated_default2.trading.risk.max_order_notional,
|
|
103632
|
+
maxPositionNotional: runtime_policy_generated_default2.trading.risk.max_position_notional
|
|
103633
|
+
});
|
|
103634
|
+
if (ceilingRefusal !== null) throw new Error(`Order rejected by risk manager: ${ceilingRefusal}`);
|
|
103635
|
+
}
|
|
103077
103636
|
const entryRequiresFlatAbsenceProof = Number.isFinite(currentPositionSize) && currentPositionSize === 0 || targetResolution.closeOpposingPosition;
|
|
103078
103637
|
if (entryRequiresFlatAbsenceProof) {
|
|
103079
103638
|
const finalProtectionObservation = await verifyNoLiveClientProtectiveTriggers(
|
|
@@ -103201,53 +103760,70 @@ var init_runtime_execution = __esm({
|
|
|
103201
103760
|
let marketOrderResponse;
|
|
103202
103761
|
let entryDispatchBoundaryPassed = false;
|
|
103203
103762
|
let settledServerProtectedEntry = null;
|
|
103204
|
-
|
|
103205
|
-
|
|
103206
|
-
|
|
103207
|
-
|
|
103208
|
-
|
|
103209
|
-
|
|
103210
|
-
|
|
103211
|
-
|
|
103212
|
-
|
|
103213
|
-
|
|
103214
|
-
|
|
103215
|
-
|
|
103216
|
-
|
|
103217
|
-
|
|
103218
|
-
|
|
103219
|
-
|
|
103220
|
-
|
|
103221
|
-
|
|
103222
|
-
|
|
103223
|
-
|
|
103224
|
-
|
|
103225
|
-
|
|
103226
|
-
input.onExchangeOrderDispatched?.(
|
|
103227
|
-
classified.intent === "open" || classified.intent === "add" || classified.intent === "flip" ? "entry" : "action"
|
|
103763
|
+
const entrySide = classified.side;
|
|
103764
|
+
let entryAssets;
|
|
103765
|
+
const sendEntry = () => executeClientMarketOrder({
|
|
103766
|
+
...entryAssets ? { assets: entryAssets } : {},
|
|
103767
|
+
profileId: input.profileId,
|
|
103768
|
+
runtimeSessionId: input.sessionId || "__missing_runtime_session__",
|
|
103769
|
+
runtimeLeaseToken: input.runtimeLeaseToken,
|
|
103770
|
+
runtimeDeviceId: input.runtimeDeviceId,
|
|
103771
|
+
schedulerInstanceId: input.schedulerInstanceId,
|
|
103772
|
+
walletAddress: input.executionContext.walletAddress,
|
|
103773
|
+
config: input.config ?? null,
|
|
103774
|
+
signal: input.signal,
|
|
103775
|
+
signingKey: input.signingKey,
|
|
103776
|
+
onExchangeOrderDispatched: () => {
|
|
103777
|
+
if (persistedProtectiveGroupSet != null && pendingProtectiveCleanup != null && !replaceExactClientProtectiveGroupSet(
|
|
103778
|
+
pendingProtectiveCleanup.profileId,
|
|
103779
|
+
pendingProtectiveCleanup.symbol,
|
|
103780
|
+
persistedProtectiveGroupSet,
|
|
103781
|
+
persistedProtectiveGroupSet
|
|
103782
|
+
)) {
|
|
103783
|
+
throw createClientRuntimeWindowHandoffBeforePlanDispatchError(
|
|
103784
|
+
pendingProtectiveCleanup
|
|
103228
103785
|
);
|
|
103229
|
-
|
|
103786
|
+
}
|
|
103787
|
+
input.onExchangeOrderDispatched?.(
|
|
103788
|
+
classified.intent === "open" || classified.intent === "add" || classified.intent === "flip" ? "entry" : "exit"
|
|
103789
|
+
);
|
|
103790
|
+
entryDispatchBoundaryPassed = true;
|
|
103791
|
+
},
|
|
103792
|
+
symbol: input.executionContext.symbol,
|
|
103793
|
+
side: entrySide,
|
|
103794
|
+
size: sizeAsset,
|
|
103795
|
+
estimatedPrice: executionPrice,
|
|
103796
|
+
slippage: input.executionContext.maxSlippageFraction,
|
|
103797
|
+
reduceOnly: classified.reduceOnly,
|
|
103798
|
+
mutationId: entryMutationId,
|
|
103799
|
+
clientOrderId: entryClientOrderId,
|
|
103800
|
+
...serverOwnedProtection ? {
|
|
103801
|
+
// The server attaches the configured Auto SL/TP to this entry.
|
|
103802
|
+
protection: {
|
|
103803
|
+
source: "runtime_config",
|
|
103804
|
+
requested_entry_size: sizeAsset,
|
|
103805
|
+
is_long: entrySide === "buy"
|
|
103230
103806
|
},
|
|
103231
|
-
|
|
103232
|
-
|
|
103233
|
-
|
|
103234
|
-
|
|
103235
|
-
|
|
103236
|
-
|
|
103237
|
-
|
|
103238
|
-
|
|
103239
|
-
|
|
103240
|
-
|
|
103241
|
-
|
|
103242
|
-
|
|
103243
|
-
|
|
103244
|
-
|
|
103245
|
-
|
|
103246
|
-
|
|
103247
|
-
|
|
103248
|
-
|
|
103249
|
-
|
|
103250
|
-
}
|
|
103807
|
+
onSettled: (mutation) => {
|
|
103808
|
+
settledServerProtectedEntry = mutation;
|
|
103809
|
+
}
|
|
103810
|
+
} : {}
|
|
103811
|
+
});
|
|
103812
|
+
try {
|
|
103813
|
+
try {
|
|
103814
|
+
marketOrderResponse = await sendEntry();
|
|
103815
|
+
} catch (rejection) {
|
|
103816
|
+
const retry = await serverOrderMetadataRetry(input, rejection, "entry", entryMutationId);
|
|
103817
|
+
const retrySize = retry === null ? 0 : quantizeHyperliquidOrderSizeValue(intendedSizeAsset, retry.sizeDecimals, "nearest");
|
|
103818
|
+
if (retry === null || !(retrySize > 0)) throw rejection;
|
|
103819
|
+
sizeAsset = retrySize;
|
|
103820
|
+
entryAssets = retry.assets;
|
|
103821
|
+
executionPrice = retry.markPrice ?? executionPrice;
|
|
103822
|
+
entryMutationId = retry.mutationId;
|
|
103823
|
+
entryClientOrderId = clientOrderIdForMutation(retry.mutationId);
|
|
103824
|
+
entryDispatchBoundaryPassed = false;
|
|
103825
|
+
marketOrderResponse = await sendEntry();
|
|
103826
|
+
}
|
|
103251
103827
|
} catch (entryDispatchError) {
|
|
103252
103828
|
const handoffVeto = isClientRuntimeWindowHandoffBeforePlanDispatch(entryDispatchError);
|
|
103253
103829
|
const handoffBeforeDispatch = handoffVeto || !entryDispatchBoundaryPassed && input.shouldCancelBeforeExchangeOrderDispatch?.() === true;
|
|
@@ -103306,6 +103882,15 @@ var init_runtime_execution = __esm({
|
|
|
103306
103882
|
status: "executed",
|
|
103307
103883
|
execution_metadata: classified.intent === "flip" ? { ..._toExecutionMetadata(marketOrderResponse), decision_leg: "entry" } : { ..._toExecutionMetadata(marketOrderResponse), entry_began_flat: livePositionDirection === 0 }
|
|
103308
103884
|
});
|
|
103885
|
+
progress.committedReports = executionReports;
|
|
103886
|
+
progress.committedOrder = {
|
|
103887
|
+
intent: classified.intent,
|
|
103888
|
+
side: classified.side,
|
|
103889
|
+
reduceOnly: classified.reduceOnly,
|
|
103890
|
+
requestedUnits: classified.requestedUnits,
|
|
103891
|
+
targetSignedUnits: classified.targetSignedUnits,
|
|
103892
|
+
executedSizeAsset: confirmedMarketFill == null ? 0 : confirmedMarketFill.filledSize
|
|
103893
|
+
};
|
|
103309
103894
|
const appendPostEntryProtectionFailure = (error48) => {
|
|
103310
103895
|
const projection = projectExecutionErrorContract({
|
|
103311
103896
|
error: error48,
|
|
@@ -103471,10 +104056,11 @@ var init_runtime_execution = __esm({
|
|
|
103471
104056
|
const kind = triggerInput.isTakeProfit ? "tp" : "sl";
|
|
103472
104057
|
const alreadyProtected = (liveDirectionMatches ? (await storedClientProtectiveCover(
|
|
103473
104058
|
input,
|
|
104059
|
+
isLong,
|
|
103474
104060
|
readClientProtectiveGroups(
|
|
103475
104061
|
String(input.profileId).trim(),
|
|
103476
104062
|
input.executionContext.symbol
|
|
103477
|
-
)
|
|
104063
|
+
)
|
|
103478
104064
|
))[kind] : 0) + activeLegs.filter((leg2) => leg2.kind === kind).reduce((total, leg2) => total + leg2.size, 0);
|
|
103479
104065
|
const liveExposure = Math.abs(livePositionSize);
|
|
103480
104066
|
const availableExposure = Math.max(0, liveExposure - alreadyProtected);
|
|
@@ -103869,7 +104455,6 @@ var init_runtime_execution = __esm({
|
|
|
103869
104455
|
size: destinationSize,
|
|
103870
104456
|
roundingMode: "nearest",
|
|
103871
104457
|
includePrivateContext: desiredPosition != null && Number.isFinite(desiredPosition),
|
|
103872
|
-
profileId: input.profileId,
|
|
103873
104458
|
// The device reads its own position and mark; the server never reads
|
|
103874
104459
|
// a Client wallet.
|
|
103875
104460
|
walletAddress: input.walletAddress,
|
|
@@ -104643,6 +105228,7 @@ var init_provider_observability = __esm({
|
|
|
104643
105228
|
}
|
|
104644
105229
|
if (typeof raw.credential_ref === "string" && /^[a-f0-9]{64}$/.test(raw.credential_ref)) result.credential_ref = raw.credential_ref;
|
|
104645
105230
|
if (raw.execution_mode === "client" || raw.execution_mode === "server") result.execution_mode = raw.execution_mode;
|
|
105231
|
+
if (raw.timeout_bound === "attempt_cap") result.timeout_bound = "attempt_cap";
|
|
104646
105232
|
if (typeof raw.quota_project_ref === "string" && /^[a-f0-9]{64}$/.test(raw.quota_project_ref) && raw.quota_project_source === "provider_quota_subject") {
|
|
104647
105233
|
result.quota_project_ref = raw.quota_project_ref;
|
|
104648
105234
|
result.quota_project_source = "provider_quota_subject";
|
|
@@ -107468,7 +108054,7 @@ var init_client_runtime_status_store = __esm({
|
|
|
107468
108054
|
});
|
|
107469
108055
|
|
|
107470
108056
|
// lib/runtime/perp-dex-scope.ts
|
|
107471
|
-
var perpDexScopeForSymbols, equityVenuesForSymbols, profileEquityVenues, positionsOnVenues;
|
|
108057
|
+
var perpDexScopeForSymbols, equityVenuesForSymbols, profileEquityVenues, profileExchanges, positionsOnVenues;
|
|
107472
108058
|
var init_perp_dex_scope = __esm({
|
|
107473
108059
|
"lib/runtime/perp-dex-scope.ts"() {
|
|
107474
108060
|
"use strict";
|
|
@@ -107497,6 +108083,14 @@ var init_perp_dex_scope = __esm({
|
|
|
107497
108083
|
profileEquityVenues = (tradingSymbols, defaultTradingSymbols) => equityVenuesForSymbols(
|
|
107498
108084
|
Array.isArray(tradingSymbols) && tradingSymbols.length > 0 ? tradingSymbols : defaultTradingSymbols ?? []
|
|
107499
108085
|
);
|
|
108086
|
+
profileExchanges = (exchanges, tradingSymbols, defaultTradingSymbols, configuredDexes) => {
|
|
108087
|
+
if (Array.isArray(exchanges) && exchanges.length > 0) {
|
|
108088
|
+
const configured2 = /* @__PURE__ */ new Set(["", ...(configuredDexes ?? []).map((dex) => String(dex).trim().toLowerCase())]);
|
|
108089
|
+
const names2 = exchanges.map((exchange) => typeof exchange === "string" ? exchange.trim().toLowerCase() : null);
|
|
108090
|
+
if (names2.every((name) => name !== null && configured2.has(name))) return [...new Set(names2)].sort();
|
|
108091
|
+
}
|
|
108092
|
+
return profileEquityVenues(tradingSymbols, defaultTradingSymbols);
|
|
108093
|
+
};
|
|
107500
108094
|
positionsOnVenues = (positions, venues) => venues ? positions.filter((position) => normalizeHyperliquidMarketSymbol(position.symbol) && venues.includes(getHyperliquidMarketDex(position.symbol))) : [...positions];
|
|
107501
108095
|
}
|
|
107502
108096
|
});
|
|
@@ -107567,6 +108161,12 @@ var init_client_killswitch = __esm({
|
|
|
107567
108161
|
const symbol2 = firstConfiguredSymbol(settings, input.config);
|
|
107568
108162
|
const leverage = toPositiveFinite2(settings.leverage) ?? 1;
|
|
107569
108163
|
const equityVenues = profileEquityVenues(settings.trading_symbols, input.config.default_trading_symbols);
|
|
108164
|
+
const closeVenues = profileExchanges(
|
|
108165
|
+
settings.exchanges,
|
|
108166
|
+
settings.trading_symbols,
|
|
108167
|
+
input.config.default_trading_symbols,
|
|
108168
|
+
input.config.client_runtime_hyperliquid_perp_dexs?.allowed_dexes
|
|
108169
|
+
);
|
|
107570
108170
|
const accountState = await fetchBrowserAccountState2({
|
|
107571
108171
|
publicRequestPriority: "trading_reduce",
|
|
107572
108172
|
config: input.config,
|
|
@@ -107609,7 +108209,8 @@ var init_client_killswitch = __esm({
|
|
|
107609
108209
|
accountState,
|
|
107610
108210
|
walletAddress,
|
|
107611
108211
|
symbol: symbol2,
|
|
107612
|
-
equityVenues
|
|
108212
|
+
equityVenues,
|
|
108213
|
+
closeVenues
|
|
107613
108214
|
};
|
|
107614
108215
|
}
|
|
107615
108216
|
if (!context.snapshot_trusted || context.status === "untrusted") {
|
|
@@ -107621,7 +108222,8 @@ var init_client_killswitch = __esm({
|
|
|
107621
108222
|
accountState,
|
|
107622
108223
|
walletAddress,
|
|
107623
108224
|
symbol: symbol2,
|
|
107624
|
-
equityVenues
|
|
108225
|
+
equityVenues,
|
|
108226
|
+
closeVenues
|
|
107625
108227
|
};
|
|
107626
108228
|
}
|
|
107627
108229
|
const peakEquity = toPositiveFinite2(context.peak_equity);
|
|
@@ -107634,7 +108236,8 @@ var init_client_killswitch = __esm({
|
|
|
107634
108236
|
accountState,
|
|
107635
108237
|
walletAddress,
|
|
107636
108238
|
symbol: symbol2,
|
|
107637
|
-
equityVenues
|
|
108239
|
+
equityVenues,
|
|
108240
|
+
closeVenues
|
|
107638
108241
|
};
|
|
107639
108242
|
}
|
|
107640
108243
|
const drawdownPercent = calculateClientKillswitchDrawdownPercent(
|
|
@@ -107650,7 +108253,8 @@ var init_client_killswitch = __esm({
|
|
|
107650
108253
|
accountState,
|
|
107651
108254
|
walletAddress,
|
|
107652
108255
|
symbol: symbol2,
|
|
107653
|
-
equityVenues
|
|
108256
|
+
equityVenues,
|
|
108257
|
+
closeVenues
|
|
107654
108258
|
};
|
|
107655
108259
|
};
|
|
107656
108260
|
closeClientKillswitchPositions = async (input) => {
|
|
@@ -108136,6 +108740,7 @@ var init_ai_settings_helpers = __esm({
|
|
|
108136
108740
|
init_define_VTX_EXO_POLICY();
|
|
108137
108741
|
init_define_VTX_GROK_POLICY();
|
|
108138
108742
|
init_define_VTX_PI_MODEL_POLICY();
|
|
108743
|
+
init_perp_dex_scope();
|
|
108139
108744
|
sortAiSettings = (settings) => {
|
|
108140
108745
|
if (!settings || typeof settings !== "object") return settings;
|
|
108141
108746
|
const normalized = { ...settings };
|
|
@@ -109446,8 +110051,14 @@ var init_native_provider_budget = __esm({
|
|
|
109446
110051
|
init_define_VTX_GROK_POLICY();
|
|
109447
110052
|
init_define_VTX_PI_MODEL_POLICY();
|
|
109448
110053
|
NativeModelTimeoutError = class extends Error {
|
|
109449
|
-
|
|
110054
|
+
/**
|
|
110055
|
+
* attemptCapExpired: one Google egress attempt ran out its per-attempt cap
|
|
110056
|
+
* while the model's own budget had time left, which the Server loop reads
|
|
110057
|
+
* as an unreachable route (google_runtime_transport), not as a timeout.
|
|
110058
|
+
*/
|
|
110059
|
+
constructor(attemptCapExpired = false) {
|
|
109450
110060
|
super("Native model request timed out.");
|
|
110061
|
+
this.attemptCapExpired = attemptCapExpired;
|
|
109451
110062
|
this.runtimeNativeFailureKind = "timeout";
|
|
109452
110063
|
this.name = "NativeModelTimeoutError";
|
|
109453
110064
|
}
|
|
@@ -109819,7 +110430,10 @@ var init_provider_client = __esm({
|
|
|
109819
110430
|
}
|
|
109820
110431
|
sanitizedError.runtimeProviderStatusCode = response?.status ?? null;
|
|
109821
110432
|
sanitizedError.runtimeProviderRequestId = providerRequestId(response);
|
|
109822
|
-
sanitizedError.runtimeProviderDiagnostics =
|
|
110433
|
+
sanitizedError.runtimeProviderDiagnostics = {
|
|
110434
|
+
...marker?.providerDiagnostics ?? {},
|
|
110435
|
+
...error48 instanceof NativeModelTimeoutError && error48.attemptCapExpired ? { timeout_bound: "attempt_cap" } : {}
|
|
110436
|
+
};
|
|
109823
110437
|
if (marker?.googleQuotaFailure) sanitizedError.runtimeGoogleQuotaFailure = true;
|
|
109824
110438
|
sanitizedError.runtimeRequestInputTokens = marker?.requestInputTokens ?? null;
|
|
109825
110439
|
if (marker) {
|
|
@@ -112095,7 +112709,8 @@ var init_provider_client = __esm({
|
|
|
112095
112709
|
if (egress && (timeoutMs <= 0 || !googleEgressHasBudget(egress))) throw new NativeModelTimeoutError();
|
|
112096
112710
|
signal?.addEventListener("abort", cancelAttempt, { once: true });
|
|
112097
112711
|
if (signal?.aborted) cancelAttempt();
|
|
112098
|
-
const
|
|
112712
|
+
const capBound = Boolean(egress && egress.policy.attempt_timeout_seconds * MS_PER_SECOND < egress.deadline - Date.now());
|
|
112713
|
+
const attemptTimer = attemptController ? setTimeout(() => attemptController.abort(new NativeModelTimeoutError(capBound)), timeoutMs) : void 0;
|
|
112099
112714
|
try {
|
|
112100
112715
|
response = await callGoogle(
|
|
112101
112716
|
remoteApiKey,
|
|
@@ -113940,6 +114555,7 @@ __export(local_analysis_exports, {
|
|
|
113940
114555
|
ClientRuntimeAgentInstructionEmpty: () => ClientRuntimeAgentInstructionEmpty,
|
|
113941
114556
|
ClientRuntimeAiSchedulePaused: () => ClientRuntimeAiSchedulePaused,
|
|
113942
114557
|
ClientRuntimeAiScheduleStillActive: () => ClientRuntimeAiScheduleStillActive,
|
|
114558
|
+
SERVER_UNREADABLE_REPLY_HOLD_REASONING: () => SERVER_UNREADABLE_REPLY_HOLD_REASONING,
|
|
113943
114559
|
ServerDispatchAccountStateStale: () => ServerDispatchAccountStateStale,
|
|
113944
114560
|
aiOrderSlippageFraction: () => aiOrderSlippageFraction,
|
|
113945
114561
|
buildLocalRuntimePromptArtifacts: () => buildLocalRuntimePromptArtifacts,
|
|
@@ -113960,7 +114576,7 @@ __export(local_analysis_exports, {
|
|
|
113960
114576
|
runLocalRuntimeCycle: () => runLocalRuntimeCycle,
|
|
113961
114577
|
summarizeReviewFailureExplanation: () => summarizeReviewFailureExplanation
|
|
113962
114578
|
});
|
|
113963
|
-
var CYCLE_TIMEOUT_FLOOR_MS, DECISION_SETTLEMENT_RESERVE_MAX_BUDGET_DIVISOR, MIN_AGENT_INSTRUCTION_RETRY_AFTER_MS, PROMPT_PARITY_ERROR_DETAIL_MAX_CHARS, EXTERNAL_INFERENCE_RUNTIME_POLL_INTERVAL_MS, REVIEW_PROVIDER_SERVER_ERROR_STATUSES, TRUNCATION_ELLIPSIS2, normalizeNativeValues, assertPromptModelController, resolveRuntimeReasoningControlsForModel, modelScopedKey, resolveNativeValuesForModel, observeRuntimeCycle, observeAccountState, aiOrderSlippageFraction, serverBehaviorStateArtifacts, ClientRuntimeAgentInstructionEmpty, isClientRuntimeAgentInstructionEmpty, ClientRuntimeAiSchedulePaused, ClientRuntimeAiScheduleStillActive, isClientRuntimeAiScheduleStillActive, ServerDispatchAccountStateStale, isServerDispatchAccountStateStale, isClientRuntimeAiSchedulePaused, acceptancePositionCaps, accountSnapshotCapturedAt, buildClaimedAgentRuntimeCycleResult, resolveRuntimeMarginModePreference, resolveRuntimeLeveragePreference, resolveBooleanSetting2, CLIENT_RUNTIME_LIVE_CONTEXT_UNAVAILABLE_ERRORS, BEHAVIOR_STATE_UNAVAILABLE_ERROR, CriticalBehaviorStateError, clampNumber, resolveExternalInferenceRuntimeTimeoutSeconds, toPositiveFinite3, compactSnippet, hashRuntimeDebugText, EFFECTIVE_INPUT_MANIFEST_SCHEMA_VERSION, PROMPT_ASSEMBLY_DEFINITION_VERSION, RUNTIME_SOURCE_DEFINITION_VERSION, DECISION_INPUT_DEFINITION_VERSION, CONTEXT_ENVELOPE_DEFINITION_VERSION, CLIENT_RUNTIME_SOURCE_VERSION, CLIENT_MAIN_PROMPT_RENDERER, SERVER_MAIN_PROMPT_RENDERER, CLIENT_REVIEW_PROMPT_RENDERER, SERVER_REVIEW_PROMPT_RENDERER, resolveEffectivePromptRuntimeProvenance, canonicalManifestValue, canonicalManifestJson, sha256ManifestHex, effectiveInputComponent, buildEffectiveInputManifest, derivePromptVisibleSections, decodeDecisionTracePayload, extractDecisionSymbolTrace, formatDecisionSymbolTrace, formatActionableDecisionSymbols, decisionRecordsBySymbol, normalizePromptSymbols, JSON_MODEL_OUTPUT_FENCE_PATTERN, STRICT_MODEL_OUTPUT_KEYS, currentModelOutputValidationErrors, currentModelOutputMatchesContract, projectCurrentModelDecisionContent, modelOutputValidationError, buildMissingDecisionHold, buildDecisionPlansFromResponse, buildReviewCandidatePlansFromResponse, forceUnavailableSymbolsToHold, extractTemplatePlaceholders, requireReviewPrimaryUserPromptTemplate, containsCompetingBehaviorStateMarkup, containsCompetingMainBehaviorStateMarkup, requireStrategyReviewTemplates, preflightStrategyReviewPromptContract, extractRuntimeReasoningSelection, isAbortError, isRuntimeTimeoutAbortReason, REVIEW_FAILURE_SENSITIVE_DB_TOKENS, REVIEW_FAILURE_SCHEMA_DISCLOSURE_TOKENS, REVIEW_FAILURE_SQL_STATEMENT_PATTERN, REVIEW_FAILURE_TRACEBACK_PATTERN, isSensitiveReviewFailureDetail, summarizeReviewFailureExplanation, buildReviewFailureHoldReason, createAbortError2, settleRuntimeCyclePromise, unwrapRuntimeCycleSettledResult, normalizeDecisionLabel, normalizeRuntimeSymbol, PromptContractFetchError, isLivePromptContextUnavailableError, buildFailClosedHoldResult, buildPromptConstructionFailureResult, buildLivePromptContextUnavailableFailureResult, pickFirstString, normalizeRuntimeStringList, requirePositiveRuntimeLimit, resolveRuntimeTradingScope, normalizeRuntimeProviderAlias, resolveCatalogModelEntry, createClientRuntimeProviderSetupError, createProviderSetupRejectionError, evaluateModelEligibility, extractReviewRuntimeReasoningSelection, isUsableRuntimeSettingsFallback, resolveRuntimeSettings, formatRuntimeDurationMs, normalizeRuntimeTimingNote, appendRuntimeTimingEvent, reportPromptParityTelemetry, resolveLocalRuntimeSecretRequirements, resolveLocalRuntimeSecretProvider, toEpochSeconds, REQUIRED_AI_INDICATOR_KEYS, sortTradingTimeframes, normalizePromptIdentityTimestamp, resolveCompletedCandleBoundary, normalizeAiIndicatorFlags, getPromptLookback, computeSma, computeEma, computeRsi, computeAtr, computeMacd, computeBollingerBands, getIndicatorValue, buildPromptCandlesComponent, CANDLE_CLOSE_TICKER_TIMEFRAME, candleCloseTicker, buildPromptCandlesPayload, formatUtcTimestampWithWeekday, formatUtcNowWithWeekday, formatPromptPrice, capacityUnitSize, computePromptUnitsUsedForPosition, buildPromptAccountStatusValue, buildPromptPositionsValue, sanitizePromptSymbol, fillTimeMs, fillSize, normalizeFillSide, normalizeFillOrderId, normalizeFillRiskOrderIdentity, fillStartPosition, fillSortValue, sortFillsAscending, sortFillsDescending, inferEntryFromStartPositionChain, inferEntryFromCurrentPositionSize, calculateCurrentPositionState, calculatePositionEntryTimes, countPositionAdds, latestPositionRiskIncreaseTimeMs, latestPositionRiskIncreaseEvidence, compactPromptRiskIncrease, roundPositiveDecimalHalfUp, compactPromptLastTrade, ENTRY_TRADE_FIELDS, PREVIOUS_DECISION_FIELDS, PREVIOUS_CAMPAIGN_FIELDS, hasExactKeys2, isNonnegativeInteger, isFiniteNumber, isExactEnumString, isNonemptyPromptText, isCampaignReasoningText, projectBackendDecisionMemoryItem, requireRenderedStrategyBehaviorState, canonicalFillSideForRiskEvidence, isValidRiskEvidenceFill, isValidCampaignBoundaryFill, normalizeFillHistoryCoverage, resolveFillHistoryCoverageForSymbol, buildPromptBehaviorStateArtifacts, buildPromptBehaviorStateValue, shouldCompareServerPromptParity, buildLocalRuntimePromptArtifacts, createRuntimeId2, asRecord, buildRuntimeConstraintRejectionMessage, hasDeviceProviderSecret, requireNonEmptyStringField, requirePositiveIntegerField, compareContractVersion, parsePromptContractTimestamp, assertPromptContractCompatibility, assertPromptContractTemporalBounds, sleepWithAbort, requireAgentPollRetryAfterMs, materializeClaimedClientRuntimeAgentInstruction, attachClientRuntimeErrorProvenance, isExternalRuntimeProviderResult, invokeClientExternalInference, assertPromptContractBindingTupleEqual, assertPromptContractScopeMatch, fetchBoundPromptContracts, formatTemplateWithNamedVariables, carryReturnedModelCalls, runLocalRuntimeCycle;
|
|
114579
|
+
var CYCLE_TIMEOUT_FLOOR_MS, DECISION_SETTLEMENT_RESERVE_MAX_BUDGET_DIVISOR, MIN_AGENT_INSTRUCTION_RETRY_AFTER_MS, PROMPT_PARITY_ERROR_DETAIL_MAX_CHARS, EXTERNAL_INFERENCE_RUNTIME_POLL_INTERVAL_MS, REVIEW_PROVIDER_SERVER_ERROR_STATUSES, TRUNCATION_ELLIPSIS2, normalizeNativeValues, assertPromptModelController, resolveRuntimeReasoningControlsForModel, modelScopedKey, resolveNativeValuesForModel, observeRuntimeCycle, observeAccountState, aiOrderSlippageFraction, serverBehaviorStateArtifacts, ClientRuntimeAgentInstructionEmpty, isClientRuntimeAgentInstructionEmpty, ClientRuntimeAiSchedulePaused, ClientRuntimeAiScheduleStillActive, isClientRuntimeAiScheduleStillActive, ServerDispatchAccountStateStale, isServerDispatchAccountStateStale, isClientRuntimeAiSchedulePaused, acceptancePositionCaps, accountSnapshotCapturedAt, buildClaimedAgentRuntimeCycleResult, resolveRuntimeMarginModePreference, resolveRuntimeLeveragePreference, resolveBooleanSetting2, CLIENT_RUNTIME_LIVE_CONTEXT_UNAVAILABLE_ERRORS, BEHAVIOR_STATE_UNAVAILABLE_ERROR, CriticalBehaviorStateError, clampNumber, resolveExternalInferenceRuntimeTimeoutSeconds, toPositiveFinite3, compactSnippet, hashRuntimeDebugText, EFFECTIVE_INPUT_MANIFEST_SCHEMA_VERSION, PROMPT_ASSEMBLY_DEFINITION_VERSION, RUNTIME_SOURCE_DEFINITION_VERSION, DECISION_INPUT_DEFINITION_VERSION, CONTEXT_ENVELOPE_DEFINITION_VERSION, CLIENT_RUNTIME_SOURCE_VERSION, CLIENT_MAIN_PROMPT_RENDERER, SERVER_MAIN_PROMPT_RENDERER, CLIENT_REVIEW_PROMPT_RENDERER, SERVER_REVIEW_PROMPT_RENDERER, resolveEffectivePromptRuntimeProvenance, canonicalManifestValue, canonicalManifestJson, sha256ManifestHex, effectiveInputComponent, buildEffectiveInputManifest, derivePromptVisibleSections, decodeDecisionTracePayload, extractDecisionSymbolTrace, formatDecisionSymbolTrace, formatActionableDecisionSymbols, decisionRecordsBySymbol, normalizePromptSymbols, JSON_MODEL_OUTPUT_FENCE_PATTERN, STRICT_MODEL_OUTPUT_KEYS, currentModelOutputValidationErrors, currentModelOutputMatchesContract, projectCurrentModelDecisionContent, modelOutputValidationError, SERVER_UNREADABLE_REPLY_HOLD_REASONING, buildMissingDecisionHold, buildDecisionPlansFromResponse, buildReviewCandidatePlansFromResponse, forceUnavailableSymbolsToHold, extractTemplatePlaceholders, requireReviewPrimaryUserPromptTemplate, containsCompetingBehaviorStateMarkup, containsCompetingMainBehaviorStateMarkup, requireStrategyReviewTemplates, preflightStrategyReviewPromptContract, extractRuntimeReasoningSelection, isAbortError, isRuntimeTimeoutAbortReason, REVIEW_FAILURE_SENSITIVE_DB_TOKENS, REVIEW_FAILURE_SCHEMA_DISCLOSURE_TOKENS, REVIEW_FAILURE_SQL_STATEMENT_PATTERN, REVIEW_FAILURE_TRACEBACK_PATTERN, isSensitiveReviewFailureDetail, summarizeReviewFailureExplanation, buildReviewFailureHoldReason, createAbortError2, settleRuntimeCyclePromise, unwrapRuntimeCycleSettledResult, normalizeDecisionLabel, normalizeRuntimeSymbol, PromptContractFetchError, isLivePromptContextUnavailableError, buildFailClosedHoldResult, buildPromptConstructionFailureResult, buildLivePromptContextUnavailableFailureResult, pickFirstString, normalizeRuntimeStringList, requirePositiveRuntimeLimit, resolveRuntimeTradingScope, normalizeRuntimeProviderAlias, resolveCatalogModelEntry, createClientRuntimeProviderSetupError, createProviderSetupRejectionError, evaluateModelEligibility, extractReviewRuntimeReasoningSelection, isUsableRuntimeSettingsFallback, resolveRuntimeSettings, formatRuntimeDurationMs, normalizeRuntimeTimingNote, appendRuntimeTimingEvent, reportPromptParityTelemetry, resolveLocalRuntimeSecretRequirements, resolveLocalRuntimeSecretProvider, toEpochSeconds, REQUIRED_AI_INDICATOR_KEYS, sortTradingTimeframes, normalizePromptIdentityTimestamp, resolveCompletedCandleBoundary, normalizeAiIndicatorFlags, getPromptLookback, computeSma, computeEma, computeRsi, computeAtr, computeMacd, computeBollingerBands, getIndicatorValue, buildPromptCandlesComponent, CANDLE_CLOSE_TICKER_TIMEFRAME, candleCloseTicker, buildPromptCandlesPayload, formatUtcTimestampWithWeekday, formatUtcNowWithWeekday, formatPromptPrice, capacityUnitSize, computePromptUnitsUsedForPosition, buildPromptAccountStatusValue, buildPromptPositionsValue, sanitizePromptSymbol, fillTimeMs, fillSize, normalizeFillSide, normalizeFillOrderId, normalizeFillRiskOrderIdentity, fillStartPosition, fillSortValue, sortFillsAscending, sortFillsDescending, inferEntryFromStartPositionChain, inferEntryFromCurrentPositionSize, calculateCurrentPositionState, calculatePositionEntryTimes, countPositionAdds, latestPositionRiskIncreaseTimeMs, latestPositionRiskIncreaseEvidence, compactPromptRiskIncrease, roundPositiveDecimalHalfUp, compactPromptLastTrade, ENTRY_TRADE_FIELDS, PREVIOUS_DECISION_FIELDS, PREVIOUS_CAMPAIGN_FIELDS, hasExactKeys2, isNonnegativeInteger, isFiniteNumber, isExactEnumString, isNonemptyPromptText, isCampaignReasoningText, projectBackendDecisionMemoryItem, requireRenderedStrategyBehaviorState, canonicalFillSideForRiskEvidence, isValidRiskEvidenceFill, isValidCampaignBoundaryFill, normalizeFillHistoryCoverage, resolveFillHistoryCoverageForSymbol, buildPromptBehaviorStateArtifacts, buildPromptBehaviorStateValue, shouldCompareServerPromptParity, buildLocalRuntimePromptArtifacts, createRuntimeId2, asRecord, buildRuntimeConstraintRejectionMessage, hasDeviceProviderSecret, requireNonEmptyStringField, requirePositiveIntegerField, compareContractVersion, parsePromptContractTimestamp, assertPromptContractCompatibility, assertPromptContractTemporalBounds, sleepWithAbort, requireAgentPollRetryAfterMs, materializeClaimedClientRuntimeAgentInstruction, attachClientRuntimeErrorProvenance, isExternalRuntimeProviderResult, invokeClientExternalInference, assertPromptContractBindingTupleEqual, assertPromptContractScopeMatch, fetchBoundPromptContracts, formatTemplateWithNamedVariables, carryReturnedModelCalls, runLocalRuntimeCycle;
|
|
113964
114580
|
var init_local_analysis = __esm({
|
|
113965
114581
|
"lib/runtime/local-analysis.ts"() {
|
|
113966
114582
|
"use strict";
|
|
@@ -114178,6 +114794,8 @@ var init_local_analysis = __esm({
|
|
|
114178
114794
|
perpDexScope: perpDexScopeForSymbols(symbols),
|
|
114179
114795
|
feeSymbols: symbols,
|
|
114180
114796
|
includeEffectiveTakerRate: true,
|
|
114797
|
+
// A Server bot's account is valued as the Python Server loop valued it.
|
|
114798
|
+
serverLoopAccountValue: runtimeInput.executionMode === "server",
|
|
114181
114799
|
sessionId: String(runtimeInput.sessionId || "").trim(),
|
|
114182
114800
|
signal
|
|
114183
114801
|
});
|
|
@@ -114352,7 +114970,8 @@ var init_local_analysis = __esm({
|
|
|
114352
114970
|
decision: "HOLD",
|
|
114353
114971
|
units: 0,
|
|
114354
114972
|
reasoning: `Skipped by client runtime constraints: ${accepted.reason_code}`,
|
|
114355
|
-
executionContext
|
|
114973
|
+
executionContext,
|
|
114974
|
+
...entry.decision === "BUY" || entry.decision === "SELL" ? { unsentOrder: { decision: entry.decision, units: entry.units, constraintReasonCode: accepted.reason_code } } : {}
|
|
114356
114975
|
};
|
|
114357
114976
|
}
|
|
114358
114977
|
throw new Error(buildRuntimeConstraintRejectionMessage({
|
|
@@ -114925,6 +115544,7 @@ var init_local_analysis = __esm({
|
|
|
114925
115544
|
}
|
|
114926
115545
|
);
|
|
114927
115546
|
};
|
|
115547
|
+
SERVER_UNREADABLE_REPLY_HOLD_REASONING = "Configured symbol was omitted from the model response. Defaulted to HOLD.";
|
|
114928
115548
|
buildMissingDecisionHold = (symbol2, reasoning = `No valid model decision was returned for configured symbol ${symbol2}.`) => ({
|
|
114929
115549
|
symbol: symbol2,
|
|
114930
115550
|
decision: "HOLD",
|
|
@@ -117492,7 +118112,7 @@ ${behaviorJson}
|
|
|
117492
118112
|
);
|
|
117493
118113
|
}
|
|
117494
118114
|
};
|
|
117495
|
-
fetchBoundPromptContracts = async (profileId, payload, signal, walletAddress, getEquity, getTotalUnrealizedPnl, getAccountStateResolvedAtMs, getUserFills, waitForLiveAccountState, initialMetadata, getPositions, getPerpDexAccounts) => {
|
|
118115
|
+
fetchBoundPromptContracts = async (profileId, payload, signal, walletAddress, getEquity, getTotalUnrealizedPnl, getAccountStateResolvedAtMs, getUserFills, waitForLiveAccountState, initialMetadata, getPositions, getPerpDexAccounts, runsWithoutEquity = false) => {
|
|
117496
118116
|
let attempt = 0;
|
|
117497
118117
|
while (true) {
|
|
117498
118118
|
if (waitForLiveAccountState) {
|
|
@@ -117542,7 +118162,7 @@ ${behaviorJson}
|
|
|
117542
118162
|
const liveEquity = Number.isFinite(Number(liveEquityRaw)) ? Number(liveEquityRaw) : 0;
|
|
117543
118163
|
const liveUnrealizedPnlRaw = getTotalUnrealizedPnl ? getTotalUnrealizedPnl() : null;
|
|
117544
118164
|
const liveUnrealizedPnl = liveUnrealizedPnlRaw !== null && liveUnrealizedPnlRaw !== void 0 && Number.isFinite(Number(liveUnrealizedPnlRaw)) ? Number(liveUnrealizedPnlRaw) : null;
|
|
117545
|
-
const parityIncluded = liveEquity > 0;
|
|
118165
|
+
const parityIncluded = liveEquity > 0 || runsWithoutEquity;
|
|
117546
118166
|
const parityPreparedAtMs = Date.now();
|
|
117547
118167
|
const accountStateResolvedAtMs = getAccountStateResolvedAtMs ? getAccountStateResolvedAtMs() : null;
|
|
117548
118168
|
const accountStateAgeMs = typeof accountStateResolvedAtMs === "number" ? Math.max(0, parityPreparedAtMs - accountStateResolvedAtMs) : null;
|
|
@@ -118126,6 +118746,10 @@ ${behaviorJson}
|
|
|
118126
118746
|
// A Server bot's cycle reads the account authoritatively, as the Python
|
|
118127
118747
|
// Server loop does: never a cached or rate-limit-stale observation.
|
|
118128
118748
|
forceRefresh: input.executionMode === "server",
|
|
118749
|
+
// And values it as that loop does: Perps equity alone unless the loop's
|
|
118750
|
+
// own tests count Spot (serverLoopAccountValue). A Client bot's cycle
|
|
118751
|
+
// keeps the device rule.
|
|
118752
|
+
serverLoopAccountValue: input.executionMode === "server",
|
|
118129
118753
|
sessionId,
|
|
118130
118754
|
signal: timeoutController.signal
|
|
118131
118755
|
}).catch(async (error48) => {
|
|
@@ -118236,7 +118860,8 @@ ${behaviorJson}
|
|
|
118236
118860
|
},
|
|
118237
118861
|
initialPromptMetadata,
|
|
118238
118862
|
() => latestPositions,
|
|
118239
|
-
() => _latestPerpDexAccounts
|
|
118863
|
+
() => _latestPerpDexAccounts,
|
|
118864
|
+
input.executionMode === "server"
|
|
118240
118865
|
).then((contracts) => {
|
|
118241
118866
|
appendRuntimeTimingEvent("prompt_contract_loaded", promptContractStartedAtMs);
|
|
118242
118867
|
return contracts;
|
|
@@ -119268,18 +119893,31 @@ ${stringifyPromptJson(candlesPayload)}
|
|
|
119268
119893
|
`provider=${provider} requested_model=${authoritativeModel} response_model=${providerResponse.model} llm_latency_s=${providerResponse.latency} snippet=${responseSnippet || "(empty)"}`
|
|
119269
119894
|
);
|
|
119270
119895
|
let primaryDecisionContent = providerResponse.content;
|
|
119896
|
+
let mainReplyUnreadable = false;
|
|
119271
119897
|
if (!allPromptSymbolsUnavailable && !isExternalRuntimeProviderResult(providerResponse)) {
|
|
119272
119898
|
const validationErrors = currentModelOutputValidationErrors(providerResponse.content, promptSymbols);
|
|
119273
|
-
if (validationErrors.length > 0) {
|
|
119899
|
+
if (validationErrors.length > 0 && input.executionMode !== "server") {
|
|
119274
119900
|
throw modelOutputValidationError("Main", providerResponse.invocations, validationErrors, promptSymbols);
|
|
119275
119901
|
}
|
|
119276
|
-
|
|
119902
|
+
if (validationErrors.length > 0) {
|
|
119903
|
+
mainReplyUnreadable = true;
|
|
119904
|
+
primaryDecisionContent = JSON.stringify(Object.fromEntries(promptSymbols.map((promptSymbol) => [promptSymbol, {
|
|
119905
|
+
decision: "HOLD",
|
|
119906
|
+
units: 0,
|
|
119907
|
+
tradability: null,
|
|
119908
|
+
reasoning: SERVER_UNREADABLE_REPLY_HOLD_REASONING
|
|
119909
|
+
}])));
|
|
119910
|
+
} else {
|
|
119911
|
+
primaryDecisionContent = projectCurrentModelDecisionContent(providerResponse.content);
|
|
119912
|
+
}
|
|
119277
119913
|
}
|
|
119278
|
-
const primaryParseOutcome =
|
|
119279
|
-
|
|
119280
|
-
|
|
119281
|
-
|
|
119282
|
-
|
|
119914
|
+
const primaryParseOutcome = mainReplyUnreadable ? {
|
|
119915
|
+
status: "failed",
|
|
119916
|
+
fallbackStrategy: null,
|
|
119917
|
+
// The loop records this one code for a reply its strict parser rejects.
|
|
119918
|
+
validationErrorCodes: ["model_output_schema_invalid"],
|
|
119919
|
+
discardedFields: []
|
|
119920
|
+
} : classifyDecisionParseOutcome(providerResponse.content, symbol2, promptSymbols);
|
|
119283
119921
|
invocationAttempts = applyInvocationParseOutcome(
|
|
119284
119922
|
providerResponse.invocations,
|
|
119285
119923
|
{
|
|
@@ -119395,7 +120033,7 @@ ${stringifyPromptJson(candlesPayload)}
|
|
|
119395
120033
|
return entry.decision === "BUY" || entry.decision === "SELL" ? total + Math.max(0, Math.trunc(entry.units)) : total;
|
|
119396
120034
|
}, 0);
|
|
119397
120035
|
const reviewMaxTrades = Math.max(0, maxTradesPerPrompt - unreviewedPrimaryUnits);
|
|
119398
|
-
const shouldReview = !allPromptSymbolsUnavailable && reviewEnabled && reviewCandidatePlans.length > 0;
|
|
120036
|
+
const shouldReview = !allPromptSymbolsUnavailable && reviewEnabled && !mainReplyUnreadable && reviewCandidatePlans.length > 0;
|
|
119399
120037
|
if (shouldReview) {
|
|
119400
120038
|
let reviewModel = requireNonEmptyStringField(promptMetadata.review_model, "review_model");
|
|
119401
120039
|
const requestedReviewModel = reviewModel;
|
|
@@ -119696,6 +120334,9 @@ ${reviewOutputContract}`;
|
|
|
119696
120334
|
if (error48 instanceof CriticalBehaviorStateError || detail.includes(BEHAVIOR_STATE_UNAVAILABLE_ERROR) || detail.includes("Critical behavior context could not be constructed")) {
|
|
119697
120335
|
throw new CriticalBehaviorStateError(error48);
|
|
119698
120336
|
}
|
|
120337
|
+
if (input.executionMode === "server" && error48?.code === "settings_superseded") {
|
|
120338
|
+
throw error48;
|
|
120339
|
+
}
|
|
119699
120340
|
invocationAttempts = mergeInvocationAttemptChains(
|
|
119700
120341
|
invocationAttempts,
|
|
119701
120342
|
Array.isArray(error48?.runtimeInvocationAttempts) ? error48.runtimeInvocationAttempts : []
|
|
@@ -119835,7 +120476,14 @@ ${reviewOutputContract}`;
|
|
|
119835
120476
|
units: 0,
|
|
119836
120477
|
tradability: entry.tradability,
|
|
119837
120478
|
reasoning: `Skipped by client runtime constraints: ${planAcceptance.reason_code || "capacity_reached"}`,
|
|
119838
|
-
executionContext: buildExecutionContextForSymbol(entry.symbol)
|
|
120479
|
+
executionContext: buildExecutionContextForSymbol(entry.symbol),
|
|
120480
|
+
...entry.decision === "BUY" || entry.decision === "SELL" ? {
|
|
120481
|
+
unsentOrder: {
|
|
120482
|
+
decision: entry.decision,
|
|
120483
|
+
units: entry.units,
|
|
120484
|
+
constraintReasonCode: planAcceptance.reason_code || "capacity_reached"
|
|
120485
|
+
}
|
|
120486
|
+
} : {}
|
|
119839
120487
|
};
|
|
119840
120488
|
}
|
|
119841
120489
|
throw new Error(buildRuntimeConstraintRejectionMessage({
|
|
@@ -120847,6 +121495,9 @@ var init_engine = __esm({
|
|
|
120847
121495
|
this._lastErrorReportCalls = null;
|
|
120848
121496
|
// The retry wait the API returned for this runtime's latest error report.
|
|
120849
121497
|
this._reportedProviderRetryAfterSeconds = null;
|
|
121498
|
+
// Whether the server answered the last error report with the failure shown
|
|
121499
|
+
// on its decision's card.
|
|
121500
|
+
this._reportedOrderFailureOnDecisionCard = false;
|
|
120850
121501
|
this._activeRuntimeContractIdentity = null;
|
|
120851
121502
|
this._contractRebindInFlight = false;
|
|
120852
121503
|
this._contractRebindExhausted = false;
|
|
@@ -121035,7 +121686,12 @@ var init_engine = __esm({
|
|
|
121035
121686
|
await this._trailingMaintenancePromise;
|
|
121036
121687
|
await this._pendingProtectionRecoveryPromise;
|
|
121037
121688
|
await waitForBrowserExchangeMutationSettlement(profileId);
|
|
121038
|
-
const stopCloseVenues =
|
|
121689
|
+
const stopCloseVenues = profileExchanges(
|
|
121690
|
+
paused.settings.exchanges,
|
|
121691
|
+
paused.settings.trading_symbols,
|
|
121692
|
+
paused.config.default_trading_symbols,
|
|
121693
|
+
paused.config.client_runtime_hyperliquid_perp_dexs?.allowed_dexes
|
|
121694
|
+
);
|
|
121039
121695
|
const { positions } = await fetchBrowserAccountState2({
|
|
121040
121696
|
publicRequestPriority: "trading_reduce",
|
|
121041
121697
|
config: paused.config,
|
|
@@ -123229,6 +123885,7 @@ var init_engine = __esm({
|
|
|
123229
123885
|
let cycleObservation = { stage: "setup" };
|
|
123230
123886
|
let cycleOutcome = "unknown";
|
|
123231
123887
|
let cycleReason = null;
|
|
123888
|
+
let cycleOrderFailure = null;
|
|
123232
123889
|
let cycleFailureStage = null;
|
|
123233
123890
|
let decisionSnapshotId = null;
|
|
123234
123891
|
let observationClosed = false;
|
|
@@ -123815,6 +124472,7 @@ var init_engine = __esm({
|
|
|
123815
124472
|
}
|
|
123816
124473
|
const executionResults = [];
|
|
123817
124474
|
const executionFailures = [];
|
|
124475
|
+
const executionFailureCauses = [];
|
|
123818
124476
|
const executionLeaseToken = () => {
|
|
123819
124477
|
const lease = getPersistedClientRuntimeServerLease(profileId);
|
|
123820
124478
|
return lease?.runtimeSessionId === sessionId && lease.deviceId === deviceId && lease.mode === "trader" ? lease.runtimeLeaseToken : null;
|
|
@@ -123838,6 +124496,7 @@ var init_engine = __esm({
|
|
|
123838
124496
|
}
|
|
123839
124497
|
const runPlan = async (plan, planIndex) => {
|
|
123840
124498
|
let planEntryOrderDispatched = false;
|
|
124499
|
+
let planExitOrderDispatched = false;
|
|
123841
124500
|
const decisionWallet = String(
|
|
123842
124501
|
plan.executionContext.walletAddress || ""
|
|
123843
124502
|
).trim().toLowerCase();
|
|
@@ -123930,100 +124589,171 @@ var init_engine = __esm({
|
|
|
123930
124589
|
if (dispatchKind === "entry") {
|
|
123931
124590
|
planEntryOrderDispatched = true;
|
|
123932
124591
|
}
|
|
124592
|
+
if (dispatchKind === "exit") {
|
|
124593
|
+
planExitOrderDispatched = true;
|
|
124594
|
+
}
|
|
123933
124595
|
this._executionFinalizationRequired = true;
|
|
123934
124596
|
},
|
|
123935
124597
|
shouldCancelBeforeExchangeOrderDispatch: () => this._windowHandoffRequested
|
|
123936
124598
|
});
|
|
123937
124599
|
} catch (executionError) {
|
|
124600
|
+
const committedReports = getCommittedExecutionReports(executionError);
|
|
124601
|
+
const committedOrder = getCommittedDecisionOrder(executionError);
|
|
124602
|
+
const plannedUnits = Number.isFinite(Number(plan.units)) ? Math.max(0, Math.trunc(Number(plan.units))) : 0;
|
|
123938
124603
|
if (isClientRuntimeWindowHandoffBeforePlanDispatch(executionError)) {
|
|
123939
124604
|
const handoffCleanup = getClientRuntimeWindowHandoffCleanup(executionError);
|
|
123940
|
-
if (handoffCleanup) {
|
|
124605
|
+
if (handoffCleanup || committedReports.length > 0) {
|
|
123941
124606
|
this._executionFinalizationRequired = true;
|
|
123942
124607
|
return { control: "break", result: {
|
|
123943
|
-
status: "skipped",
|
|
124608
|
+
status: committedReports.length > 0 ? "executed" : "skipped",
|
|
123944
124609
|
intent: "hold",
|
|
123945
124610
|
side: null,
|
|
123946
124611
|
reduceOnly: false,
|
|
123947
|
-
requestedUnits:
|
|
124612
|
+
requestedUnits: plannedUnits,
|
|
123948
124613
|
targetSignedUnits: 0,
|
|
123949
124614
|
executedSizeAsset: 0,
|
|
123950
|
-
|
|
123951
|
-
|
|
123952
|
-
handoffCleanup,
|
|
124615
|
+
...committedOrder ?? {},
|
|
124616
|
+
executionReports: committedReports,
|
|
124617
|
+
message: handoffCleanup ? "Stopped before protective replacement dispatch; cleanup remains blocked." : "Stopped after the order for ownership handoff.",
|
|
124618
|
+
...handoffCleanup ? { handoffCleanup } : {},
|
|
123953
124619
|
executionSnapshotId: `handoff-cleanup-${planIndex + 1}-${Date.now()}`,
|
|
123954
124620
|
executionSnapshotCapturedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
123955
124621
|
} };
|
|
123956
124622
|
}
|
|
123957
124623
|
return { control: "break" };
|
|
123958
124624
|
}
|
|
123959
|
-
const committedReports = getCommittedExecutionReports(executionError);
|
|
123960
124625
|
const abortedAfterCommittedOrder = committedReports.length > 0 && (analysisAbortController.signal.aborted || isRuntimeAbortError(executionError));
|
|
123961
124626
|
if (!abortedAfterCommittedOrder && (analysisAbortController.signal.aborted || isRuntimeAbortError(executionError)) || isRuntimeContractMismatchError(executionError) || isClientExecutionModeMismatchError(executionError) || isClientRuntimeSessionStoppedError(executionError) || isClientRuntimeLeaseAuthError(executionError) || isTransientRuntimeConflictError(executionError) && committedReports.length === 0) {
|
|
123962
124627
|
throw executionError;
|
|
123963
124628
|
}
|
|
123964
124629
|
const sanitizedReason = getSanitizedRuntimeErrorMessage(executionError) || "Unknown runtime execution error.";
|
|
123965
|
-
|
|
123966
|
-
|
|
123967
|
-
|
|
123968
|
-
|
|
123969
|
-
reasonCode: typeof typedExecutionError?.reasonCode === "string" ? typedExecutionError.reasonCode : planEntryOrderDispatched ? "outcome_unknown" : "local_safety_block"
|
|
123970
|
-
});
|
|
123971
|
-
const failureDiagnostics = getExchangeFailureDiagnostics(executionError);
|
|
123972
|
-
if (!abortedAfterCommittedOrder) {
|
|
123973
|
-
executionFailures.push({
|
|
123974
|
-
symbol: plan.executionContext.symbol,
|
|
123975
|
-
projection: projectedFailure
|
|
124630
|
+
if (committedOrder !== null) {
|
|
124631
|
+
const stepFailure = projectExecutionErrorContract({
|
|
124632
|
+
error: executionError,
|
|
124633
|
+
symbol: plan.executionContext.symbol
|
|
123976
124634
|
});
|
|
123977
|
-
|
|
123978
|
-
|
|
123979
|
-
|
|
123980
|
-
|
|
123981
|
-
|
|
123982
|
-
|
|
123983
|
-
|
|
123984
|
-
|
|
123985
|
-
|
|
123986
|
-
|
|
123987
|
-
|
|
123988
|
-
|
|
123989
|
-
|
|
123990
|
-
|
|
123991
|
-
|
|
123992
|
-
|
|
123993
|
-
|
|
123994
|
-
|
|
123995
|
-
|
|
123996
|
-
|
|
123997
|
-
|
|
123998
|
-
|
|
123999
|
-
|
|
124000
|
-
|
|
124001
|
-
|
|
124002
|
-
|
|
124003
|
-
|
|
124004
|
-
|
|
124005
|
-
|
|
124635
|
+
appendRuntimeDebugEvent({
|
|
124636
|
+
label: "execution_plan_failed_after_order",
|
|
124637
|
+
note: [
|
|
124638
|
+
`cycle_id=${result.cycleId}`,
|
|
124639
|
+
`decision_snapshot_id=${result.decisionSnapshotId}`,
|
|
124640
|
+
`index=${planIndex + 1}/${executionPlans.length}`,
|
|
124641
|
+
`symbol=${plan.executionContext.symbol}`,
|
|
124642
|
+
`decision=${plan.decision}`,
|
|
124643
|
+
`error=${sanitizedReason}`
|
|
124644
|
+
].join(" "),
|
|
124645
|
+
outcome: "error"
|
|
124646
|
+
});
|
|
124647
|
+
executionResult = {
|
|
124648
|
+
status: "executed",
|
|
124649
|
+
...committedOrder,
|
|
124650
|
+
message: stepFailure.message,
|
|
124651
|
+
executionSnapshotId: `execution-error-${planIndex + 1}-${Date.now()}`,
|
|
124652
|
+
executionSnapshotCapturedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
124653
|
+
executionReports: abortedAfterCommittedOrder ? committedReports : [...committedReports, {
|
|
124654
|
+
order_id: null,
|
|
124655
|
+
symbol: plan.executionContext.symbol,
|
|
124656
|
+
action: "PROTECTIVE_RECONCILIATION",
|
|
124657
|
+
status: "failed",
|
|
124658
|
+
execution_metadata: {
|
|
124659
|
+
reason_code: stepFailure.reason_code,
|
|
124660
|
+
execution_stage: stepFailure.execution_stage,
|
|
124661
|
+
dispatch_outcome: stepFailure.dispatch_outcome,
|
|
124662
|
+
operation_stage: committedOrder.intent === "close" ? "post_close_protection" : "post_entry_protection",
|
|
124663
|
+
error: stepFailure.message,
|
|
124664
|
+
cycle_id: result.cycleId,
|
|
124665
|
+
decision_snapshot_id: result.decisionSnapshotId
|
|
124666
|
+
}
|
|
124667
|
+
}]
|
|
124668
|
+
};
|
|
124669
|
+
if (abortedAfterCommittedOrder) {
|
|
124670
|
+
this._executionFinalizationRequired = true;
|
|
124671
|
+
return { control: "break", result: executionResult };
|
|
124672
|
+
}
|
|
124673
|
+
} else {
|
|
124674
|
+
const typedExecutionError = executionError;
|
|
124675
|
+
const planOrderMayHaveGoneOut = planEntryOrderDispatched || planExitOrderDispatched && committedReports.length === 0;
|
|
124676
|
+
const projectedFailure = projectExecutionErrorContract({
|
|
124677
|
+
error: executionError,
|
|
124006
124678
|
symbol: plan.executionContext.symbol,
|
|
124007
|
-
|
|
124008
|
-
|
|
124009
|
-
|
|
124010
|
-
|
|
124011
|
-
|
|
124012
|
-
|
|
124013
|
-
|
|
124014
|
-
|
|
124015
|
-
|
|
124016
|
-
|
|
124017
|
-
|
|
124018
|
-
|
|
124019
|
-
|
|
124020
|
-
|
|
124021
|
-
|
|
124022
|
-
|
|
124023
|
-
|
|
124679
|
+
reasonCode: typeof typedExecutionError?.reasonCode === "string" ? typedExecutionError.reasonCode : planOrderMayHaveGoneOut ? "outcome_unknown" : "local_safety_block"
|
|
124680
|
+
});
|
|
124681
|
+
const failureDiagnostics = getExchangeFailureDiagnostics(executionError);
|
|
124682
|
+
if (!abortedAfterCommittedOrder) {
|
|
124683
|
+
executionFailures.push({
|
|
124684
|
+
symbol: plan.executionContext.symbol,
|
|
124685
|
+
projection: projectedFailure
|
|
124686
|
+
});
|
|
124687
|
+
executionFailureCauses.push(executionError);
|
|
124688
|
+
}
|
|
124689
|
+
appendRuntimeDebugEvent({
|
|
124690
|
+
label: "execution_plan_failed",
|
|
124691
|
+
note: [
|
|
124692
|
+
`cycle_id=${result.cycleId}`,
|
|
124693
|
+
`decision_snapshot_id=${result.decisionSnapshotId}`,
|
|
124694
|
+
`index=${planIndex + 1}/${executionPlans.length}`,
|
|
124695
|
+
`symbol=${plan.executionContext.symbol}`,
|
|
124696
|
+
`decision=${plan.decision}`,
|
|
124697
|
+
`units=${plan.units}`,
|
|
124698
|
+
`error=${sanitizedReason}`
|
|
124699
|
+
].join(" "),
|
|
124700
|
+
outcome: "error"
|
|
124701
|
+
});
|
|
124702
|
+
const flipCloseCommitted = committedReports.some((report) => report.status === "executed" && report.execution_metadata?.decision_leg === "flip_close");
|
|
124703
|
+
const planSide = String(plan.decision || "").toUpperCase() === "BUY" ? "buy" : String(plan.decision || "").toUpperCase() === "SELL" ? "sell" : null;
|
|
124704
|
+
executionResult = {
|
|
124705
|
+
status: committedReports.length > 0 ? "executed" : "skipped",
|
|
124706
|
+
intent: flipCloseCommitted ? "flip" : "hold",
|
|
124707
|
+
side: flipCloseCommitted ? planSide : null,
|
|
124708
|
+
reduceOnly: false,
|
|
124709
|
+
requestedUnits: plannedUnits,
|
|
124710
|
+
targetSignedUnits: 0,
|
|
124711
|
+
executedSizeAsset: 0,
|
|
124712
|
+
message: projectedFailure.message,
|
|
124713
|
+
executionSnapshotId: `execution-error-${planIndex + 1}-${Date.now()}`,
|
|
124714
|
+
executionSnapshotCapturedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
124715
|
+
executionReports: [...committedReports, {
|
|
124716
|
+
order_id: null,
|
|
124717
|
+
symbol: plan.executionContext.symbol,
|
|
124718
|
+
action: String(plan.decision || "UNKNOWN").toUpperCase(),
|
|
124719
|
+
status: "failed",
|
|
124720
|
+
execution_metadata: {
|
|
124721
|
+
error: projectedFailure.message,
|
|
124722
|
+
reason_code: projectedFailure.reason_code,
|
|
124723
|
+
execution_stage: projectedFailure.execution_stage,
|
|
124724
|
+
dispatch_outcome: projectedFailure.dispatch_outcome,
|
|
124725
|
+
cycle_id: result.cycleId,
|
|
124726
|
+
decision_snapshot_id: result.decisionSnapshotId,
|
|
124727
|
+
...flipCloseCommitted ? { decision_leg: "entry" } : {},
|
|
124728
|
+
...failureDiagnostics ?? {}
|
|
124729
|
+
}
|
|
124730
|
+
}]
|
|
124731
|
+
};
|
|
124732
|
+
if (abortedAfterCommittedOrder) {
|
|
124733
|
+
this._executionFinalizationRequired = true;
|
|
124734
|
+
return { control: "break", result: executionResult };
|
|
124735
|
+
}
|
|
124024
124736
|
}
|
|
124025
124737
|
}
|
|
124026
124738
|
}
|
|
124739
|
+
if (plan.unsentOrder) {
|
|
124740
|
+
executionResult = {
|
|
124741
|
+
...executionResult,
|
|
124742
|
+
executionReports: [...executionResult.executionReports, {
|
|
124743
|
+
order_id: null,
|
|
124744
|
+
symbol: plan.executionContext.symbol,
|
|
124745
|
+
action: plan.unsentOrder.decision,
|
|
124746
|
+
status: "blocked",
|
|
124747
|
+
execution_metadata: {
|
|
124748
|
+
reason_code: "execution_capacity_refused",
|
|
124749
|
+
constraint_reason_code: plan.unsentOrder.constraintReasonCode,
|
|
124750
|
+
requested_units: plan.unsentOrder.units,
|
|
124751
|
+
cycle_id: result.cycleId,
|
|
124752
|
+
decision_snapshot_id: result.decisionSnapshotId
|
|
124753
|
+
}
|
|
124754
|
+
}]
|
|
124755
|
+
};
|
|
124756
|
+
}
|
|
124027
124757
|
return { control: "continue", result: executionResult };
|
|
124028
124758
|
};
|
|
124029
124759
|
const recordPlanResult = (executionResult) => {
|
|
@@ -124226,16 +124956,23 @@ var init_engine = __esm({
|
|
|
124226
124956
|
cycleReason = "execution_failed";
|
|
124227
124957
|
cycleFailureStage = "execution";
|
|
124228
124958
|
const primaryFailure = selectPrimaryExecutionFailure(executionFailures);
|
|
124229
|
-
|
|
124230
|
-
|
|
124231
|
-
|
|
124232
|
-
|
|
124233
|
-
|
|
124234
|
-
|
|
124235
|
-
|
|
124236
|
-
|
|
124237
|
-
|
|
124238
|
-
|
|
124959
|
+
const reportedFailures = this._expectedExecutionMode === "server" ? executionFailures.filter((_, index) => executionFailureCauses.indexOf(executionFailureCauses[index]) === index) : primaryFailure ? [primaryFailure] : [];
|
|
124960
|
+
this._lastError = null;
|
|
124961
|
+
for (const failure2 of reportedFailures) {
|
|
124962
|
+
await this.reportError(failure2.projection.message, {
|
|
124963
|
+
fatal: false,
|
|
124964
|
+
model: result.model,
|
|
124965
|
+
modelSource: result.model_source ?? result.provider,
|
|
124966
|
+
executionSymbol: failure2.symbol,
|
|
124967
|
+
executionReasonCode: failure2.projection.reason_code,
|
|
124968
|
+
executionStage: failure2.projection.execution_stage,
|
|
124969
|
+
dispatchOutcome: failure2.projection.dispatch_outcome,
|
|
124970
|
+
recordedOrderFailure: true
|
|
124971
|
+
});
|
|
124972
|
+
if (this._reportedOrderFailureOnDecisionCard) {
|
|
124973
|
+
cycleOrderFailure = failure2.projection.message;
|
|
124974
|
+
}
|
|
124975
|
+
}
|
|
124239
124976
|
return;
|
|
124240
124977
|
}
|
|
124241
124978
|
}
|
|
@@ -124502,7 +125239,7 @@ var init_engine = __esm({
|
|
|
124502
125239
|
requestId,
|
|
124503
125240
|
outcome: cycleOutcome,
|
|
124504
125241
|
reason: cycleReason,
|
|
124505
|
-
error: cycleOutcome === "failed" ? this._lastError : null,
|
|
125242
|
+
error: cycleOutcome === "failed" ? this._lastError ?? cycleOrderFailure : null,
|
|
124506
125243
|
decisionSubmitted,
|
|
124507
125244
|
executionOccurred: executedExchangeOrderInCycle
|
|
124508
125245
|
};
|
|
@@ -124695,6 +125432,7 @@ var init_engine = __esm({
|
|
|
124695
125432
|
}
|
|
124696
125433
|
async reportError(reason, options) {
|
|
124697
125434
|
this._reportedProviderRetryAfterSeconds = null;
|
|
125435
|
+
this._reportedOrderFailureOnDecisionCard = false;
|
|
124698
125436
|
if (this._isStopping) {
|
|
124699
125437
|
this._lastError = null;
|
|
124700
125438
|
return null;
|
|
@@ -124729,10 +125467,13 @@ var init_engine = __esm({
|
|
|
124729
125467
|
});
|
|
124730
125468
|
const projectedErrorWithoutWarning = String(projected.error_message || "").replace(/^\s*⚠️?\s*/u, "").trim();
|
|
124731
125469
|
const persistedError = executionProjection?.message ?? (projectedErrorWithoutWarning === sanitizedReason ? sanitizedReason : projected.error_message);
|
|
124732
|
-
|
|
125470
|
+
const awaitsDecisionCardAnswer = options?.recordedOrderFailure === true && !isFatal;
|
|
125471
|
+
if (!awaitsDecisionCardAnswer) {
|
|
125472
|
+
this._lastError = persistedError;
|
|
125473
|
+
}
|
|
124733
125474
|
if (isFatal) {
|
|
124734
125475
|
this._setState("error");
|
|
124735
|
-
} else {
|
|
125476
|
+
} else if (!awaitsDecisionCardAnswer) {
|
|
124736
125477
|
this._notifyListeners();
|
|
124737
125478
|
}
|
|
124738
125479
|
this.recordLocalBreadcrumb("runtime_error_detected", projected.error_message, {
|
|
@@ -124772,13 +125513,18 @@ var init_engine = __esm({
|
|
|
124772
125513
|
requestTimeoutMs: this._settlementRequestTimeoutMs ?? void 0
|
|
124773
125514
|
}
|
|
124774
125515
|
);
|
|
125516
|
+
const shownOnDecisionCard = awaitsDecisionCardAnswer && response.shown_on_decision_card === true;
|
|
125517
|
+
this._reportedOrderFailureOnDecisionCard = shownOnDecisionCard;
|
|
125518
|
+
if (!shownOnDecisionCard) {
|
|
125519
|
+
this._lastError = persistedError;
|
|
125520
|
+
}
|
|
124775
125521
|
const accepted = this._setRuntimeStatus(response.runtime, "error_report");
|
|
124776
125522
|
const retryAfterSeconds = Number(response.provider_retry_after_seconds);
|
|
124777
125523
|
this._reportedProviderRetryAfterSeconds = accepted && response.provider_retry_after_seconds != null && Number.isFinite(retryAfterSeconds) && retryAfterSeconds >= 0 ? retryAfterSeconds : null;
|
|
124778
|
-
this._lastError = persistedError;
|
|
124779
125524
|
this._notifyListeners();
|
|
124780
125525
|
return accepted ? response.runtime ?? null : null;
|
|
124781
125526
|
} catch (error48) {
|
|
125527
|
+
this._lastError = persistedError;
|
|
124782
125528
|
if (isClientRuntimeReleasedError(error48)) {
|
|
124783
125529
|
await this._handleRuntimeReleased("error_report", { deferUntilExecutionLoopSettles: true });
|
|
124784
125530
|
return null;
|
|
@@ -125314,7 +126060,7 @@ var init_engine = __esm({
|
|
|
125314
126060
|
positionCloseFailures: 0
|
|
125315
126061
|
};
|
|
125316
126062
|
if (context.close_positions) {
|
|
125317
|
-
const stalePositions = positionsOnVenues(evaluation.accountState?.positions ?? [], evaluation.
|
|
126063
|
+
const stalePositions = positionsOnVenues(evaluation.accountState?.positions ?? [], evaluation.closeVenues);
|
|
125318
126064
|
try {
|
|
125319
126065
|
const signingKey = String(
|
|
125320
126066
|
this._deviceSecrets?.hyperliquidSigningKey || ""
|
|
@@ -125343,8 +126089,8 @@ var init_engine = __esm({
|
|
|
125343
126089
|
tickerPrice: 0,
|
|
125344
126090
|
leverage: 1,
|
|
125345
126091
|
aggregatePerpDexs: true,
|
|
125346
|
-
// The exchanges
|
|
125347
|
-
perpDexScope: evaluation.
|
|
126092
|
+
// The bot's exchanges: positions elsewhere are not the bot's to close.
|
|
126093
|
+
perpDexScope: evaluation.closeVenues?.filter(Boolean),
|
|
125348
126094
|
forceRefresh: true,
|
|
125349
126095
|
sessionId: this._sessionId ?? void 0,
|
|
125350
126096
|
signal: refreshController.signal
|
|
@@ -125368,7 +126114,7 @@ var init_engine = __esm({
|
|
|
125368
126114
|
config: config2,
|
|
125369
126115
|
signingKey,
|
|
125370
126116
|
timeoutSeconds: closeTimeoutSeconds,
|
|
125371
|
-
venues: evaluation.
|
|
126117
|
+
venues: evaluation.closeVenues
|
|
125372
126118
|
});
|
|
125373
126119
|
} else {
|
|
125374
126120
|
closeSummary = {
|