@vtxmacro/cli 2026.10.32 → 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 +588 -146
- 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
|
|
@@ -21026,6 +21027,7 @@ var init_runtime_policy_generated2 = __esm({
|
|
|
21026
21027
|
runtime: {
|
|
21027
21028
|
assignment_page_default_limit: 20,
|
|
21028
21029
|
client_candidate_owner_lease_grace_ms: 6e4,
|
|
21030
|
+
bot_switch_max_retries: 2,
|
|
21029
21031
|
client_server_heartbeats_per_owner_lease: 2,
|
|
21030
21032
|
client_server_heartbeat_min_ms: 5e3,
|
|
21031
21033
|
client_server_heartbeat_max_ms: 3e4
|
|
@@ -57837,6 +57839,7 @@ async function getLLMConfig(cookie, profileId, signal) {
|
|
|
57837
57839
|
method: "GET",
|
|
57838
57840
|
headers,
|
|
57839
57841
|
credentials: "include",
|
|
57842
|
+
cache: "no-store",
|
|
57840
57843
|
signal: requestSignal
|
|
57841
57844
|
});
|
|
57842
57845
|
if (held && response.status === HTTP_STATUS.NOT_MODIFIED) return JSON.parse(held.text);
|
|
@@ -57961,6 +57964,17 @@ var init_account_summary = __esm({
|
|
|
57961
57964
|
}
|
|
57962
57965
|
});
|
|
57963
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
|
+
|
|
57964
57978
|
// lib/runtime/hyperliquid-account-mode-contract.ts
|
|
57965
57979
|
function resolveExactHyperliquidAccountMode(userAbstraction, ...dexEvidence) {
|
|
57966
57980
|
const mode = extractCanonicalHyperliquidAccountMode(userAbstraction);
|
|
@@ -59882,7 +59896,7 @@ var init_error_surface_contract = __esm({
|
|
|
59882
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.`;
|
|
59883
59897
|
}
|
|
59884
59898
|
if (classificationBasis.includes("critical behavior state is unavailable for this trading cycle")) {
|
|
59885
|
-
return `${pausePrefix}: Your prompt on the AI page contains something VTX can't use, for example
|
|
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.`;
|
|
59886
59900
|
}
|
|
59887
59901
|
if (classificationBasis.includes(
|
|
59888
59902
|
"client runtime decision persistence deadline exceeded after the ai run completed"
|
|
@@ -91657,7 +91671,12 @@ var init_hyperliquid_client = __esm({
|
|
|
91657
91671
|
};
|
|
91658
91672
|
fetchBrowserAccountState = async (input) => {
|
|
91659
91673
|
const user = requireWalletAddress(input.walletAddress);
|
|
91660
|
-
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
|
+
);
|
|
91661
91680
|
if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
|
|
91662
91681
|
throw new Error("Malformed Hyperliquid clearinghouseState response.");
|
|
91663
91682
|
}
|
|
@@ -91675,8 +91694,10 @@ var init_hyperliquid_client = __esm({
|
|
|
91675
91694
|
const positions = Array.isArray(state2.assetPositions) ? state2.assetPositions.map((entry) => {
|
|
91676
91695
|
const assetPosition = entry;
|
|
91677
91696
|
const position = assetPosition.position || {};
|
|
91697
|
+
const coin = String(position.coin || assetPosition.coin || "");
|
|
91678
91698
|
return {
|
|
91679
|
-
|
|
91699
|
+
// A HIP-3 DEX may name its coins without the DEX.
|
|
91700
|
+
symbol: dex && coin && !coin.includes(":") ? `${dex}:${coin}` : coin,
|
|
91680
91701
|
size: toFiniteNumber(position.szi, 0),
|
|
91681
91702
|
entry_price: position.entryPx == null ? null : toFiniteNumber(position.entryPx, 0),
|
|
91682
91703
|
unrealized_pnl: position.unrealizedPnl == null ? null : toFiniteNumber(position.unrealizedPnl, 0),
|
|
@@ -91706,7 +91727,7 @@ var init_hyperliquid_client = __esm({
|
|
|
91706
91727
|
};
|
|
91707
91728
|
fetchBrowserPosition = async (input) => {
|
|
91708
91729
|
const symbol2 = normalizeSymbol(input.symbol);
|
|
91709
|
-
const accountState = await fetchBrowserAccountState(input);
|
|
91730
|
+
const accountState = await fetchBrowserAccountState({ ...input, dex: getHyperliquidMarketDex(symbol2) });
|
|
91710
91731
|
return accountState.positions.find((position) => normalizeSymbol(position.symbol) === symbol2) ?? null;
|
|
91711
91732
|
};
|
|
91712
91733
|
buildHyperliquidOrderWire = async (input, tif, price, priceKind) => {
|
|
@@ -94716,6 +94737,7 @@ var init_api2 = __esm({
|
|
|
94716
94737
|
init_updates();
|
|
94717
94738
|
init_profile_emoji();
|
|
94718
94739
|
init_account_summary();
|
|
94740
|
+
init_mobile_notifications();
|
|
94719
94741
|
init_server_runtime_lease();
|
|
94720
94742
|
clientRuntimeSecretHeaders = (profileId) => {
|
|
94721
94743
|
const headers = getProfileHeaders({}, profileId);
|
|
@@ -94799,9 +94821,8 @@ var init_api2 = __esm({
|
|
|
94799
94821
|
if ("invocations" in payload) {
|
|
94800
94822
|
body.invocations = payload.invocations ?? [];
|
|
94801
94823
|
}
|
|
94802
|
-
if (payload.stopReason !== void 0)
|
|
94803
|
-
|
|
94804
|
-
}
|
|
94824
|
+
if (payload.stopReason !== void 0) body.stop_reason = payload.stopReason ?? null;
|
|
94825
|
+
if (payload.modeSwitch) body.mode_switch = true;
|
|
94805
94826
|
if (payload.authoritativeIntent !== void 0) {
|
|
94806
94827
|
body.authoritative_intent = payload.authoritativeIntent;
|
|
94807
94828
|
}
|
|
@@ -98688,7 +98709,7 @@ var init_protective_evidence = __esm({
|
|
|
98688
98709
|
});
|
|
98689
98710
|
|
|
98690
98711
|
// lib/runtime/protective-actions.ts
|
|
98691
|
-
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;
|
|
98692
98713
|
var init_protective_actions = __esm({
|
|
98693
98714
|
"lib/runtime/protective-actions.ts"() {
|
|
98694
98715
|
"use strict";
|
|
@@ -98705,6 +98726,7 @@ var init_protective_actions = __esm({
|
|
|
98705
98726
|
init_error_surface_contract();
|
|
98706
98727
|
init_protective_evidence();
|
|
98707
98728
|
DECIMAL = /^(?:0|[1-9]\d*)(?:\.\d+)?$/;
|
|
98729
|
+
PERCENT = /^(?:0|[1-9]\d*)(?:\.\d+)?%$/;
|
|
98708
98730
|
CLOID = /^0x[0-9a-f]{32}$/;
|
|
98709
98731
|
fail2 = (message) => {
|
|
98710
98732
|
throw new RuntimeExecutionError(
|
|
@@ -98783,9 +98805,48 @@ var init_protective_actions = __esm({
|
|
|
98783
98805
|
if (oid <= 0) fail2("cancel target is invalid.");
|
|
98784
98806
|
return { type: "cancel", cancels: [{ a: nonNegativeInteger(cancel.a, "asset"), o: oid }] };
|
|
98785
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
|
+
}
|
|
98786
98835
|
return fail2("unsupported action type.");
|
|
98787
98836
|
};
|
|
98788
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
|
+
}
|
|
98789
98850
|
const assets = canonical.type === "cancel" ? canonical.cancels.map((cancel) => cancel.a) : canonical.type === "modify" ? [canonical.order.a] : canonical.orders.map((order) => order.a);
|
|
98790
98851
|
if (assets.some((asset) => asset !== action.exchange_asset_id)) fail2("asset does not match the symbol.");
|
|
98791
98852
|
if (canonical.type === "cancel") {
|
|
@@ -99695,7 +99756,7 @@ var init_protective_trigger_price = __esm({
|
|
|
99695
99756
|
});
|
|
99696
99757
|
|
|
99697
99758
|
// lib/runtime/protective-stop-replacement.ts
|
|
99698
|
-
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;
|
|
99699
99760
|
var init_protective_stop_replacement = __esm({
|
|
99700
99761
|
"lib/runtime/protective-stop-replacement.ts"() {
|
|
99701
99762
|
"use strict";
|
|
@@ -99772,16 +99833,13 @@ var init_protective_stop_replacement = __esm({
|
|
|
99772
99833
|
}
|
|
99773
99834
|
return ordered;
|
|
99774
99835
|
};
|
|
99775
|
-
|
|
99776
|
-
if (!
|
|
99777
|
-
const
|
|
99778
|
-
if (statusMs == null || !Array.isArray(input.fills)) return false;
|
|
99779
|
-
const market = normalizeHyperliquidMarketSymbol(input.symbol);
|
|
99780
|
-
const sign = input.isLong ? 1 : -1;
|
|
99836
|
+
marketFillChain = (fills, symbol2) => {
|
|
99837
|
+
if (!Array.isArray(fills)) return null;
|
|
99838
|
+
const market = normalizeHyperliquidMarketSymbol(symbol2);
|
|
99781
99839
|
const rows = [];
|
|
99782
99840
|
const seen = /* @__PURE__ */ new Set();
|
|
99783
|
-
for (const fill of
|
|
99784
|
-
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;
|
|
99785
99843
|
const record5 = fill;
|
|
99786
99844
|
if (normalizeHyperliquidMarketSymbol(String(record5.coin ?? "")) !== market) continue;
|
|
99787
99845
|
const tradeId = positiveSafeInteger(record5.tid);
|
|
@@ -99789,12 +99847,26 @@ var init_protective_stop_replacement = __esm({
|
|
|
99789
99847
|
const size = decimalOrNull(record5.sz);
|
|
99790
99848
|
const start = decimalOrNull(record5.startPosition);
|
|
99791
99849
|
if (tradeId == null || seen.has(tradeId) || time3 == null || record5.side !== "B" && record5.side !== "A" || size == null || size <= 0 || start == null) {
|
|
99792
|
-
return
|
|
99850
|
+
return null;
|
|
99793
99851
|
}
|
|
99794
99852
|
seen.add(tradeId);
|
|
99795
|
-
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
|
+
});
|
|
99796
99860
|
}
|
|
99797
|
-
|
|
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);
|
|
99798
99870
|
if (chained == null) return false;
|
|
99799
99871
|
const before = chained.filter((row) => row.time <= statusMs);
|
|
99800
99872
|
const after = chained.filter((row) => row.time > statusMs);
|
|
@@ -99947,7 +100019,7 @@ var init_protective_entry_cover = __esm({
|
|
|
99947
100019
|
});
|
|
99948
100020
|
|
|
99949
100021
|
// lib/runtime/native-position-protection.ts
|
|
99950
|
-
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;
|
|
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;
|
|
99951
100023
|
var init_native_position_protection = __esm({
|
|
99952
100024
|
"lib/runtime/native-position-protection.ts"() {
|
|
99953
100025
|
"use strict";
|
|
@@ -100167,11 +100239,60 @@ var init_native_position_protection = __esm({
|
|
|
100167
100239
|
if (typeof record5.enabled !== "boolean" || legacy == null || native == null) return null;
|
|
100168
100240
|
return { enabled: record5.enabled, legacySymbols: new Set(legacy), nativeSymbols: new Set(native) };
|
|
100169
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
|
+
};
|
|
100170
100291
|
}
|
|
100171
100292
|
});
|
|
100172
100293
|
|
|
100173
100294
|
// lib/runtime/native-protection-device.ts
|
|
100174
|
-
var NATIVE_PROTECTION_RECORD_VERSION, nativeProtectionStorage, resolveStorage, setNativeProtectionStorage, recordKey, isMember, isRetracement, isLot, readNativeProtectionRecord, versioned, writeNativeProtectionRecord, NativeOrderNotSentError, withDispatchBoundary, attempt, notSentRestores, errorText, actionOf, isOpenInDirection2, coverRows, restingOrderIdAt, definitivelyRefused, TRAILING_LOT_FIRED, ownLotOrderIds, lotRetracement, lotReport, sendTrailingLot, planNativeFillLot, dropNativePendingLot, planNativePendingLot, 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;
|
|
100175
100296
|
var init_native_protection_device = __esm({
|
|
100176
100297
|
"lib/runtime/native-protection-device.ts"() {
|
|
100177
100298
|
"use strict";
|
|
@@ -100179,6 +100300,8 @@ var init_native_protection_device = __esm({
|
|
|
100179
100300
|
init_define_VTX_GROK_POLICY();
|
|
100180
100301
|
init_define_VTX_PI_MODEL_POLICY();
|
|
100181
100302
|
init_constants();
|
|
100303
|
+
init_hyperliquid_market_symbol();
|
|
100304
|
+
init_hyperliquid_order_status();
|
|
100182
100305
|
init_order_identity();
|
|
100183
100306
|
init_native_position_protection();
|
|
100184
100307
|
NATIVE_PROTECTION_RECORD_VERSION = 1;
|
|
@@ -100199,7 +100322,7 @@ var init_native_protection_device = __esm({
|
|
|
100199
100322
|
isMember = (value) => {
|
|
100200
100323
|
if (!value || typeof value !== "object") return false;
|
|
100201
100324
|
const member = value;
|
|
100202
|
-
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");
|
|
100203
100326
|
};
|
|
100204
100327
|
isRetracement = (value) => {
|
|
100205
100328
|
if (!value || typeof value !== "object") return false;
|
|
@@ -100210,7 +100333,12 @@ var init_native_protection_device = __esm({
|
|
|
100210
100333
|
isLot = (value) => {
|
|
100211
100334
|
if (!value || typeof value !== "object") return false;
|
|
100212
100335
|
const lot = value;
|
|
100213
|
-
return (lot.mutationId === null || typeof lot.mutationId === "string") && typeof lot.fillKey === "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");
|
|
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";
|
|
100214
100342
|
};
|
|
100215
100343
|
readNativeProtectionRecord = (profileId, symbol2) => {
|
|
100216
100344
|
const storage3 = resolveStorage();
|
|
@@ -100218,7 +100346,7 @@ var init_native_protection_device = __esm({
|
|
|
100218
100346
|
const raw = storage3.getItem(recordKey(profileId, symbol2));
|
|
100219
100347
|
if (raw == null) return null;
|
|
100220
100348
|
const parsed = JSON.parse(raw);
|
|
100221
|
-
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))) {
|
|
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") {
|
|
100222
100350
|
throw new Error("Stored native protection record is invalid.");
|
|
100223
100351
|
}
|
|
100224
100352
|
return parsed;
|
|
@@ -100238,6 +100366,63 @@ var init_native_protection_device = __esm({
|
|
|
100238
100366
|
return false;
|
|
100239
100367
|
}
|
|
100240
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
|
+
};
|
|
100241
100426
|
NativeOrderNotSentError = class extends Error {
|
|
100242
100427
|
constructor(cause) {
|
|
100243
100428
|
super(cause instanceof Error ? cause.message : "The exchange call failed before dispatch.");
|
|
@@ -100303,6 +100488,24 @@ var init_native_protection_device = __esm({
|
|
|
100303
100488
|
return Array.isArray(statuses) && statuses.length > 0 && statuses.every((status) => Boolean(status && typeof status === "object" && "error" in status));
|
|
100304
100489
|
};
|
|
100305
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
|
+
};
|
|
100306
100509
|
ownLotOrderIds = (record5) => (record5.lots ?? []).flatMap((lot) => lot.orderId == null ? [] : [lot.orderId]);
|
|
100307
100510
|
lotRetracement = (settings, size, sizeDecimals) => {
|
|
100308
100511
|
const stopLoss = settings.stopLoss;
|
|
@@ -100385,6 +100588,22 @@ var init_native_protection_device = __esm({
|
|
|
100385
100588
|
else lots.push(planned);
|
|
100386
100589
|
return { ...record5, lots };
|
|
100387
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
|
+
};
|
|
100388
100607
|
dropNativePendingLot = (record5, key) => versioned({
|
|
100389
100608
|
...record5,
|
|
100390
100609
|
lots: (record5.lots ?? []).filter((lot) => !(lot.fillKey === key && lot.mutationId == null && lot.size === ""))
|
|
@@ -100495,7 +100714,7 @@ var init_native_protection_device = __esm({
|
|
|
100495
100714
|
}
|
|
100496
100715
|
continue;
|
|
100497
100716
|
}
|
|
100498
|
-
if (member.orderId != null || member.retiredReason) {
|
|
100717
|
+
if (member.orderId != null || member.retiredReason || member.plannedAfterMs != null) {
|
|
100499
100718
|
members.push(member);
|
|
100500
100719
|
continue;
|
|
100501
100720
|
}
|
|
@@ -100508,6 +100727,109 @@ var init_native_protection_device = __esm({
|
|
|
100508
100727
|
}
|
|
100509
100728
|
return { ...record5, members };
|
|
100510
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
|
+
};
|
|
100511
100833
|
settleNativeProtectionAfterFill = async (input) => {
|
|
100512
100834
|
const { io } = input;
|
|
100513
100835
|
const reports = [];
|
|
@@ -100516,6 +100838,17 @@ var init_native_protection_device = __esm({
|
|
|
100516
100838
|
const page = await io.readOpenOrders();
|
|
100517
100839
|
const position = await io.readPosition();
|
|
100518
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
|
+
}
|
|
100519
100852
|
if (!isOpenInDirection2(position.size, record5.isLong)) {
|
|
100520
100853
|
reports.push({
|
|
100521
100854
|
order_id: input.entryOrderId,
|
|
@@ -100554,7 +100887,10 @@ var init_native_protection_device = __esm({
|
|
|
100554
100887
|
});
|
|
100555
100888
|
let eventMs = Math.max(
|
|
100556
100889
|
0,
|
|
100557
|
-
...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)
|
|
100558
100894
|
);
|
|
100559
100895
|
if (eventMs <= 0 && input.entryOrderId) {
|
|
100560
100896
|
const entryStatus = await io.readOrderStatus(input.entryOrderId);
|
|
@@ -100634,7 +100970,7 @@ var init_native_protection_device = __esm({
|
|
|
100634
100970
|
});
|
|
100635
100971
|
continue;
|
|
100636
100972
|
}
|
|
100637
|
-
if (existing != null && existing.orderId == null && !unknownClientOrderIds.has(existing.clientOrderId)) {
|
|
100973
|
+
if (existing != null && existing.orderId == null && existing.plannedAfterMs == null && !unknownClientOrderIds.has(existing.clientOrderId)) {
|
|
100638
100974
|
continue;
|
|
100639
100975
|
}
|
|
100640
100976
|
if (gate !== "place") {
|
|
@@ -100753,8 +101089,15 @@ var init_native_protection_device = __esm({
|
|
|
100753
101089
|
const retracement = lotRetracement(input.settings, size, input.sizeDecimals);
|
|
100754
101090
|
if (retracement) {
|
|
100755
101091
|
const { fillEventFromDevice: _deviceTime, ...withoutDeviceTime } = journaledLot;
|
|
100756
|
-
|
|
100757
|
-
if (gate === "place") {
|
|
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") {
|
|
100758
101101
|
const index = lotIndex;
|
|
100759
101102
|
const sent = await sendTrailingLot({
|
|
100760
101103
|
io,
|
|
@@ -100800,6 +101143,28 @@ var init_native_protection_device = __esm({
|
|
|
100800
101143
|
const position = await io.readPosition();
|
|
100801
101144
|
const symbol2 = record5.symbol;
|
|
100802
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
|
+
};
|
|
100803
101168
|
const observations = observeMembers(record5, page).map((entry) => ({
|
|
100804
101169
|
...entry,
|
|
100805
101170
|
member: entry.row ? { ...entry.member, placedAtMs: entry.row.timestamp || entry.member.placedAtMs } : entry.member
|
|
@@ -100971,6 +101336,33 @@ var init_native_protection_device = __esm({
|
|
|
100971
101336
|
members.push(member);
|
|
100972
101337
|
continue;
|
|
100973
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
|
+
}
|
|
100974
101366
|
if (member.orderId == null) {
|
|
100975
101367
|
if (io.nowMs() <= io.neverLandsAfterMs(member.sentAtMs) || !unknownClientOrderIds.has(member.clientOrderId)) {
|
|
100976
101368
|
anyResting = true;
|
|
@@ -101014,10 +101406,9 @@ var init_native_protection_device = __esm({
|
|
|
101014
101406
|
});
|
|
101015
101407
|
explained = end2 === "resting" || end2 === "pending" || end2 === "unknown" ? "status_read" : "ended_with_position";
|
|
101016
101408
|
}
|
|
101017
|
-
if (explained
|
|
101018
|
-
|
|
101019
|
-
|
|
101020
|
-
}
|
|
101409
|
+
if (explained === "ended_with_position" && await membersEnded() === "ended") continue;
|
|
101410
|
+
anyResting = true;
|
|
101411
|
+
members.push(member);
|
|
101021
101412
|
continue;
|
|
101022
101413
|
}
|
|
101023
101414
|
const evidence = await io.readOrderStatus(member.orderId);
|
|
@@ -101039,7 +101430,7 @@ var init_native_protection_device = __esm({
|
|
|
101039
101430
|
});
|
|
101040
101431
|
if (rearm === "retire" || !kindEnabled(member)) continue;
|
|
101041
101432
|
const rearmTrigger = currentTrigger(member);
|
|
101042
|
-
if (rearm === "need_reads" || rearmTrigger == null) {
|
|
101433
|
+
if (rearm === "need_reads" || rearmTrigger == null || undecidedAdds) {
|
|
101043
101434
|
members.push(member);
|
|
101044
101435
|
continue;
|
|
101045
101436
|
}
|
|
@@ -101124,7 +101515,8 @@ var init_native_protection_device = __esm({
|
|
|
101124
101515
|
for (const [index, prior] of priorLots.entries()) {
|
|
101125
101516
|
let lot = prior;
|
|
101126
101517
|
const restingRow = lot.orderId == null ? null : page.find((order) => order.oid === lot.orderId) ?? null;
|
|
101127
|
-
|
|
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")) {
|
|
101128
101520
|
lots.push(lot);
|
|
101129
101521
|
continue;
|
|
101130
101522
|
}
|
|
@@ -101133,7 +101525,8 @@ var init_native_protection_device = __esm({
|
|
|
101133
101525
|
const entryStatus = await io.readOrderStatus(lot.fillKey);
|
|
101134
101526
|
if (entryStatus.responseValid && entryStatus.orderMatches && entryStatus.statusTimestampMs != null) {
|
|
101135
101527
|
const { fillEventFromDevice: _deviceTime, ...exchangeTimed } = lot;
|
|
101136
|
-
|
|
101528
|
+
const named = lotFillOrderId(lot) == null ? namedOrderId(entryStatus) : null;
|
|
101529
|
+
lot = { ...exchangeTimed, fillEventMs: entryStatus.statusTimestampMs, ...named != null ? { fillOrderId: named } : {} };
|
|
101137
101530
|
} else if (entryStatus.responseStatus === UNKNOWN_ORDER_RESPONSE && io.nowMs() > io.neverLandsAfterMs(lot.sentAtMs)) {
|
|
101138
101531
|
continue;
|
|
101139
101532
|
} else {
|
|
@@ -101154,9 +101547,28 @@ var init_native_protection_device = __esm({
|
|
|
101154
101547
|
lots.push(lot);
|
|
101155
101548
|
continue;
|
|
101156
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
|
+
}
|
|
101157
101569
|
if (!lot.size) {
|
|
101158
101570
|
const others = [...lots, ...priorLots.slice(index + 1)];
|
|
101159
|
-
const covered = others.reduce((total, other) => other.size && other
|
|
101571
|
+
const covered = others.reduce((total, other) => other.size && !lotFillLeftPosition(other) ? total + Number(other.size) : total, 0);
|
|
101160
101572
|
const uncovered = Number((Math.abs(position.size) - covered).toFixed(input.sizeDecimals));
|
|
101161
101573
|
if (!(uncovered > 0)) continue;
|
|
101162
101574
|
lot = { ...lot, size: String(uncovered) };
|
|
@@ -101183,11 +101595,24 @@ var init_native_protection_device = __esm({
|
|
|
101183
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;
|
|
101184
101596
|
if (named) {
|
|
101185
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;
|
|
101186
101601
|
} else if (answer?.status === "settled" && answer.outcome_code === "rejected") {
|
|
101187
101602
|
lots.push({ ...lot, retiredReason: "protective_place_rejected" });
|
|
101188
101603
|
continue;
|
|
101189
101604
|
} else if (answer?.status === "reconciled" && answer.outcome_code === "exchange_expired_unconfirmed" || answer?.status === "absent" && io.nowMs() > io.neverLandsAfterMs(lot.sentAtMs)) {
|
|
101190
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
|
+
}
|
|
101191
101616
|
const sent2 = await sendTrailingLot({ io, symbol: symbol2, lot: { ...lot, mutationId: null }, journal: (next) => journalLot(index, next) });
|
|
101192
101617
|
lots.push(sent2.lot);
|
|
101193
101618
|
if (sent2.report) reports.push(sent2.report);
|
|
@@ -101203,7 +101628,7 @@ var init_native_protection_device = __esm({
|
|
|
101203
101628
|
const row = lot === prior ? restingRow : page.find((order) => order.oid === lotOrderId) ?? null;
|
|
101204
101629
|
if (row && readListedProtectiveRow({ triggerCondition: row.trigger_condition }) === "resting") {
|
|
101205
101630
|
lot = { ...lot, placedAtMs: row.timestamp || lot.placedAtMs };
|
|
101206
|
-
const stray = nativeStrayOrderDecision({
|
|
101631
|
+
const stray = lot.retiredReason === TRAILING_LOT_OTHER_SIDE ? "cancel" : nativeStrayOrderDecision({
|
|
101207
101632
|
placedMs: lot.placedAtMs ?? Number.POSITIVE_INFINITY,
|
|
101208
101633
|
position: position.size,
|
|
101209
101634
|
positionStateMs: stateMs,
|
|
@@ -101282,6 +101707,15 @@ var init_native_protection_device = __esm({
|
|
|
101282
101707
|
lots.push(lot);
|
|
101283
101708
|
continue;
|
|
101284
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
|
+
}
|
|
101285
101719
|
const sent = await sendTrailingLot({
|
|
101286
101720
|
io,
|
|
101287
101721
|
symbol: symbol2,
|
|
@@ -101293,7 +101727,7 @@ var init_native_protection_device = __esm({
|
|
|
101293
101727
|
if (sent.report) reports.push(sent.report);
|
|
101294
101728
|
if (!sent.lot.retiredReason) anyResting = true;
|
|
101295
101729
|
}
|
|
101296
|
-
if (!positionOpen && !anyResting) {
|
|
101730
|
+
if (!positionOpen && !anyResting && !undecidedAdds) {
|
|
101297
101731
|
return { record: null, reports };
|
|
101298
101732
|
}
|
|
101299
101733
|
const { lots: _priorLots, ...withoutLots } = record5;
|
|
@@ -105020,6 +105454,19 @@ var init_runtime_execution = __esm({
|
|
|
105020
105454
|
if (mutation.operation_kind !== "trailing_stop") throw new Error("The ledger names another action for this trailing lot.");
|
|
105021
105455
|
return { status: mutation.status, outcome_code: mutation.outcome_code, exchange_order_id: mutation.exchange_order_id };
|
|
105022
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
|
+
},
|
|
105023
105470
|
isDefinitiveRefusal: (error48) => error48 instanceof HyperliquidExchangeRejectionError || error48 instanceof NativeOrderNotSentError,
|
|
105024
105471
|
neverLandsAfterMs: (sentAtMs) => clientOrderNeverLandsAfterMs(request.config, { kind: "absent", ageStartMs: sentAtMs }),
|
|
105025
105472
|
newMutationId: () => createRuntimeId().toLowerCase(),
|
|
@@ -105053,17 +105500,29 @@ var init_runtime_execution = __esm({
|
|
|
105053
105500
|
if (read.record.walletAddress !== wallet) return [nativeStorageReport(symbol2, "protective_wallet_mismatch")];
|
|
105054
105501
|
try {
|
|
105055
105502
|
const io = nativeProtectionIo(request, read.record.isLong);
|
|
105056
|
-
|
|
105503
|
+
const standby = read.record.standby ?? [];
|
|
105504
|
+
if (read.record.phase === "entry_pending" || standby.length > 0) {
|
|
105057
105505
|
const settled = await settleNativeProtectionAfterFill({
|
|
105058
105506
|
record: read.record,
|
|
105059
105507
|
settings: nativeSettingsOf(request.executionContext),
|
|
105060
105508
|
sizeDecimals: request.executionContext.sizeDecimals,
|
|
105061
105509
|
fillSize: "0",
|
|
105062
|
-
entryOrderId: read.record.entryClientOrderId,
|
|
105510
|
+
entryOrderId: read.record.phase === "entry_pending" ? read.record.entryClientOrderId : standby[0].orderId ?? standby[0].clientOrderId,
|
|
105063
105511
|
io
|
|
105064
105512
|
});
|
|
105065
105513
|
const reports2 = [...settled.reports];
|
|
105066
|
-
|
|
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)) {
|
|
105067
105526
|
reports2.push(nativeStorageReport(symbol2, "protective_lifecycle_persistence_failed"));
|
|
105068
105527
|
}
|
|
105069
105528
|
return reports2;
|
|
@@ -108439,13 +108898,14 @@ var init_runtime_execution = __esm({
|
|
|
108439
108898
|
entryMutationId ??= createRuntimeId().toLowerCase();
|
|
108440
108899
|
entryClientOrderId = clientOrderIdForMutation(entryMutationId);
|
|
108441
108900
|
nativePendingLotKey = entryClientOrderId;
|
|
108442
|
-
|
|
108901
|
+
const journaledAt = Date.now();
|
|
108902
|
+
nativeAddRecord = planNativeStandbyAdd(planNativePendingLot(existingNative.record, {
|
|
108443
108903
|
settings: nativeSettingsOf(input.executionContext),
|
|
108444
108904
|
sizeDecimals: input.executionContext.sizeDecimals,
|
|
108445
108905
|
key: entryClientOrderId,
|
|
108446
108906
|
sizeHint: sizeAsset,
|
|
108447
|
-
nowMs:
|
|
108448
|
-
});
|
|
108907
|
+
nowMs: journaledAt
|
|
108908
|
+
}), { clientOrderId: entryClientOrderId, nowMs: journaledAt });
|
|
108449
108909
|
if (nativeAddRecord !== existingNative.record && !writeNativeProtectionRecord(nativeProfileId, input.executionContext.symbol, nativeAddRecord)) {
|
|
108450
108910
|
return nativeBlocked(
|
|
108451
108911
|
"protective_lifecycle_persistence_failed",
|
|
@@ -108632,7 +109092,7 @@ var init_runtime_execution = __esm({
|
|
|
108632
109092
|
writeNativeProtectionRecord(
|
|
108633
109093
|
nativeProfileId,
|
|
108634
109094
|
input.executionContext.symbol,
|
|
108635
|
-
dropNativePendingLot(stored.record, nativePendingLotKey)
|
|
109095
|
+
dropNativeStandbyAdd(dropNativePendingLot(stored.record, nativePendingLotKey), nativePendingLotKey)
|
|
108636
109096
|
);
|
|
108637
109097
|
}
|
|
108638
109098
|
}
|
|
@@ -108759,6 +109219,9 @@ var init_runtime_execution = __esm({
|
|
|
108759
109219
|
let record5 = nativeOpen != null ? recordEntryChildren(nativeOpen.record, marketOrderResponse) : nativeAddRecord;
|
|
108760
109220
|
let keepNativeJournal = false;
|
|
108761
109221
|
if (confirmedMarketFill?.orderId) {
|
|
109222
|
+
if (nativeOpen == null && nativePendingLotKey != null) {
|
|
109223
|
+
record5 = nameNativeStandbyAdd(record5, nativePendingLotKey, String(confirmedMarketFill.orderId));
|
|
109224
|
+
}
|
|
108762
109225
|
record5 = planNativeFillLot(record5, {
|
|
108763
109226
|
settings: nativeSettingsOf(input.executionContext),
|
|
108764
109227
|
sizeDecimals: input.executionContext.sizeDecimals,
|
|
@@ -113599,7 +114062,7 @@ var init_profile_model_cascade = __esm({
|
|
|
113599
114062
|
});
|
|
113600
114063
|
|
|
113601
114064
|
// lib/runtime/prompt-variable-validation-contract.ts
|
|
113602
|
-
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;
|
|
113603
114066
|
var init_prompt_variable_validation_contract = __esm({
|
|
113604
114067
|
"lib/runtime/prompt-variable-validation-contract.ts"() {
|
|
113605
114068
|
"use strict";
|
|
@@ -113685,6 +114148,40 @@ var init_prompt_variable_validation_contract = __esm({
|
|
|
113685
114148
|
rendered.push(prepared.slice(cursor));
|
|
113686
114149
|
return restoreEscapedBraces(rendered.join(""));
|
|
113687
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
|
+
};
|
|
113688
114185
|
promptTemplatePlaceholderSpans = (template) => {
|
|
113689
114186
|
if (typeof template !== "string" || !template) {
|
|
113690
114187
|
return [];
|
|
@@ -118420,7 +118917,7 @@ var init_provider_client = __esm({
|
|
|
118420
118917
|
});
|
|
118421
118918
|
|
|
118422
118919
|
// lib/runtime/prompt-contract.ts
|
|
118423
|
-
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;
|
|
118424
118921
|
var init_prompt_contract = __esm({
|
|
118425
118922
|
"lib/runtime/prompt-contract.ts"() {
|
|
118426
118923
|
"use strict";
|
|
@@ -118837,28 +119334,6 @@ var init_prompt_contract = __esm({
|
|
|
118837
119334
|
}
|
|
118838
119335
|
return text.replace(/\r\n/g, "\n").replace(/[\t ]{2,}\n/g, "\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
118839
119336
|
};
|
|
118840
|
-
formatInstructionTemplate = (template, vars) => {
|
|
118841
|
-
const escapedOpen = "__VTX_INSTR_OPEN_BRACE__";
|
|
118842
|
-
const escapedClose = "__VTX_INSTR_CLOSE_BRACE__";
|
|
118843
|
-
const prepared = String(template ?? "").replaceAll("{{", escapedOpen).replaceAll("}}", escapedClose);
|
|
118844
|
-
const replacements = [];
|
|
118845
|
-
const formatted = prepared.replace(/\{([a-zA-Z0-9_]+)\}/g, (_match, key) => {
|
|
118846
|
-
if (!Object.prototype.hasOwnProperty.call(vars, key)) {
|
|
118847
|
-
throw new Error(`Unexpected instruction template placeholder: ${key}`);
|
|
118848
|
-
}
|
|
118849
|
-
const marker = `__VTX_INSTR_VALUE_${replacements.length}__`;
|
|
118850
|
-
replacements.push(String(vars[key]));
|
|
118851
|
-
return marker;
|
|
118852
|
-
});
|
|
118853
|
-
if (/[{}]/.test(formatted)) {
|
|
118854
|
-
throw new Error(`Invalid instruction template: ${template}`);
|
|
118855
|
-
}
|
|
118856
|
-
let rendered = formatted.replaceAll(escapedOpen, "{").replaceAll(escapedClose, "}");
|
|
118857
|
-
replacements.forEach((value, index) => {
|
|
118858
|
-
rendered = rendered.replaceAll(`__VTX_INSTR_VALUE_${index}__`, value);
|
|
118859
|
-
});
|
|
118860
|
-
return rendered;
|
|
118861
|
-
};
|
|
118862
119337
|
constructPromptSystemTemplate = (systemTemplate, options) => {
|
|
118863
119338
|
const instructions = options.instructions ?? {};
|
|
118864
119339
|
const symbols = (options.symbols ?? []).map((symbol2) => String(symbol2).trim()).filter(Boolean);
|
|
@@ -119730,7 +120205,7 @@ __export(local_analysis_exports, {
|
|
|
119730
120205
|
runLocalRuntimeCycle: () => runLocalRuntimeCycle,
|
|
119731
120206
|
summarizeReviewFailureExplanation: () => summarizeReviewFailureExplanation
|
|
119732
120207
|
});
|
|
119733
|
-
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,
|
|
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;
|
|
119734
120209
|
var init_local_analysis = __esm({
|
|
119735
120210
|
"lib/runtime/local-analysis.ts"() {
|
|
119736
120211
|
"use strict";
|
|
@@ -120910,29 +121385,27 @@ var init_local_analysis = __esm({
|
|
|
120910
121385
|
return assembledUserTemplate;
|
|
120911
121386
|
};
|
|
120912
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);
|
|
120913
121394
|
try {
|
|
120914
|
-
requireStrategyReviewTemplates(
|
|
120915
|
-
requireNonEmptyStringField(metadata.review_system_template, "review_system_template"),
|
|
120916
|
-
requireNonEmptyStringField(metadata.review_user_template, "review_user_template")
|
|
120917
|
-
);
|
|
120918
121395
|
const reviewInstructions = asRecord(metadata.review_instructions);
|
|
120919
121396
|
const reviewSecurity = requireNonEmptyStringField(
|
|
120920
121397
|
reviewInstructions.review_security,
|
|
120921
121398
|
"review_instructions.review_security"
|
|
120922
121399
|
);
|
|
120923
|
-
const reviewOutputContract =
|
|
121400
|
+
const reviewOutputContract = formatInstructionTemplate(
|
|
120924
121401
|
requireNonEmptyStringField(
|
|
120925
121402
|
reviewInstructions.review_json_format,
|
|
120926
121403
|
"review_instructions.review_json_format"
|
|
120927
121404
|
),
|
|
120928
121405
|
buildDecisionInstructionVariables(symbols, maxTrades)
|
|
120929
121406
|
);
|
|
120930
|
-
|
|
120931
|
-
|
|
120932
|
-
"review_system_template"
|
|
120933
|
-
);
|
|
120934
|
-
if (extractTemplatePlaceholders(reviewSystemTemplate).length > 0 || extractTemplatePlaceholders(reviewSecurity).length > 0) {
|
|
120935
|
-
throw new CriticalBehaviorStateError();
|
|
121407
|
+
if (extractTemplatePlaceholders(reviewSecurity).length > 0) {
|
|
121408
|
+
throw new BehaviorMemoryUnavailableError();
|
|
120936
121409
|
}
|
|
120937
121410
|
const securedReviewSystem = reviewSystemTemplate.includes(reviewSecurity) ? reviewSystemTemplate : `${reviewSystemTemplate.trim()}
|
|
120938
121411
|
|
|
@@ -120941,13 +121414,13 @@ ${reviewSecurity}`;
|
|
|
120941
121414
|
|
|
120942
121415
|
${reviewOutputContract}`;
|
|
120943
121416
|
if (containsCompetingBehaviorStateMarkup(renderedReviewSystem)) {
|
|
120944
|
-
throw new
|
|
121417
|
+
throw new BehaviorMemoryUnavailableError();
|
|
120945
121418
|
}
|
|
120946
121419
|
} catch (error48) {
|
|
120947
|
-
if (error48 instanceof
|
|
121420
|
+
if (error48 instanceof BehaviorMemoryUnavailableError) {
|
|
120948
121421
|
throw error48;
|
|
120949
121422
|
}
|
|
120950
|
-
throw new
|
|
121423
|
+
throw new BehaviorMemoryUnavailableError(error48);
|
|
120951
121424
|
}
|
|
120952
121425
|
};
|
|
120953
121426
|
extractRuntimeReasoningSelection = (settings, controlType, toggleBehavior = "disable_reasoning") => {
|
|
@@ -121932,33 +122405,11 @@ ${reviewOutputContract}`;
|
|
|
121932
122405
|
].join("\n");
|
|
121933
122406
|
buildPromptPositionsValue = (input) => {
|
|
121934
122407
|
const validateInstructionTemplate = (template, allowedKeys) => {
|
|
121935
|
-
|
|
121936
|
-
|
|
121937
|
-
|
|
121938
|
-
|
|
121939
|
-
|
|
121940
|
-
throw new Error(`Unexpected positions instruction placeholder: ${key}`);
|
|
121941
|
-
}
|
|
121942
|
-
return "";
|
|
121943
|
-
});
|
|
121944
|
-
if (/[{}]/.test(formatted)) {
|
|
121945
|
-
throw new Error(`Invalid positions instruction template: ${template}`);
|
|
121946
|
-
}
|
|
121947
|
-
};
|
|
121948
|
-
const formatInstructionTemplate2 = (template, values) => {
|
|
121949
|
-
const escapedOpen = "__VTX_ESCAPED_OPEN__";
|
|
121950
|
-
const escapedClose = "__VTX_ESCAPED_CLOSE__";
|
|
121951
|
-
const normalizedTemplate = template.replace(/\{\{/g, escapedOpen).replace(/\}\}/g, escapedClose);
|
|
121952
|
-
const formatted = normalizedTemplate.replace(/\{([a-z_]+)\}/g, (_match, key) => {
|
|
121953
|
-
if (!Object.prototype.hasOwnProperty.call(values, key)) {
|
|
121954
|
-
throw new Error(`Unexpected positions instruction placeholder: ${key}`);
|
|
121955
|
-
}
|
|
121956
|
-
return String(values[key]);
|
|
121957
|
-
});
|
|
121958
|
-
if (/[{}]/.test(formatted)) {
|
|
121959
|
-
throw new Error(`Invalid positions instruction template: ${template}`);
|
|
121960
|
-
}
|
|
121961
|
-
return formatted.replaceAll(escapedOpen, "{").replaceAll(escapedClose, "}");
|
|
122408
|
+
formatInstructionTemplate(
|
|
122409
|
+
template,
|
|
122410
|
+
Object.fromEntries(allowedKeys.map((key) => [key, ""])),
|
|
122411
|
+
"positions instruction template"
|
|
122412
|
+
);
|
|
121962
122413
|
};
|
|
121963
122414
|
validateInstructionTemplate(input.positionsInstructions.close_reduce, []);
|
|
121964
122415
|
validateInstructionTemplate(input.positionsInstructions.capacity_flat, []);
|
|
@@ -122053,9 +122504,9 @@ ${reviewOutputContract}`;
|
|
|
122053
122504
|
if (remainingGlobal <= 0) {
|
|
122054
122505
|
parts.push(`${input.positionsInstructions.capacity_full} `);
|
|
122055
122506
|
} else if (input.maxTradesPerPrompt < input.maxTradesGlobal && remainingGlobal < input.maxTradesPerPrompt) {
|
|
122056
|
-
parts.push(`${
|
|
122507
|
+
parts.push(`${formatInstructionTemplate(input.positionsInstructions.capacity_low, {
|
|
122057
122508
|
remaining: remainingGlobal
|
|
122058
|
-
})} `);
|
|
122509
|
+
}, "positions instruction template")} `);
|
|
122059
122510
|
}
|
|
122060
122511
|
return parts.join("\n");
|
|
122061
122512
|
};
|
|
@@ -122551,6 +123002,9 @@ ${reviewOutputContract}`;
|
|
|
122551
123002
|
const matches2 = Array.from(
|
|
122552
123003
|
userPrompt.matchAll(/<behavior_state>\s*([\s\S]*?)\s*<\/behavior_state>/g)
|
|
122553
123004
|
);
|
|
123005
|
+
if (openingTags.length === 0 && closingTags.length === 0) {
|
|
123006
|
+
throw new BehaviorMemoryUnavailableError();
|
|
123007
|
+
}
|
|
122554
123008
|
if (openingTags.length !== 1 || closingTags.length !== 1 || matches2.length !== 1) {
|
|
122555
123009
|
throw new CriticalBehaviorStateError();
|
|
122556
123010
|
}
|
|
@@ -123533,27 +123987,6 @@ ${behaviorJson}
|
|
|
123533
123987
|
}
|
|
123534
123988
|
}
|
|
123535
123989
|
};
|
|
123536
|
-
formatTemplateWithNamedVariables = (template, values) => {
|
|
123537
|
-
const escapedOpen = "__VTX_FMT_OPEN__";
|
|
123538
|
-
const escapedClose = "__VTX_FMT_CLOSE__";
|
|
123539
|
-
const prepared = String(template || "").replaceAll("{{", escapedOpen).replaceAll("}}", escapedClose);
|
|
123540
|
-
const validatedTemplate = prepared.replace(/\{([a-zA-Z_][a-zA-Z0-9_]*)\}/g, (_match, key) => {
|
|
123541
|
-
if (!Object.prototype.hasOwnProperty.call(values, key)) {
|
|
123542
|
-
throw new Error(`Missing required review template variable: ${key}`);
|
|
123543
|
-
}
|
|
123544
|
-
return "";
|
|
123545
|
-
});
|
|
123546
|
-
if (/[{}]/.test(validatedTemplate)) {
|
|
123547
|
-
throw new Error(`Invalid review template: ${template}`);
|
|
123548
|
-
}
|
|
123549
|
-
const formatted = prepared.replace(/\{([a-zA-Z_][a-zA-Z0-9_]*)\}/g, (_match, key) => {
|
|
123550
|
-
if (!Object.prototype.hasOwnProperty.call(values, key)) {
|
|
123551
|
-
throw new Error(`Missing required review template variable: ${key}`);
|
|
123552
|
-
}
|
|
123553
|
-
return String(values[key]);
|
|
123554
|
-
});
|
|
123555
|
-
return formatted.replaceAll(escapedOpen, "{").replaceAll(escapedClose, "}");
|
|
123556
|
-
};
|
|
123557
123990
|
carryReturnedModelCalls = (error48, attempts) => {
|
|
123558
123991
|
if (!attempts.length || !error48 || typeof error48 !== "object" && typeof error48 !== "function") return error48;
|
|
123559
123992
|
error48.runtimeReturnedModelCalls = attempts;
|
|
@@ -125291,7 +125724,7 @@ ${stringifyPromptJson(candlesPayload)}
|
|
|
125291
125724
|
reviewInstructions.review_security,
|
|
125292
125725
|
"review_instructions.review_security"
|
|
125293
125726
|
);
|
|
125294
|
-
const reviewOutputContract =
|
|
125727
|
+
const reviewOutputContract = formatInstructionTemplate(
|
|
125295
125728
|
reviewOutputFormat,
|
|
125296
125729
|
buildDecisionInstructionVariables(reviewSymbols, reviewMaxTrades)
|
|
125297
125730
|
);
|
|
@@ -125314,12 +125747,18 @@ ${reviewOutputContract}`;
|
|
|
125314
125747
|
configuredReviewUserTemplate
|
|
125315
125748
|
) : configuredReviewUserTemplate;
|
|
125316
125749
|
const renderedPrimaryUserPrompt = stringifyPromptJson(userPrompt);
|
|
125317
|
-
|
|
125318
|
-
|
|
125319
|
-
|
|
125320
|
-
|
|
125321
|
-
|
|
125322
|
-
|
|
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
|
+
}
|
|
125323
125762
|
if (input.mode === "trader" && (reviewUserPrompt.split(renderedPrimaryUserPrompt).length - 1 !== 1 || /<\/?behavior_state\b/.test(reviewUserPrompt) || containsCompetingBehaviorStateMarkup(reviewSystemPrompt))) {
|
|
125324
125763
|
throw new CriticalBehaviorStateError();
|
|
125325
125764
|
}
|
|
@@ -128111,6 +128550,7 @@ var init_engine = __esm({
|
|
|
128111
128550
|
const runtime = await this.notifyRuntimeStop(this._profileId, {
|
|
128112
128551
|
keepalive: options?.keepalive === true,
|
|
128113
128552
|
reason: stopReason,
|
|
128553
|
+
modeSwitch: options?.modeSwitch === true,
|
|
128114
128554
|
killswitchTrigger: options?.killswitchTrigger ?? null,
|
|
128115
128555
|
authoritativeIntent: this._remoteStopPending === "authoritative-stop" && this._pendingAuthoritativeStopDetails?.authoritativeIntent === true
|
|
128116
128556
|
});
|
|
@@ -128190,7 +128630,8 @@ var init_engine = __esm({
|
|
|
128190
128630
|
reason: effectiveRemoteStopReason,
|
|
128191
128631
|
killswitchTrigger: supersedingStop?.killswitchTrigger ?? options?.killswitchTrigger ?? null,
|
|
128192
128632
|
acceptDeferredStopCompletion: !remoteStopWasAuthoritativeAtDispatch,
|
|
128193
|
-
authoritativeIntent: supersedingStop?.authoritativeIntent === true
|
|
128633
|
+
authoritativeIntent: supersedingStop?.authoritativeIntent === true,
|
|
128634
|
+
modeSwitch: !supersedingStop && options?.modeSwitch === true
|
|
128194
128635
|
});
|
|
128195
128636
|
this._setRuntimeStatus(runtime, "stop");
|
|
128196
128637
|
appendRuntimeDebugEvent({
|
|
@@ -131735,7 +132176,8 @@ var init_engine = __esm({
|
|
|
131735
132176
|
lastRunAt: this._lastRunAt,
|
|
131736
132177
|
stopReason: options?.reason ?? null,
|
|
131737
132178
|
killswitchTrigger: options?.killswitchTrigger ?? null,
|
|
131738
|
-
authoritativeIntent: options?.authoritativeIntent === true
|
|
132179
|
+
authoritativeIntent: options?.authoritativeIntent === true,
|
|
132180
|
+
modeSwitch: options?.modeSwitch === true
|
|
131739
132181
|
},
|
|
131740
132182
|
{
|
|
131741
132183
|
...options,
|