@vtxmacro/cli 2026.10.31 → 2026.10.33
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 +1 -0
- package/bin/vtx-mcp.js +2 -1
- package/bin/vtx-service-bootstrap.js +2 -1
- package/bin/vtx-service-launcher.js +1 -0
- package/bin/vtx.js +1180 -172
- 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.33", 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
|
|
|
@@ -1195,6 +1195,7 @@ var init_runtime_policy_generated = __esm({
|
|
|
1195
1195
|
runtime: {
|
|
1196
1196
|
assignment_page_default_limit: 20,
|
|
1197
1197
|
client_candidate_owner_lease_grace_ms: 6e4,
|
|
1198
|
+
bot_switch_max_retries: 2,
|
|
1198
1199
|
client_server_heartbeats_per_owner_lease: 2,
|
|
1199
1200
|
client_server_heartbeat_min_ms: 5e3,
|
|
1200
1201
|
client_server_heartbeat_max_ms: 3e4
|
|
@@ -1472,7 +1473,7 @@ var init_runtime_policy_generated = __esm({
|
|
|
1472
1473
|
});
|
|
1473
1474
|
|
|
1474
1475
|
// lib/constants.ts
|
|
1475
|
-
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, PROMPT_RESCUE_ASKS_PER_CYCLE_BUILD, 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_RELATIVE_VOLUME_DIGITS, BINARY_RADIX, 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;
|
|
1476
|
+
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, PROMPT_RESCUE_ASKS_PER_CYCLE_BUILD, 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, NATIVE_PROTECTION_RECORD_WITH_LOTS_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_RELATIVE_VOLUME_DIGITS, BINARY_RADIX, 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;
|
|
1476
1477
|
var init_constants = __esm({
|
|
1477
1478
|
"lib/constants.ts"() {
|
|
1478
1479
|
"use strict";
|
|
@@ -1772,6 +1773,7 @@ var init_constants = __esm({
|
|
|
1772
1773
|
};
|
|
1773
1774
|
INFERENCE_MCP_SCHEMA_PROBE_MAX_DEPTH = 4;
|
|
1774
1775
|
INFERENCE_HOST_PROCESS_LOCK_RECORD_SCHEMA_VERSION = 2;
|
|
1776
|
+
NATIVE_PROTECTION_RECORD_WITH_LOTS_VERSION = 2;
|
|
1775
1777
|
INFERENCE_HOST_RECLAIM_GUARD_CREATE_PASSES = 2;
|
|
1776
1778
|
LINUX_PROC_STAT_COMM_TERMINATOR_CHARS = 2;
|
|
1777
1779
|
INFERENCE_HOST_RANDOM_BYTES = {
|
|
@@ -21025,6 +21027,7 @@ var init_runtime_policy_generated2 = __esm({
|
|
|
21025
21027
|
runtime: {
|
|
21026
21028
|
assignment_page_default_limit: 20,
|
|
21027
21029
|
client_candidate_owner_lease_grace_ms: 6e4,
|
|
21030
|
+
bot_switch_max_retries: 2,
|
|
21028
21031
|
client_server_heartbeats_per_owner_lease: 2,
|
|
21029
21032
|
client_server_heartbeat_min_ms: 5e3,
|
|
21030
21033
|
client_server_heartbeat_max_ms: 3e4
|
|
@@ -21860,8 +21863,8 @@ var init_external_inference_contract = __esm({
|
|
|
21860
21863
|
if (value.runtime_binding.binding_kind !== value.execution_mode && !(value.runtime_binding.binding_kind === "historical_chat" && value.execution_mode === "server" && value.use_case === "decision_chat")) {
|
|
21861
21864
|
context.addIssue({ code: "custom", message: "runtime binding must match execution_mode", path: ["runtime_binding", "binding_kind"] });
|
|
21862
21865
|
}
|
|
21863
|
-
if (value.lane === "screener" && value.runtime_binding.bot_mode
|
|
21864
|
-
context.addIssue({ code: "custom", message: "screener jobs require a confirmed
|
|
21866
|
+
if (value.lane === "screener" && !["trader", "assistant"].includes(value.runtime_binding.bot_mode)) {
|
|
21867
|
+
context.addIssue({ code: "custom", message: "screener jobs require a confirmed bot binding", path: ["runtime_binding", "bot_mode"] });
|
|
21865
21868
|
}
|
|
21866
21869
|
if (value.controller.host_id !== value.host_id) {
|
|
21867
21870
|
context.addIssue({ code: "custom", message: "controller host_id must match job host_id", path: ["controller", "host_id"] });
|
|
@@ -57836,6 +57839,7 @@ async function getLLMConfig(cookie, profileId, signal) {
|
|
|
57836
57839
|
method: "GET",
|
|
57837
57840
|
headers,
|
|
57838
57841
|
credentials: "include",
|
|
57842
|
+
cache: "no-store",
|
|
57839
57843
|
signal: requestSignal
|
|
57840
57844
|
});
|
|
57841
57845
|
if (held && response.status === HTTP_STATUS.NOT_MODIFIED) return JSON.parse(held.text);
|
|
@@ -57960,6 +57964,17 @@ var init_account_summary = __esm({
|
|
|
57960
57964
|
}
|
|
57961
57965
|
});
|
|
57962
57966
|
|
|
57967
|
+
// lib/api/mobile-notifications.ts
|
|
57968
|
+
var init_mobile_notifications = __esm({
|
|
57969
|
+
"lib/api/mobile-notifications.ts"() {
|
|
57970
|
+
"use strict";
|
|
57971
|
+
init_define_VTX_EXO_POLICY();
|
|
57972
|
+
init_define_VTX_GROK_POLICY();
|
|
57973
|
+
init_define_VTX_PI_MODEL_POLICY();
|
|
57974
|
+
init_shared();
|
|
57975
|
+
}
|
|
57976
|
+
});
|
|
57977
|
+
|
|
57963
57978
|
// lib/runtime/hyperliquid-account-mode-contract.ts
|
|
57964
57979
|
function resolveExactHyperliquidAccountMode(userAbstraction, ...dexEvidence) {
|
|
57965
57980
|
const mode = extractCanonicalHyperliquidAccountMode(userAbstraction);
|
|
@@ -59393,9 +59408,15 @@ var init_runtime_error_reason_rules = __esm({
|
|
|
59393
59408
|
{ contains: "hyperliquid fresh public read returned non-json" },
|
|
59394
59409
|
{ contains: "hyperliquid public freshness bracket moved backwards" }
|
|
59395
59410
|
] } },
|
|
59396
|
-
{ reason_code: "behavior_state_unavailable", when: {
|
|
59397
|
-
{
|
|
59398
|
-
|
|
59411
|
+
{ reason_code: "behavior_state_unavailable", when: { any: [
|
|
59412
|
+
{ all: [
|
|
59413
|
+
{ contains: "your prompt on the ai page contains something vtx can't use" },
|
|
59414
|
+
{ contains: "next scheduled cycle" }
|
|
59415
|
+
] },
|
|
59416
|
+
{ all: [
|
|
59417
|
+
{ contains: "critical behavior context could not be constructed" },
|
|
59418
|
+
{ contains: "next scheduled cycle" }
|
|
59419
|
+
] }
|
|
59399
59420
|
] } },
|
|
59400
59421
|
{ reason_code: "hyperliquid_wallet_not_authorized", when: { any: [
|
|
59401
59422
|
{ contains: "hyperliquid api wallet is not authorized" },
|
|
@@ -59514,6 +59535,8 @@ var init_runtime_error_reason_rules = __esm({
|
|
|
59514
59535
|
model_unavailable: { transient: false, severity: "ERROR" },
|
|
59515
59536
|
outcome_unknown: { transient: true, severity: "ERROR" },
|
|
59516
59537
|
private_node_stale: { transient: true, severity: "ERROR" },
|
|
59538
|
+
protective_order_not_placed: { transient: false, severity: "WARN" },
|
|
59539
|
+
protective_order_unmanaged: { transient: false, severity: "WARN" },
|
|
59517
59540
|
provider_network_failure: { transient: true, severity: "ERROR" },
|
|
59518
59541
|
provider_not_configured: { transient: false, severity: "ERROR" },
|
|
59519
59542
|
provider_unavailable: { transient: true, severity: "ERROR" },
|
|
@@ -59869,9 +59892,12 @@ var init_error_surface_contract = __esm({
|
|
|
59869
59892
|
const detailLower = normalizedDetail.toLowerCase();
|
|
59870
59893
|
const classificationBasis = detailLower || lowered;
|
|
59871
59894
|
const pausePrefix = runtimePausePrefix(Boolean(isAssistantActive));
|
|
59872
|
-
if (classificationBasis.includes("
|
|
59895
|
+
if (classificationBasis.includes("behavior memory is unavailable for this trading cycle")) {
|
|
59873
59896
|
return `${pausePrefix}: Critical behavior context could not be constructed for this cycle. The cycle was skipped safely; VTX will retry at the next scheduled cycle.`;
|
|
59874
59897
|
}
|
|
59898
|
+
if (classificationBasis.includes("critical behavior state is unavailable for this trading cycle")) {
|
|
59899
|
+
return `${pausePrefix}: Your prompt on the AI page contains something VTX can't use, for example a <behavior_state> line in the System Prompt that doesn't start with "- ". Fix the prompt; VTX skipped this cycle and will retry at the next scheduled cycle.`;
|
|
59900
|
+
}
|
|
59875
59901
|
if (classificationBasis.includes(
|
|
59876
59902
|
"client runtime decision persistence deadline exceeded after the ai run completed"
|
|
59877
59903
|
)) {
|
|
@@ -68468,12 +68494,12 @@ function getKzgLibrary(kzg) {
|
|
|
68468
68494
|
return { blobToKzgCommitment, computeBlobKzgProof };
|
|
68469
68495
|
}
|
|
68470
68496
|
function getVersionedHash(version3, hash5) {
|
|
68471
|
-
let
|
|
68472
|
-
while (
|
|
68473
|
-
|
|
68497
|
+
let versioned2 = version3.toString(16);
|
|
68498
|
+
while (versioned2.length < 2) {
|
|
68499
|
+
versioned2 = "0" + versioned2;
|
|
68474
68500
|
}
|
|
68475
|
-
|
|
68476
|
-
return "0x" +
|
|
68501
|
+
versioned2 += sha2563(hash5).substring(4);
|
|
68502
|
+
return "0x" + versioned2;
|
|
68477
68503
|
}
|
|
68478
68504
|
function handleAddress(value) {
|
|
68479
68505
|
if (value === "0x") {
|
|
@@ -90550,7 +90576,7 @@ var init_hyperliquid_signer = __esm({
|
|
|
90550
90576
|
});
|
|
90551
90577
|
|
|
90552
90578
|
// lib/runtime/hyperliquid-client.ts
|
|
90553
|
-
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, parseOpenOrderNonNegativeNumber, NATIVE_FIRED_TRIGGER_CONDITION, 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, acknowledgementLookupPacing, lookupUntilListed, resolveHyperliquidTriggerAcknowledgements, resolveHyperliquidModifyAcknowledgement, isDefinitiveHyperliquidExchangeResponse, extractDefinitiveHyperliquidOrderId, CANONICAL_POSITIVE_DECIMAL_PATTERN, extractCanonicalHyperliquidOrderStateAcknowledgement, extractCanonicalHyperliquidOrderStateAcknowledgements, extractCanonicalHyperliquidFilledOrderAcknowledgement, extractDefinitiveHyperliquidOrderMemberResults, buildHyperliquidOrderDiagnostics, loadClientExecutionReferenceEvidence, sha256Hex, extractSignedPayloadClientOrderId, extractSignedPayloadMutationCorrelation, assertDurableMutationMatchesSignedAction, exchangeRejectionReason, exchangeActionPriority, submitHyperliquidExchangePayload;
|
|
90579
|
+
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, parseOpenOrderNonNegativeNumber, NATIVE_FIRED_TRIGGER_CONDITION, 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, TRAILING_PCT_PATTERN, buildHyperliquidTrailingStopPayload, extractHyperliquidExchangeError, acknowledgementLookupPacing, lookupUntilListed, resolveHyperliquidTriggerAcknowledgements, readHyperliquidTrailingStopAcknowledgement, resolveHyperliquidModifyAcknowledgement, isDefinitiveHyperliquidExchangeResponse, extractDefinitiveHyperliquidOrderId, CANONICAL_POSITIVE_DECIMAL_PATTERN, extractCanonicalHyperliquidOrderStateAcknowledgement, extractCanonicalHyperliquidOrderStateAcknowledgements, extractCanonicalHyperliquidFilledOrderAcknowledgement, extractDefinitiveHyperliquidOrderMemberResults, buildHyperliquidOrderDiagnostics, loadClientExecutionReferenceEvidence, sha256Hex, extractSignedPayloadClientOrderId, extractSignedPayloadMutationCorrelation, assertDurableMutationMatchesSignedAction, exchangeRejectionReason, exchangeActionPriority, submitHyperliquidExchangePayload;
|
|
90554
90580
|
var init_hyperliquid_client = __esm({
|
|
90555
90581
|
"lib/runtime/hyperliquid-client.ts"() {
|
|
90556
90582
|
"use strict";
|
|
@@ -91645,7 +91671,12 @@ var init_hyperliquid_client = __esm({
|
|
|
91645
91671
|
};
|
|
91646
91672
|
fetchBrowserAccountState = async (input) => {
|
|
91647
91673
|
const user = requireWalletAddress(input.walletAddress);
|
|
91648
|
-
const
|
|
91674
|
+
const dex = String(input.dex ?? "").trim().toLowerCase();
|
|
91675
|
+
const payload = await postHyperliquidInfo(
|
|
91676
|
+
input,
|
|
91677
|
+
{ type: "clearinghouseState", user, ...dex ? { dex } : {} },
|
|
91678
|
+
"hyperliquid.clearinghouseState"
|
|
91679
|
+
);
|
|
91649
91680
|
if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
|
|
91650
91681
|
throw new Error("Malformed Hyperliquid clearinghouseState response.");
|
|
91651
91682
|
}
|
|
@@ -91663,8 +91694,10 @@ var init_hyperliquid_client = __esm({
|
|
|
91663
91694
|
const positions = Array.isArray(state2.assetPositions) ? state2.assetPositions.map((entry) => {
|
|
91664
91695
|
const assetPosition = entry;
|
|
91665
91696
|
const position = assetPosition.position || {};
|
|
91697
|
+
const coin = String(position.coin || assetPosition.coin || "");
|
|
91666
91698
|
return {
|
|
91667
|
-
|
|
91699
|
+
// A HIP-3 DEX may name its coins without the DEX.
|
|
91700
|
+
symbol: dex && coin && !coin.includes(":") ? `${dex}:${coin}` : coin,
|
|
91668
91701
|
size: toFiniteNumber(position.szi, 0),
|
|
91669
91702
|
entry_price: position.entryPx == null ? null : toFiniteNumber(position.entryPx, 0),
|
|
91670
91703
|
unrealized_pnl: position.unrealizedPnl == null ? null : toFiniteNumber(position.unrealizedPnl, 0),
|
|
@@ -91694,7 +91727,7 @@ var init_hyperliquid_client = __esm({
|
|
|
91694
91727
|
};
|
|
91695
91728
|
fetchBrowserPosition = async (input) => {
|
|
91696
91729
|
const symbol2 = normalizeSymbol(input.symbol);
|
|
91697
|
-
const accountState = await fetchBrowserAccountState(input);
|
|
91730
|
+
const accountState = await fetchBrowserAccountState({ ...input, dex: getHyperliquidMarketDex(symbol2) });
|
|
91698
91731
|
return accountState.positions.find((position) => normalizeSymbol(position.symbol) === symbol2) ?? null;
|
|
91699
91732
|
};
|
|
91700
91733
|
buildHyperliquidOrderWire = async (input, tif, price, priceKind) => {
|
|
@@ -92029,6 +92062,52 @@ var init_hyperliquid_client = __esm({
|
|
|
92029
92062
|
order
|
|
92030
92063
|
});
|
|
92031
92064
|
};
|
|
92065
|
+
TRAILING_PCT_PATTERN = /^\d+(\.\d+)?%$/;
|
|
92066
|
+
buildHyperliquidTrailingStopPayload = async (input) => {
|
|
92067
|
+
input = { ...input, publicRequestPriority: "trading_reduce" };
|
|
92068
|
+
assertPositiveNumber(input.size, "Hyperliquid trailing stop size");
|
|
92069
|
+
const { asset_index: assetIndex, sz_decimals: sizeDecimals } = await resolveHyperliquidAsset(input);
|
|
92070
|
+
const side = normalizeOrderSide(input.side);
|
|
92071
|
+
const roundedSize = quantizeHyperliquidOrderSizeValue(input.size, sizeDecimals, "nearest");
|
|
92072
|
+
assertPositiveNumber(roundedSize, "Hyperliquid trailing stop size");
|
|
92073
|
+
const sizeWire = formatSizeWire(roundedSize, sizeDecimals);
|
|
92074
|
+
const sizeValidation = validateHyperliquidSizeWire(sizeWire, sizeDecimals);
|
|
92075
|
+
if (!sizeValidation.valid) {
|
|
92076
|
+
throw new Error(`Invalid Hyperliquid trailing stop size wire: ${sizeValidation.reason}.`);
|
|
92077
|
+
}
|
|
92078
|
+
let retracement;
|
|
92079
|
+
if ("pct" in input.retracement) {
|
|
92080
|
+
const pct = input.retracement.pct.trim();
|
|
92081
|
+
const decimals = pct.includes(".") ? pct.slice(pct.indexOf(".") + 1, -1).length : 0;
|
|
92082
|
+
if (!TRAILING_PCT_PATTERN.test(pct) || !(Number(pct.slice(0, -1)) > 0) || decimals > HYPERLIQUID_EXCHANGE_SPECIFICATION.trailing_retracement_pct_max_decimals) {
|
|
92083
|
+
throw new Error(
|
|
92084
|
+
`Hyperliquid trailing stop percent must be positive with at most ${HYPERLIQUID_EXCHANGE_SPECIFICATION.trailing_retracement_pct_max_decimals} decimals.`
|
|
92085
|
+
);
|
|
92086
|
+
}
|
|
92087
|
+
retracement = { pct };
|
|
92088
|
+
} else {
|
|
92089
|
+
const px = input.retracement.px.trim();
|
|
92090
|
+
const pxValidation = validateHyperliquidPerpPriceWire(px, sizeDecimals);
|
|
92091
|
+
if (!(Number(px) > 0) || !pxValidation.valid) {
|
|
92092
|
+
throw new Error("Hyperliquid trailing stop distance must be a positive price on the market grid.");
|
|
92093
|
+
}
|
|
92094
|
+
retracement = { px };
|
|
92095
|
+
}
|
|
92096
|
+
let activationPx = null;
|
|
92097
|
+
if (input.activationPrice != null) {
|
|
92098
|
+
assertPositiveNumber(input.activationPrice, "Hyperliquid trailing stop activation price");
|
|
92099
|
+
activationPx = formatHyperliquidTriggerPriceWire(input.activationPrice, sizeDecimals);
|
|
92100
|
+
}
|
|
92101
|
+
return signHyperliquidPayload(input, {
|
|
92102
|
+
type: "trailingStop",
|
|
92103
|
+
asset: assetIndex,
|
|
92104
|
+
isBuy: side === "buy",
|
|
92105
|
+
sz: sizeWire,
|
|
92106
|
+
reduceOnly: true,
|
|
92107
|
+
retracement,
|
|
92108
|
+
activationPx
|
|
92109
|
+
});
|
|
92110
|
+
};
|
|
92032
92111
|
extractHyperliquidExchangeError = (payload) => {
|
|
92033
92112
|
if (!payload || typeof payload !== "object") {
|
|
92034
92113
|
return null;
|
|
@@ -92107,6 +92186,19 @@ var init_hyperliquid_client = __esm({
|
|
|
92107
92186
|
}
|
|
92108
92187
|
return { ...root, response: { ...response, data: { ...data4, statuses: resolved } } };
|
|
92109
92188
|
};
|
|
92189
|
+
readHyperliquidTrailingStopAcknowledgement = (payload) => {
|
|
92190
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload)) return { outcome: "unknown" };
|
|
92191
|
+
const record5 = payload;
|
|
92192
|
+
const body = record5.response;
|
|
92193
|
+
if (record5.status === "err" && typeof body === "string" && body.trim()) return { outcome: "refused", reason: body };
|
|
92194
|
+
if (record5.status !== "ok" || !body || typeof body !== "object") return { outcome: "unknown" };
|
|
92195
|
+
const answer = body;
|
|
92196
|
+
const orderId = answer.data?.oid;
|
|
92197
|
+
if (answer.type === "trailingStop" && typeof orderId === "number" && Number.isSafeInteger(orderId) && orderId > 0) {
|
|
92198
|
+
return { outcome: "placed", order_id: orderId };
|
|
92199
|
+
}
|
|
92200
|
+
return { outcome: "unknown" };
|
|
92201
|
+
};
|
|
92110
92202
|
resolveHyperliquidModifyAcknowledgement = async (payload, action, lookup, pacing = acknowledgementLookupPacing()) => {
|
|
92111
92203
|
if (action.type !== "modify" || payload == null || typeof payload !== "object" || Array.isArray(payload)) {
|
|
92112
92204
|
return payload;
|
|
@@ -92149,6 +92241,9 @@ var init_hyperliquid_client = __esm({
|
|
|
92149
92241
|
if (action.type === "updateLeverage") {
|
|
92150
92242
|
return exchangeResponse.type === "default";
|
|
92151
92243
|
}
|
|
92244
|
+
if (action.type === "trailingStop") {
|
|
92245
|
+
return readHyperliquidTrailingStopAcknowledgement(payload).outcome === "placed";
|
|
92246
|
+
}
|
|
92152
92247
|
const actionItems = action.type === "order" ? action.orders : action.type === "modify" ? [action.order] : action.type === "cancel" || action.type === "cancelByCloid" ? action.cancels : null;
|
|
92153
92248
|
const expectedCount = Array.isArray(actionItems) ? actionItems.length : 0;
|
|
92154
92249
|
const data4 = exchangeResponse.data && typeof exchangeResponse.data === "object" && !Array.isArray(exchangeResponse.data) ? exchangeResponse.data : null;
|
|
@@ -92564,6 +92659,13 @@ var init_hyperliquid_client = __esm({
|
|
|
92564
92659
|
}
|
|
92565
92660
|
return signedAssetId2;
|
|
92566
92661
|
}
|
|
92662
|
+
if (durableMutation.operationKind === "trailing_stop") {
|
|
92663
|
+
const signedAssetId2 = Number(action.asset);
|
|
92664
|
+
if (action.type !== "trailingStop" || !Number.isInteger(signedAssetId2) || signedAssetId2 < 0 || action.reduceOnly !== true) {
|
|
92665
|
+
throw new Error("Durable trailing stop authority requires exactly one signed reduce-only trailingStop.");
|
|
92666
|
+
}
|
|
92667
|
+
return signedAssetId2;
|
|
92668
|
+
}
|
|
92567
92669
|
const signedAssetId = Number(action.asset);
|
|
92568
92670
|
if (action.type !== "updateLeverage" || !Number.isInteger(signedAssetId) || signedAssetId < 0 || !Number.isInteger(Number(action.leverage)) || Number(action.leverage) <= 0 || typeof action.isCross !== "boolean") {
|
|
92569
92671
|
throw new Error(
|
|
@@ -92585,6 +92687,7 @@ var init_hyperliquid_client = __esm({
|
|
|
92585
92687
|
};
|
|
92586
92688
|
exchangeActionPriority = (action, requested) => {
|
|
92587
92689
|
if (action.type === "cancel" || action.type === "cancelByCloid") return requested === "trading_reduce" ? "trading_reduce" : "trading_execute";
|
|
92690
|
+
if (action.type === "trailingStop") return action.reduceOnly === true ? "trading_reduce" : "trading_execute";
|
|
92588
92691
|
const orders = action.type === "order" && Array.isArray(action.orders) ? action.orders : action.type === "modify" ? [action.order] : [];
|
|
92589
92692
|
return orders.length > 0 && orders.every((order) => order && typeof order === "object" && order.r === true) ? "trading_reduce" : "trading_execute";
|
|
92590
92693
|
};
|
|
@@ -92653,7 +92756,8 @@ var init_hyperliquid_client = __esm({
|
|
|
92653
92756
|
clientOrderIds: durableMutation.clientOrderIds ?? null,
|
|
92654
92757
|
...durableMutation.protection ? { protection: durableMutation.protection } : {},
|
|
92655
92758
|
...durableMutation.protectiveActionId ? { protectiveActionId: durableMutation.protectiveActionId } : {},
|
|
92656
|
-
|
|
92759
|
+
// A trailing stop has no CLOID: the server binds the lot it signs.
|
|
92760
|
+
...durableMutation.protection || durableMutation.protectiveActionId || durableMutation.operationKind === "trailing_stop" ? { signedPayload: serializedPayload } : {},
|
|
92657
92761
|
attemptEvidence: diagnostics.first_order ? {
|
|
92658
92762
|
requestedExchangeSize: diagnostics.first_order.size,
|
|
92659
92763
|
submittedLimitPrice: diagnostics.first_order.price,
|
|
@@ -92904,7 +93008,7 @@ var init_hyperliquid_client = __esm({
|
|
|
92904
93008
|
})
|
|
92905
93009
|
);
|
|
92906
93010
|
}
|
|
92907
|
-
const exchangeError = extractHyperliquidExchangeError(payload);
|
|
93011
|
+
const exchangeError = durableMutation?.operationKind === "trailing_stop" && readHyperliquidTrailingStopAcknowledgement(payload).outcome !== "refused" ? null : extractHyperliquidExchangeError(payload);
|
|
92908
93012
|
if (exchangeError) {
|
|
92909
93013
|
emitHyperliquidExchangeRejection(String(exchangeError.message ?? ""));
|
|
92910
93014
|
await settleDurableMutation(
|
|
@@ -92944,7 +93048,8 @@ var init_hyperliquid_client = __esm({
|
|
|
92944
93048
|
"outcome_unknown"
|
|
92945
93049
|
);
|
|
92946
93050
|
}
|
|
92947
|
-
const
|
|
93051
|
+
const trailingAcknowledgement = durableMutation?.operationKind === "trailing_stop" ? readHyperliquidTrailingStopAcknowledgement(payload) : null;
|
|
93052
|
+
const exactExchangeOrderId = durableMutation?.operationKind === "order" ? extractDefinitiveHyperliquidOrderId(payload, input.payload.action) : trailingAcknowledgement?.outcome === "placed" ? String(trailingAcknowledgement.order_id) : null;
|
|
92948
93053
|
const extractedOrderMemberResults = durableMutation?.operationKind === "order" ? extractDefinitiveHyperliquidOrderMemberResults(
|
|
92949
93054
|
payload,
|
|
92950
93055
|
input.payload.action
|
|
@@ -93042,12 +93147,21 @@ var init_exchange_mutation_evidence = __esm({
|
|
|
93042
93147
|
{ type: "activeAssetData", user: wallet, coin },
|
|
93043
93148
|
"hyperliquid.activeAssetData"
|
|
93044
93149
|
) : null;
|
|
93150
|
+
const dex = input.required.open_orders_dex;
|
|
93151
|
+
const openOrders = dex == null ? void 0 : await fetchBrowserHyperliquidInfoPayload(
|
|
93152
|
+
readInput,
|
|
93153
|
+
{ type: "frontendOpenOrders", user: wallet, ...dex ? { dex } : {} },
|
|
93154
|
+
"hyperliquid.frontendOpenOrders"
|
|
93155
|
+
);
|
|
93156
|
+
const historicalOrders = input.required.historical_orders === true ? await fetchBrowserHyperliquidInfoPayload(readInput, { type: "historicalOrders", user: wallet }, "hyperliquid.historicalOrders") : void 0;
|
|
93045
93157
|
return {
|
|
93046
93158
|
evidence: {
|
|
93047
93159
|
wallet_address: wallet,
|
|
93048
93160
|
observed_at: observedAt,
|
|
93049
93161
|
order_statuses: orderStatuses,
|
|
93050
|
-
active_asset_data: activeAssetData
|
|
93162
|
+
active_asset_data: activeAssetData,
|
|
93163
|
+
...openOrders === void 0 ? {} : { open_orders: openOrders },
|
|
93164
|
+
...historicalOrders === void 0 ? {} : { historical_orders: historicalOrders }
|
|
93051
93165
|
},
|
|
93052
93166
|
startedAtMonotonicMs
|
|
93053
93167
|
};
|
|
@@ -94623,6 +94737,7 @@ var init_api2 = __esm({
|
|
|
94623
94737
|
init_updates();
|
|
94624
94738
|
init_profile_emoji();
|
|
94625
94739
|
init_account_summary();
|
|
94740
|
+
init_mobile_notifications();
|
|
94626
94741
|
init_server_runtime_lease();
|
|
94627
94742
|
clientRuntimeSecretHeaders = (profileId) => {
|
|
94628
94743
|
const headers = getProfileHeaders({}, profileId);
|
|
@@ -94706,9 +94821,8 @@ var init_api2 = __esm({
|
|
|
94706
94821
|
if ("invocations" in payload) {
|
|
94707
94822
|
body.invocations = payload.invocations ?? [];
|
|
94708
94823
|
}
|
|
94709
|
-
if (payload.stopReason !== void 0)
|
|
94710
|
-
|
|
94711
|
-
}
|
|
94824
|
+
if (payload.stopReason !== void 0) body.stop_reason = payload.stopReason ?? null;
|
|
94825
|
+
if (payload.modeSwitch) body.mode_switch = true;
|
|
94712
94826
|
if (payload.authoritativeIntent !== void 0) {
|
|
94713
94827
|
body.authoritative_intent = payload.authoritativeIntent;
|
|
94714
94828
|
}
|
|
@@ -96333,7 +96447,7 @@ var init_vault = __esm({
|
|
|
96333
96447
|
});
|
|
96334
96448
|
|
|
96335
96449
|
// lib/runtime/browser-trading.ts
|
|
96336
|
-
var resolveProfileId, requirePositiveNumber, assertFreshPreparedContext, throwIfAborted, UUID_PATTERN, createExchangeMutationIdentity, requireClientExchangeExpiresAfterSeconds, loadSigningKey, priorityOf, resolveSigningKey, requireWalletAddress2, resolveEstimatedPrice, executeClientLeverageUpdate, executeClientMarketOrder, resolveClientProtectiveSigningKey, executeClientPreparedProtectiveAction, executeClientLimitOrder, executeClientTriggerOrder, executeClientOrderBatch, executeClientModifyOrder, executeClientCancelOrder, executeClientClosePosition;
|
|
96450
|
+
var resolveProfileId, requirePositiveNumber, assertFreshPreparedContext, throwIfAborted, UUID_PATTERN, createExchangeMutationIdentity, requireClientExchangeExpiresAfterSeconds, loadSigningKey, priorityOf, resolveSigningKey, requireWalletAddress2, resolveEstimatedPrice, executeClientLeverageUpdate, executeClientMarketOrder, resolveClientProtectiveSigningKey, executeClientPreparedProtectiveAction, executeClientLimitOrder, executeClientTriggerOrder, executeClientOrderBatch, executeClientModifyOrder, executeClientCancelOrder, executeClientTrailingStop, executeClientClosePosition;
|
|
96337
96451
|
var init_browser_trading = __esm({
|
|
96338
96452
|
"lib/runtime/browser-trading.ts"() {
|
|
96339
96453
|
"use strict";
|
|
@@ -96794,6 +96908,41 @@ var init_browser_trading = __esm({
|
|
|
96794
96908
|
}
|
|
96795
96909
|
});
|
|
96796
96910
|
};
|
|
96911
|
+
executeClientTrailingStop = async (input) => {
|
|
96912
|
+
input = { ...input, publicRequestPriority: "trading_reduce" };
|
|
96913
|
+
throwIfAborted(input.signal);
|
|
96914
|
+
const signingKey = await resolveSigningKey(input);
|
|
96915
|
+
throwIfAborted(input.signal);
|
|
96916
|
+
const mutation = createExchangeMutationIdentity(false, input);
|
|
96917
|
+
const payload = await buildHyperliquidTrailingStopPayload({
|
|
96918
|
+
config: input.config ?? null,
|
|
96919
|
+
publicRequestPriority: priorityOf(input),
|
|
96920
|
+
signingKey,
|
|
96921
|
+
symbol: input.symbol,
|
|
96922
|
+
side: input.side,
|
|
96923
|
+
size: input.size,
|
|
96924
|
+
retracement: input.retracement,
|
|
96925
|
+
expiresAfterSeconds: requireClientExchangeExpiresAfterSeconds(input.config)
|
|
96926
|
+
});
|
|
96927
|
+
return submitHyperliquidExchangePayload({
|
|
96928
|
+
config: input.config ?? null,
|
|
96929
|
+
publicRequestPriority: priorityOf(input),
|
|
96930
|
+
payload,
|
|
96931
|
+
signal: input.signal,
|
|
96932
|
+
mutationScope: resolveProfileId(input.profileId),
|
|
96933
|
+
durableMutation: {
|
|
96934
|
+
profileId: input.profileId,
|
|
96935
|
+
requiredRuntimeSessionId: input.runtimeSessionId,
|
|
96936
|
+
runtimeLeaseToken: input.runtimeLeaseToken,
|
|
96937
|
+
runtimeDeviceId: input.runtimeDeviceId,
|
|
96938
|
+
schedulerInstanceId: input.schedulerInstanceId,
|
|
96939
|
+
mutationId: mutation.mutationId,
|
|
96940
|
+
operationKind: "trailing_stop",
|
|
96941
|
+
symbol: input.symbol,
|
|
96942
|
+
onExchangeOrderDispatched: input.onExchangeOrderDispatched
|
|
96943
|
+
}
|
|
96944
|
+
});
|
|
96945
|
+
};
|
|
96797
96946
|
executeClientClosePosition = async (input) => {
|
|
96798
96947
|
input = { ...input, publicRequestPriority: "trading_reduce" };
|
|
96799
96948
|
throwIfAborted(input.signal);
|
|
@@ -98560,7 +98709,7 @@ var init_protective_evidence = __esm({
|
|
|
98560
98709
|
});
|
|
98561
98710
|
|
|
98562
98711
|
// lib/runtime/protective-actions.ts
|
|
98563
|
-
var DECIMAL, CLOID, fail2, exactKeys, nonNegativeInteger, decimalString, POSITION_ORDER_SIZE, orderSizeString, canonicalTriggerOrder, canonicalProtectiveWireAction, assertProtectiveActionLocallySafe, authorityArgs2, errorCode2, foreignClaimExpiresAtMs, drainLocks, refusedUntil, drainClientProtectiveActions, drainOnce;
|
|
98712
|
+
var DECIMAL, PERCENT, CLOID, fail2, exactKeys, nonNegativeInteger, decimalString, POSITION_ORDER_SIZE, orderSizeString, canonicalTriggerOrder, canonicalProtectiveWireAction, assertProtectiveActionLocallySafe, authorityArgs2, errorCode2, foreignClaimExpiresAtMs, drainLocks, refusedUntil, drainClientProtectiveActions, drainOnce;
|
|
98564
98713
|
var init_protective_actions = __esm({
|
|
98565
98714
|
"lib/runtime/protective-actions.ts"() {
|
|
98566
98715
|
"use strict";
|
|
@@ -98577,6 +98726,7 @@ var init_protective_actions = __esm({
|
|
|
98577
98726
|
init_error_surface_contract();
|
|
98578
98727
|
init_protective_evidence();
|
|
98579
98728
|
DECIMAL = /^(?:0|[1-9]\d*)(?:\.\d+)?$/;
|
|
98729
|
+
PERCENT = /^(?:0|[1-9]\d*)(?:\.\d+)?%$/;
|
|
98580
98730
|
CLOID = /^0x[0-9a-f]{32}$/;
|
|
98581
98731
|
fail2 = (message) => {
|
|
98582
98732
|
throw new RuntimeExecutionError(
|
|
@@ -98655,9 +98805,48 @@ var init_protective_actions = __esm({
|
|
|
98655
98805
|
if (oid <= 0) fail2("cancel target is invalid.");
|
|
98656
98806
|
return { type: "cancel", cancels: [{ a: nonNegativeInteger(cancel.a, "asset"), o: oid }] };
|
|
98657
98807
|
}
|
|
98808
|
+
if (kind === "trailingStop") {
|
|
98809
|
+
const action = exactKeys(wire, ["type", "asset", "isBuy", "sz", "reduceOnly", "retracement", "activationPx"], "action");
|
|
98810
|
+
if (action.reduceOnly !== true) fail2("a trailing stop must be reduce-only.");
|
|
98811
|
+
if (typeof action.isBuy !== "boolean") fail2("trailing stop side is invalid.");
|
|
98812
|
+
if (action.activationPx !== null) fail2("a trailing stop is active at once.");
|
|
98813
|
+
const distance = action.retracement;
|
|
98814
|
+
let retracement;
|
|
98815
|
+
if (distance && typeof distance === "object" && "pct" in distance) {
|
|
98816
|
+
const pct = exactKeys(distance, ["pct"], "retracement").pct;
|
|
98817
|
+
const decimals = typeof pct === "string" && pct.includes(".") ? pct.slice(pct.indexOf(".") + 1, -1).length : 0;
|
|
98818
|
+
if (typeof pct !== "string" || !PERCENT.test(pct) || !(Number(pct.slice(0, -1)) > 0) || decimals > HYPERLIQUID_EXCHANGE_SPECIFICATION.trailing_retracement_pct_max_decimals) {
|
|
98819
|
+
fail2("trailing stop percent is invalid.");
|
|
98820
|
+
}
|
|
98821
|
+
retracement = { pct };
|
|
98822
|
+
} else {
|
|
98823
|
+
retracement = { px: decimalString(exactKeys(distance, ["px"], "retracement").px, "trailing stop distance") };
|
|
98824
|
+
}
|
|
98825
|
+
return {
|
|
98826
|
+
type: "trailingStop",
|
|
98827
|
+
asset: nonNegativeInteger(action.asset, "asset"),
|
|
98828
|
+
isBuy: action.isBuy,
|
|
98829
|
+
sz: decimalString(action.sz, "trailing stop size"),
|
|
98830
|
+
reduceOnly: true,
|
|
98831
|
+
retracement,
|
|
98832
|
+
activationPx: null
|
|
98833
|
+
};
|
|
98834
|
+
}
|
|
98658
98835
|
return fail2("unsupported action type.");
|
|
98659
98836
|
};
|
|
98660
98837
|
assertProtectiveActionLocallySafe = (action, canonical, livePositionSize) => {
|
|
98838
|
+
if (canonical.type === "trailingStop" !== (action.operation_kind === "trailing_stop")) {
|
|
98839
|
+
fail2("operation kind does not match the action.");
|
|
98840
|
+
}
|
|
98841
|
+
if (canonical.type === "trailingStop") {
|
|
98842
|
+
if (action.action_kind !== "place" || action.client_order_ids.length > 0) fail2("trailing stop metadata does not match.");
|
|
98843
|
+
if (canonical.asset !== action.exchange_asset_id) fail2("asset does not match the symbol.");
|
|
98844
|
+
if (livePositionSize == null || !Number.isFinite(livePositionSize) || livePositionSize === 0) {
|
|
98845
|
+
fail2("the live position is flat or unknown.");
|
|
98846
|
+
}
|
|
98847
|
+
if (canonical.isBuy !== livePositionSize < 0) fail2("the trailing stop would not close the live position.");
|
|
98848
|
+
return;
|
|
98849
|
+
}
|
|
98661
98850
|
const assets = canonical.type === "cancel" ? canonical.cancels.map((cancel) => cancel.a) : canonical.type === "modify" ? [canonical.order.a] : canonical.orders.map((order) => order.a);
|
|
98662
98851
|
if (assets.some((asset) => asset !== action.exchange_asset_id)) fail2("asset does not match the symbol.");
|
|
98663
98852
|
if (canonical.type === "cancel") {
|
|
@@ -99567,7 +99756,7 @@ var init_protective_trigger_price = __esm({
|
|
|
99567
99756
|
});
|
|
99568
99757
|
|
|
99569
99758
|
// lib/runtime/protective-stop-replacement.ts
|
|
99570
|
-
var STOP_REPLACED, STOP_REPLACEMENT_EXHAUSTED, STOP_REPLACEMENT_REJECTED, STOP_REPLACEMENT_NOT_LANDED, STOP_CLEANUP_IN_FLIGHT, TERMINAL_WITHOUT_FILL, CANCELLED_BY_USER, POSITION_FLAT_AFTER_TERMINAL, CAPACITY_ALREADY_ALLOCATED, TRIGGER_INVALID, STOP_EXECUTION_REJECTED, STOP_TRIGGER_CROSSED, permanentStopRejectionStatuses, protectiveStopRejectionIsPermanent, POSITION_ENDED_ORDER_STATUSES, finiteOrNull, floorToLot, positiveSafeInteger, decimalOrNull, positionTolerance, chainFillChronology, protectivePositionEpisodeEnded, decideProtectiveStopReplacement;
|
|
99759
|
+
var STOP_REPLACED, STOP_REPLACEMENT_EXHAUSTED, STOP_REPLACEMENT_REJECTED, STOP_REPLACEMENT_NOT_LANDED, STOP_CLEANUP_IN_FLIGHT, TERMINAL_WITHOUT_FILL, CANCELLED_BY_USER, POSITION_FLAT_AFTER_TERMINAL, CAPACITY_ALREADY_ALLOCATED, TRIGGER_INVALID, STOP_EXECUTION_REJECTED, STOP_TRIGGER_CROSSED, permanentStopRejectionStatuses, protectiveStopRejectionIsPermanent, POSITION_ENDED_ORDER_STATUSES, finiteOrNull, floorToLot, positiveSafeInteger, decimalOrNull, positionTolerance, chainFillChronology, marketFillChain, noExposureOnSide, protectivePositionEpisodeEnded, decideProtectiveStopReplacement;
|
|
99571
99760
|
var init_protective_stop_replacement = __esm({
|
|
99572
99761
|
"lib/runtime/protective-stop-replacement.ts"() {
|
|
99573
99762
|
"use strict";
|
|
@@ -99644,16 +99833,13 @@ var init_protective_stop_replacement = __esm({
|
|
|
99644
99833
|
}
|
|
99645
99834
|
return ordered;
|
|
99646
99835
|
};
|
|
99647
|
-
|
|
99648
|
-
if (!
|
|
99649
|
-
const
|
|
99650
|
-
if (statusMs == null || !Array.isArray(input.fills)) return false;
|
|
99651
|
-
const market = normalizeHyperliquidMarketSymbol(input.symbol);
|
|
99652
|
-
const sign = input.isLong ? 1 : -1;
|
|
99836
|
+
marketFillChain = (fills, symbol2) => {
|
|
99837
|
+
if (!Array.isArray(fills)) return null;
|
|
99838
|
+
const market = normalizeHyperliquidMarketSymbol(symbol2);
|
|
99653
99839
|
const rows = [];
|
|
99654
99840
|
const seen = /* @__PURE__ */ new Set();
|
|
99655
|
-
for (const fill of
|
|
99656
|
-
if (fill == null || typeof fill !== "object" || Array.isArray(fill)) return
|
|
99841
|
+
for (const fill of fills) {
|
|
99842
|
+
if (fill == null || typeof fill !== "object" || Array.isArray(fill)) return null;
|
|
99657
99843
|
const record5 = fill;
|
|
99658
99844
|
if (normalizeHyperliquidMarketSymbol(String(record5.coin ?? "")) !== market) continue;
|
|
99659
99845
|
const tradeId = positiveSafeInteger(record5.tid);
|
|
@@ -99661,12 +99847,26 @@ var init_protective_stop_replacement = __esm({
|
|
|
99661
99847
|
const size = decimalOrNull(record5.sz);
|
|
99662
99848
|
const start = decimalOrNull(record5.startPosition);
|
|
99663
99849
|
if (tradeId == null || seen.has(tradeId) || time3 == null || record5.side !== "B" && record5.side !== "A" || size == null || size <= 0 || start == null) {
|
|
99664
|
-
return
|
|
99850
|
+
return null;
|
|
99665
99851
|
}
|
|
99666
99852
|
seen.add(tradeId);
|
|
99667
|
-
rows.push({
|
|
99853
|
+
rows.push({
|
|
99854
|
+
time: time3,
|
|
99855
|
+
tradeId,
|
|
99856
|
+
start,
|
|
99857
|
+
end: start + (record5.side === "B" ? size : -size),
|
|
99858
|
+
orderId: String(record5.oid ?? "").trim()
|
|
99859
|
+
});
|
|
99668
99860
|
}
|
|
99669
|
-
|
|
99861
|
+
return chainFillChronology(rows);
|
|
99862
|
+
};
|
|
99863
|
+
noExposureOnSide = (position, isLong) => (isLong ? 1 : -1) * position <= positionTolerance(position, 0);
|
|
99864
|
+
protectivePositionEpisodeEnded = (input) => {
|
|
99865
|
+
if (!POSITION_ENDED_ORDER_STATUSES.has(String(input.orderStatus ?? ""))) return false;
|
|
99866
|
+
const statusMs = positiveSafeInteger(input.statusTimestampMs);
|
|
99867
|
+
if (statusMs == null) return false;
|
|
99868
|
+
const sign = input.isLong ? 1 : -1;
|
|
99869
|
+
const chained = marketFillChain(input.fills, input.symbol);
|
|
99670
99870
|
if (chained == null) return false;
|
|
99671
99871
|
const before = chained.filter((row) => row.time <= statusMs);
|
|
99672
99872
|
const after = chained.filter((row) => row.time > statusMs);
|
|
@@ -99819,7 +100019,7 @@ var init_protective_entry_cover = __esm({
|
|
|
99819
100019
|
});
|
|
99820
100020
|
|
|
99821
100021
|
// lib/runtime/native-position-protection.ts
|
|
99822
|
-
var nativeProtectionSettings, memberSetting, KINDS, formatTriggerOrNull, nativePositionTriggerPrice, nativeEntryRequest, HALF_UP_DIGIT, roundDecimalHalfUp, nativeTrailingRetracement, nativeAfterFillActions, classifyNativeOrderEnd, isOpenInDirection, nativePlacementGate, nativeStrayOrderDecision, FIRED_TRIGGER_CONDITION, closingSide, DECIMAL_PATTERN, decimalUnits2, fractionDigits, nativePlaceCover, nativeRearmDecision, nativeLostStopCrossed, explainAbsentProtectiveOrder, readServerNativeProtectionState;
|
|
100022
|
+
var nativeProtectionSettings, memberSetting, KINDS, formatTriggerOrNull, nativePositionTriggerPrice, nativeEntryRequest, HALF_UP_DIGIT, roundDecimalHalfUp, nativeTrailingRetracement, nativeAfterFillActions, classifyNativeOrderEnd, isOpenInDirection, nativePlacementGate, nativeStrayOrderDecision, FIRED_TRIGGER_CONDITION, TRAILING_ORDER_TYPE, closingSide, DECIMAL_PATTERN, decimalUnits2, fractionDigits, nativePlaceCover, positiveOrderId, nativeRearmDecision, nativeLostStopCrossed, readListedProtectiveRow, explainAbsentProtectiveOrder, readServerNativeProtectionState, nativeFillOpenedPosition, nativePositionEndedSince, flatReadEndsPosition;
|
|
99823
100023
|
var init_native_position_protection = __esm({
|
|
99824
100024
|
"lib/runtime/native-position-protection.ts"() {
|
|
99825
100025
|
"use strict";
|
|
@@ -99966,6 +100166,7 @@ var init_native_position_protection = __esm({
|
|
|
99966
100166
|
return input.positionStateMs > input.placedMs ? "cancel" : "need_reads";
|
|
99967
100167
|
};
|
|
99968
100168
|
FIRED_TRIGGER_CONDITION = "Triggered";
|
|
100169
|
+
TRAILING_ORDER_TYPE = "trailing stop market";
|
|
99969
100170
|
closingSide = (isLong) => isLong ? "a" : "b";
|
|
99970
100171
|
DECIMAL_PATTERN = /^-?\d+(\.\d+)?$/;
|
|
99971
100172
|
decimalUnits2 = (value, scale) => {
|
|
@@ -99979,6 +100180,7 @@ var init_native_position_protection = __esm({
|
|
|
99979
100180
|
nativePlaceCover = (input) => {
|
|
99980
100181
|
const market = normalizeHyperliquidMarketSymbol(input.symbol);
|
|
99981
100182
|
const own = new Set(input.ownClientOrderIds.map((value) => String(value).trim().toLowerCase()).filter(Boolean));
|
|
100183
|
+
const ownTrailing = new Set((input.ownTrailingOrderIds ?? []).map(positiveOrderId).filter((id2) => id2 != null));
|
|
99982
100184
|
const positionText = String(input.positionSize).replace(/^-/, "");
|
|
99983
100185
|
const sized = [];
|
|
99984
100186
|
for (const row of input.rows) {
|
|
@@ -99986,7 +100188,9 @@ var init_native_position_protection = __esm({
|
|
|
99986
100188
|
if (row.reduceOnly !== true || row.isTrigger !== true) continue;
|
|
99987
100189
|
if (String(row.triggerCondition ?? "").trim() === FIRED_TRIGGER_CONDITION) continue;
|
|
99988
100190
|
if (String(row.side ?? "").trim().toLowerCase() !== closingSide(input.isLong)) continue;
|
|
99989
|
-
const orderType = String(row.orderType ?? "").toLowerCase();
|
|
100191
|
+
const orderType = String(row.orderType ?? "").trim().toLowerCase();
|
|
100192
|
+
const rowOrderId = positiveOrderId(row.oid);
|
|
100193
|
+
if (orderType === TRAILING_ORDER_TYPE && rowOrderId != null && ownTrailing.has(rowOrderId)) continue;
|
|
99990
100194
|
const rowKind = orderType.includes("take profit") ? "tp" : orderType.includes("stop") ? "sl" : null;
|
|
99991
100195
|
if (rowKind !== input.kind) continue;
|
|
99992
100196
|
if (own.has(String(row.cloid ?? "").trim().toLowerCase())) {
|
|
@@ -100004,6 +100208,13 @@ var init_native_position_protection = __esm({
|
|
|
100004
100208
|
const covered = sized.reduce((total, size) => total + decimalUnits2(size, scale), BigInt(0));
|
|
100005
100209
|
return position > BigInt(0) && covered >= position ? { decision: "covered" } : { decision: "place" };
|
|
100006
100210
|
};
|
|
100211
|
+
positiveOrderId = (value) => {
|
|
100212
|
+
if (typeof value === "boolean") return null;
|
|
100213
|
+
const text = String(value ?? "").trim();
|
|
100214
|
+
if (!/^\d+$/.test(text)) return null;
|
|
100215
|
+
const orderId = Number(text);
|
|
100216
|
+
return orderId > 0 && Number.isSafeInteger(orderId) ? orderId : null;
|
|
100217
|
+
};
|
|
100007
100218
|
nativeRearmDecision = (input) => {
|
|
100008
100219
|
if (!isOpenInDirection(input.position, input.isLong)) return "retire";
|
|
100009
100220
|
if (input.endedMs == null || !(input.positionStateMs > input.endedMs)) return "need_reads";
|
|
@@ -100013,6 +100224,7 @@ var init_native_position_protection = __esm({
|
|
|
100013
100224
|
if (input.mark == null || !Number.isFinite(input.mark)) return false;
|
|
100014
100225
|
return input.isLong ? input.mark <= input.trigger : input.mark >= input.trigger;
|
|
100015
100226
|
};
|
|
100227
|
+
readListedProtectiveRow = (row) => String(row.triggerCondition ?? "").trim() === FIRED_TRIGGER_CONDITION ? "not_resting_status_read_decides" : "resting";
|
|
100016
100228
|
explainAbsentProtectiveOrder = (input) => {
|
|
100017
100229
|
if (isOpenInDirection(input.position, input.isLong)) return "status_read";
|
|
100018
100230
|
return input.positionStateMs > input.lastSeenRestingMs ? "ended_with_position" : "need_reads";
|
|
@@ -100027,17 +100239,69 @@ var init_native_position_protection = __esm({
|
|
|
100027
100239
|
if (typeof record5.enabled !== "boolean" || legacy == null || native == null) return null;
|
|
100028
100240
|
return { enabled: record5.enabled, legacySymbols: new Set(legacy), nativeSymbols: new Set(native) };
|
|
100029
100241
|
};
|
|
100242
|
+
nativeFillOpenedPosition = (input) => {
|
|
100243
|
+
if (!input.complete || !Array.isArray(input.fills)) return "unknown";
|
|
100244
|
+
const market = normalizeHyperliquidMarketSymbol(input.symbol);
|
|
100245
|
+
const moves = [];
|
|
100246
|
+
const decimal = (value) => {
|
|
100247
|
+
const text = typeof value === "number" && Number.isFinite(value) ? String(value) : typeof value === "string" ? value.trim() : "";
|
|
100248
|
+
return DECIMAL_PATTERN.test(text) ? Number(text) : null;
|
|
100249
|
+
};
|
|
100250
|
+
for (const fill of input.fills) {
|
|
100251
|
+
if (fill == null || typeof fill !== "object" || Array.isArray(fill)) continue;
|
|
100252
|
+
const record5 = fill;
|
|
100253
|
+
if (String(record5.oid ?? "").trim() !== input.orderId.trim()) continue;
|
|
100254
|
+
if (normalizeHyperliquidMarketSymbol(String(record5.coin ?? "")) !== market) continue;
|
|
100255
|
+
const start = decimal(record5.startPosition);
|
|
100256
|
+
const size = decimal(record5.sz);
|
|
100257
|
+
if (start == null || size == null || size <= 0 || record5.side !== "B" && record5.side !== "A") return "unknown";
|
|
100258
|
+
moves.push({ start, end: start + (record5.side === "B" ? size : -size) });
|
|
100259
|
+
}
|
|
100260
|
+
if (moves.length === 0) return "unknown";
|
|
100261
|
+
if (moves.some(({ start, end }) => noExposureOnSide(start, input.isLong) && !noExposureOnSide(end, input.isLong))) {
|
|
100262
|
+
return "opened";
|
|
100263
|
+
}
|
|
100264
|
+
if (moves.every(({ start }) => !noExposureOnSide(start, input.isLong))) return "joined";
|
|
100265
|
+
if (moves.every(({ end }) => noExposureOnSide(end, input.isLong))) return "other_side";
|
|
100266
|
+
return "unknown";
|
|
100267
|
+
};
|
|
100268
|
+
nativePositionEndedSince = (input) => {
|
|
100269
|
+
let answer = "unknown";
|
|
100270
|
+
const chain = input.complete ? marketFillChain(input.fills, input.symbol) : null;
|
|
100271
|
+
if (chain != null) {
|
|
100272
|
+
let last = -1;
|
|
100273
|
+
chain.forEach((row, index) => {
|
|
100274
|
+
if (row.orderId === input.orderId.trim()) last = index;
|
|
100275
|
+
});
|
|
100276
|
+
if (last >= 0) {
|
|
100277
|
+
answer = chain.slice(last).some((row) => noExposureOnSide(row.end, input.isLong)) ? "ended" : "open";
|
|
100278
|
+
}
|
|
100279
|
+
}
|
|
100280
|
+
if (answer === "unknown" && input.flatRead != null && flatReadEndsPosition(input.flatRead, input.isLong)) return "ended";
|
|
100281
|
+
return answer;
|
|
100282
|
+
};
|
|
100283
|
+
flatReadEndsPosition = (read, isLong) => {
|
|
100284
|
+
if (read.pageComplete !== true || read.newestFillMs === void 0) return false;
|
|
100285
|
+
const text = String(read.position ?? "").trim();
|
|
100286
|
+
if (!DECIMAL_PATTERN.test(text) || !Number.isSafeInteger(read.stateMs)) return false;
|
|
100287
|
+
if (!noExposureOnSide(Number(text), isLong)) return false;
|
|
100288
|
+
if (read.newestFillMs == null) return true;
|
|
100289
|
+
return Number.isSafeInteger(read.newestFillMs) && read.newestFillMs < read.stateMs;
|
|
100290
|
+
};
|
|
100030
100291
|
}
|
|
100031
100292
|
});
|
|
100032
100293
|
|
|
100033
100294
|
// lib/runtime/native-protection-device.ts
|
|
100034
|
-
var NATIVE_PROTECTION_RECORD_VERSION, nativeProtectionStorage, resolveStorage, setNativeProtectionStorage, recordKey, isMember, readNativeProtectionRecord, writeNativeProtectionRecord, NativeOrderNotSentError, withDispatchBoundary, attempt, notSentRestores, errorText, actionOf, isOpenInDirection2, coverRows, restingOrderIdAt, definitivelyRefused, planNativeOpen, recordEntryChildren, observeMembers, UNKNOWN_ORDER_RESPONSE, resolveUnknownOrderIds, settleNativeProtectionAfterFill, reconcileNativeProtection;
|
|
100295
|
+
var NATIVE_PROTECTION_RECORD_VERSION, nativeProtectionStorage, resolveStorage, setNativeProtectionStorage, recordKey, isMember, isRetracement, isLot, isStandbyAdd, readNativeProtectionRecord, versioned, writeNativeProtectionRecord, NO_FILLS, nativeFillsPageFromUserFills, fillsReader, flatReadOf, orderFillTimes, namedOrderId, NativeOrderNotSentError, withDispatchBoundary, attempt, notSentRestores, errorText, actionOf, isOpenInDirection2, coverRows, restingOrderIdAt, definitivelyRefused, TRAILING_LOT_FIRED, TRAILING_LOT_POSITION_ENDED, TRAILING_LOT_OTHER_SIDE, lotFillLeftPosition, lotOfAdd, ORDER_ID_PATTERN, lotFillOrderId, lotPositionSince, ownLotOrderIds, lotRetracement, lotReport, sendTrailingLot, planNativeFillLot, planNativeStandbyAdd, nameNativeStandbyAdd, dropNativeStandbyAdd, dropNativePendingLot, planNativePendingLot, planNativeOpen, recordEntryChildren, observeMembers, UNKNOWN_ORDER_RESPONSE, resolveUnknownOrderIds, plannedPair, resolveStandbyAdds, settleNativeProtectionAfterFill, reconcileNativeProtection;
|
|
100035
100296
|
var init_native_protection_device = __esm({
|
|
100036
100297
|
"lib/runtime/native-protection-device.ts"() {
|
|
100037
100298
|
"use strict";
|
|
100038
100299
|
init_define_VTX_EXO_POLICY();
|
|
100039
100300
|
init_define_VTX_GROK_POLICY();
|
|
100040
100301
|
init_define_VTX_PI_MODEL_POLICY();
|
|
100302
|
+
init_constants();
|
|
100303
|
+
init_hyperliquid_market_symbol();
|
|
100304
|
+
init_hyperliquid_order_status();
|
|
100041
100305
|
init_order_identity();
|
|
100042
100306
|
init_native_position_protection();
|
|
100043
100307
|
NATIVE_PROTECTION_RECORD_VERSION = 1;
|
|
@@ -100058,7 +100322,23 @@ var init_native_protection_device = __esm({
|
|
|
100058
100322
|
isMember = (value) => {
|
|
100059
100323
|
if (!value || typeof value !== "object") return false;
|
|
100060
100324
|
const member = value;
|
|
100061
|
-
return (member.kind === "sl" || member.kind === "tp") && typeof member.clientOrderId === "string" && (member.orderId === null || typeof member.orderId === "number" && Number.isSafeInteger(member.orderId)) && typeof member.trigger === "string" && (member.placedAtMs === null || typeof member.placedAtMs === "number") && typeof member.sentAtMs === "number" && typeof member.replacedOnce === "boolean" && (member.pendingModify === void 0 || typeof member.pendingModify === "object" && member.pendingModify !== null && typeof member.pendingModify.clientOrderId === "string" && typeof member.pendingModify.trigger === "string" && typeof member.pendingModify.sentAtMs === "number");
|
|
100325
|
+
return (member.kind === "sl" || member.kind === "tp") && typeof member.clientOrderId === "string" && (member.orderId === null || typeof member.orderId === "number" && Number.isSafeInteger(member.orderId)) && typeof member.trigger === "string" && (member.placedAtMs === null || typeof member.placedAtMs === "number") && typeof member.sentAtMs === "number" && typeof member.replacedOnce === "boolean" && (member.plannedAfterMs === void 0 || typeof member.plannedAfterMs === "number") && (member.pendingModify === void 0 || typeof member.pendingModify === "object" && member.pendingModify !== null && typeof member.pendingModify.clientOrderId === "string" && typeof member.pendingModify.trigger === "string" && typeof member.pendingModify.sentAtMs === "number");
|
|
100326
|
+
};
|
|
100327
|
+
isRetracement = (value) => {
|
|
100328
|
+
if (!value || typeof value !== "object") return false;
|
|
100329
|
+
const keys = Object.keys(value);
|
|
100330
|
+
const record5 = value;
|
|
100331
|
+
return keys.length === 1 && (typeof record5.pct === "string" || typeof record5.px === "string");
|
|
100332
|
+
};
|
|
100333
|
+
isLot = (value) => {
|
|
100334
|
+
if (!value || typeof value !== "object") return false;
|
|
100335
|
+
const lot = value;
|
|
100336
|
+
return (lot.mutationId === null || typeof lot.mutationId === "string") && typeof lot.fillKey === "string" && (lot.fillOrderId === void 0 || typeof lot.fillOrderId === "string") && typeof lot.fillEventMs === "number" && typeof lot.size === "string" && isRetracement(lot.retracement) && (lot.orderId === null || typeof lot.orderId === "number" && Number.isSafeInteger(lot.orderId)) && (lot.placedAtMs === null || typeof lot.placedAtMs === "number") && typeof lot.sentAtMs === "number" && typeof lot.replacedOnce === "boolean" && (lot.userCancelledOrderId === void 0 || typeof lot.userCancelledOrderId === "number") && (lot.fillEventFromDevice === void 0 || typeof lot.fillEventFromDevice === "boolean") && (lot.retiredReason === void 0 || typeof lot.retiredReason === "string");
|
|
100337
|
+
};
|
|
100338
|
+
isStandbyAdd = (value) => {
|
|
100339
|
+
if (!value || typeof value !== "object") return false;
|
|
100340
|
+
const add = value;
|
|
100341
|
+
return typeof add.clientOrderId === "string" && (add.orderId === null || typeof add.orderId === "string") && typeof add.sentAtMs === "number";
|
|
100062
100342
|
};
|
|
100063
100343
|
readNativeProtectionRecord = (profileId, symbol2) => {
|
|
100064
100344
|
const storage3 = resolveStorage();
|
|
@@ -100066,22 +100346,83 @@ var init_native_protection_device = __esm({
|
|
|
100066
100346
|
const raw = storage3.getItem(recordKey(profileId, symbol2));
|
|
100067
100347
|
if (raw == null) return null;
|
|
100068
100348
|
const parsed = JSON.parse(raw);
|
|
100069
|
-
if (parsed?.version !== NATIVE_PROTECTION_RECORD_VERSION || parsed.profileId !== profileId || parsed.symbol !== symbol2 || typeof parsed.walletAddress !== "string" || typeof parsed.isLong !== "boolean" || parsed.phase !== "entry_pending" && parsed.phase !== "active" || typeof parsed.entryMutationId !== "string" || typeof parsed.entryClientOrderId !== "string" || typeof parsed.createdAtMs !== "number" || !Array.isArray(parsed.members) || !parsed.members.every(isMember)) {
|
|
100349
|
+
if (parsed?.version !== NATIVE_PROTECTION_RECORD_VERSION && parsed?.version !== NATIVE_PROTECTION_RECORD_WITH_LOTS_VERSION || parsed.profileId !== profileId || parsed.symbol !== symbol2 || typeof parsed.walletAddress !== "string" || typeof parsed.isLong !== "boolean" || parsed.phase !== "entry_pending" && parsed.phase !== "active" || typeof parsed.entryMutationId !== "string" || typeof parsed.entryClientOrderId !== "string" || typeof parsed.createdAtMs !== "number" || !Array.isArray(parsed.members) || !parsed.members.every(isMember) || parsed.lots !== void 0 && (parsed.version !== NATIVE_PROTECTION_RECORD_WITH_LOTS_VERSION || !Array.isArray(parsed.lots) || !parsed.lots.every(isLot)) || parsed.standby !== void 0 && (!Array.isArray(parsed.standby) || !parsed.standby.every(isStandbyAdd)) || parsed.positionOrderId !== void 0 && typeof parsed.positionOrderId !== "string") {
|
|
100070
100350
|
throw new Error("Stored native protection record is invalid.");
|
|
100071
100351
|
}
|
|
100072
100352
|
return parsed;
|
|
100073
100353
|
};
|
|
100354
|
+
versioned = (record5) => {
|
|
100355
|
+
const { lots, ...rest } = record5;
|
|
100356
|
+
return lots && lots.length > 0 ? { ...rest, version: NATIVE_PROTECTION_RECORD_WITH_LOTS_VERSION, lots } : { ...rest, version: NATIVE_PROTECTION_RECORD_VERSION };
|
|
100357
|
+
};
|
|
100074
100358
|
writeNativeProtectionRecord = (profileId, symbol2, record5) => {
|
|
100075
100359
|
const storage3 = resolveStorage();
|
|
100076
100360
|
if (!storage3) return false;
|
|
100077
100361
|
try {
|
|
100078
100362
|
if (record5 == null) storage3.removeItem(recordKey(profileId, symbol2));
|
|
100079
|
-
else storage3.setItem(recordKey(profileId, symbol2), JSON.stringify(record5));
|
|
100363
|
+
else storage3.setItem(recordKey(profileId, symbol2), JSON.stringify(versioned(record5)));
|
|
100080
100364
|
return true;
|
|
100081
100365
|
} catch {
|
|
100082
100366
|
return false;
|
|
100083
100367
|
}
|
|
100084
100368
|
};
|
|
100369
|
+
NO_FILLS = { fills: [], complete: false, coversFromMs: null };
|
|
100370
|
+
nativeFillsPageFromUserFills = (rawFills, evidence) => {
|
|
100371
|
+
const live = evidence.source === "live";
|
|
100372
|
+
if (evidence.providerRowCount < evidence.providerPageCap) return { fills: [...rawFills], complete: live, coversFromMs: null };
|
|
100373
|
+
const oldest = evidence.oldestFillTimeMs;
|
|
100374
|
+
if (oldest == null) return NO_FILLS;
|
|
100375
|
+
return {
|
|
100376
|
+
fills: rawFills.filter((fill) => Number(fill?.time) > oldest),
|
|
100377
|
+
complete: live,
|
|
100378
|
+
coversFromMs: oldest + 1
|
|
100379
|
+
};
|
|
100380
|
+
};
|
|
100381
|
+
fillsReader = (io) => {
|
|
100382
|
+
let read = null;
|
|
100383
|
+
return () => {
|
|
100384
|
+
read ??= io.readFills().catch((error48) => {
|
|
100385
|
+
if (io.endsPass?.(error48)) throw error48;
|
|
100386
|
+
return NO_FILLS;
|
|
100387
|
+
});
|
|
100388
|
+
return read;
|
|
100389
|
+
};
|
|
100390
|
+
};
|
|
100391
|
+
flatReadOf = (position, page, symbol2) => {
|
|
100392
|
+
const stateMs = position.stateTimeMs;
|
|
100393
|
+
if (!page.complete || stateMs == null || !Number.isSafeInteger(stateMs)) return null;
|
|
100394
|
+
const market = normalizeHyperliquidMarketSymbol(symbol2);
|
|
100395
|
+
let newest = null;
|
|
100396
|
+
for (const fill of page.fills) {
|
|
100397
|
+
if (fill == null || typeof fill !== "object" || Array.isArray(fill)) continue;
|
|
100398
|
+
const row = fill;
|
|
100399
|
+
if (normalizeHyperliquidMarketSymbol(String(row.coin ?? "")) !== market) continue;
|
|
100400
|
+
const time3 = Number(row.time);
|
|
100401
|
+
if (!Number.isSafeInteger(time3)) return null;
|
|
100402
|
+
newest = newest == null ? time3 : Math.max(newest, time3);
|
|
100403
|
+
}
|
|
100404
|
+
return {
|
|
100405
|
+
position: String(position.size),
|
|
100406
|
+
stateMs,
|
|
100407
|
+
newestFillMs: newest,
|
|
100408
|
+
pageComplete: page.coversFromMs == null || page.coversFromMs < stateMs
|
|
100409
|
+
};
|
|
100410
|
+
};
|
|
100411
|
+
orderFillTimes = (page, orderId, symbol2) => {
|
|
100412
|
+
const market = normalizeHyperliquidMarketSymbol(symbol2);
|
|
100413
|
+
return page.fills.flatMap((fill) => {
|
|
100414
|
+
if (fill == null || typeof fill !== "object" || Array.isArray(fill)) return [];
|
|
100415
|
+
const row = fill;
|
|
100416
|
+
if (String(row.oid ?? "").trim() !== orderId.trim()) return [];
|
|
100417
|
+
if (normalizeHyperliquidMarketSymbol(String(row.coin ?? "")) !== market) return [];
|
|
100418
|
+
const time3 = Number(row.time);
|
|
100419
|
+
return [Number.isSafeInteger(time3) && time3 > 0 ? time3 : Number.NaN];
|
|
100420
|
+
});
|
|
100421
|
+
};
|
|
100422
|
+
namedOrderId = (evidence) => {
|
|
100423
|
+
const orderId = Number(evidence.orderId);
|
|
100424
|
+
return evidence.responseValid && evidence.orderMatches && Number.isSafeInteger(orderId) && orderId > 0 ? String(orderId) : null;
|
|
100425
|
+
};
|
|
100085
100426
|
NativeOrderNotSentError = class extends Error {
|
|
100086
100427
|
constructor(cause) {
|
|
100087
100428
|
super(cause instanceof Error ? cause.message : "The exchange call failed before dispatch.");
|
|
@@ -100146,8 +100487,147 @@ var init_native_protection_device = __esm({
|
|
|
100146
100487
|
const statuses = root?.response?.data?.statuses;
|
|
100147
100488
|
return Array.isArray(statuses) && statuses.length > 0 && statuses.every((status) => Boolean(status && typeof status === "object" && "error" in status));
|
|
100148
100489
|
};
|
|
100490
|
+
TRAILING_LOT_FIRED = "protective_trailing_lot_fired";
|
|
100491
|
+
TRAILING_LOT_POSITION_ENDED = "protective_trailing_lot_position_ended";
|
|
100492
|
+
TRAILING_LOT_OTHER_SIDE = "protective_trailing_lot_other_side";
|
|
100493
|
+
lotFillLeftPosition = (lot) => lot.retiredReason === TRAILING_LOT_FIRED || lot.retiredReason === TRAILING_LOT_POSITION_ENDED || lot.retiredReason === TRAILING_LOT_OTHER_SIDE;
|
|
100494
|
+
lotOfAdd = (lot, add) => lot.fillKey === add.clientOrderId || add.orderId != null && (lot.fillKey === add.orderId || lot.fillOrderId === add.orderId);
|
|
100495
|
+
ORDER_ID_PATTERN = /^\d+$/;
|
|
100496
|
+
lotFillOrderId = (lot) => lot.fillOrderId ?? (ORDER_ID_PATTERN.test(lot.fillKey) ? lot.fillKey : null);
|
|
100497
|
+
lotPositionSince = async (lot, record5, fills) => {
|
|
100498
|
+
const orderId = lotFillOrderId(lot);
|
|
100499
|
+
if (orderId == null) return "unknown";
|
|
100500
|
+
const page = await fills();
|
|
100501
|
+
return nativePositionEndedSince({
|
|
100502
|
+
fills: page.fills,
|
|
100503
|
+
complete: page.complete,
|
|
100504
|
+
orderId,
|
|
100505
|
+
isLong: record5.isLong,
|
|
100506
|
+
symbol: record5.symbol
|
|
100507
|
+
});
|
|
100508
|
+
};
|
|
100509
|
+
ownLotOrderIds = (record5) => (record5.lots ?? []).flatMap((lot) => lot.orderId == null ? [] : [lot.orderId]);
|
|
100510
|
+
lotRetracement = (settings, size, sizeDecimals) => {
|
|
100511
|
+
const stopLoss = settings.stopLoss;
|
|
100512
|
+
if (!stopLoss?.trailing || !(Number(size) > 0)) return null;
|
|
100513
|
+
return nativeTrailingRetracement({ mode: stopLoss.mode, value: stopLoss.value, lotSize: Number(size), sizeDecimals });
|
|
100514
|
+
};
|
|
100515
|
+
lotReport = (symbol2, lot, status, metadata) => ({
|
|
100516
|
+
order_id: lot.orderId == null ? null : String(lot.orderId),
|
|
100517
|
+
symbol: symbol2,
|
|
100518
|
+
action: "AUTO_SL",
|
|
100519
|
+
status,
|
|
100520
|
+
execution_metadata: { trailing_lot: true, protected_size: lot.size, retracement: lot.retracement, ...metadata }
|
|
100521
|
+
});
|
|
100522
|
+
sendTrailingLot = async (args) => {
|
|
100523
|
+
const { io } = args;
|
|
100524
|
+
if (!io.placeTrailingLot) return { lot: args.lot, report: null };
|
|
100525
|
+
const mutationId = io.newMutationId();
|
|
100526
|
+
const journaled = {
|
|
100527
|
+
...args.lot,
|
|
100528
|
+
mutationId,
|
|
100529
|
+
orderId: null,
|
|
100530
|
+
placedAtMs: null,
|
|
100531
|
+
sentAtMs: io.nowMs()
|
|
100532
|
+
};
|
|
100533
|
+
if (!args.journal(journaled)) {
|
|
100534
|
+
return {
|
|
100535
|
+
lot: args.lot,
|
|
100536
|
+
report: lotReport(args.symbol, args.lot, "failed", { reason_code: "protective_lifecycle_persistence_failed" })
|
|
100537
|
+
};
|
|
100538
|
+
}
|
|
100539
|
+
const place = io.placeTrailingLot;
|
|
100540
|
+
const outcome = await notSentRestores(
|
|
100541
|
+
() => attempt(io, () => place({ mutationId, size: journaled.size, retracement: journaled.retracement })),
|
|
100542
|
+
() => args.journal(args.lot)
|
|
100543
|
+
);
|
|
100544
|
+
if (!outcome.ok && outcome.error instanceof NativeOrderNotSentError) {
|
|
100545
|
+
args.journal(args.lot);
|
|
100546
|
+
return {
|
|
100547
|
+
lot: args.lot,
|
|
100548
|
+
report: lotReport(args.symbol, args.lot, "failed", { reason_code: "protective_place_not_sent", error: errorText(outcome.error) })
|
|
100549
|
+
};
|
|
100550
|
+
}
|
|
100551
|
+
if (!outcome.ok && outcome.refused) {
|
|
100552
|
+
const retired = { ...journaled, retiredReason: "protective_place_rejected" };
|
|
100553
|
+
return {
|
|
100554
|
+
lot: retired,
|
|
100555
|
+
report: lotReport(args.symbol, retired, "failed", { reason_code: "protective_place_rejected", error: errorText(outcome.error) })
|
|
100556
|
+
};
|
|
100557
|
+
}
|
|
100558
|
+
const orderId = outcome.ok ? outcome.response?.orderId ?? null : null;
|
|
100559
|
+
const placed = { ...journaled, orderId };
|
|
100560
|
+
return {
|
|
100561
|
+
lot: placed,
|
|
100562
|
+
report: lotReport(args.symbol, placed, "executed", {
|
|
100563
|
+
...args.reasonCode ? { reason_code: args.reasonCode } : {},
|
|
100564
|
+
...args.lot.orderId != null ? { replaced_order_id: String(args.lot.orderId) } : {}
|
|
100565
|
+
})
|
|
100566
|
+
};
|
|
100567
|
+
};
|
|
100568
|
+
planNativeFillLot = (record5, input) => {
|
|
100569
|
+
const fillKey = input.fillKey.trim();
|
|
100570
|
+
const retracement = lotRetracement(input.settings, input.fillSize, input.sizeDecimals);
|
|
100571
|
+
if (!fillKey || retracement == null) return record5;
|
|
100572
|
+
const lots = [...record5.lots ?? []];
|
|
100573
|
+
if (lots.some((lot) => lot.fillKey === fillKey)) return record5;
|
|
100574
|
+
const planned = {
|
|
100575
|
+
mutationId: null,
|
|
100576
|
+
fillKey,
|
|
100577
|
+
fillEventMs: input.nowMs,
|
|
100578
|
+
size: input.fillSize,
|
|
100579
|
+
retracement,
|
|
100580
|
+
orderId: null,
|
|
100581
|
+
placedAtMs: null,
|
|
100582
|
+
sentAtMs: input.nowMs,
|
|
100583
|
+
replacedOnce: false,
|
|
100584
|
+
fillEventFromDevice: true
|
|
100585
|
+
};
|
|
100586
|
+
const pendingIndex = input.pendingKey ? lots.findIndex((lot) => lot.fillKey === input.pendingKey && lot.mutationId == null && lot.size === "") : -1;
|
|
100587
|
+
if (pendingIndex >= 0) lots[pendingIndex] = planned;
|
|
100588
|
+
else lots.push(planned);
|
|
100589
|
+
return { ...record5, lots };
|
|
100590
|
+
};
|
|
100591
|
+
planNativeStandbyAdd = (record5, input) => {
|
|
100592
|
+
if (!input.clientOrderId || (record5.standby ?? []).some((add) => add.clientOrderId === input.clientOrderId)) return record5;
|
|
100593
|
+
return {
|
|
100594
|
+
...record5,
|
|
100595
|
+
standby: [...record5.standby ?? [], { clientOrderId: input.clientOrderId, orderId: null, sentAtMs: input.nowMs }]
|
|
100596
|
+
};
|
|
100597
|
+
};
|
|
100598
|
+
nameNativeStandbyAdd = (record5, clientOrderId, orderId) => (record5.standby ?? []).some((add) => add.clientOrderId === clientOrderId && add.orderId !== orderId) ? {
|
|
100599
|
+
...record5,
|
|
100600
|
+
standby: (record5.standby ?? []).map((add) => add.clientOrderId === clientOrderId ? { ...add, orderId } : add)
|
|
100601
|
+
} : record5;
|
|
100602
|
+
dropNativeStandbyAdd = (record5, clientOrderId) => {
|
|
100603
|
+
const standby = (record5.standby ?? []).filter((add) => add.clientOrderId !== clientOrderId);
|
|
100604
|
+
const { standby: _dropped, ...rest } = record5;
|
|
100605
|
+
return standby.length > 0 ? { ...rest, standby } : rest;
|
|
100606
|
+
};
|
|
100607
|
+
dropNativePendingLot = (record5, key) => versioned({
|
|
100608
|
+
...record5,
|
|
100609
|
+
lots: (record5.lots ?? []).filter((lot) => !(lot.fillKey === key && lot.mutationId == null && lot.size === ""))
|
|
100610
|
+
});
|
|
100611
|
+
planNativePendingLot = (record5, input) => {
|
|
100612
|
+
const retracement = lotRetracement(input.settings, String(input.sizeHint), input.sizeDecimals);
|
|
100613
|
+
if (retracement == null || !input.key || (record5.lots ?? []).some((lot) => lot.fillKey === input.key)) return record5;
|
|
100614
|
+
return versioned({
|
|
100615
|
+
...record5,
|
|
100616
|
+
lots: [...record5.lots ?? [], {
|
|
100617
|
+
mutationId: null,
|
|
100618
|
+
fillKey: input.key,
|
|
100619
|
+
fillEventMs: input.nowMs,
|
|
100620
|
+
fillEventFromDevice: true,
|
|
100621
|
+
size: "",
|
|
100622
|
+
retracement,
|
|
100623
|
+
orderId: null,
|
|
100624
|
+
placedAtMs: null,
|
|
100625
|
+
sentAtMs: input.nowMs,
|
|
100626
|
+
replacedOnce: false
|
|
100627
|
+
}]
|
|
100628
|
+
});
|
|
100629
|
+
};
|
|
100149
100630
|
planNativeOpen = (input) => {
|
|
100150
|
-
if (input.settings.stopLoss?.trailing) return null;
|
|
100151
100631
|
const request = nativeEntryRequest({
|
|
100152
100632
|
settings: input.settings,
|
|
100153
100633
|
isLong: input.isLong,
|
|
@@ -100173,7 +100653,9 @@ var init_native_protection_device = __esm({
|
|
|
100173
100653
|
triggerPrice: Number(member.trigger),
|
|
100174
100654
|
clientOrderId: member.clientOrderId
|
|
100175
100655
|
})),
|
|
100176
|
-
|
|
100656
|
+
// Trailing mode: the open's lot is journaled with the entry, sized once
|
|
100657
|
+
// its fill is known (or from the position it opened), so no settle can lose it.
|
|
100658
|
+
record: planNativePendingLot({
|
|
100177
100659
|
version: NATIVE_PROTECTION_RECORD_VERSION,
|
|
100178
100660
|
profileId: input.profileId,
|
|
100179
100661
|
symbol: input.symbol,
|
|
@@ -100184,7 +100666,13 @@ var init_native_protection_device = __esm({
|
|
|
100184
100666
|
entryClientOrderId: input.entryClientOrderId,
|
|
100185
100667
|
createdAtMs: input.nowMs,
|
|
100186
100668
|
members
|
|
100187
|
-
}
|
|
100669
|
+
}, {
|
|
100670
|
+
settings: input.settings,
|
|
100671
|
+
sizeDecimals: input.sizeDecimals,
|
|
100672
|
+
key: input.entryClientOrderId,
|
|
100673
|
+
sizeHint: input.entrySize,
|
|
100674
|
+
nowMs: input.nowMs
|
|
100675
|
+
})
|
|
100188
100676
|
};
|
|
100189
100677
|
};
|
|
100190
100678
|
recordEntryChildren = (record5, entryResponse) => ({
|
|
@@ -100226,7 +100714,7 @@ var init_native_protection_device = __esm({
|
|
|
100226
100714
|
}
|
|
100227
100715
|
continue;
|
|
100228
100716
|
}
|
|
100229
|
-
if (member.orderId != null || member.retiredReason) {
|
|
100717
|
+
if (member.orderId != null || member.retiredReason || member.plannedAfterMs != null) {
|
|
100230
100718
|
members.push(member);
|
|
100231
100719
|
continue;
|
|
100232
100720
|
}
|
|
@@ -100239,6 +100727,109 @@ var init_native_protection_device = __esm({
|
|
|
100239
100727
|
}
|
|
100240
100728
|
return { ...record5, members };
|
|
100241
100729
|
};
|
|
100730
|
+
plannedPair = (settings, afterMs, io) => ["sl", "tp"].filter((kind) => (kind === "sl" ? settings.stopLoss : settings.takeProfit) != null).map((kind) => ({
|
|
100731
|
+
kind,
|
|
100732
|
+
clientOrderId: clientOrderIdForMutation(io.newMutationId()),
|
|
100733
|
+
orderId: null,
|
|
100734
|
+
trigger: "",
|
|
100735
|
+
placedAtMs: null,
|
|
100736
|
+
sentAtMs: io.nowMs(),
|
|
100737
|
+
replacedOnce: false,
|
|
100738
|
+
plannedAfterMs: afterMs
|
|
100739
|
+
}));
|
|
100740
|
+
resolveStandbyAdds = async (args) => {
|
|
100741
|
+
const { io } = args;
|
|
100742
|
+
let record5 = args.record;
|
|
100743
|
+
const standby = record5.standby ?? [];
|
|
100744
|
+
if (standby.length === 0) return { record: record5, addFillMs: null, undecided: false };
|
|
100745
|
+
const left = [];
|
|
100746
|
+
let addFillMs = null;
|
|
100747
|
+
for (const add of standby) {
|
|
100748
|
+
if (left.length > 0) {
|
|
100749
|
+
left.push(add);
|
|
100750
|
+
continue;
|
|
100751
|
+
}
|
|
100752
|
+
let orderId = add.orderId;
|
|
100753
|
+
let endedUnfilledAtMs = null;
|
|
100754
|
+
if (orderId == null) {
|
|
100755
|
+
const evidence = await io.readOrderStatus(add.clientOrderId);
|
|
100756
|
+
orderId = namedOrderId(evidence);
|
|
100757
|
+
if (orderId == null) {
|
|
100758
|
+
if (!(evidence.responseStatus === UNKNOWN_ORDER_RESPONSE && io.nowMs() > io.neverLandsAfterMs(add.sentAtMs))) {
|
|
100759
|
+
left.push(add);
|
|
100760
|
+
}
|
|
100761
|
+
continue;
|
|
100762
|
+
}
|
|
100763
|
+
if (classifyHyperliquidOrderStatus(evidence.orderStatus) === "terminal_unfilled") {
|
|
100764
|
+
endedUnfilledAtMs = evidence.orderTimestampMs ?? null;
|
|
100765
|
+
}
|
|
100766
|
+
}
|
|
100767
|
+
const page = await args.fills();
|
|
100768
|
+
const times = orderFillTimes(page, orderId, record5.symbol);
|
|
100769
|
+
const verdict = nativeFillOpenedPosition({
|
|
100770
|
+
fills: page.fills,
|
|
100771
|
+
complete: page.complete,
|
|
100772
|
+
orderId,
|
|
100773
|
+
isLong: record5.isLong,
|
|
100774
|
+
symbol: record5.symbol
|
|
100775
|
+
});
|
|
100776
|
+
const fillMs = times.length > 0 && times.every(Number.isFinite) ? Math.max(...times) : null;
|
|
100777
|
+
if (verdict === "other_side") {
|
|
100778
|
+
const lots = record5.lots ?? [];
|
|
100779
|
+
if (lots.some((lot) => lotOfAdd(lot, { clientOrderId: add.clientOrderId, orderId }))) {
|
|
100780
|
+
record5 = {
|
|
100781
|
+
...record5,
|
|
100782
|
+
lots: lots.map((lot) => lotOfAdd(lot, { clientOrderId: add.clientOrderId, orderId }) && !lot.retiredReason ? { ...lot, retiredReason: TRAILING_LOT_OTHER_SIDE } : lot)
|
|
100783
|
+
};
|
|
100784
|
+
}
|
|
100785
|
+
continue;
|
|
100786
|
+
}
|
|
100787
|
+
if (verdict === "unknown" || fillMs == null) {
|
|
100788
|
+
const neverFilled = endedUnfilledAtMs != null && page.complete && times.length === 0 && (page.coversFromMs == null || page.coversFromMs <= endedUnfilledAtMs);
|
|
100789
|
+
if (neverFilled) continue;
|
|
100790
|
+
let pageAccountsForAdd = times.length > 0;
|
|
100791
|
+
if (!pageAccountsForAdd && page.coversFromMs != null) {
|
|
100792
|
+
const evidence = await io.readOrderStatus(orderId);
|
|
100793
|
+
const endedMs = evidence.statusTimestampMs;
|
|
100794
|
+
pageAccountsForAdd = evidence.responseValid && evidence.terminal && endedMs != null && endedMs < page.coversFromMs;
|
|
100795
|
+
}
|
|
100796
|
+
const positionEnded = nativePositionEndedSince({
|
|
100797
|
+
fills: page.fills,
|
|
100798
|
+
complete: page.complete,
|
|
100799
|
+
orderId,
|
|
100800
|
+
isLong: record5.isLong,
|
|
100801
|
+
symbol: record5.symbol,
|
|
100802
|
+
flatRead: pageAccountsForAdd ? flatReadOf(args.position, page, record5.symbol) : null
|
|
100803
|
+
}) === "ended";
|
|
100804
|
+
if (!positionEnded) left.push(add);
|
|
100805
|
+
continue;
|
|
100806
|
+
}
|
|
100807
|
+
const stateMs = args.position.stateTimeMs;
|
|
100808
|
+
if (stateMs == null || !(stateMs > fillMs)) {
|
|
100809
|
+
left.push(add);
|
|
100810
|
+
continue;
|
|
100811
|
+
}
|
|
100812
|
+
record5 = { ...record5, positionOrderId: orderId };
|
|
100813
|
+
addFillMs = fillMs;
|
|
100814
|
+
if (verdict === "opened") {
|
|
100815
|
+
const resting = record5.members.filter((member) => member.orderId != null && !member.retiredReason && args.page.some((order) => order.oid === member.orderId));
|
|
100816
|
+
const planned = plannedPair(args.settings, fillMs, io);
|
|
100817
|
+
record5 = {
|
|
100818
|
+
...record5,
|
|
100819
|
+
members: [
|
|
100820
|
+
...planned.map((member) => {
|
|
100821
|
+
const kept = resting.find((entry) => entry.kind === member.kind);
|
|
100822
|
+
return kept ? { ...kept, replacedOnce: false } : member;
|
|
100823
|
+
}),
|
|
100824
|
+
// A kind the settings no longer enable stays tracked while it rests.
|
|
100825
|
+
...resting.filter((entry) => !planned.some((member) => member.kind === entry.kind))
|
|
100826
|
+
]
|
|
100827
|
+
};
|
|
100828
|
+
}
|
|
100829
|
+
}
|
|
100830
|
+
const { standby: _decided, ...rest } = record5;
|
|
100831
|
+
return { record: left.length > 0 ? { ...rest, standby: left } : rest, addFillMs, undecided: left.length > 0 };
|
|
100832
|
+
};
|
|
100242
100833
|
settleNativeProtectionAfterFill = async (input) => {
|
|
100243
100834
|
const { io } = input;
|
|
100244
100835
|
const reports = [];
|
|
@@ -100247,6 +100838,17 @@ var init_native_protection_device = __esm({
|
|
|
100247
100838
|
const page = await io.readOpenOrders();
|
|
100248
100839
|
const position = await io.readPosition();
|
|
100249
100840
|
const symbol2 = record5.symbol;
|
|
100841
|
+
const fills = fillsReader(io);
|
|
100842
|
+
const settlingAdds = (record5.standby ?? []).length > 0;
|
|
100843
|
+
const boundary = await resolveStandbyAdds({ record: record5, settings: input.settings, io, fills, position, page });
|
|
100844
|
+
record5 = boundary.record;
|
|
100845
|
+
if (boundary.undecided) {
|
|
100846
|
+
return { record: record5, reports };
|
|
100847
|
+
}
|
|
100848
|
+
const entryOrderId = String(input.entryOrderId ?? "").trim();
|
|
100849
|
+
if (record5.positionOrderId == null && boundary.addFillMs == null && !settlingAdds && ORDER_ID_PATTERN.test(entryOrderId)) {
|
|
100850
|
+
record5 = { ...record5, positionOrderId: entryOrderId };
|
|
100851
|
+
}
|
|
100250
100852
|
if (!isOpenInDirection2(position.size, record5.isLong)) {
|
|
100251
100853
|
reports.push({
|
|
100252
100854
|
order_id: input.entryOrderId,
|
|
@@ -100285,7 +100887,10 @@ var init_native_protection_device = __esm({
|
|
|
100285
100887
|
});
|
|
100286
100888
|
let eventMs = Math.max(
|
|
100287
100889
|
0,
|
|
100288
|
-
...observations.map((entry) => entry.row?.timestamp ?? entry.member.placedAtMs ?? 0)
|
|
100890
|
+
...observations.map((entry) => entry.row?.timestamp ?? entry.member.placedAtMs ?? 0),
|
|
100891
|
+
// An add's own fill, and the fill a planned pair answers: Hyperliquid's times.
|
|
100892
|
+
boundary.addFillMs ?? 0,
|
|
100893
|
+
...record5.members.map((member) => member.plannedAfterMs ?? 0)
|
|
100289
100894
|
);
|
|
100290
100895
|
if (eventMs <= 0 && input.entryOrderId) {
|
|
100291
100896
|
const entryStatus = await io.readOrderStatus(input.entryOrderId);
|
|
@@ -100365,7 +100970,7 @@ var init_native_protection_device = __esm({
|
|
|
100365
100970
|
});
|
|
100366
100971
|
continue;
|
|
100367
100972
|
}
|
|
100368
|
-
if (existing != null && existing.orderId == null && !unknownClientOrderIds.has(existing.clientOrderId)) {
|
|
100973
|
+
if (existing != null && existing.orderId == null && existing.plannedAfterMs == null && !unknownClientOrderIds.has(existing.clientOrderId)) {
|
|
100369
100974
|
continue;
|
|
100370
100975
|
}
|
|
100371
100976
|
if (gate !== "place") {
|
|
@@ -100386,7 +100991,8 @@ var init_native_protection_device = __esm({
|
|
|
100386
100991
|
symbol: symbol2,
|
|
100387
100992
|
positionSize: String(position.size),
|
|
100388
100993
|
ownClientOrderIds: [],
|
|
100389
|
-
rows: coverRows(page)
|
|
100994
|
+
rows: coverRows(page),
|
|
100995
|
+
ownTrailingOrderIds: ownLotOrderIds(record5)
|
|
100390
100996
|
});
|
|
100391
100997
|
if (cover.decision !== "place") {
|
|
100392
100998
|
continue;
|
|
@@ -100424,7 +101030,7 @@ var init_native_protection_device = __esm({
|
|
|
100424
101030
|
() => io.persist({ ...record5, phase: "active", members: before })
|
|
100425
101031
|
);
|
|
100426
101032
|
if (!outcome.ok && outcome.refused) {
|
|
100427
|
-
members.splice(0, members.length, ...before);
|
|
101033
|
+
if (outcome.error instanceof NativeOrderNotSentError) members.splice(0, members.length, ...before);
|
|
100428
101034
|
reports.push({
|
|
100429
101035
|
order_id: null,
|
|
100430
101036
|
symbol: symbol2,
|
|
@@ -100433,6 +101039,8 @@ var init_native_protection_device = __esm({
|
|
|
100433
101039
|
execution_metadata: {
|
|
100434
101040
|
reason_code: outcome.error instanceof NativeOrderNotSentError ? "protective_place_not_sent" : "protective_place_rejected",
|
|
100435
101041
|
trigger_price: step.trigger,
|
|
101042
|
+
// The fill this stop protects: its warning is shown once per stop.
|
|
101043
|
+
entry_order_id: input.entryOrderId,
|
|
100436
101044
|
error: errorText(outcome.error)
|
|
100437
101045
|
}
|
|
100438
101046
|
});
|
|
@@ -100456,6 +101064,59 @@ var init_native_protection_device = __esm({
|
|
|
100456
101064
|
}
|
|
100457
101065
|
});
|
|
100458
101066
|
}
|
|
101067
|
+
const lots = [...record5.lots ?? []];
|
|
101068
|
+
const fillKey = String(input.entryOrderId ?? "").trim();
|
|
101069
|
+
let lotIndex = fillKey ? lots.findIndex((lot) => lot.fillKey === fillKey) : -1;
|
|
101070
|
+
const fillLotSize = Number(input.fillSize) > 0 ? input.fillSize : record5.phase === "entry_pending" ? String(Math.abs(position.size)) : "0";
|
|
101071
|
+
const fillRetracement = lotRetracement(input.settings, fillLotSize, input.sizeDecimals);
|
|
101072
|
+
if (lotIndex < 0 && fillKey && fillRetracement) {
|
|
101073
|
+
lots.push({
|
|
101074
|
+
mutationId: null,
|
|
101075
|
+
fillKey,
|
|
101076
|
+
fillEventMs: eventMs,
|
|
101077
|
+
size: fillLotSize,
|
|
101078
|
+
retracement: fillRetracement,
|
|
101079
|
+
orderId: null,
|
|
101080
|
+
placedAtMs: null,
|
|
101081
|
+
sentAtMs: io.nowMs(),
|
|
101082
|
+
replacedOnce: false
|
|
101083
|
+
});
|
|
101084
|
+
lotIndex = lots.length - 1;
|
|
101085
|
+
}
|
|
101086
|
+
const journaledLot = lotIndex >= 0 ? lots[lotIndex] : null;
|
|
101087
|
+
if (journaledLot && journaledLot.mutationId == null && !journaledLot.retiredReason && journaledLot.userCancelledOrderId == null && io.placeTrailingLot) {
|
|
101088
|
+
const size = journaledLot.size || fillLotSize;
|
|
101089
|
+
const retracement = lotRetracement(input.settings, size, input.sizeDecimals);
|
|
101090
|
+
if (retracement) {
|
|
101091
|
+
const { fillEventFromDevice: _deviceTime, ...withoutDeviceTime } = journaledLot;
|
|
101092
|
+
let planned = eventMs > 0 ? { ...withoutDeviceTime, size, retracement, fillEventMs: eventMs } : { ...journaledLot, size, retracement };
|
|
101093
|
+
if (gate === "place" && lotFillOrderId(planned) == null) {
|
|
101094
|
+
const named = namedOrderId(await io.readOrderStatus(planned.fillKey));
|
|
101095
|
+
if (named != null) planned = { ...planned, fillOrderId: named };
|
|
101096
|
+
}
|
|
101097
|
+
const since = gate === "place" ? await lotPositionSince(planned, record5, fills) : "unknown";
|
|
101098
|
+
if (since === "ended") {
|
|
101099
|
+
lots[lotIndex] = { ...planned, retiredReason: TRAILING_LOT_POSITION_ENDED };
|
|
101100
|
+
} else if (since === "open") {
|
|
101101
|
+
const index = lotIndex;
|
|
101102
|
+
const sent = await sendTrailingLot({
|
|
101103
|
+
io,
|
|
101104
|
+
symbol: symbol2,
|
|
101105
|
+
lot: planned,
|
|
101106
|
+
journal: (lot) => io.persist({
|
|
101107
|
+
...record5,
|
|
101108
|
+
phase: "active",
|
|
101109
|
+
members,
|
|
101110
|
+
lots: [...lots.slice(0, index), lot, ...lots.slice(index + 1)]
|
|
101111
|
+
})
|
|
101112
|
+
});
|
|
101113
|
+
lots[index] = sent.lot;
|
|
101114
|
+
if (sent.report) reports.push(sent.report);
|
|
101115
|
+
} else {
|
|
101116
|
+
lots[lotIndex] = planned;
|
|
101117
|
+
}
|
|
101118
|
+
}
|
|
101119
|
+
}
|
|
100459
101120
|
for (const entry of observations) {
|
|
100460
101121
|
if (!entry.row || reports.some((report) => report.order_id === String(entry.row?.oid))) continue;
|
|
100461
101122
|
reports.push({
|
|
@@ -100470,7 +101131,7 @@ var init_native_protection_device = __esm({
|
|
|
100470
101131
|
}
|
|
100471
101132
|
});
|
|
100472
101133
|
}
|
|
100473
|
-
record5 = { ...record5, phase: "active", members };
|
|
101134
|
+
record5 = { ...record5, phase: "active", members, ...lots.length > 0 ? { lots } : {} };
|
|
100474
101135
|
return { record: record5, reports };
|
|
100475
101136
|
};
|
|
100476
101137
|
reconcileNativeProtection = async (input) => {
|
|
@@ -100482,6 +101143,28 @@ var init_native_protection_device = __esm({
|
|
|
100482
101143
|
const position = await io.readPosition();
|
|
100483
101144
|
const symbol2 = record5.symbol;
|
|
100484
101145
|
const stateMs = position.stateTimeMs ?? Number.NEGATIVE_INFINITY;
|
|
101146
|
+
const fills = fillsReader(io);
|
|
101147
|
+
const undecidedAdds = (record5.standby ?? []).length > 0;
|
|
101148
|
+
let membersPositionEnded = null;
|
|
101149
|
+
const membersEnded = () => {
|
|
101150
|
+
membersPositionEnded ??= (async () => {
|
|
101151
|
+
let anchor = record5.positionOrderId ?? null;
|
|
101152
|
+
if (anchor == null) {
|
|
101153
|
+
anchor = namedOrderId(await io.readOrderStatus(record5.entryClientOrderId));
|
|
101154
|
+
if (anchor != null) record5 = { ...record5, positionOrderId: anchor };
|
|
101155
|
+
}
|
|
101156
|
+
const fillsPage = await fills();
|
|
101157
|
+
return nativePositionEndedSince({
|
|
101158
|
+
fills: fillsPage.fills,
|
|
101159
|
+
complete: fillsPage.complete,
|
|
101160
|
+
orderId: anchor ?? "",
|
|
101161
|
+
isLong: record5.isLong,
|
|
101162
|
+
symbol: symbol2,
|
|
101163
|
+
flatRead: flatReadOf(position, fillsPage, symbol2)
|
|
101164
|
+
});
|
|
101165
|
+
})();
|
|
101166
|
+
return membersPositionEnded;
|
|
101167
|
+
};
|
|
100485
101168
|
const observations = observeMembers(record5, page).map((entry) => ({
|
|
100486
101169
|
...entry,
|
|
100487
101170
|
member: entry.row ? { ...entry.member, placedAtMs: entry.row.timestamp || entry.member.placedAtMs } : entry.member
|
|
@@ -100516,7 +101199,8 @@ var init_native_protection_device = __esm({
|
|
|
100516
101199
|
symbol: symbol2,
|
|
100517
101200
|
positionSize: String(position.size),
|
|
100518
101201
|
ownClientOrderIds: [],
|
|
100519
|
-
rows: coverRows(page)
|
|
101202
|
+
rows: coverRows(page),
|
|
101203
|
+
ownTrailingOrderIds: ownLotOrderIds(record5)
|
|
100520
101204
|
});
|
|
100521
101205
|
if (cover.decision !== "place") return args.member;
|
|
100522
101206
|
const clientOrderId = clientOrderIdForMutation(io.newMutationId());
|
|
@@ -100606,7 +101290,8 @@ var init_native_protection_device = __esm({
|
|
|
100606
101290
|
trigger_price: args.trigger,
|
|
100607
101291
|
position_tpsl: true,
|
|
100608
101292
|
protected_size: Math.abs(position.size),
|
|
100609
|
-
|
|
101293
|
+
// A refused replacement or re-arm is not placed again: left to a person.
|
|
101294
|
+
...refused ? { error: errorText(outcome.error), manual_intervention: true } : {}
|
|
100610
101295
|
}
|
|
100611
101296
|
});
|
|
100612
101297
|
return placed;
|
|
@@ -100651,6 +101336,33 @@ var init_native_protection_device = __esm({
|
|
|
100651
101336
|
members.push(member);
|
|
100652
101337
|
continue;
|
|
100653
101338
|
}
|
|
101339
|
+
if (member.plannedAfterMs != null) {
|
|
101340
|
+
if (!kindEnabled(member)) continue;
|
|
101341
|
+
const plannedGate = nativePlacementGate({
|
|
101342
|
+
eventMs: member.plannedAfterMs,
|
|
101343
|
+
position: position.size,
|
|
101344
|
+
positionStateMs: stateMs,
|
|
101345
|
+
isLong: record5.isLong
|
|
101346
|
+
});
|
|
101347
|
+
if (plannedGate === "not_required") continue;
|
|
101348
|
+
const plannedTrigger = currentTrigger(member);
|
|
101349
|
+
if (plannedGate === "need_reads" || plannedTrigger == null) {
|
|
101350
|
+
anyResting = true;
|
|
101351
|
+
members.push(member);
|
|
101352
|
+
continue;
|
|
101353
|
+
}
|
|
101354
|
+
const placed = await placeMember({
|
|
101355
|
+
member,
|
|
101356
|
+
trigger: plannedTrigger,
|
|
101357
|
+
replacedOnce: false,
|
|
101358
|
+
eventMs: member.plannedAfterMs,
|
|
101359
|
+
reasonCode: "protective_native_position_opened_by_add",
|
|
101360
|
+
observationIndex
|
|
101361
|
+
});
|
|
101362
|
+
members.push(placed);
|
|
101363
|
+
if (!placed.retiredReason) anyResting = true;
|
|
101364
|
+
continue;
|
|
101365
|
+
}
|
|
100654
101366
|
if (member.orderId == null) {
|
|
100655
101367
|
if (io.nowMs() <= io.neverLandsAfterMs(member.sentAtMs) || !unknownClientOrderIds.has(member.clientOrderId)) {
|
|
100656
101368
|
anyResting = true;
|
|
@@ -100694,10 +101406,9 @@ var init_native_protection_device = __esm({
|
|
|
100694
101406
|
});
|
|
100695
101407
|
explained = end2 === "resting" || end2 === "pending" || end2 === "unknown" ? "status_read" : "ended_with_position";
|
|
100696
101408
|
}
|
|
100697
|
-
if (explained
|
|
100698
|
-
|
|
100699
|
-
|
|
100700
|
-
}
|
|
101409
|
+
if (explained === "ended_with_position" && await membersEnded() === "ended") continue;
|
|
101410
|
+
anyResting = true;
|
|
101411
|
+
members.push(member);
|
|
100701
101412
|
continue;
|
|
100702
101413
|
}
|
|
100703
101414
|
const evidence = await io.readOrderStatus(member.orderId);
|
|
@@ -100719,7 +101430,7 @@ var init_native_protection_device = __esm({
|
|
|
100719
101430
|
});
|
|
100720
101431
|
if (rearm === "retire" || !kindEnabled(member)) continue;
|
|
100721
101432
|
const rearmTrigger = currentTrigger(member);
|
|
100722
|
-
if (rearm === "need_reads" || rearmTrigger == null) {
|
|
101433
|
+
if (rearm === "need_reads" || rearmTrigger == null || undecidedAdds) {
|
|
100723
101434
|
members.push(member);
|
|
100724
101435
|
continue;
|
|
100725
101436
|
}
|
|
@@ -100792,10 +101503,235 @@ var init_native_protection_device = __esm({
|
|
|
100792
101503
|
members.push(replacement);
|
|
100793
101504
|
if (replacement !== member && !replacement.retiredReason) anyResting = true;
|
|
100794
101505
|
}
|
|
100795
|
-
|
|
101506
|
+
const lots = [];
|
|
101507
|
+
const storedLots = record5.lots ?? [];
|
|
101508
|
+
const isUnsized = (lot) => lot.mutationId == null && lot.size === "";
|
|
101509
|
+
const priorLots = [...storedLots.filter((lot) => !isUnsized(lot)), ...storedLots.filter(isUnsized)];
|
|
101510
|
+
const journalLot = (index, lot) => io.persist({
|
|
101511
|
+
...record5,
|
|
101512
|
+
members,
|
|
101513
|
+
lots: [...lots, lot, ...priorLots.slice(index + 1)]
|
|
101514
|
+
});
|
|
101515
|
+
for (const [index, prior] of priorLots.entries()) {
|
|
101516
|
+
let lot = prior;
|
|
101517
|
+
const restingRow = lot.orderId == null ? null : page.find((order) => order.oid === lot.orderId) ?? null;
|
|
101518
|
+
const otherSideUnnamed = lot.retiredReason === TRAILING_LOT_OTHER_SIDE && lot.mutationId != null && lot.orderId == null;
|
|
101519
|
+
if ((lot.retiredReason || lot.userCancelledOrderId != null) && !otherSideUnnamed && !(restingRow && readListedProtectiveRow({ triggerCondition: restingRow.trigger_condition }) === "resting")) {
|
|
101520
|
+
lots.push(lot);
|
|
101521
|
+
continue;
|
|
101522
|
+
}
|
|
101523
|
+
if (lot.mutationId == null) {
|
|
101524
|
+
if (lot.fillEventFromDevice) {
|
|
101525
|
+
const entryStatus = await io.readOrderStatus(lot.fillKey);
|
|
101526
|
+
if (entryStatus.responseValid && entryStatus.orderMatches && entryStatus.statusTimestampMs != null) {
|
|
101527
|
+
const { fillEventFromDevice: _deviceTime, ...exchangeTimed } = lot;
|
|
101528
|
+
const named = lotFillOrderId(lot) == null ? namedOrderId(entryStatus) : null;
|
|
101529
|
+
lot = { ...exchangeTimed, fillEventMs: entryStatus.statusTimestampMs, ...named != null ? { fillOrderId: named } : {} };
|
|
101530
|
+
} else if (entryStatus.responseStatus === UNKNOWN_ORDER_RESPONSE && io.nowMs() > io.neverLandsAfterMs(lot.sentAtMs)) {
|
|
101531
|
+
continue;
|
|
101532
|
+
} else {
|
|
101533
|
+
anyResting = true;
|
|
101534
|
+
lots.push(lot);
|
|
101535
|
+
continue;
|
|
101536
|
+
}
|
|
101537
|
+
}
|
|
101538
|
+
const gate = nativePlacementGate({
|
|
101539
|
+
eventMs: lot.fillEventMs,
|
|
101540
|
+
position: position.size,
|
|
101541
|
+
positionStateMs: stateMs,
|
|
101542
|
+
isLong: record5.isLong
|
|
101543
|
+
});
|
|
101544
|
+
if (gate === "not_required") continue;
|
|
101545
|
+
if (gate !== "place") {
|
|
101546
|
+
anyResting = true;
|
|
101547
|
+
lots.push(lot);
|
|
101548
|
+
continue;
|
|
101549
|
+
}
|
|
101550
|
+
if (lotFillOrderId(lot) == null) {
|
|
101551
|
+
const named = namedOrderId(await io.readOrderStatus(lot.fillKey));
|
|
101552
|
+
if (named != null) lot = { ...lot, fillOrderId: named };
|
|
101553
|
+
}
|
|
101554
|
+
if ((record5.standby ?? []).some((add) => lotOfAdd(lot, add))) {
|
|
101555
|
+
anyResting = true;
|
|
101556
|
+
lots.push(lot);
|
|
101557
|
+
continue;
|
|
101558
|
+
}
|
|
101559
|
+
const since = await lotPositionSince(lot, record5, fills);
|
|
101560
|
+
if (since === "ended") {
|
|
101561
|
+
lots.push({ ...lot, retiredReason: TRAILING_LOT_POSITION_ENDED });
|
|
101562
|
+
continue;
|
|
101563
|
+
}
|
|
101564
|
+
if (since !== "open") {
|
|
101565
|
+
anyResting = true;
|
|
101566
|
+
lots.push(lot);
|
|
101567
|
+
continue;
|
|
101568
|
+
}
|
|
101569
|
+
if (!lot.size) {
|
|
101570
|
+
const others = [...lots, ...priorLots.slice(index + 1)];
|
|
101571
|
+
const covered = others.reduce((total, other) => other.size && !lotFillLeftPosition(other) ? total + Number(other.size) : total, 0);
|
|
101572
|
+
const uncovered = Number((Math.abs(position.size) - covered).toFixed(input.sizeDecimals));
|
|
101573
|
+
if (!(uncovered > 0)) continue;
|
|
101574
|
+
lot = { ...lot, size: String(uncovered) };
|
|
101575
|
+
}
|
|
101576
|
+
const retracement2 = lotRetracement(input.settings, lot.size, input.sizeDecimals);
|
|
101577
|
+
if (retracement2 == null) {
|
|
101578
|
+
lots.push(lot);
|
|
101579
|
+
continue;
|
|
101580
|
+
}
|
|
101581
|
+
const sent2 = await sendTrailingLot({ io, symbol: symbol2, lot: { ...lot, retracement: retracement2 }, journal: (next) => journalLot(index, next) });
|
|
101582
|
+
lots.push(sent2.lot);
|
|
101583
|
+
if (sent2.report) reports.push(sent2.report);
|
|
101584
|
+
if (!sent2.lot.retiredReason) anyResting = true;
|
|
101585
|
+
continue;
|
|
101586
|
+
}
|
|
101587
|
+
if (lot.orderId == null) {
|
|
101588
|
+
let answer = null;
|
|
101589
|
+
try {
|
|
101590
|
+
answer = io.readLotMutation ? await io.readLotMutation(lot.mutationId) : null;
|
|
101591
|
+
} catch (error48) {
|
|
101592
|
+
if (io.endsPass?.(error48)) throw error48;
|
|
101593
|
+
}
|
|
101594
|
+
const orderId = Number(answer?.exchange_order_id);
|
|
101595
|
+
const named = answer != null && (answer.status === "settled" && answer.outcome_code === "success" || answer.status === "reconciled" && answer.outcome_code === "exchange_effect_observed") && Number.isSafeInteger(orderId) && orderId > 0;
|
|
101596
|
+
if (named) {
|
|
101597
|
+
lot = { ...lot, orderId };
|
|
101598
|
+
} else if (lot.retiredReason && (answer?.status === "settled" && answer.outcome_code === "rejected" || answer?.status === "reconciled" && answer.outcome_code === "exchange_expired_unconfirmed" || answer?.status === "absent" && io.nowMs() > io.neverLandsAfterMs(lot.sentAtMs))) {
|
|
101599
|
+
lots.push({ ...lot, mutationId: null });
|
|
101600
|
+
continue;
|
|
101601
|
+
} else if (answer?.status === "settled" && answer.outcome_code === "rejected") {
|
|
101602
|
+
lots.push({ ...lot, retiredReason: "protective_place_rejected" });
|
|
101603
|
+
continue;
|
|
101604
|
+
} else if (answer?.status === "reconciled" && answer.outcome_code === "exchange_expired_unconfirmed" || answer?.status === "absent" && io.nowMs() > io.neverLandsAfterMs(lot.sentAtMs)) {
|
|
101605
|
+
if (!positionOpen) continue;
|
|
101606
|
+
const since = await lotPositionSince(lot, record5, fills);
|
|
101607
|
+
if (since === "ended") {
|
|
101608
|
+
lots.push({ ...lot, retiredReason: TRAILING_LOT_POSITION_ENDED });
|
|
101609
|
+
continue;
|
|
101610
|
+
}
|
|
101611
|
+
if (since !== "open") {
|
|
101612
|
+
anyResting = true;
|
|
101613
|
+
lots.push(lot);
|
|
101614
|
+
continue;
|
|
101615
|
+
}
|
|
101616
|
+
const sent2 = await sendTrailingLot({ io, symbol: symbol2, lot: { ...lot, mutationId: null }, journal: (next) => journalLot(index, next) });
|
|
101617
|
+
lots.push(sent2.lot);
|
|
101618
|
+
if (sent2.report) reports.push(sent2.report);
|
|
101619
|
+
if (!sent2.lot.retiredReason) anyResting = true;
|
|
101620
|
+
continue;
|
|
101621
|
+
} else {
|
|
101622
|
+
anyResting = true;
|
|
101623
|
+
lots.push(lot);
|
|
101624
|
+
continue;
|
|
101625
|
+
}
|
|
101626
|
+
}
|
|
101627
|
+
const lotOrderId = lot.orderId;
|
|
101628
|
+
const row = lot === prior ? restingRow : page.find((order) => order.oid === lotOrderId) ?? null;
|
|
101629
|
+
if (row && readListedProtectiveRow({ triggerCondition: row.trigger_condition }) === "resting") {
|
|
101630
|
+
lot = { ...lot, placedAtMs: row.timestamp || lot.placedAtMs };
|
|
101631
|
+
const stray = lot.retiredReason === TRAILING_LOT_OTHER_SIDE ? "cancel" : nativeStrayOrderDecision({
|
|
101632
|
+
placedMs: lot.placedAtMs ?? Number.POSITIVE_INFINITY,
|
|
101633
|
+
position: position.size,
|
|
101634
|
+
positionStateMs: stateMs,
|
|
101635
|
+
isLong: record5.isLong
|
|
101636
|
+
});
|
|
101637
|
+
if (stray === "cancel") {
|
|
101638
|
+
const outcome = await attempt(io, () => io.cancelOrder(lotOrderId));
|
|
101639
|
+
reports.push(lotReport(symbol2, lot, outcome.ok ? "executed" : "failed", {
|
|
101640
|
+
reason_code: outcome.ok ? "protective_native_stray_cancelled" : "protective_native_stray_cancel_failed",
|
|
101641
|
+
live_position_size: position.size,
|
|
101642
|
+
...outcome.ok ? {} : { error: errorText(outcome.error) }
|
|
101643
|
+
}));
|
|
101644
|
+
if (!outcome.ok) {
|
|
101645
|
+
anyResting = true;
|
|
101646
|
+
lots.push(lot);
|
|
101647
|
+
}
|
|
101648
|
+
continue;
|
|
101649
|
+
}
|
|
101650
|
+
anyResting = true;
|
|
101651
|
+
lots.push(lot);
|
|
101652
|
+
continue;
|
|
101653
|
+
}
|
|
101654
|
+
if (lot.retiredReason || lot.userCancelledOrderId != null) {
|
|
101655
|
+
lots.push(lot);
|
|
101656
|
+
continue;
|
|
101657
|
+
}
|
|
101658
|
+
if (!positionOpen) {
|
|
101659
|
+
const explained = lot.placedAtMs != null ? explainAbsentProtectiveOrder({
|
|
101660
|
+
lastSeenRestingMs: lot.placedAtMs,
|
|
101661
|
+
position: position.size,
|
|
101662
|
+
positionStateMs: stateMs,
|
|
101663
|
+
isLong: record5.isLong
|
|
101664
|
+
}) : "status_read";
|
|
101665
|
+
if (explained === "ended_with_position") continue;
|
|
101666
|
+
const evidence2 = await io.readOrderStatus(lotOrderId);
|
|
101667
|
+
const end2 = classifyNativeOrderEnd({
|
|
101668
|
+
orderStatus: evidence2.responseValid ? String(evidence2.orderStatus ?? "") : "",
|
|
101669
|
+
replacedByOwnModify: false,
|
|
101670
|
+
userCancelledThroughVtx: false
|
|
101671
|
+
});
|
|
101672
|
+
if (end2 === "resting" || end2 === "pending" || end2 === "unknown") {
|
|
101673
|
+
anyResting = true;
|
|
101674
|
+
lots.push(lot);
|
|
101675
|
+
}
|
|
101676
|
+
continue;
|
|
101677
|
+
}
|
|
101678
|
+
const evidence = await io.readOrderStatus(lotOrderId);
|
|
101679
|
+
const end = classifyNativeOrderEnd({
|
|
101680
|
+
orderStatus: evidence.responseValid ? String(evidence.orderStatus ?? "") : "",
|
|
101681
|
+
replacedByOwnModify: false,
|
|
101682
|
+
userCancelledThroughVtx: false
|
|
101683
|
+
});
|
|
101684
|
+
if (end === "resting" || end === "pending" || end === "unknown" || end === "superseded" || end === "user_cancelled") {
|
|
101685
|
+
anyResting = true;
|
|
101686
|
+
lots.push(lot);
|
|
101687
|
+
continue;
|
|
101688
|
+
}
|
|
101689
|
+
if (end === "fired" || end === "ended_with_position") {
|
|
101690
|
+
lots.push({ ...lot, retiredReason: TRAILING_LOT_FIRED });
|
|
101691
|
+
continue;
|
|
101692
|
+
}
|
|
101693
|
+
if (end === "lost_permanent" || lot.replacedOnce) {
|
|
101694
|
+
const reason = end === "lost_permanent" ? "protective_stop_execution_rejected" : "protective_replacement_lost";
|
|
101695
|
+
lots.push({ ...lot, retiredReason: reason });
|
|
101696
|
+
reports.push(lotReport(symbol2, lot, "failed", { reason_code: reason, order_status: evidence.orderStatus, manual_intervention: true }));
|
|
101697
|
+
continue;
|
|
101698
|
+
}
|
|
101699
|
+
const lostGate = nativePlacementGate({
|
|
101700
|
+
eventMs: evidence.statusTimestampMs ?? Number.POSITIVE_INFINITY,
|
|
101701
|
+
position: position.size,
|
|
101702
|
+
positionStateMs: stateMs,
|
|
101703
|
+
isLong: record5.isLong
|
|
101704
|
+
});
|
|
101705
|
+
const retracement = lotRetracement(input.settings, lot.size, input.sizeDecimals);
|
|
101706
|
+
if (lostGate !== "place" || retracement == null) {
|
|
101707
|
+
lots.push(lot);
|
|
101708
|
+
continue;
|
|
101709
|
+
}
|
|
101710
|
+
const lostSince = await lotPositionSince(lot, record5, fills);
|
|
101711
|
+
if (lostSince === "ended") {
|
|
101712
|
+
lots.push({ ...lot, retiredReason: TRAILING_LOT_POSITION_ENDED });
|
|
101713
|
+
continue;
|
|
101714
|
+
}
|
|
101715
|
+
if (lostSince !== "open") {
|
|
101716
|
+
lots.push(lot);
|
|
101717
|
+
continue;
|
|
101718
|
+
}
|
|
101719
|
+
const sent = await sendTrailingLot({
|
|
101720
|
+
io,
|
|
101721
|
+
symbol: symbol2,
|
|
101722
|
+
lot: { ...lot, retracement, replacedOnce: true },
|
|
101723
|
+
journal: (next) => journalLot(index, next),
|
|
101724
|
+
reasonCode: "protective_stop_replaced"
|
|
101725
|
+
});
|
|
101726
|
+
lots.push(sent.lot);
|
|
101727
|
+
if (sent.report) reports.push(sent.report);
|
|
101728
|
+
if (!sent.lot.retiredReason) anyResting = true;
|
|
101729
|
+
}
|
|
101730
|
+
if (!positionOpen && !anyResting && !undecidedAdds) {
|
|
100796
101731
|
return { record: null, reports };
|
|
100797
101732
|
}
|
|
100798
|
-
|
|
101733
|
+
const { lots: _priorLots, ...withoutLots } = record5;
|
|
101734
|
+
record5 = { ...withoutLots, members, ...lots.length > 0 ? { lots } : {} };
|
|
100799
101735
|
return { record: record5, reports };
|
|
100800
101736
|
};
|
|
100801
101737
|
}
|
|
@@ -104500,6 +105436,37 @@ var init_runtime_execution = __esm({
|
|
|
104500
105436
|
publicRequestPriority: "trading_reduce",
|
|
104501
105437
|
orderId
|
|
104502
105438
|
})),
|
|
105439
|
+
placeTrailingLot: async ({ mutationId, size, retracement }) => {
|
|
105440
|
+
const response = await fenced((onExchangeOrderDispatched) => executeClientTrailingStop({
|
|
105441
|
+
...common,
|
|
105442
|
+
onExchangeOrderDispatched,
|
|
105443
|
+
mutationId,
|
|
105444
|
+
side: exitSide,
|
|
105445
|
+
size: Number(size),
|
|
105446
|
+
retracement
|
|
105447
|
+
}));
|
|
105448
|
+
const answer = readHyperliquidTrailingStopAcknowledgement(response);
|
|
105449
|
+
return { orderId: answer.outcome === "placed" ? answer.order_id : null };
|
|
105450
|
+
},
|
|
105451
|
+
readLotMutation: async (mutationId) => {
|
|
105452
|
+
const mutation = await getClientRuntimeExchangeMutation(request.profileId, mutationId, request.signal);
|
|
105453
|
+
if (mutation == null) return { status: "absent" };
|
|
105454
|
+
if (mutation.operation_kind !== "trailing_stop") throw new Error("The ledger names another action for this trailing lot.");
|
|
105455
|
+
return { status: mutation.status, outcome_code: mutation.outcome_code, exchange_order_id: mutation.exchange_order_id };
|
|
105456
|
+
},
|
|
105457
|
+
// The device's own fills read (Client Mode: every Hyperliquid read comes
|
|
105458
|
+
// from the device), fresh, as the per-entry lane's episode rule reads it.
|
|
105459
|
+
readFills: async () => {
|
|
105460
|
+
const { rawFills, evidence } = await fetchBrowserUserFills({
|
|
105461
|
+
publicRequestPriority: "trading_reduce",
|
|
105462
|
+
config: request.config ?? {},
|
|
105463
|
+
walletAddress,
|
|
105464
|
+
symbols: [symbol2],
|
|
105465
|
+
forceRefresh: true,
|
|
105466
|
+
signal: request.signal
|
|
105467
|
+
});
|
|
105468
|
+
return nativeFillsPageFromUserFills(rawFills, evidence);
|
|
105469
|
+
},
|
|
104503
105470
|
isDefinitiveRefusal: (error48) => error48 instanceof HyperliquidExchangeRejectionError || error48 instanceof NativeOrderNotSentError,
|
|
104504
105471
|
neverLandsAfterMs: (sentAtMs) => clientOrderNeverLandsAfterMs(request.config, { kind: "absent", ageStartMs: sentAtMs }),
|
|
104505
105472
|
newMutationId: () => createRuntimeId().toLowerCase(),
|
|
@@ -104533,17 +105500,29 @@ var init_runtime_execution = __esm({
|
|
|
104533
105500
|
if (read.record.walletAddress !== wallet) return [nativeStorageReport(symbol2, "protective_wallet_mismatch")];
|
|
104534
105501
|
try {
|
|
104535
105502
|
const io = nativeProtectionIo(request, read.record.isLong);
|
|
104536
|
-
|
|
105503
|
+
const standby = read.record.standby ?? [];
|
|
105504
|
+
if (read.record.phase === "entry_pending" || standby.length > 0) {
|
|
104537
105505
|
const settled = await settleNativeProtectionAfterFill({
|
|
104538
105506
|
record: read.record,
|
|
104539
105507
|
settings: nativeSettingsOf(request.executionContext),
|
|
104540
105508
|
sizeDecimals: request.executionContext.sizeDecimals,
|
|
104541
105509
|
fillSize: "0",
|
|
104542
|
-
entryOrderId: read.record.entryClientOrderId,
|
|
105510
|
+
entryOrderId: read.record.phase === "entry_pending" ? read.record.entryClientOrderId : standby[0].orderId ?? standby[0].clientOrderId,
|
|
104543
105511
|
io
|
|
104544
105512
|
});
|
|
104545
105513
|
const reports2 = [...settled.reports];
|
|
104546
|
-
|
|
105514
|
+
let record5 = settled.record;
|
|
105515
|
+
if (record5 != null && record5.phase !== "entry_pending" && (record5.standby ?? []).length > 0) {
|
|
105516
|
+
const kept = await reconcileNativeProtection({
|
|
105517
|
+
record: record5,
|
|
105518
|
+
settings: nativeSettingsOf(request.executionContext),
|
|
105519
|
+
sizeDecimals: request.executionContext.sizeDecimals,
|
|
105520
|
+
io
|
|
105521
|
+
});
|
|
105522
|
+
reports2.push(...kept.reports);
|
|
105523
|
+
record5 = kept.record;
|
|
105524
|
+
}
|
|
105525
|
+
if (!writeNativeProtectionRecord(profileId, symbol2, record5)) {
|
|
104547
105526
|
reports2.push(nativeStorageReport(symbol2, "protective_lifecycle_persistence_failed"));
|
|
104548
105527
|
}
|
|
104549
105528
|
return reports2;
|
|
@@ -107877,6 +108856,7 @@ var init_runtime_execution = __esm({
|
|
|
107877
108856
|
if (entryMutationId) entryClientOrderId = clientOrderIdForMutation(entryMutationId);
|
|
107878
108857
|
let nativeOpen = null;
|
|
107879
108858
|
let nativeAddRecord = null;
|
|
108859
|
+
let nativePendingLotKey = null;
|
|
107880
108860
|
const nativeProfileId = String(input.profileId).trim();
|
|
107881
108861
|
const nativeBlocked = (reasonCode, message) => ({
|
|
107882
108862
|
// A flip whose close already filled reports that close as executed.
|
|
@@ -107915,7 +108895,23 @@ var init_runtime_execution = __esm({
|
|
|
107915
108895
|
}
|
|
107916
108896
|
if (classified.intent === "add") {
|
|
107917
108897
|
if (existingNative.kind === "record" && existingNative.record.isLong === (classified.side === "buy")) {
|
|
107918
|
-
|
|
108898
|
+
entryMutationId ??= createRuntimeId().toLowerCase();
|
|
108899
|
+
entryClientOrderId = clientOrderIdForMutation(entryMutationId);
|
|
108900
|
+
nativePendingLotKey = entryClientOrderId;
|
|
108901
|
+
const journaledAt = Date.now();
|
|
108902
|
+
nativeAddRecord = planNativeStandbyAdd(planNativePendingLot(existingNative.record, {
|
|
108903
|
+
settings: nativeSettingsOf(input.executionContext),
|
|
108904
|
+
sizeDecimals: input.executionContext.sizeDecimals,
|
|
108905
|
+
key: entryClientOrderId,
|
|
108906
|
+
sizeHint: sizeAsset,
|
|
108907
|
+
nowMs: journaledAt
|
|
108908
|
+
}), { clientOrderId: entryClientOrderId, nowMs: journaledAt });
|
|
108909
|
+
if (nativeAddRecord !== existingNative.record && !writeNativeProtectionRecord(nativeProfileId, input.executionContext.symbol, nativeAddRecord)) {
|
|
108910
|
+
return nativeBlocked(
|
|
108911
|
+
"protective_lifecycle_persistence_failed",
|
|
108912
|
+
"Blocked new exposure because its position protection could not be stored."
|
|
108913
|
+
);
|
|
108914
|
+
}
|
|
107919
108915
|
}
|
|
107920
108916
|
} else if (existingNative.kind === "record") {
|
|
107921
108917
|
return nativeBlocked(
|
|
@@ -108090,6 +109086,16 @@ var init_runtime_execution = __esm({
|
|
|
108090
109086
|
if (nativeOpen != null && (!entryDispatchBoundaryPassed || isDefinitiveEntryRejection(entryDispatchError, entryMutationId))) {
|
|
108091
109087
|
writeNativeProtectionRecord(nativeProfileId, input.executionContext.symbol, null);
|
|
108092
109088
|
}
|
|
109089
|
+
if (nativePendingLotKey != null && nativeOpen == null && (!entryDispatchBoundaryPassed || isDefinitiveEntryRejection(entryDispatchError, entryMutationId))) {
|
|
109090
|
+
const stored = readNativeRecord(nativeProfileId, input.executionContext.symbol);
|
|
109091
|
+
if (stored.kind === "record") {
|
|
109092
|
+
writeNativeProtectionRecord(
|
|
109093
|
+
nativeProfileId,
|
|
109094
|
+
input.executionContext.symbol,
|
|
109095
|
+
dropNativeStandbyAdd(dropNativePendingLot(stored.record, nativePendingLotKey), nativePendingLotKey)
|
|
109096
|
+
);
|
|
109097
|
+
}
|
|
109098
|
+
}
|
|
108093
109099
|
const handoffVeto = isClientRuntimeWindowHandoffBeforePlanDispatch(entryDispatchError);
|
|
108094
109100
|
const handoffBeforeDispatch = handoffVeto || !entryDispatchBoundaryPassed && input.shouldCancelBeforeExchangeOrderDispatch?.() === true;
|
|
108095
109101
|
const hasCommittedReports = executionReports.some((report) => report.status === "executed" && String(report.order_id || "").trim().length > 0);
|
|
@@ -108212,7 +109218,20 @@ var init_runtime_execution = __esm({
|
|
|
108212
109218
|
const symbol2 = input.executionContext.symbol;
|
|
108213
109219
|
let record5 = nativeOpen != null ? recordEntryChildren(nativeOpen.record, marketOrderResponse) : nativeAddRecord;
|
|
108214
109220
|
let keepNativeJournal = false;
|
|
108215
|
-
if (
|
|
109221
|
+
if (confirmedMarketFill?.orderId) {
|
|
109222
|
+
if (nativeOpen == null && nativePendingLotKey != null) {
|
|
109223
|
+
record5 = nameNativeStandbyAdd(record5, nativePendingLotKey, String(confirmedMarketFill.orderId));
|
|
109224
|
+
}
|
|
109225
|
+
record5 = planNativeFillLot(record5, {
|
|
109226
|
+
settings: nativeSettingsOf(input.executionContext),
|
|
109227
|
+
sizeDecimals: input.executionContext.sizeDecimals,
|
|
109228
|
+
fillKey: String(confirmedMarketFill.orderId),
|
|
109229
|
+
fillSize: String(confirmedMarketFill.filledSize),
|
|
109230
|
+
nowMs: Date.now(),
|
|
109231
|
+
pendingKey: nativeOpen != null ? record5.entryClientOrderId : nativePendingLotKey
|
|
109232
|
+
});
|
|
109233
|
+
}
|
|
109234
|
+
if ((nativeOpen != null || nativePendingLotKey != null || record5 !== nativeAddRecord) && !writeNativeProtectionRecord(nativeProfileId, symbol2, record5)) {
|
|
108216
109235
|
executionReports.push(nativeStorageReport(symbol2, "protective_lifecycle_persistence_failed"));
|
|
108217
109236
|
}
|
|
108218
109237
|
if (confirmedMarketFill == null) {
|
|
@@ -113043,7 +114062,7 @@ var init_profile_model_cascade = __esm({
|
|
|
113043
114062
|
});
|
|
113044
114063
|
|
|
113045
114064
|
// lib/runtime/prompt-variable-validation-contract.ts
|
|
113046
|
-
var ESCAPED_OPEN_BRACE, ESCAPED_CLOSE_BRACE, PROMPT_PLACEHOLDER_PATTERN, ESCAPED_BRACE_PAIR_PATTERN, readPromptTemplate, restoreEscapedBraces, countAtMost, countBelow, locatePlaceholders, isPromptVariableName, renderPromptTemplate, promptTemplatePlaceholderSpans, promptTemplatePlaceholders, promptTemplateVariables, NEWS_PROMPT_VARIABLES, REFERENCE_CANDLES_PROMPT_VARIABLE, ALLOWED_PROMPT_VARIABLES, OPTIONAL_BLANK_PROMPT_VARIABLES, coercePromptVariableValue, isMissingPromptVariableValue, validatePromptVariables;
|
|
114065
|
+
var ESCAPED_OPEN_BRACE, ESCAPED_CLOSE_BRACE, PROMPT_PLACEHOLDER_PATTERN, ESCAPED_BRACE_PAIR_PATTERN, readPromptTemplate, restoreEscapedBraces, countAtMost, countBelow, locatePlaceholders, isPromptVariableName, renderPromptTemplate, formatInstructionTemplate, promptTemplatePlaceholderSpans, promptTemplatePlaceholders, promptTemplateVariables, NEWS_PROMPT_VARIABLES, REFERENCE_CANDLES_PROMPT_VARIABLE, ALLOWED_PROMPT_VARIABLES, OPTIONAL_BLANK_PROMPT_VARIABLES, coercePromptVariableValue, isMissingPromptVariableValue, validatePromptVariables;
|
|
113047
114066
|
var init_prompt_variable_validation_contract = __esm({
|
|
113048
114067
|
"lib/runtime/prompt-variable-validation-contract.ts"() {
|
|
113049
114068
|
"use strict";
|
|
@@ -113129,6 +114148,40 @@ var init_prompt_variable_validation_contract = __esm({
|
|
|
113129
114148
|
rendered.push(prepared.slice(cursor));
|
|
113130
114149
|
return restoreEscapedBraces(rendered.join(""));
|
|
113131
114150
|
};
|
|
114151
|
+
formatInstructionTemplate = (template, values, label2 = "instruction template") => {
|
|
114152
|
+
const text = String(template || "");
|
|
114153
|
+
const rendered = [];
|
|
114154
|
+
let index = 0;
|
|
114155
|
+
while (index < text.length) {
|
|
114156
|
+
const char = text[index];
|
|
114157
|
+
const escapedPair = `${char}${char}`;
|
|
114158
|
+
if ((char === "{" || char === "}") && text.startsWith(escapedPair, index)) {
|
|
114159
|
+
rendered.push(char);
|
|
114160
|
+
index += escapedPair.length;
|
|
114161
|
+
continue;
|
|
114162
|
+
}
|
|
114163
|
+
if (char === "}") {
|
|
114164
|
+
throw new Error(`Invalid ${label2}: ${template}`);
|
|
114165
|
+
}
|
|
114166
|
+
if (char !== "{") {
|
|
114167
|
+
rendered.push(char);
|
|
114168
|
+
index += 1;
|
|
114169
|
+
continue;
|
|
114170
|
+
}
|
|
114171
|
+
const end = text.indexOf("}", index + 1);
|
|
114172
|
+
const field = end < 0 ? "" : text.slice(index + 1, end);
|
|
114173
|
+
const name = field.endsWith(":") ? field.slice(0, -1) : field;
|
|
114174
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(name)) {
|
|
114175
|
+
throw new Error(`Invalid ${label2}: ${template}`);
|
|
114176
|
+
}
|
|
114177
|
+
if (!Object.prototype.hasOwnProperty.call(values, name)) {
|
|
114178
|
+
throw new Error(`Unexpected ${label2} placeholder: ${name}`);
|
|
114179
|
+
}
|
|
114180
|
+
rendered.push(String(values[name]));
|
|
114181
|
+
index = end + 1;
|
|
114182
|
+
}
|
|
114183
|
+
return rendered.join("");
|
|
114184
|
+
};
|
|
113132
114185
|
promptTemplatePlaceholderSpans = (template) => {
|
|
113133
114186
|
if (typeof template !== "string" || !template) {
|
|
113134
114187
|
return [];
|
|
@@ -117864,7 +118917,7 @@ var init_provider_client = __esm({
|
|
|
117864
118917
|
});
|
|
117865
118918
|
|
|
117866
118919
|
// lib/runtime/prompt-contract.ts
|
|
117867
|
-
var PROMPT_PLACEHOLDER_MAP, DATA_FORMAT_TAG_ALIASES, buildDecisionInstructionVariables, renderCandleIndicatorDefinitions, NEWS_COLUMN_DESCRIPTIONS, isNewsPromptTag, newsTagBlock, newsRowColumns, renderNewsLegendLine, behaviorStateHasObjectField, candleBlockPayload, candlesHaveLiveField, templateReferencesTag, templateTagOrder, renderDataFormatLegend, replaceEmbeddedDataFormatLegend, SIZE_AMOUNT_USDC_LABEL_PATTERN, labelSizeAmountInUsd, canonicalizePromptPlaceholders, normalizePromptWhitespace,
|
|
118920
|
+
var PROMPT_PLACEHOLDER_MAP, DATA_FORMAT_TAG_ALIASES, buildDecisionInstructionVariables, renderCandleIndicatorDefinitions, NEWS_COLUMN_DESCRIPTIONS, isNewsPromptTag, newsTagBlock, newsRowColumns, renderNewsLegendLine, behaviorStateHasObjectField, candleBlockPayload, candlesHaveLiveField, templateReferencesTag, templateTagOrder, renderDataFormatLegend, replaceEmbeddedDataFormatLegend, SIZE_AMOUNT_USDC_LABEL_PATTERN, labelSizeAmountInUsd, canonicalizePromptPlaceholders, normalizePromptWhitespace, constructPromptSystemTemplate;
|
|
117868
118921
|
var init_prompt_contract = __esm({
|
|
117869
118922
|
"lib/runtime/prompt-contract.ts"() {
|
|
117870
118923
|
"use strict";
|
|
@@ -118281,28 +119334,6 @@ var init_prompt_contract = __esm({
|
|
|
118281
119334
|
}
|
|
118282
119335
|
return text.replace(/\r\n/g, "\n").replace(/[\t ]{2,}\n/g, "\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
118283
119336
|
};
|
|
118284
|
-
formatInstructionTemplate = (template, vars) => {
|
|
118285
|
-
const escapedOpen = "__VTX_INSTR_OPEN_BRACE__";
|
|
118286
|
-
const escapedClose = "__VTX_INSTR_CLOSE_BRACE__";
|
|
118287
|
-
const prepared = String(template ?? "").replaceAll("{{", escapedOpen).replaceAll("}}", escapedClose);
|
|
118288
|
-
const replacements = [];
|
|
118289
|
-
const formatted = prepared.replace(/\{([a-zA-Z0-9_]+)\}/g, (_match, key) => {
|
|
118290
|
-
if (!Object.prototype.hasOwnProperty.call(vars, key)) {
|
|
118291
|
-
throw new Error(`Unexpected instruction template placeholder: ${key}`);
|
|
118292
|
-
}
|
|
118293
|
-
const marker = `__VTX_INSTR_VALUE_${replacements.length}__`;
|
|
118294
|
-
replacements.push(String(vars[key]));
|
|
118295
|
-
return marker;
|
|
118296
|
-
});
|
|
118297
|
-
if (/[{}]/.test(formatted)) {
|
|
118298
|
-
throw new Error(`Invalid instruction template: ${template}`);
|
|
118299
|
-
}
|
|
118300
|
-
let rendered = formatted.replaceAll(escapedOpen, "{").replaceAll(escapedClose, "}");
|
|
118301
|
-
replacements.forEach((value, index) => {
|
|
118302
|
-
rendered = rendered.replaceAll(`__VTX_INSTR_VALUE_${index}__`, value);
|
|
118303
|
-
});
|
|
118304
|
-
return rendered;
|
|
118305
|
-
};
|
|
118306
119337
|
constructPromptSystemTemplate = (systemTemplate, options) => {
|
|
118307
119338
|
const instructions = options.instructions ?? {};
|
|
118308
119339
|
const symbols = (options.symbols ?? []).map((symbol2) => String(symbol2).trim()).filter(Boolean);
|
|
@@ -119174,7 +120205,7 @@ __export(local_analysis_exports, {
|
|
|
119174
120205
|
runLocalRuntimeCycle: () => runLocalRuntimeCycle,
|
|
119175
120206
|
summarizeReviewFailureExplanation: () => summarizeReviewFailureExplanation
|
|
119176
120207
|
});
|
|
119177
|
-
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, MANIFEST_COMPONENT_NAME, 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, AI_INDICATOR_KEYS_NEWER_THAN_SOME_SERVERS, sortTradingTimeframes, normalizePromptIdentityTimestamp, resolveCompletedCandleBoundary, normalizeAiIndicatorFlags, getPromptLookback, computeSma, computeEma, computeRsi, computeAtr, computeMacd, computeBollingerBands, getIndicatorValue, buildPromptCandlesComponent, buildPromptCandleTimeframeComponent, resolvePromptRelativeVolumeContext, promptRelativeVolumeBaseline, 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,
|
|
120208
|
+
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, BEHAVIOR_MEMORY_UNAVAILABLE_ERROR, BehaviorMemoryUnavailableError, 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, MANIFEST_COMPONENT_NAME, 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, AI_INDICATOR_KEYS_NEWER_THAN_SOME_SERVERS, sortTradingTimeframes, normalizePromptIdentityTimestamp, resolveCompletedCandleBoundary, normalizeAiIndicatorFlags, getPromptLookback, computeSma, computeEma, computeRsi, computeAtr, computeMacd, computeBollingerBands, getIndicatorValue, buildPromptCandlesComponent, buildPromptCandleTimeframeComponent, resolvePromptRelativeVolumeContext, promptRelativeVolumeBaseline, 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, carryReturnedModelCalls, runLocalRuntimeCycle;
|
|
119178
120209
|
var init_local_analysis = __esm({
|
|
119179
120210
|
"lib/runtime/local-analysis.ts"() {
|
|
119180
120211
|
"use strict";
|
|
@@ -119728,6 +120759,13 @@ var init_local_analysis = __esm({
|
|
|
119728
120759
|
this.name = "CriticalBehaviorStateError";
|
|
119729
120760
|
}
|
|
119730
120761
|
};
|
|
120762
|
+
BEHAVIOR_MEMORY_UNAVAILABLE_ERROR = "Behavior memory is unavailable for this trading cycle";
|
|
120763
|
+
BehaviorMemoryUnavailableError = class extends Error {
|
|
120764
|
+
constructor(cause) {
|
|
120765
|
+
super(BEHAVIOR_MEMORY_UNAVAILABLE_ERROR, cause === void 0 ? void 0 : { cause });
|
|
120766
|
+
this.name = "BehaviorMemoryUnavailableError";
|
|
120767
|
+
}
|
|
120768
|
+
};
|
|
119731
120769
|
clampNumber = (value, fallback) => {
|
|
119732
120770
|
const numeric2 = Number(value);
|
|
119733
120771
|
return Number.isFinite(numeric2) ? numeric2 : fallback;
|
|
@@ -120347,29 +121385,27 @@ var init_local_analysis = __esm({
|
|
|
120347
121385
|
return assembledUserTemplate;
|
|
120348
121386
|
};
|
|
120349
121387
|
preflightStrategyReviewPromptContract = (metadata, symbols, maxTrades) => {
|
|
121388
|
+
const reviewSystemTemplate = String(metadata.review_system_template ?? "");
|
|
121389
|
+
const reviewUserTemplate = String(metadata.review_user_template ?? "");
|
|
121390
|
+
if (!reviewSystemTemplate.trim() || !reviewUserTemplate.trim() || extractTemplatePlaceholders(reviewSystemTemplate).length > 0) {
|
|
121391
|
+
throw new CriticalBehaviorStateError();
|
|
121392
|
+
}
|
|
121393
|
+
requireStrategyReviewTemplates(reviewSystemTemplate, reviewUserTemplate);
|
|
120350
121394
|
try {
|
|
120351
|
-
requireStrategyReviewTemplates(
|
|
120352
|
-
requireNonEmptyStringField(metadata.review_system_template, "review_system_template"),
|
|
120353
|
-
requireNonEmptyStringField(metadata.review_user_template, "review_user_template")
|
|
120354
|
-
);
|
|
120355
121395
|
const reviewInstructions = asRecord(metadata.review_instructions);
|
|
120356
121396
|
const reviewSecurity = requireNonEmptyStringField(
|
|
120357
121397
|
reviewInstructions.review_security,
|
|
120358
121398
|
"review_instructions.review_security"
|
|
120359
121399
|
);
|
|
120360
|
-
const reviewOutputContract =
|
|
121400
|
+
const reviewOutputContract = formatInstructionTemplate(
|
|
120361
121401
|
requireNonEmptyStringField(
|
|
120362
121402
|
reviewInstructions.review_json_format,
|
|
120363
121403
|
"review_instructions.review_json_format"
|
|
120364
121404
|
),
|
|
120365
121405
|
buildDecisionInstructionVariables(symbols, maxTrades)
|
|
120366
121406
|
);
|
|
120367
|
-
|
|
120368
|
-
|
|
120369
|
-
"review_system_template"
|
|
120370
|
-
);
|
|
120371
|
-
if (extractTemplatePlaceholders(reviewSystemTemplate).length > 0 || extractTemplatePlaceholders(reviewSecurity).length > 0) {
|
|
120372
|
-
throw new CriticalBehaviorStateError();
|
|
121407
|
+
if (extractTemplatePlaceholders(reviewSecurity).length > 0) {
|
|
121408
|
+
throw new BehaviorMemoryUnavailableError();
|
|
120373
121409
|
}
|
|
120374
121410
|
const securedReviewSystem = reviewSystemTemplate.includes(reviewSecurity) ? reviewSystemTemplate : `${reviewSystemTemplate.trim()}
|
|
120375
121411
|
|
|
@@ -120378,13 +121414,13 @@ ${reviewSecurity}`;
|
|
|
120378
121414
|
|
|
120379
121415
|
${reviewOutputContract}`;
|
|
120380
121416
|
if (containsCompetingBehaviorStateMarkup(renderedReviewSystem)) {
|
|
120381
|
-
throw new
|
|
121417
|
+
throw new BehaviorMemoryUnavailableError();
|
|
120382
121418
|
}
|
|
120383
121419
|
} catch (error48) {
|
|
120384
|
-
if (error48 instanceof
|
|
121420
|
+
if (error48 instanceof BehaviorMemoryUnavailableError) {
|
|
120385
121421
|
throw error48;
|
|
120386
121422
|
}
|
|
120387
|
-
throw new
|
|
121423
|
+
throw new BehaviorMemoryUnavailableError(error48);
|
|
120388
121424
|
}
|
|
120389
121425
|
};
|
|
120390
121426
|
extractRuntimeReasoningSelection = (settings, controlType, toggleBehavior = "disable_reasoning") => {
|
|
@@ -121369,33 +122405,11 @@ ${reviewOutputContract}`;
|
|
|
121369
122405
|
].join("\n");
|
|
121370
122406
|
buildPromptPositionsValue = (input) => {
|
|
121371
122407
|
const validateInstructionTemplate = (template, allowedKeys) => {
|
|
121372
|
-
|
|
121373
|
-
|
|
121374
|
-
|
|
121375
|
-
|
|
121376
|
-
|
|
121377
|
-
throw new Error(`Unexpected positions instruction placeholder: ${key}`);
|
|
121378
|
-
}
|
|
121379
|
-
return "";
|
|
121380
|
-
});
|
|
121381
|
-
if (/[{}]/.test(formatted)) {
|
|
121382
|
-
throw new Error(`Invalid positions instruction template: ${template}`);
|
|
121383
|
-
}
|
|
121384
|
-
};
|
|
121385
|
-
const formatInstructionTemplate2 = (template, values) => {
|
|
121386
|
-
const escapedOpen = "__VTX_ESCAPED_OPEN__";
|
|
121387
|
-
const escapedClose = "__VTX_ESCAPED_CLOSE__";
|
|
121388
|
-
const normalizedTemplate = template.replace(/\{\{/g, escapedOpen).replace(/\}\}/g, escapedClose);
|
|
121389
|
-
const formatted = normalizedTemplate.replace(/\{([a-z_]+)\}/g, (_match, key) => {
|
|
121390
|
-
if (!Object.prototype.hasOwnProperty.call(values, key)) {
|
|
121391
|
-
throw new Error(`Unexpected positions instruction placeholder: ${key}`);
|
|
121392
|
-
}
|
|
121393
|
-
return String(values[key]);
|
|
121394
|
-
});
|
|
121395
|
-
if (/[{}]/.test(formatted)) {
|
|
121396
|
-
throw new Error(`Invalid positions instruction template: ${template}`);
|
|
121397
|
-
}
|
|
121398
|
-
return formatted.replaceAll(escapedOpen, "{").replaceAll(escapedClose, "}");
|
|
122408
|
+
formatInstructionTemplate(
|
|
122409
|
+
template,
|
|
122410
|
+
Object.fromEntries(allowedKeys.map((key) => [key, ""])),
|
|
122411
|
+
"positions instruction template"
|
|
122412
|
+
);
|
|
121399
122413
|
};
|
|
121400
122414
|
validateInstructionTemplate(input.positionsInstructions.close_reduce, []);
|
|
121401
122415
|
validateInstructionTemplate(input.positionsInstructions.capacity_flat, []);
|
|
@@ -121490,9 +122504,9 @@ ${reviewOutputContract}`;
|
|
|
121490
122504
|
if (remainingGlobal <= 0) {
|
|
121491
122505
|
parts.push(`${input.positionsInstructions.capacity_full} `);
|
|
121492
122506
|
} else if (input.maxTradesPerPrompt < input.maxTradesGlobal && remainingGlobal < input.maxTradesPerPrompt) {
|
|
121493
|
-
parts.push(`${
|
|
122507
|
+
parts.push(`${formatInstructionTemplate(input.positionsInstructions.capacity_low, {
|
|
121494
122508
|
remaining: remainingGlobal
|
|
121495
|
-
})} `);
|
|
122509
|
+
}, "positions instruction template")} `);
|
|
121496
122510
|
}
|
|
121497
122511
|
return parts.join("\n");
|
|
121498
122512
|
};
|
|
@@ -121988,6 +123002,9 @@ ${reviewOutputContract}`;
|
|
|
121988
123002
|
const matches2 = Array.from(
|
|
121989
123003
|
userPrompt.matchAll(/<behavior_state>\s*([\s\S]*?)\s*<\/behavior_state>/g)
|
|
121990
123004
|
);
|
|
123005
|
+
if (openingTags.length === 0 && closingTags.length === 0) {
|
|
123006
|
+
throw new BehaviorMemoryUnavailableError();
|
|
123007
|
+
}
|
|
121991
123008
|
if (openingTags.length !== 1 || closingTags.length !== 1 || matches2.length !== 1) {
|
|
121992
123009
|
throw new CriticalBehaviorStateError();
|
|
121993
123010
|
}
|
|
@@ -122006,7 +123023,7 @@ ${reviewOutputContract}`;
|
|
|
122006
123023
|
projectBackendDecisionMemoryItem(entry.et, "et");
|
|
122007
123024
|
}
|
|
122008
123025
|
} catch (error48) {
|
|
122009
|
-
throw new
|
|
123026
|
+
throw new BehaviorMemoryUnavailableError(error48);
|
|
122010
123027
|
}
|
|
122011
123028
|
};
|
|
122012
123029
|
canonicalFillSideForRiskEvidence = (fill) => {
|
|
@@ -122970,27 +123987,6 @@ ${behaviorJson}
|
|
|
122970
123987
|
}
|
|
122971
123988
|
}
|
|
122972
123989
|
};
|
|
122973
|
-
formatTemplateWithNamedVariables = (template, values) => {
|
|
122974
|
-
const escapedOpen = "__VTX_FMT_OPEN__";
|
|
122975
|
-
const escapedClose = "__VTX_FMT_CLOSE__";
|
|
122976
|
-
const prepared = String(template || "").replaceAll("{{", escapedOpen).replaceAll("}}", escapedClose);
|
|
122977
|
-
const validatedTemplate = prepared.replace(/\{([a-zA-Z_][a-zA-Z0-9_]*)\}/g, (_match, key) => {
|
|
122978
|
-
if (!Object.prototype.hasOwnProperty.call(values, key)) {
|
|
122979
|
-
throw new Error(`Missing required review template variable: ${key}`);
|
|
122980
|
-
}
|
|
122981
|
-
return "";
|
|
122982
|
-
});
|
|
122983
|
-
if (/[{}]/.test(validatedTemplate)) {
|
|
122984
|
-
throw new Error(`Invalid review template: ${template}`);
|
|
122985
|
-
}
|
|
122986
|
-
const formatted = prepared.replace(/\{([a-zA-Z_][a-zA-Z0-9_]*)\}/g, (_match, key) => {
|
|
122987
|
-
if (!Object.prototype.hasOwnProperty.call(values, key)) {
|
|
122988
|
-
throw new Error(`Missing required review template variable: ${key}`);
|
|
122989
|
-
}
|
|
122990
|
-
return String(values[key]);
|
|
122991
|
-
});
|
|
122992
|
-
return formatted.replaceAll(escapedOpen, "{").replaceAll(escapedClose, "}");
|
|
122993
|
-
};
|
|
122994
123990
|
carryReturnedModelCalls = (error48, attempts) => {
|
|
122995
123991
|
if (!attempts.length || !error48 || typeof error48 !== "object" && typeof error48 !== "function") return error48;
|
|
122996
123992
|
error48.runtimeReturnedModelCalls = attempts;
|
|
@@ -123665,7 +124661,7 @@ ${behaviorJson}
|
|
|
123665
124661
|
};
|
|
123666
124662
|
tradeHistory = browserUserFills?.tradeHistory ?? [];
|
|
123667
124663
|
if (input.mode === "trader" && !serverOwnsBehaviorState && browserUserFills?.evidence?.source !== "live") {
|
|
123668
|
-
throw new
|
|
124664
|
+
throw new BehaviorMemoryUnavailableError();
|
|
123669
124665
|
}
|
|
123670
124666
|
const metadataSymbol = requireNonEmptyStringField(promptMetadata.symbol, "symbol");
|
|
123671
124667
|
const metadataTimeframe = requireNonEmptyStringField(promptMetadata.timeframe, "timeframe");
|
|
@@ -123974,7 +124970,7 @@ ${behaviorJson}
|
|
|
123974
124970
|
let preMemoryBehaviorState = "";
|
|
123975
124971
|
try {
|
|
123976
124972
|
if (input.mode === "trader" && !behaviorMemoryEnabled) {
|
|
123977
|
-
throw new
|
|
124973
|
+
throw new BehaviorMemoryUnavailableError();
|
|
123978
124974
|
}
|
|
123979
124975
|
const browserFillEvidence = browserUserFills?.evidence;
|
|
123980
124976
|
const behaviorFillCoverage = browserFillEvidence?.source === "live" && browserFillEvidence.exactTerminalFillEvidenceComplete === true ? "complete" : "capped";
|
|
@@ -123994,7 +124990,7 @@ ${behaviorJson}
|
|
|
123994
124990
|
fillHistoryCoverage: behaviorFillCoverage
|
|
123995
124991
|
});
|
|
123996
124992
|
} catch (error48) {
|
|
123997
|
-
throw new
|
|
124993
|
+
throw new BehaviorMemoryUnavailableError(error48);
|
|
123998
124994
|
}
|
|
123999
124995
|
preMemoryBehaviorState = behaviorStateArtifacts.preMemoryRendered;
|
|
124000
124996
|
behaviorPolicyState = behaviorStateArtifacts.policyState;
|
|
@@ -124049,7 +125045,7 @@ ${stringifyPromptJson(candlesPayload)}
|
|
|
124049
125045
|
note: detail,
|
|
124050
125046
|
outcome: "error"
|
|
124051
125047
|
});
|
|
124052
|
-
if (input.mode !== "trader" || error48 instanceof CriticalBehaviorStateError) {
|
|
125048
|
+
if (input.mode !== "trader" || error48 instanceof CriticalBehaviorStateError || error48 instanceof BehaviorMemoryUnavailableError) {
|
|
124053
125049
|
throw error48;
|
|
124054
125050
|
}
|
|
124055
125051
|
return attachDecisionSettlementDeadline(buildPromptConstructionFailureResult({
|
|
@@ -124179,7 +125175,7 @@ ${stringifyPromptJson(candlesPayload)}
|
|
|
124179
125175
|
outcome: "error"
|
|
124180
125176
|
});
|
|
124181
125177
|
appendRuntimeTimingEvent("prompt_render_failed", promptRenderStartedAtMs, detail, "error");
|
|
124182
|
-
if (input.mode !== "trader" || error48 instanceof CriticalBehaviorStateError) {
|
|
125178
|
+
if (input.mode !== "trader" || error48 instanceof CriticalBehaviorStateError || error48 instanceof BehaviorMemoryUnavailableError) {
|
|
124183
125179
|
throw error48;
|
|
124184
125180
|
}
|
|
124185
125181
|
return attachDecisionSettlementDeadline(buildPromptConstructionFailureResult({
|
|
@@ -124728,7 +125724,7 @@ ${stringifyPromptJson(candlesPayload)}
|
|
|
124728
125724
|
reviewInstructions.review_security,
|
|
124729
125725
|
"review_instructions.review_security"
|
|
124730
125726
|
);
|
|
124731
|
-
const reviewOutputContract =
|
|
125727
|
+
const reviewOutputContract = formatInstructionTemplate(
|
|
124732
125728
|
reviewOutputFormat,
|
|
124733
125729
|
buildDecisionInstructionVariables(reviewSymbols, reviewMaxTrades)
|
|
124734
125730
|
);
|
|
@@ -124751,12 +125747,18 @@ ${reviewOutputContract}`;
|
|
|
124751
125747
|
configuredReviewUserTemplate
|
|
124752
125748
|
) : configuredReviewUserTemplate;
|
|
124753
125749
|
const renderedPrimaryUserPrompt = stringifyPromptJson(userPrompt);
|
|
124754
|
-
|
|
124755
|
-
|
|
124756
|
-
|
|
124757
|
-
|
|
124758
|
-
|
|
124759
|
-
|
|
125750
|
+
let reviewUserPrompt;
|
|
125751
|
+
try {
|
|
125752
|
+
reviewUserPrompt = formatInstructionTemplate(reviewUserTemplate, {
|
|
125753
|
+
primary_model: selectedPrimaryModel,
|
|
125754
|
+
primary_system_prompt: stringifyPromptJson(systemPrompt),
|
|
125755
|
+
primary_user_prompt: renderedPrimaryUserPrompt,
|
|
125756
|
+
primary_decision_json: primaryDecisionJson
|
|
125757
|
+
});
|
|
125758
|
+
} catch (error48) {
|
|
125759
|
+
if (input.mode === "trader") throw new CriticalBehaviorStateError(error48);
|
|
125760
|
+
throw error48;
|
|
125761
|
+
}
|
|
124760
125762
|
if (input.mode === "trader" && (reviewUserPrompt.split(renderedPrimaryUserPrompt).length - 1 !== 1 || /<\/?behavior_state\b/.test(reviewUserPrompt) || containsCompetingBehaviorStateMarkup(reviewSystemPrompt))) {
|
|
124761
125763
|
throw new CriticalBehaviorStateError();
|
|
124762
125764
|
}
|
|
@@ -124989,7 +125991,10 @@ ${reviewOutputContract}`;
|
|
|
124989
125991
|
});
|
|
124990
125992
|
} catch (error48) {
|
|
124991
125993
|
const detail = error48 instanceof Error ? error48.message : String(error48);
|
|
124992
|
-
if (error48 instanceof
|
|
125994
|
+
if (error48 instanceof BehaviorMemoryUnavailableError || detail.includes(BEHAVIOR_MEMORY_UNAVAILABLE_ERROR) || detail.includes("Critical behavior context could not be constructed")) {
|
|
125995
|
+
throw new BehaviorMemoryUnavailableError(error48);
|
|
125996
|
+
}
|
|
125997
|
+
if (error48 instanceof CriticalBehaviorStateError || detail.includes(BEHAVIOR_STATE_UNAVAILABLE_ERROR) || detail.includes("Your prompt on the AI page contains something VTX can't use")) {
|
|
124993
125998
|
throw new CriticalBehaviorStateError(error48);
|
|
124994
125999
|
}
|
|
124995
126000
|
if (input.executionMode === "server" && error48?.code === "settings_superseded") {
|
|
@@ -127545,6 +128550,7 @@ var init_engine = __esm({
|
|
|
127545
128550
|
const runtime = await this.notifyRuntimeStop(this._profileId, {
|
|
127546
128551
|
keepalive: options?.keepalive === true,
|
|
127547
128552
|
reason: stopReason,
|
|
128553
|
+
modeSwitch: options?.modeSwitch === true,
|
|
127548
128554
|
killswitchTrigger: options?.killswitchTrigger ?? null,
|
|
127549
128555
|
authoritativeIntent: this._remoteStopPending === "authoritative-stop" && this._pendingAuthoritativeStopDetails?.authoritativeIntent === true
|
|
127550
128556
|
});
|
|
@@ -127624,7 +128630,8 @@ var init_engine = __esm({
|
|
|
127624
128630
|
reason: effectiveRemoteStopReason,
|
|
127625
128631
|
killswitchTrigger: supersedingStop?.killswitchTrigger ?? options?.killswitchTrigger ?? null,
|
|
127626
128632
|
acceptDeferredStopCompletion: !remoteStopWasAuthoritativeAtDispatch,
|
|
127627
|
-
authoritativeIntent: supersedingStop?.authoritativeIntent === true
|
|
128633
|
+
authoritativeIntent: supersedingStop?.authoritativeIntent === true,
|
|
128634
|
+
modeSwitch: !supersedingStop && options?.modeSwitch === true
|
|
127628
128635
|
});
|
|
127629
128636
|
this._setRuntimeStatus(runtime, "stop");
|
|
127630
128637
|
appendRuntimeDebugEvent({
|
|
@@ -131169,7 +132176,8 @@ var init_engine = __esm({
|
|
|
131169
132176
|
lastRunAt: this._lastRunAt,
|
|
131170
132177
|
stopReason: options?.reason ?? null,
|
|
131171
132178
|
killswitchTrigger: options?.killswitchTrigger ?? null,
|
|
131172
|
-
authoritativeIntent: options?.authoritativeIntent === true
|
|
132179
|
+
authoritativeIntent: options?.authoritativeIntent === true,
|
|
132180
|
+
modeSwitch: options?.modeSwitch === true
|
|
131173
132181
|
},
|
|
131174
132182
|
{
|
|
131175
132183
|
...options,
|