@vtxmacro/cli 2026.10.10 → 2026.10.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/vtx-mcp.js +1 -1
- package/bin/vtx-service-bootstrap.js +1 -1
- package/bin/vtx.js +740 -71
- 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.11", 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
|
|
|
@@ -50219,7 +50219,7 @@ function getProfileHeaders(baseHeaders = {}, explicitProfileId) {
|
|
|
50219
50219
|
if (profileId) headers["x-profile-id"] = profileId.toString();
|
|
50220
50220
|
return headers;
|
|
50221
50221
|
}
|
|
50222
|
-
var configuredApiTransport, getApiUrl, apiFetch, sleep, inFlightClientGetRequests, recentClientGetResponses, clientGetRequestGenerations, initializedClientGetRequestKeys, CLIENT_GET_DEDUPE_TTL_MS, CLIENT_LLM_CONFIG_PRIME_TTL_MS, AUTH_BOOTSTRAP_GET_MAX_ATTEMPTS, AUTH_BOOTSTRAP_RETRY_JITTER_MS, canUseClientGetRequestCache, invalidateClientGetRequestCache, raceWithAbortSignal, shareClientGetRequest, clientGetRequestKey, clientPreferencesRequestKey, invalidateClientPreferencesCache, parseRetryAfterMs2, resolveAuthBootstrapRetryDelayMs, fetchAuthBootstrapGetWithRetry, annotateMarketDataRequestError, buildMarketDataFetchError, buildMarketDataNetworkError, buildMarketDataResponseBodyError, isTransientNetworkFetchError, createIdempotencyKey, getErrorMessage, getErrorPayloadOrEmpty, getErrorPayloadOrFallbackDetail, getErrorMessageFromResponse, throwUnauthorizedIfNeeded, activeProfileId, PROFILE_STORAGE_KEY;
|
|
50222
|
+
var configuredApiTransport, getApiUrl, apiFetch, sleep, inFlightClientGetRequests, recentClientGetResponses, clientGetRequestGenerations, initializedClientGetRequestKeys, CLIENT_GET_DEDUPE_TTL_MS, CLIENT_RUNTIME_STATUSES_DEDUPE_TTL_MS, CLIENT_LLM_CONFIG_PRIME_TTL_MS, AUTH_BOOTSTRAP_GET_MAX_ATTEMPTS, AUTH_BOOTSTRAP_RETRY_JITTER_MS, canUseClientGetRequestCache, invalidateClientGetRequestCache, raceWithAbortSignal, shareClientGetRequest, clientGetRequestKey, clientPreferencesRequestKey, invalidateClientPreferencesCache, parseRetryAfterMs2, resolveAuthBootstrapRetryDelayMs, fetchAuthBootstrapGetWithRetry, annotateMarketDataRequestError, buildMarketDataFetchError, buildMarketDataNetworkError, buildMarketDataResponseBodyError, isTransientNetworkFetchError, createIdempotencyKey, getErrorMessage, getErrorPayloadOrEmpty, getErrorPayloadOrFallbackDetail, getErrorMessageFromResponse, throwUnauthorizedIfNeeded, activeProfileId, PROFILE_STORAGE_KEY;
|
|
50223
50223
|
var init_shared = __esm({
|
|
50224
50224
|
"lib/api/shared.ts"() {
|
|
50225
50225
|
"use strict";
|
|
@@ -50259,6 +50259,7 @@ var init_shared = __esm({
|
|
|
50259
50259
|
clientGetRequestGenerations = /* @__PURE__ */ new Map();
|
|
50260
50260
|
initializedClientGetRequestKeys = /* @__PURE__ */ new Set();
|
|
50261
50261
|
CLIENT_GET_DEDUPE_TTL_MS = 2e3;
|
|
50262
|
+
CLIENT_RUNTIME_STATUSES_DEDUPE_TTL_MS = 5e3;
|
|
50262
50263
|
CLIENT_LLM_CONFIG_PRIME_TTL_MS = 1e4;
|
|
50263
50264
|
AUTH_BOOTSTRAP_GET_MAX_ATTEMPTS = runtime_policy_generated_default2.ui.auth_bootstrap_retry.max_attempts;
|
|
50264
50265
|
AUTH_BOOTSTRAP_RETRY_JITTER_MS = runtime_policy_generated_default2.ui.auth_bootstrap_retry.jitter_milliseconds;
|
|
@@ -84600,7 +84601,7 @@ var init_hyperliquid_signer = __esm({
|
|
|
84600
84601
|
});
|
|
84601
84602
|
|
|
84602
84603
|
// lib/runtime/hyperliquid-client.ts
|
|
84603
|
-
var HyperliquidExchangeRejectionError, durableMutationAuthorityArgs, assertFreshPreparedExecutionContext, normalizeSymbol, HYPERLIQUID_NONCE_STORAGE_KEY, HYPERLIQUID_NONCE_LOCK_NAME, lastGeneratedNonce, readBrowserStoredHyperliquidNonce, writeBrowserStoredHyperliquidNonce, browserNonceCoordinator, allocateHyperliquidNonce, hostNonceAllocator, allocateActionNonce, generateHyperliquidNonce, normalizeDecimalString, HYPERLIQUID_PRICE_SIGNIFICANT_FIGURES, HYPERLIQUID_INTEGER_PRICE_MINIMUM, shortestDecimalParts, formatHyperliquidPerpPriceGrid, formatHyperliquidTriggerPriceWire, hyperliquidOrderPriceRounding, formatHyperliquidOrderPriceWire, countSignificantDigits, countDecimalPlaces, validateHyperliquidPerpPriceWire, validateHyperliquidSizeWire, formatSizeWire, inferApiUrl, inferIsTestnet, postHyperliquidInfoRead, postHyperliquidInfo, fetchBrowserHyperliquidInfoPayload, fetchBrowserHyperliquidInfoText, toFiniteNumber, OPEN_ORDER_NUMERIC_STRING, OPEN_ORDER_ID_STRING, parseCanonicalOpenOrderId, parseOpenOrderFiniteNumber, parseOpenOrderPositiveNumber, parseOpenOrderPresentationNumber, readOpenOrderField, firstFiniteNumber, parseFundingUsdcFromInfoPosition, isExchangeIsolatedOnly, computeHip3AssetId, getPerpDexIndexMap, buildAssetInfosFromMetaResponse, requireWalletAddress, assertPositiveInteger, assertPositiveNumber, normalizeOrderSide, normalizeHyperliquidClientOrderId, resolveAssets, findResolvedAsset, normalizeExecutionAssetMetadata, resolveHyperliquidAsset, resolveHyperliquidAssetIndex, decimalUnits, quantizeHyperliquidOrderSizeValue, hyperliquidSignedSizeMatchesRequestedSize, finitePositive, readDevicePrivateExecutionContext, quantizeHyperliquidOrderSize, fetchBrowserAvailableAssets, fetchBrowserAllMids, fetchBrowserSymbolMidPrice, fetchBrowserOpenOrders, parseCanonicalHyperliquidOrderStatusEvidence, fetchBrowserOrderStatusEvidence, fetchBrowserUserRole, fetchBrowserAccountState, fetchBrowserPosition, buildHyperliquidOrderWire, buildHyperliquidTriggerOrderWire, signHyperliquidPayload, signHyperliquidPreparedAction, buildHyperliquidCancelPayload, buildHyperliquidUpdateLeveragePayload, buildHyperliquidMarketOrderPayload, buildHyperliquidLimitOrderPayload, buildHyperliquidTriggerOrderPayload, buildHyperliquidOrderBatchPayload, buildHyperliquidModifyOrderPayload, extractHyperliquidExchangeError, resolveHyperliquidTriggerAcknowledgements, isDefinitiveHyperliquidExchangeResponse, extractDefinitiveHyperliquidOrderId, CANONICAL_POSITIVE_DECIMAL_PATTERN, extractCanonicalHyperliquidOrderStateAcknowledgement, extractCanonicalHyperliquidOrderStateAcknowledgements, extractCanonicalHyperliquidFilledOrderAcknowledgement, extractDefinitiveHyperliquidOrderMemberResults, buildHyperliquidOrderDiagnostics, loadClientExecutionReferenceEvidence, sha256Hex, extractSignedPayloadClientOrderId, extractSignedPayloadMutationCorrelation, assertDurableMutationMatchesSignedAction, exchangeRejectionReason, exchangeActionPriority, submitHyperliquidExchangePayload;
|
|
84604
|
+
var HyperliquidExchangeRejectionError, durableMutationAuthorityArgs, assertFreshPreparedExecutionContext, normalizeSymbol, HYPERLIQUID_NONCE_STORAGE_KEY, HYPERLIQUID_NONCE_LOCK_NAME, lastGeneratedNonce, readBrowserStoredHyperliquidNonce, writeBrowserStoredHyperliquidNonce, browserNonceCoordinator, allocateHyperliquidNonce, hostNonceAllocator, allocateActionNonce, generateHyperliquidNonce, normalizeDecimalString, HYPERLIQUID_PRICE_SIGNIFICANT_FIGURES, HYPERLIQUID_INTEGER_PRICE_MINIMUM, shortestDecimalParts, formatHyperliquidPerpPriceGrid, formatHyperliquidTriggerPriceWire, hyperliquidOrderPriceRounding, formatHyperliquidOrderPriceWire, countSignificantDigits, countDecimalPlaces, validateHyperliquidPerpPriceWire, validateHyperliquidSizeWire, formatSizeWire, inferApiUrl, inferIsTestnet, postHyperliquidInfoRead, postHyperliquidInfo, fetchBrowserHyperliquidInfoPayload, fetchBrowserHyperliquidInfoRead, fetchBrowserHyperliquidInfoText, toFiniteNumber, OPEN_ORDER_NUMERIC_STRING, OPEN_ORDER_ID_STRING, parseCanonicalOpenOrderId, parseOpenOrderFiniteNumber, parseOpenOrderPositiveNumber, parseOpenOrderPresentationNumber, readOpenOrderField, firstFiniteNumber, parseFundingUsdcFromInfoPosition, isExchangeIsolatedOnly, computeHip3AssetId, getPerpDexIndexMap, buildAssetInfosFromMetaResponse, requireWalletAddress, assertPositiveInteger, assertPositiveNumber, normalizeOrderSide, normalizeHyperliquidClientOrderId, resolveAssets, findResolvedAsset, normalizeExecutionAssetMetadata, resolveHyperliquidAsset, resolveHyperliquidAssetIndex, decimalUnits, quantizeHyperliquidOrderSizeValue, hyperliquidSignedSizeMatchesRequestedSize, finitePositive, readDevicePrivateExecutionContext, quantizeHyperliquidOrderSize, fetchBrowserAvailableAssets, fetchBrowserAllMids, fetchBrowserSymbolMidPrice, fetchBrowserOpenOrders, parseCanonicalHyperliquidOrderStatusEvidence, fetchBrowserOrderStatusEvidence, fetchBrowserUserRole, fetchBrowserAccountState, fetchBrowserPosition, buildHyperliquidOrderWire, buildHyperliquidTriggerOrderWire, signHyperliquidPayload, signHyperliquidPreparedAction, buildHyperliquidCancelPayload, buildHyperliquidUpdateLeveragePayload, buildHyperliquidMarketOrderPayload, buildHyperliquidLimitOrderPayload, buildHyperliquidTriggerOrderPayload, buildHyperliquidOrderBatchPayload, buildHyperliquidModifyOrderPayload, extractHyperliquidExchangeError, resolveHyperliquidTriggerAcknowledgements, isDefinitiveHyperliquidExchangeResponse, extractDefinitiveHyperliquidOrderId, CANONICAL_POSITIVE_DECIMAL_PATTERN, extractCanonicalHyperliquidOrderStateAcknowledgement, extractCanonicalHyperliquidOrderStateAcknowledgements, extractCanonicalHyperliquidFilledOrderAcknowledgement, extractDefinitiveHyperliquidOrderMemberResults, buildHyperliquidOrderDiagnostics, loadClientExecutionReferenceEvidence, sha256Hex, extractSignedPayloadClientOrderId, extractSignedPayloadMutationCorrelation, assertDurableMutationMatchesSignedAction, exchangeRejectionReason, exchangeActionPriority, submitHyperliquidExchangePayload;
|
|
84604
84605
|
var init_hyperliquid_client = __esm({
|
|
84605
84606
|
"lib/runtime/hyperliquid-client.ts"() {
|
|
84606
84607
|
"use strict";
|
|
@@ -84852,13 +84853,14 @@ var init_hyperliquid_client = __esm({
|
|
|
84852
84853
|
url: requestUrl
|
|
84853
84854
|
});
|
|
84854
84855
|
try {
|
|
84855
|
-
const { payload, bodyText } = await readHyperliquidPublicInfo(apiUrl, body, {
|
|
84856
|
+
const { payload, bodyText, fetchedAtMs } = await readHyperliquidPublicInfo(apiUrl, body, {
|
|
84856
84857
|
signal: input.signal,
|
|
84857
84858
|
publicRequestPriority: input.publicRequestPriority,
|
|
84858
|
-
includeBodyText
|
|
84859
|
+
includeBodyText,
|
|
84860
|
+
...input.cacheAccountMode ? { cacheAccountMode: true } : {}
|
|
84859
84861
|
});
|
|
84860
84862
|
trace.completeSuccess(200);
|
|
84861
|
-
return { payload, bodyText };
|
|
84863
|
+
return { payload, bodyText, fetchedAtMs };
|
|
84862
84864
|
} catch (error48) {
|
|
84863
84865
|
const sanitizedError = toSanitizedRuntimeError(error48);
|
|
84864
84866
|
trace.completeError(sanitizedError, error48?.status ?? null);
|
|
@@ -84867,6 +84869,10 @@ var init_hyperliquid_client = __esm({
|
|
|
84867
84869
|
};
|
|
84868
84870
|
postHyperliquidInfo = async (input, body, label2) => (await postHyperliquidInfoRead(input, body, label2)).payload;
|
|
84869
84871
|
fetchBrowserHyperliquidInfoPayload = (input, body, label2) => postHyperliquidInfo(input, body, label2);
|
|
84872
|
+
fetchBrowserHyperliquidInfoRead = async (input, body, label2) => {
|
|
84873
|
+
const { payload, fetchedAtMs } = await postHyperliquidInfoRead(input, body, label2);
|
|
84874
|
+
return { payload, fetchedAtMs };
|
|
84875
|
+
};
|
|
84870
84876
|
fetchBrowserHyperliquidInfoText = async (input, body, label2) => {
|
|
84871
84877
|
const { bodyText } = await postHyperliquidInfoRead(input, body, label2, true);
|
|
84872
84878
|
if (typeof bodyText !== "string") throw new Error("Hyperliquid returned no response text.");
|
|
@@ -86928,14 +86934,14 @@ var init_exchange_mutation_evidence = __esm({
|
|
|
86928
86934
|
const wallet = String(input.required.wallet_address ?? "").trim();
|
|
86929
86935
|
if (!wallet) throw new Error("Missing wallet address for reconciliation evidence.");
|
|
86930
86936
|
const apiUrl = await resolveHyperliquidApiUrl(input.profileId, input.required.hyperliquid_api_url, input.signal);
|
|
86931
|
-
const
|
|
86937
|
+
const readInput = { apiUrl, signal: input.signal, publicRequestPriority: "trading_reconcile" };
|
|
86932
86938
|
const startedAtMonotonicMs = monotonicNowMs();
|
|
86933
86939
|
const observedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
86934
86940
|
const orderStatuses = await Promise.all((input.required.order_refs ?? []).map(async (ref) => {
|
|
86935
86941
|
const orderRef = String(ref).trim();
|
|
86936
86942
|
const oid = /^\d+$/.test(orderRef) ? Number(orderRef) : orderRef;
|
|
86937
86943
|
const response = await fetchBrowserHyperliquidInfoPayload(
|
|
86938
|
-
|
|
86944
|
+
readInput,
|
|
86939
86945
|
{ type: "orderStatus", user: wallet, oid },
|
|
86940
86946
|
"hyperliquid.orderStatus"
|
|
86941
86947
|
);
|
|
@@ -86943,7 +86949,7 @@ var init_exchange_mutation_evidence = __esm({
|
|
|
86943
86949
|
}));
|
|
86944
86950
|
const coin = String(input.required.active_asset_coin ?? "").trim();
|
|
86945
86951
|
const activeAssetData = coin ? await fetchBrowserHyperliquidInfoPayload(
|
|
86946
|
-
|
|
86952
|
+
readInput,
|
|
86947
86953
|
{ type: "activeAssetData", user: wallet, coin },
|
|
86948
86954
|
"hyperliquid.activeAssetData"
|
|
86949
86955
|
) : null;
|
|
@@ -86961,6 +86967,27 @@ var init_exchange_mutation_evidence = __esm({
|
|
|
86961
86967
|
});
|
|
86962
86968
|
|
|
86963
86969
|
// lib/api.ts
|
|
86970
|
+
async function reportServerBackupReadiness(profileId, ready, hostId, signal, power) {
|
|
86971
|
+
const response = await apiFetch(`${getApiUrl()}/trading/ai/client/server-backup/readiness`, {
|
|
86972
|
+
method: "POST",
|
|
86973
|
+
headers: getProfileHeaders({ "Content-Type": "application/json" }, profileId),
|
|
86974
|
+
credentials: "include",
|
|
86975
|
+
// A host too low on battery to take a runtime over is not ready to take a backup back.
|
|
86976
|
+
body: JSON.stringify({
|
|
86977
|
+
ready,
|
|
86978
|
+
host_id: hostId,
|
|
86979
|
+
...power ? {
|
|
86980
|
+
power_source: power.source,
|
|
86981
|
+
...typeof power.batteryPercent === "number" ? { battery_percent: power.batteryPercent } : {}
|
|
86982
|
+
} : {}
|
|
86983
|
+
}),
|
|
86984
|
+
signal
|
|
86985
|
+
});
|
|
86986
|
+
if (!response.ok) {
|
|
86987
|
+
throw new Error(await getErrorMessageFromResponse(response, "Failed to report client readiness"));
|
|
86988
|
+
}
|
|
86989
|
+
return response.json();
|
|
86990
|
+
}
|
|
86964
86991
|
function relayNativeProviderRequest(provider, apiKey, payload, options = {}) {
|
|
86965
86992
|
return apiFetch(`${getApiUrl()}/llm/native-provider-relay`, {
|
|
86966
86993
|
method: "POST",
|
|
@@ -87031,6 +87058,21 @@ async function getClientRuntimeSecrets(profileId, options) {
|
|
|
87031
87058
|
client_runtime_secret_version: fetchedPayload.client_runtime_secret_version
|
|
87032
87059
|
};
|
|
87033
87060
|
}
|
|
87061
|
+
async function getLocalAiEndpointSecret(baseUrl, profileId, signal) {
|
|
87062
|
+
const params = new URLSearchParams({ base_url: baseUrl });
|
|
87063
|
+
const response = await apiFetch(`${getApiUrl()}/auth/me/local-ai-endpoint-secret?${params.toString()}`, {
|
|
87064
|
+
method: "GET",
|
|
87065
|
+
cache: "no-store",
|
|
87066
|
+
headers: clientRuntimeSecretHeaders(profileId),
|
|
87067
|
+
credentials: "include",
|
|
87068
|
+
signal
|
|
87069
|
+
});
|
|
87070
|
+
if (!response.ok) {
|
|
87071
|
+
const message = await getErrorMessageFromResponse(response, "Failed to fetch Local AI endpoint secret", { fallbackDetail: true });
|
|
87072
|
+
throw new Error(message);
|
|
87073
|
+
}
|
|
87074
|
+
return response.json();
|
|
87075
|
+
}
|
|
87034
87076
|
async function getPreferences(cookie, profileId, signal, includeTradeLayouts = false, runtimeAuthority) {
|
|
87035
87077
|
const effectiveProfileId = profileId ?? getActiveProfileId() ?? null;
|
|
87036
87078
|
const schedulerInstanceId = String(runtimeAuthority?.schedulerInstanceId ?? "").trim() || void 0;
|
|
@@ -87099,7 +87141,8 @@ async function pollCopyTradingRuntimeSource(profileId, options) {
|
|
|
87099
87141
|
body: JSON.stringify({
|
|
87100
87142
|
dry_run: Boolean(options?.dryRun),
|
|
87101
87143
|
force_refresh: Boolean(options?.forceRefresh),
|
|
87102
|
-
...options?.maxEvents ? { max_events: options.maxEvents } : {}
|
|
87144
|
+
...options?.maxEvents ? { max_events: options.maxEvents } : {},
|
|
87145
|
+
...options?.accountEvidence ? { account_evidence: options.accountEvidence } : {}
|
|
87103
87146
|
}),
|
|
87104
87147
|
credentials: "include",
|
|
87105
87148
|
cache: "no-store",
|
|
@@ -87522,6 +87565,10 @@ async function claimClientRuntime(profileId, payload, options) {
|
|
|
87522
87565
|
kind: payload.kind,
|
|
87523
87566
|
takeover: payload.kind === "explicit" && payload.takeover === true,
|
|
87524
87567
|
...payload.claimSurface ? { claim_surface: payload.claimSurface } : {},
|
|
87568
|
+
...payload.power ? {
|
|
87569
|
+
power_source: payload.power.source,
|
|
87570
|
+
...typeof payload.power.batteryPercent === "number" ? { battery_percent: payload.power.batteryPercent } : {}
|
|
87571
|
+
} : {},
|
|
87525
87572
|
// This build signs server-issued TP/SL actions; a profile whose
|
|
87526
87573
|
// protection the server owns admits only claims that say so.
|
|
87527
87574
|
client_protection_capability_version: CLIENT_PROTECTION_CAPABILITY_VERSION
|
|
@@ -88440,6 +88487,41 @@ async function fetchClientRuntimeKillswitchContext(profileId, payload, options)
|
|
|
88440
88487
|
options
|
|
88441
88488
|
);
|
|
88442
88489
|
}
|
|
88490
|
+
async function getClientRuntimeStatuses(profileIds, signal, options) {
|
|
88491
|
+
const normalizedProfileIds = [...new Set(profileIds)].sort((left, right) => left - right);
|
|
88492
|
+
const params = new URLSearchParams();
|
|
88493
|
+
for (const profileId of normalizedProfileIds) {
|
|
88494
|
+
params.append("profile_id", String(profileId));
|
|
88495
|
+
}
|
|
88496
|
+
const viewer = resolveClientRuntimeStatusViewerHeaders(options?.runtimeViewer);
|
|
88497
|
+
const requestKey = `client-runtime-statuses:${normalizedProfileIds.join(",")}${viewer.requestKey}`;
|
|
88498
|
+
return shareClientGetRequest(requestKey, async () => {
|
|
88499
|
+
const headers = { ...viewer.headers };
|
|
88500
|
+
const response = await apiFetch(
|
|
88501
|
+
`${getApiUrl()}/trading/ai/runtime/statuses?${params.toString()}`,
|
|
88502
|
+
{
|
|
88503
|
+
method: "GET",
|
|
88504
|
+
credentials: "include",
|
|
88505
|
+
cache: "no-store",
|
|
88506
|
+
headers,
|
|
88507
|
+
// Without the browser's shared request a caller's abort ends the request too.
|
|
88508
|
+
signal: typeof window === "undefined" ? signal : void 0
|
|
88509
|
+
}
|
|
88510
|
+
);
|
|
88511
|
+
if (!response.ok) {
|
|
88512
|
+
const error48 = await createRuntimeRequestError(response, "Failed to fetch client runtime statuses");
|
|
88513
|
+
throw error48;
|
|
88514
|
+
}
|
|
88515
|
+
return response.json();
|
|
88516
|
+
}, {
|
|
88517
|
+
signal,
|
|
88518
|
+
shareAbortScoped: true,
|
|
88519
|
+
// A host-named read decides whether that host claims: it must see an
|
|
88520
|
+
// intent change made a moment ago, so it shares only an in-flight read
|
|
88521
|
+
// and never reuses a finished one.
|
|
88522
|
+
ttlMs: viewer.requestKey ? 0 : CLIENT_RUNTIME_STATUSES_DEDUPE_TTL_MS
|
|
88523
|
+
});
|
|
88524
|
+
}
|
|
88443
88525
|
var clientRuntimeSecretHeaders, preferencesWriteQueue, getCopyTradingRuntimeLeaseToken, getCopyTradingSchedulerInstanceId, resolveClientRuntimeStatusViewerHeaders, CLIENT_SUPPORTED_PROMPT_CONTRACT_VERSION, CLIENT_PROTECTION_CAPABILITY_VERSION, completedDeferredClientRuntimeStops, rememberCompletedDeferredClientRuntimeStop, consumeCompletedDeferredClientRuntimeStop, toNumericProfileId, buildClientRuntimeBody, shouldAttachRuntimeIdempotencyKey, attachRuntimeLeaseHeader, attachRuntimeSchedulerInstanceHeader, resolveRuntimeLeaseToken, resolveSchedulerBoundRuntimeLeaseToken, persistRuntimeLeaseFromPayload, persistRuntimeLeaseStatusMetadata, shouldClearPersistedRuntimeLeaseOnError, createRuntimeRequestError, parseClientRuntimeRequestContext, recordRuntimeAuthFailureBreadcrumb, classifyRuntimeRequestError, annotateRuntimeRequestError, parseRuntimeRetryAfterMs, isRetryableClientRuntimeStatus, shouldRetryClientRuntimeHttpStatus, isRuntimeIdempotencyInProgressError, isRetryableRuntimeConflictError, resolveClientRuntimeRetryDelayMs, reconcilePendingClientExchangeMutation, CLIENT_RUNTIME_CLAIM_EXCHANGE_MUTATION_WAIT_CODES, CLIENT_EXCHANGE_AUTHORITY_DEVICE_KEY, CLIENT_EXCHANGE_AUTHORITY_SESSION_KEY, getOrCreateClientExchangeAuthorityIdentity, resolveClientExchangeMutationAuthority, pinClientExchangeMutationAuthority, CLIENT_EXCHANGE_MUTATION_AUTHORITY_MISMATCH, isClientExchangeMutationAuthorityConflict, handOffClientExchangeMutationToReconciliation, clientExchangeMutationAuthorityBody, isPendingClientExchangeMutationError, isMissingActiveClientExchangeMutationError, clientExchangeMutationReconciliationTimers, MAX_CLIENT_EXCHANGE_RECONCILIATION_DELAY_MS, CLIENT_EXCHANGE_RECONCILIATION_CLOCK_SKEW_MS, ClientExchangeMutationRebuildRequiredError, isTerminalClientExchangeMutation, clientExchangeMutationReconciliationKey, clearScheduledClientExchangeMutationReconciliation, snapshotClientExchangeMutationReconciliationAuthority, completeClientExchangeMutationReconciliation, protectiveBoundClientExchangeMutations, rememberProtectiveBoundClientExchangeMutation, isProtectiveBoundClientExchangeMutation, postClientExchangeMutationReconciliation, scheduleClientExchangeMutationReconciliation;
|
|
88444
88526
|
var init_api2 = __esm({
|
|
88445
88527
|
"lib/api.ts"() {
|
|
@@ -88495,10 +88577,17 @@ var init_api2 = __esm({
|
|
|
88495
88577
|
if (!deviceId) return { headers: {}, requestKey: "" };
|
|
88496
88578
|
const sessionId = String(viewer?.sessionId ?? "").trim();
|
|
88497
88579
|
const surface = String(viewer?.surface ?? "").trim();
|
|
88580
|
+
const power = viewer?.power?.source ?? "";
|
|
88581
|
+
const batteryPercent = viewer?.power?.batteryPercent;
|
|
88498
88582
|
const headers = { "x-client-runtime-device-id": deviceId };
|
|
88499
88583
|
if (sessionId) headers["x-client-runtime-session-id"] = sessionId;
|
|
88500
88584
|
if (surface) headers["x-client-runtime-surface"] = surface;
|
|
88501
|
-
|
|
88585
|
+
if (power) headers["x-client-runtime-power"] = power;
|
|
88586
|
+
if (typeof batteryPercent === "number") headers["x-client-runtime-battery-percent"] = String(batteryPercent);
|
|
88587
|
+
return {
|
|
88588
|
+
headers,
|
|
88589
|
+
requestKey: `:viewer:${deviceId}:${sessionId}:${surface}:${power}:${batteryPercent ?? ""}`
|
|
88590
|
+
};
|
|
88502
88591
|
};
|
|
88503
88592
|
CLIENT_SUPPORTED_PROMPT_CONTRACT_VERSION = String(
|
|
88504
88593
|
process.env.NEXT_PUBLIC_CLIENT_RUNTIME_PROMPT_CONTRACT_VERSION || "2026-08-24.1"
|
|
@@ -89481,7 +89570,7 @@ var init_sort_utils = __esm({
|
|
|
89481
89570
|
});
|
|
89482
89571
|
|
|
89483
89572
|
// lib/local-ai.ts
|
|
89484
|
-
var LOCAL_SOURCE_ALIASES, LOCAL_CONTEXT_CACHE_TTL_MS, LOCAL_AI_SERVER_TYPE_ALIASES, LOCAL_AI_ROOT_SUFFIXES, normalizeLocalAiServerType, assertSupportedLocalAiServerType, resolveLocalAiServerTypeInput, stripLocalAiKnownSuffix, getLocalAiRootUrl, normalizeLocalModelSource, isLocalModelSource, isClientOnlyModelSource, normalizeLocalAiBaseUrl, endpointOrigin, sameEndpointOriginKey, normalizeOpenAiCompatibleBaseUrl;
|
|
89573
|
+
var LOCAL_SOURCE_ALIASES, LOCAL_CONTEXT_CACHE_TTL_MS, LOCAL_AI_SERVER_TYPE_ALIASES, LOCAL_AI_ROOT_SUFFIXES, normalizeLocalAiServerType, assertSupportedLocalAiServerType, resolveLocalAiServerTypeInput, stripLocalAiKnownSuffix, getLocalAiRootUrl, normalizeLocalModelSource, isLocalModelSource, isClientOnlyModelSource, normalizeLocalAiBaseUrl, endpointOrigin, sameEndpointOriginKey, normalizeOpenAiCompatibleBaseUrl, buildLocalAiModelsEndpointForServerType;
|
|
89485
89574
|
var init_local_ai = __esm({
|
|
89486
89575
|
"lib/local-ai.ts"() {
|
|
89487
89576
|
"use strict";
|
|
@@ -89608,6 +89697,14 @@ var init_local_ai = __esm({
|
|
|
89608
89697
|
return null;
|
|
89609
89698
|
}
|
|
89610
89699
|
};
|
|
89700
|
+
buildLocalAiModelsEndpointForServerType = (baseUrl, serverType) => {
|
|
89701
|
+
assertSupportedLocalAiServerType(serverType);
|
|
89702
|
+
const normalizedBaseUrl = normalizeLocalAiBaseUrl(baseUrl);
|
|
89703
|
+
if (!normalizedBaseUrl) {
|
|
89704
|
+
return null;
|
|
89705
|
+
}
|
|
89706
|
+
return normalizedBaseUrl.toLowerCase().endsWith("/models") ? normalizedBaseUrl : `${normalizedBaseUrl}/models`;
|
|
89707
|
+
};
|
|
89611
89708
|
}
|
|
89612
89709
|
});
|
|
89613
89710
|
|
|
@@ -92161,7 +92258,7 @@ var init_hyperliquid_account_state_adapter = __esm({
|
|
|
92161
92258
|
});
|
|
92162
92259
|
|
|
92163
92260
|
// lib/runtime/protective-evidence.ts
|
|
92164
|
-
var protectivePolicy, MAX_PROTECTIVE_EVIDENCE_ITEMS_PER_REPORT, EVIDENCE_FAILURE_BACKOFF_MS, STALE_EVIDENCE_CODE, SHARED_ACCOUNT_READ_MS, sharedAccountReads, EVIDENCE_READ_PRIORITY, MIN_EVIDENCE_SWEEP_DELAY_MS, evidenceBackoffUntil, errorCode, parseDueAtMs, boundedEvidenceSweepAtMs, authorityArgs, dexBody,
|
|
92261
|
+
var protectivePolicy, MAX_PROTECTIVE_EVIDENCE_ITEMS_PER_REPORT, EVIDENCE_FAILURE_BACKOFF_MS, STALE_EVIDENCE_CODE, SHARED_ACCOUNT_READ_MS, sharedAccountReads, EVIDENCE_READ_PRIORITY, MIN_EVIDENCE_SWEEP_DELAY_MS, evidenceBackoffUntil, errorCode, parseDueAtMs, boundedEvidenceSweepAtMs, authorityArgs, dexBody, isEvidenceOrderRef, orderStatusOid, evidenceReadInput, evidenceItems, readOrNull, reportBody, readEvidenceBatch, withEvidenceReporterLock, reportDueClientProtectiveEvidence, readClientProtectiveOpenOrdersEvidence, openOrdersEvidenceForUpload;
|
|
92165
92262
|
var init_protective_evidence = __esm({
|
|
92166
92263
|
"lib/runtime/protective-evidence.ts"() {
|
|
92167
92264
|
"use strict";
|
|
@@ -92201,7 +92298,9 @@ var init_protective_evidence = __esm({
|
|
|
92201
92298
|
return scheduler ? [session, lease, device, scheduler] : [session, lease, device];
|
|
92202
92299
|
};
|
|
92203
92300
|
dexBody = (dex) => dex ? { dex } : {};
|
|
92204
|
-
|
|
92301
|
+
isEvidenceOrderRef = (orderRef) => /^\d+$/.test(orderRef) && Number.isSafeInteger(Number(orderRef)) || /^0x[0-9a-fA-F]{32}$/.test(orderRef);
|
|
92302
|
+
orderStatusOid = (orderRef) => /^\d+$/.test(orderRef) ? Number(orderRef) : orderRef;
|
|
92303
|
+
evidenceReadInput = (context) => {
|
|
92205
92304
|
const apiUrl = String(context.hyperliquidApiUrl ?? "").trim();
|
|
92206
92305
|
return {
|
|
92207
92306
|
config: context.config,
|
|
@@ -92216,7 +92315,7 @@ var init_protective_evidence = __esm({
|
|
|
92216
92315
|
const dex = String(request.dex ?? "").trim();
|
|
92217
92316
|
if (request.kind === "order_status") {
|
|
92218
92317
|
const orderRef = String(request.order_ref ?? "").trim();
|
|
92219
|
-
if (
|
|
92318
|
+
if (!isEvidenceOrderRef(orderRef)) continue;
|
|
92220
92319
|
const key = `order_status:${orderRef}`;
|
|
92221
92320
|
const existing = items.get(key);
|
|
92222
92321
|
items.set(key, {
|
|
@@ -92257,7 +92356,7 @@ var init_protective_evidence = __esm({
|
|
|
92257
92356
|
observed_age_ms: monotonicAgeMs(batch.startedAtMonotonicMs)
|
|
92258
92357
|
});
|
|
92259
92358
|
readEvidenceBatch = async (context, wallet, batch) => {
|
|
92260
|
-
const input =
|
|
92359
|
+
const input = evidenceReadInput(context);
|
|
92261
92360
|
let startedAtMonotonicMs = monotonicNowMs();
|
|
92262
92361
|
const observedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
92263
92362
|
const perDex = /* @__PURE__ */ new Map();
|
|
@@ -92289,7 +92388,7 @@ var init_protective_evidence = __esm({
|
|
|
92289
92388
|
const markets = [];
|
|
92290
92389
|
await Promise.all(batch.map(async (item) => {
|
|
92291
92390
|
if (item.kind === "order_status") {
|
|
92292
|
-
const oid =
|
|
92391
|
+
const oid = orderStatusOid(item.orderRef);
|
|
92293
92392
|
const response = await readOrNull(() => fetchBrowserHyperliquidInfoPayload(
|
|
92294
92393
|
input,
|
|
92295
92394
|
{ type: "orderStatus", user: wallet, oid },
|
|
@@ -92408,7 +92507,7 @@ var init_protective_evidence = __esm({
|
|
|
92408
92507
|
readClientProtectiveOpenOrdersEvidence = async (context, dexes) => {
|
|
92409
92508
|
const wallet = String(context.walletAddress ?? "").trim();
|
|
92410
92509
|
if (!wallet) throw new Error("Missing Hyperliquid wallet address for open-orders evidence.");
|
|
92411
|
-
const input =
|
|
92510
|
+
const input = evidenceReadInput(context);
|
|
92412
92511
|
return Promise.all([...new Set(dexes.map((dex) => String(dex ?? "").trim()))].map(async (dex) => {
|
|
92413
92512
|
const startedAtMonotonicMs = monotonicNowMs();
|
|
92414
92513
|
const observedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -93126,6 +93225,189 @@ var init_execution_guard_contract = __esm({
|
|
|
93126
93225
|
}
|
|
93127
93226
|
});
|
|
93128
93227
|
|
|
93228
|
+
// lib/runtime/copy-trading-evidence.ts
|
|
93229
|
+
var ACCOUNT_MODE_CACHE_MS, dexList, normalizeRequest, openOrderRefs, EvidenceReadFailed, readClientCopyTradingAccountEvidence, accountEvidenceForUpload, readCopyOrderStatusEvidence, orderStatusEvidenceForAck;
|
|
93230
|
+
var init_copy_trading_evidence = __esm({
|
|
93231
|
+
"lib/runtime/copy-trading-evidence.ts"() {
|
|
93232
|
+
"use strict";
|
|
93233
|
+
init_define_VTX_EXO_POLICY();
|
|
93234
|
+
init_define_VTX_GROK_POLICY();
|
|
93235
|
+
init_define_VTX_PI_MODEL_POLICY();
|
|
93236
|
+
init_runtime_policy_generated2();
|
|
93237
|
+
init_hyperliquid_account_mode_contract();
|
|
93238
|
+
init_hyperliquid_client();
|
|
93239
|
+
init_monotonic_clock();
|
|
93240
|
+
init_protective_evidence();
|
|
93241
|
+
ACCOUNT_MODE_CACHE_MS = runtime_policy_generated_default2.exchange.hyperliquid.client_public_read_budget.account_mode_ttl_seconds * 1e3;
|
|
93242
|
+
dexList = (value) => {
|
|
93243
|
+
if (!Array.isArray(value) || value.some((dex) => typeof dex !== "string")) return null;
|
|
93244
|
+
return [...new Set(value.map((dex) => dex.trim()))];
|
|
93245
|
+
};
|
|
93246
|
+
normalizeRequest = (request) => {
|
|
93247
|
+
if (!request || typeof request !== "object") return null;
|
|
93248
|
+
const requestId = typeof request.request_id === "string" ? request.request_id.trim() : "";
|
|
93249
|
+
const walletAddress = typeof request.wallet_address === "string" ? request.wallet_address.trim() : "";
|
|
93250
|
+
const dexes = dexList(request.dexes);
|
|
93251
|
+
const openOrdersDexes = dexList(request.open_orders_dexes);
|
|
93252
|
+
const maxAgeSeconds = Number(request.max_age_seconds);
|
|
93253
|
+
if (!requestId || !walletAddress || !dexes || !openOrdersDexes || !Array.isArray(request.order_refs) || !Number.isFinite(maxAgeSeconds) || maxAgeSeconds <= 0) return null;
|
|
93254
|
+
const orderRefs = /* @__PURE__ */ new Map();
|
|
93255
|
+
for (const entry of request.order_refs) {
|
|
93256
|
+
const orderRef = typeof entry?.order_ref === "string" ? entry.order_ref.trim() : "";
|
|
93257
|
+
const dex = typeof entry?.dex === "string" ? entry.dex.trim() : null;
|
|
93258
|
+
if (dex == null || !isEvidenceOrderRef(orderRef)) return null;
|
|
93259
|
+
orderRefs.set(`${dex}|${orderRef.toLowerCase()}`, { orderRef, dex });
|
|
93260
|
+
}
|
|
93261
|
+
return {
|
|
93262
|
+
requestId,
|
|
93263
|
+
walletAddress,
|
|
93264
|
+
dexes,
|
|
93265
|
+
accountMode: request.account_mode === true,
|
|
93266
|
+
openOrdersDexes,
|
|
93267
|
+
orderRefs: [...orderRefs.values()],
|
|
93268
|
+
maxAgeMs: maxAgeSeconds * 1e3
|
|
93269
|
+
};
|
|
93270
|
+
};
|
|
93271
|
+
openOrderRefs = (response) => {
|
|
93272
|
+
if (!Array.isArray(response)) return null;
|
|
93273
|
+
const refs = /* @__PURE__ */ new Set();
|
|
93274
|
+
for (const order of response) {
|
|
93275
|
+
if (!order || typeof order !== "object") continue;
|
|
93276
|
+
const { oid, cloid } = order;
|
|
93277
|
+
if (oid != null && oid !== "") refs.add(String(oid).trim().toLowerCase());
|
|
93278
|
+
if (typeof cloid === "string" && cloid.trim()) refs.add(cloid.trim().toLowerCase());
|
|
93279
|
+
}
|
|
93280
|
+
return refs;
|
|
93281
|
+
};
|
|
93282
|
+
EvidenceReadFailed = class extends Error {
|
|
93283
|
+
};
|
|
93284
|
+
readClientCopyTradingAccountEvidence = async (context) => {
|
|
93285
|
+
const request = normalizeRequest(context.request);
|
|
93286
|
+
if (!request) return { ok: false, reason: "invalid_request" };
|
|
93287
|
+
const trustedWallet = String(context.trustedWalletAddress ?? "").trim();
|
|
93288
|
+
if (!trustedWallet || trustedWallet.toLowerCase() !== request.walletAddress.toLowerCase()) {
|
|
93289
|
+
return { ok: false, reason: "wallet_mismatch" };
|
|
93290
|
+
}
|
|
93291
|
+
if (context.signal?.aborted) return { ok: false, reason: "aborted" };
|
|
93292
|
+
const controller = new AbortController();
|
|
93293
|
+
const parentSignal = context.signal;
|
|
93294
|
+
const cancelReads = () => controller.abort(parentSignal?.reason);
|
|
93295
|
+
parentSignal?.addEventListener("abort", cancelReads, { once: true });
|
|
93296
|
+
const input = evidenceReadInput({ ...context, signal: controller.signal });
|
|
93297
|
+
const user = trustedWallet;
|
|
93298
|
+
let startedAtMonotonicMs = monotonicNowMs();
|
|
93299
|
+
const read = async (body, label2) => {
|
|
93300
|
+
try {
|
|
93301
|
+
const response = await fetchBrowserHyperliquidInfoPayload(input, body, label2);
|
|
93302
|
+
if (response == null) throw new EvidenceReadFailed(label2);
|
|
93303
|
+
return response;
|
|
93304
|
+
} catch (error48) {
|
|
93305
|
+
controller.abort();
|
|
93306
|
+
throw error48;
|
|
93307
|
+
}
|
|
93308
|
+
};
|
|
93309
|
+
const cacheAccountMode = ACCOUNT_MODE_CACHE_MS * 2 <= request.maxAgeMs;
|
|
93310
|
+
const readAccountMode = async (body, label2) => {
|
|
93311
|
+
const calledAtWallMs = Date.now();
|
|
93312
|
+
const calledAtMonotonicMs = monotonicNowMs();
|
|
93313
|
+
try {
|
|
93314
|
+
const { payload, fetchedAtMs } = await fetchBrowserHyperliquidInfoRead({ ...input, cacheAccountMode }, body, label2);
|
|
93315
|
+
if (Number.isFinite(fetchedAtMs) && fetchedAtMs < calledAtWallMs) {
|
|
93316
|
+
startedAtMonotonicMs = Math.min(startedAtMonotonicMs, calledAtMonotonicMs - (calledAtWallMs - fetchedAtMs));
|
|
93317
|
+
}
|
|
93318
|
+
return payload;
|
|
93319
|
+
} catch (error48) {
|
|
93320
|
+
controller.abort();
|
|
93321
|
+
throw error48;
|
|
93322
|
+
}
|
|
93323
|
+
};
|
|
93324
|
+
try {
|
|
93325
|
+
const clearinghouseStates = Promise.all(request.dexes.map(async (dex) => ({
|
|
93326
|
+
dex,
|
|
93327
|
+
response: await read({ type: "clearinghouseState", user, ...dexBody(dex) }, "hyperliquid.clearinghouseState")
|
|
93328
|
+
})));
|
|
93329
|
+
const accountMode = request.accountMode ? (async () => {
|
|
93330
|
+
const userAbstraction = await readAccountMode({ type: "userAbstraction", user }, "hyperliquid.userAbstraction");
|
|
93331
|
+
const mode2 = extractCanonicalHyperliquidAccountMode(userAbstraction);
|
|
93332
|
+
if (!mode2) throw new EvidenceReadFailed("hyperliquid.userAbstraction");
|
|
93333
|
+
const userDexAbstraction = mode2 === "default" || mode2 === "disabled" ? await readAccountMode({ type: "userDexAbstraction", user }, "hyperliquid.userDexAbstraction") : null;
|
|
93334
|
+
return { userAbstraction, userDexAbstraction };
|
|
93335
|
+
})() : Promise.resolve({ userAbstraction: null, userDexAbstraction: null });
|
|
93336
|
+
const openOrders = Promise.all(request.openOrdersDexes.map(async (dex) => {
|
|
93337
|
+
const response = await read({ type: "frontendOpenOrders", user, ...dexBody(dex) }, "hyperliquid.frontendOpenOrders");
|
|
93338
|
+
const refs = openOrderRefs(response);
|
|
93339
|
+
if (!refs) throw new EvidenceReadFailed("hyperliquid.frontendOpenOrders");
|
|
93340
|
+
return { dex, response, refs };
|
|
93341
|
+
}));
|
|
93342
|
+
const orderStatuses = openOrders.then((orders2) => {
|
|
93343
|
+
const openByDex = new Map(orders2.map((order) => [order.dex, order.refs]));
|
|
93344
|
+
return Promise.all(request.orderRefs.filter(({ orderRef, dex }) => !openByDex.get(dex)?.has(orderRef.toLowerCase())).map(async ({ orderRef, dex }) => ({
|
|
93345
|
+
order_ref: orderRef,
|
|
93346
|
+
dex,
|
|
93347
|
+
response: await read(
|
|
93348
|
+
{ type: "orderStatus", user, oid: orderStatusOid(orderRef) },
|
|
93349
|
+
"hyperliquid.orderStatus"
|
|
93350
|
+
)
|
|
93351
|
+
})));
|
|
93352
|
+
});
|
|
93353
|
+
const [states, mode, orders, statuses] = await Promise.all([
|
|
93354
|
+
clearinghouseStates,
|
|
93355
|
+
accountMode,
|
|
93356
|
+
openOrders,
|
|
93357
|
+
orderStatuses
|
|
93358
|
+
]);
|
|
93359
|
+
if (parentSignal?.aborted) return { ok: false, reason: "aborted" };
|
|
93360
|
+
if (monotonicAgeMs(startedAtMonotonicMs) > request.maxAgeMs) return { ok: false, reason: "stale" };
|
|
93361
|
+
return {
|
|
93362
|
+
ok: true,
|
|
93363
|
+
read: {
|
|
93364
|
+
evidence: {
|
|
93365
|
+
request_id: request.requestId,
|
|
93366
|
+
wallet_address: request.walletAddress,
|
|
93367
|
+
source: "live",
|
|
93368
|
+
clearinghouse_states: states,
|
|
93369
|
+
user_abstraction: mode.userAbstraction,
|
|
93370
|
+
user_dex_abstraction: mode.userDexAbstraction,
|
|
93371
|
+
open_orders: orders.map(({ dex, response }) => ({ dex, response })),
|
|
93372
|
+
order_statuses: statuses
|
|
93373
|
+
},
|
|
93374
|
+
startedAtMonotonicMs
|
|
93375
|
+
}
|
|
93376
|
+
};
|
|
93377
|
+
} catch {
|
|
93378
|
+
return { ok: false, reason: parentSignal?.aborted ? "aborted" : "read_failed" };
|
|
93379
|
+
} finally {
|
|
93380
|
+
parentSignal?.removeEventListener("abort", cancelReads);
|
|
93381
|
+
}
|
|
93382
|
+
};
|
|
93383
|
+
accountEvidenceForUpload = (read) => ({
|
|
93384
|
+
...read.evidence,
|
|
93385
|
+
observed_age_ms: monotonicAgeMs(read.startedAtMonotonicMs)
|
|
93386
|
+
});
|
|
93387
|
+
readCopyOrderStatusEvidence = async (context, orderId) => {
|
|
93388
|
+
const user = String(context.walletAddress ?? "").trim();
|
|
93389
|
+
const orderRef = String(orderId).trim();
|
|
93390
|
+
if (!user || !isEvidenceOrderRef(orderRef) || context.signal?.aborted) return null;
|
|
93391
|
+
const startedAtMonotonicMs = monotonicNowMs();
|
|
93392
|
+
try {
|
|
93393
|
+
const response = await fetchBrowserHyperliquidInfoPayload(
|
|
93394
|
+
evidenceReadInput(context),
|
|
93395
|
+
{ type: "orderStatus", user, oid: orderStatusOid(orderRef) },
|
|
93396
|
+
"hyperliquid.orderStatus"
|
|
93397
|
+
);
|
|
93398
|
+
return response == null ? null : { order_ref: orderRef, response, startedAtMonotonicMs };
|
|
93399
|
+
} catch {
|
|
93400
|
+
return null;
|
|
93401
|
+
}
|
|
93402
|
+
};
|
|
93403
|
+
orderStatusEvidenceForAck = (read) => ({
|
|
93404
|
+
order_ref: read.order_ref,
|
|
93405
|
+
response: read.response,
|
|
93406
|
+
observed_age_ms: monotonicAgeMs(read.startedAtMonotonicMs)
|
|
93407
|
+
});
|
|
93408
|
+
}
|
|
93409
|
+
});
|
|
93410
|
+
|
|
93129
93411
|
// lib/runtime/protective-trigger-price.ts
|
|
93130
93412
|
var toPositiveNumber, resolveRiskPct, buildTriggerPrice, resolveTrailingStopTightening;
|
|
93131
93413
|
var init_protective_trigger_price = __esm({
|
|
@@ -93330,13 +93612,18 @@ function adjustCopiedTarget(target, longRemovedSince, shortRemovedSince) {
|
|
|
93330
93612
|
if (target < -1e-12) return Math.min(0, target + Math.max(0, shortRemovedSince));
|
|
93331
93613
|
return 0;
|
|
93332
93614
|
}
|
|
93615
|
+
function copiedTargetBesideOwnPosition(target, copied, actual) {
|
|
93616
|
+
const own = actual - copied;
|
|
93617
|
+
if (Math.abs(own) <= 1e-12 || Math.abs(target) <= 1e-12 || own * target > 0) return target;
|
|
93618
|
+
return Math.min(Math.max(target, Math.min(0, copied)), Math.max(0, copied));
|
|
93619
|
+
}
|
|
93333
93620
|
function removedByCap(copied, capped) {
|
|
93334
93621
|
if (copied > 0) return [Math.max(0, copied - Math.max(0, capped)), 0];
|
|
93335
93622
|
if (copied < 0) return [0, Math.max(0, Math.min(0, capped) - copied)];
|
|
93336
93623
|
return [0, 0];
|
|
93337
93624
|
}
|
|
93338
|
-
function
|
|
93339
|
-
if (!reconciliation || reconciliation.target_space !== "copied") return
|
|
93625
|
+
function copiedTargetNow(reconciliation, recordedTarget, actualPosition) {
|
|
93626
|
+
if (!reconciliation || reconciliation.target_space !== "copied") return null;
|
|
93340
93627
|
const copiedServer = Number(reconciliation.copied_now ?? 0) || 0;
|
|
93341
93628
|
const copiedNow = capCopiedToActual(copiedServer, actualPosition);
|
|
93342
93629
|
const [deviceLongRemoved, deviceShortRemoved] = removedByCap(copiedServer, copiedNow);
|
|
@@ -93347,9 +93634,9 @@ function positionSpaceCopyTarget(reconciliation, recordedTarget, actualPosition)
|
|
|
93347
93634
|
longRemovedNow - (Number(reconciliation.external_long_removed_before ?? 0) || 0),
|
|
93348
93635
|
shortRemovedNow - (Number(reconciliation.external_short_removed_before ?? 0) || 0)
|
|
93349
93636
|
);
|
|
93350
|
-
return
|
|
93637
|
+
return { copiedNow, targetNow, kept: copiedTargetBesideOwnPosition(targetNow, copiedNow, actualPosition) };
|
|
93351
93638
|
}
|
|
93352
|
-
var clientProtectiveMutationAuthority, executionReadPriority, serverEntryLeverageAlreadyHeld, fetchClientRuntimeOpenOrders, _extractOrderResponseStates, createRuntimeId, _extractFilledSize, _extractOrderId, _toExecutionMetadata, _extractClientMutationId, _stableMutationIdentity, trailingStopMemory, protectiveGroupMemory, protectiveGroupReadFailures, windowHandoffCleanupAttempts, clientRuntimeProtectionStorage, resolveClientRuntimeProtectionStorage, setClientRuntimeProtectionStorage, trailingStopStorageKey, readTrackedTrailingStops, writeTrackedTrailingStops, rememberTrailingStop, protectiveGroupStorageKey, withClientProtectivePlanSetLock, readClientProtectiveGroups, writeClientProtectiveGroups, hasClientProtectiveGroupReadFailure, readFreshClientProtectiveGroups, stableProtectionSnapshot, exactClientProtectiveGroupSnapshot, exactClientProtectiveGroupSetSnapshot, storableClientProtectiveGroup, replaceExactClientProtectiveGroup, replaceExactClientProtectiveGroupSet, isClientRuntimeLeaseOwnershipError, hasClientRuntimeProtectionState, clearClientRuntimeVetoedProtectiveIntent, rethrowWindowHandoffAfterProtectiveReplacementVeto, canPersistClientProtectiveGroups, removeTrackedTrailingStop, replaceTrackedTrailingStop, replaceProtectiveLeg, replacementJournalEntryOrderId, buildProtectiveReplacementJournalGroup, isProtectiveReplacementJournalGroup, reserveProtectiveLegReplacement, ensureProtectiveReplacementJournalCompanion, buildVetoedProtectiveReplacementCleanup, assertExactProtectiveReplacementDispatchAuthority, transitionProtectiveReplacementAcknowledgement, transitionTerminalProtectiveReplacement, pendingProtectiveReplacementReport, isConfiguredProtectionRequested, protectiveAction, isExactClientPositionTpslPair, deviceOwnsClientProtectiveLegKind, isAdoptionNarrowedPositionTpslLeg, hasAmbiguousClientPositionTpslAuthority, protectiveStableShapeMatches, observedProtectiveGroupingMatches, protectiveLiveShapeMatches, protectiveTerminalShapeMatches, cancelClientProtectiveLeg, buildPendingProtectivePlan, persistPendingClientProtectiveGroup, storedClientProtectiveCover, attachClientProtectivePlan, resolveJournaledAttachmentContinuity, protectiveMemberRested, recoverJournaledClientProtectiveAttachments, readPendingEntryMutation, requireClientRuntimeConfigSeconds, replacePendingEntryRecovery, recoverPendingClientProtectiveGroups, recoverPendingProtectiveReplacements, liveProtectiveOrderShape, observedStandaloneProtectiveGroup, migrateTrackedTrailingStopsToStandalone, reconcileClientProtectiveGroups, cancelAllClientProtectiveGroups, tightenClientTrailingStops, throwIfAborted2, sleep2, isDefinitiveEntryRejection, resolveExchangeSizeDecimals, roundAssetSize, resolvePositionSize, resolveCurrentPositionSize, buildPositionSnapshot, signedRemainingExposureAfterConfirmedReduction, runtimeProtectionAuthority, runtimeProtectionOwners, resolveRuntimeProtectionOwner, drainServerProtectionForRuntime, drainServerProtectionIfOwned, verifyNoLiveClientProtectiveTriggers, clientExecutionMutations, CLIENT_EXECUTION_QUEUE_TIMEOUT_MESSAGE, withClientExecutionMutation, withClientProtectivePlanSetMutation, allocateServerExecutionCapacity, withClientProtectiveAdoptionMutation, executeClientRuntimeDecisionLocked, SERVER_AUDIT_RECORDED_ELSEWHERE, serverExecutionAuditOutcome, executeClientRuntimeDecision, waitForFlipCloseFreshness, maintainClientRuntimeTrailingStops, listPendingClientProtectiveSymbols, listStoredClientProtectiveSymbols, hasUnresolvedClientProtectiveIdentity, resolveClientProtectiveIdentitiesForAdoption, exportClientProtectiveGroupsForAdoption, adoptionGroupKey, applyClientProtectiveAdoptionOutcomes, hasStoredClientProtectiveGroupsForWallet, hasPendingClientProtectiveGroups, recoverManualClientProtectiveGroups, clientRuntimeDecisionSizesOrders, executeClientRuntimeDecisionUnlocked, executeClientCopyTradingIntent, executeClientCopyTradingOrderAction;
|
|
93639
|
+
var clientProtectiveMutationAuthority, executionReadPriority, serverEntryLeverageAlreadyHeld, fetchClientRuntimeOpenOrders, _extractOrderResponseStates, createRuntimeId, _extractFilledSize, _extractOrderId, _toExecutionMetadata, _extractClientMutationId, _stableMutationIdentity, trailingStopMemory, protectiveGroupMemory, protectiveGroupReadFailures, windowHandoffCleanupAttempts, clientRuntimeProtectionStorage, resolveClientRuntimeProtectionStorage, setClientRuntimeProtectionStorage, trailingStopStorageKey, readTrackedTrailingStops, writeTrackedTrailingStops, rememberTrailingStop, protectiveGroupStorageKey, withClientProtectivePlanSetLock, readClientProtectiveGroups, writeClientProtectiveGroups, hasClientProtectiveGroupReadFailure, readFreshClientProtectiveGroups, stableProtectionSnapshot, exactClientProtectiveGroupSnapshot, exactClientProtectiveGroupSetSnapshot, storableClientProtectiveGroup, replaceExactClientProtectiveGroup, replaceExactClientProtectiveGroupSet, isClientRuntimeLeaseOwnershipError, hasClientRuntimeProtectionState, clearClientRuntimeVetoedProtectiveIntent, rethrowWindowHandoffAfterProtectiveReplacementVeto, canPersistClientProtectiveGroups, removeTrackedTrailingStop, replaceTrackedTrailingStop, replaceProtectiveLeg, replacementJournalEntryOrderId, buildProtectiveReplacementJournalGroup, isProtectiveReplacementJournalGroup, reserveProtectiveLegReplacement, ensureProtectiveReplacementJournalCompanion, buildVetoedProtectiveReplacementCleanup, assertExactProtectiveReplacementDispatchAuthority, transitionProtectiveReplacementAcknowledgement, transitionTerminalProtectiveReplacement, pendingProtectiveReplacementReport, isConfiguredProtectionRequested, protectiveAction, isExactClientPositionTpslPair, deviceOwnsClientProtectiveLegKind, isAdoptionNarrowedPositionTpslLeg, hasAmbiguousClientPositionTpslAuthority, protectiveStableShapeMatches, observedProtectiveGroupingMatches, protectiveLiveShapeMatches, protectiveTerminalShapeMatches, cancelClientProtectiveLeg, buildPendingProtectivePlan, persistPendingClientProtectiveGroup, storedClientProtectiveCover, attachClientProtectivePlan, resolveJournaledAttachmentContinuity, protectiveMemberRested, recoverJournaledClientProtectiveAttachments, readPendingEntryMutation, requireClientRuntimeConfigSeconds, replacePendingEntryRecovery, recoverPendingClientProtectiveGroups, recoverPendingProtectiveReplacements, liveProtectiveOrderShape, observedStandaloneProtectiveGroup, migrateTrackedTrailingStopsToStandalone, reconcileClientProtectiveGroups, cancelAllClientProtectiveGroups, tightenClientTrailingStops, throwIfAborted2, sleep2, isDefinitiveEntryRejection, resolveExchangeSizeDecimals, roundAssetSize, resolvePositionSize, resolveCurrentPositionSize, buildPositionSnapshot, signedRemainingExposureAfterConfirmedReduction, runtimeProtectionAuthority, runtimeProtectionOwners, resolveRuntimeProtectionOwner, drainServerProtectionForRuntime, drainServerProtectionIfOwned, verifyNoLiveClientProtectiveTriggers, clientExecutionMutations, CLIENT_EXECUTION_QUEUE_TIMEOUT_MESSAGE, withClientExecutionMutation, withClientProtectivePlanSetMutation, allocateServerExecutionCapacity, withClientProtectiveAdoptionMutation, executeClientRuntimeDecisionLocked, SERVER_AUDIT_RECORDED_ELSEWHERE, serverExecutionAuditOutcome, executeClientRuntimeDecision, waitForFlipCloseFreshness, maintainClientRuntimeTrailingStops, listPendingClientProtectiveSymbols, listStoredClientProtectiveSymbols, hasUnresolvedClientProtectiveIdentity, resolveClientProtectiveIdentitiesForAdoption, exportClientProtectiveGroupsForAdoption, adoptionGroupKey, applyClientProtectiveAdoptionOutcomes, hasStoredClientProtectiveGroupsForWallet, hasPendingClientProtectiveGroups, recoverManualClientProtectiveGroups, clientRuntimeDecisionSizesOrders, executeClientRuntimeDecisionUnlocked, executeClientCopyTradingIntent, _copyCancelOrderId, executeClientCopyTradingOrderAction;
|
|
93353
93640
|
var init_runtime_execution = __esm({
|
|
93354
93641
|
"lib/runtime/runtime-execution.ts"() {
|
|
93355
93642
|
"use strict";
|
|
@@ -93370,6 +93657,7 @@ var init_runtime_execution = __esm({
|
|
|
93370
93657
|
init_hyperliquid_client();
|
|
93371
93658
|
init_hyperliquid_market_symbol();
|
|
93372
93659
|
init_network_debug();
|
|
93660
|
+
init_copy_trading_evidence();
|
|
93373
93661
|
init_protective_trigger_price();
|
|
93374
93662
|
init_runtime_redaction();
|
|
93375
93663
|
init_protective_stop_replacement();
|
|
@@ -100348,6 +100636,7 @@ var init_runtime_execution = __esm({
|
|
|
100348
100636
|
let minOrderNotional = 0;
|
|
100349
100637
|
let executionReferencePrice = Number(intent.source_price);
|
|
100350
100638
|
let dispatchedOrder = null;
|
|
100639
|
+
let ownPositionHold = {};
|
|
100351
100640
|
if (reconciliation && typeof reconciliation === "object" && !Array.isArray(reconciliation)) {
|
|
100352
100641
|
const record5 = reconciliation;
|
|
100353
100642
|
const copiedNowServed = typeof record5.copied_now === "number" && Number.isFinite(record5.copied_now);
|
|
@@ -100375,7 +100664,11 @@ var init_runtime_execution = __esm({
|
|
|
100375
100664
|
size: destinationSize,
|
|
100376
100665
|
roundingMode: "nearest",
|
|
100377
100666
|
includePrivateContext: desiredPosition != null && Number.isFinite(desiredPosition),
|
|
100378
|
-
profileId: input.profileId
|
|
100667
|
+
profileId: input.profileId,
|
|
100668
|
+
// The device reads its own position and mark; the server never reads
|
|
100669
|
+
// a Client wallet.
|
|
100670
|
+
walletAddress: input.walletAddress,
|
|
100671
|
+
signal: input.signal
|
|
100379
100672
|
});
|
|
100380
100673
|
if (desiredPosition != null && Number.isFinite(desiredPosition)) {
|
|
100381
100674
|
const preparedContextMaxAgeMs = Number(
|
|
@@ -100397,26 +100690,35 @@ var init_runtime_execution = __esm({
|
|
|
100397
100690
|
if (!Number.isFinite(executionReferencePrice) || executionReferencePrice <= 0) {
|
|
100398
100691
|
throw new Error("Copy Trading private-node execution mark was unavailable.");
|
|
100399
100692
|
}
|
|
100400
|
-
|
|
100693
|
+
const copiedNow = copiedTargetNow(
|
|
100401
100694
|
reconciliation,
|
|
100402
100695
|
desiredPosition,
|
|
100403
100696
|
actualPosition
|
|
100404
100697
|
);
|
|
100698
|
+
if (copiedNow && Math.abs(copiedNow.targetNow - copiedNow.kept) > 1e-12) {
|
|
100699
|
+
ownPositionHold = {
|
|
100700
|
+
own_position_held_back_target: copiedNow.targetNow,
|
|
100701
|
+
own_position_kept_target: copiedNow.kept
|
|
100702
|
+
};
|
|
100703
|
+
}
|
|
100704
|
+
desiredPosition = copiedNow ? actualPosition + (copiedNow.kept - copiedNow.copiedNow) : desiredPosition;
|
|
100405
100705
|
const liveDelta = desiredPosition - actualPosition;
|
|
100406
100706
|
const tolerance = Math.max(1e-12, Math.abs(desiredPosition) * 1e-9);
|
|
100407
100707
|
if (Math.abs(liveDelta) <= tolerance) {
|
|
100708
|
+
const heldBack = Object.keys(ownPositionHold).length > 0;
|
|
100408
100709
|
return {
|
|
100409
100710
|
status: "executed",
|
|
100410
100711
|
orderId: null,
|
|
100411
|
-
message: "Copy Trading destination position is already at target.",
|
|
100412
|
-
skipReason: "already_at_target",
|
|
100712
|
+
message: heldBack ? "Copy Trading skipped a copy against your own opposite position." : "Copy Trading destination position is already at target.",
|
|
100713
|
+
skipReason: heldBack ? "own_position_opposite_side" : "already_at_target",
|
|
100413
100714
|
destinationSize: 0,
|
|
100414
100715
|
destinationNotional: 0,
|
|
100415
100716
|
executionMetadata: {
|
|
100416
100717
|
execution_reference_price: executionReferencePrice,
|
|
100417
100718
|
desired_destination_position_after: desiredPosition,
|
|
100418
100719
|
actual_destination_position: actualPosition,
|
|
100419
|
-
no_order_required: true
|
|
100720
|
+
no_order_required: true,
|
|
100721
|
+
...ownPositionHold
|
|
100420
100722
|
}
|
|
100421
100723
|
};
|
|
100422
100724
|
}
|
|
@@ -100477,7 +100779,8 @@ var init_runtime_execution = __esm({
|
|
|
100477
100779
|
quantized_size: 0,
|
|
100478
100780
|
sz_decimals: sizePrecision.sizeDecimals,
|
|
100479
100781
|
rounding_mode: sizePrecision.roundingMode,
|
|
100480
|
-
execution_reference_price: referencePrice
|
|
100782
|
+
execution_reference_price: referencePrice,
|
|
100783
|
+
...ownPositionHold
|
|
100481
100784
|
}
|
|
100482
100785
|
};
|
|
100483
100786
|
}
|
|
@@ -100499,7 +100802,8 @@ var init_runtime_execution = __esm({
|
|
|
100499
100802
|
rounding_mode: sizePrecision.roundingMode,
|
|
100500
100803
|
execution_reference_price: referencePrice,
|
|
100501
100804
|
minimum_usdc: minOrderNotional,
|
|
100502
|
-
order_deferred: true
|
|
100805
|
+
order_deferred: true,
|
|
100806
|
+
...ownPositionHold
|
|
100503
100807
|
}
|
|
100504
100808
|
};
|
|
100505
100809
|
}
|
|
@@ -100511,6 +100815,7 @@ var init_runtime_execution = __esm({
|
|
|
100511
100815
|
intent.sanitized_metadata?.client_order_id
|
|
100512
100816
|
);
|
|
100513
100817
|
dispatchedOrder = {
|
|
100818
|
+
...ownPositionHold,
|
|
100514
100819
|
quantized_size: destinationSize,
|
|
100515
100820
|
...desiredPosition != null && Number.isFinite(desiredPosition) && actualPosition != null && Number.isFinite(actualPosition) ? {
|
|
100516
100821
|
desired_destination_position_after: desiredPosition,
|
|
@@ -100564,6 +100869,7 @@ var init_runtime_execution = __esm({
|
|
|
100564
100869
|
// The server records the executed change in the copied-position
|
|
100565
100870
|
// ledger from these values.
|
|
100566
100871
|
...filledSize != null ? { filled_size: filledSize } : {},
|
|
100872
|
+
...ownPositionHold,
|
|
100567
100873
|
...desiredPosition != null && Number.isFinite(desiredPosition) && actualPosition != null && Number.isFinite(actualPosition) ? {
|
|
100568
100874
|
desired_destination_position_after: desiredPosition,
|
|
100569
100875
|
actual_destination_position: actualPosition
|
|
@@ -100584,6 +100890,13 @@ var init_runtime_execution = __esm({
|
|
|
100584
100890
|
};
|
|
100585
100891
|
}
|
|
100586
100892
|
};
|
|
100893
|
+
_copyCancelOrderId = (action) => {
|
|
100894
|
+
const destinationOrderId = action.previous_destination_order_id ?? action.destination_order_id;
|
|
100895
|
+
const numericOrderId = Number(destinationOrderId);
|
|
100896
|
+
if (Number.isSafeInteger(numericOrderId) && numericOrderId > 0) return numericOrderId;
|
|
100897
|
+
const cloid = String(destinationOrderId || "").trim().toLowerCase();
|
|
100898
|
+
return /^0x[0-9a-f]{32}$/.test(cloid) ? cloid : null;
|
|
100899
|
+
};
|
|
100587
100900
|
executeClientCopyTradingOrderAction = async (input) => {
|
|
100588
100901
|
throwIfAborted2(input.signal);
|
|
100589
100902
|
const action = input.action;
|
|
@@ -100614,12 +100927,18 @@ var init_runtime_execution = __esm({
|
|
|
100614
100927
|
signal: input.signal,
|
|
100615
100928
|
onExchangeOrderDispatched: () => input.onExchangeOrderDispatched?.("action")
|
|
100616
100929
|
};
|
|
100930
|
+
const cancelledOrderStatusEvidence = async (orderId) => {
|
|
100931
|
+
if (orderId == null) return {};
|
|
100932
|
+
const evidence = await readCopyOrderStatusEvidence(
|
|
100933
|
+
{ config: input.config ?? null, signal: input.signal, walletAddress: input.walletAddress },
|
|
100934
|
+
orderId
|
|
100935
|
+
);
|
|
100936
|
+
return evidence ? { orderStatusEvidence: evidence } : {};
|
|
100937
|
+
};
|
|
100617
100938
|
try {
|
|
100618
100939
|
if (action.action_type === "cancel") {
|
|
100619
|
-
const
|
|
100620
|
-
|
|
100621
|
-
const orderId = Number.isSafeInteger(numericOrderId) && numericOrderId > 0 ? numericOrderId : String(destinationOrderId2 || "").trim().toLowerCase();
|
|
100622
|
-
if (typeof orderId === "number" && orderId <= 0 || typeof orderId === "string" && !/^0x[0-9a-f]{32}$/.test(orderId)) {
|
|
100940
|
+
const orderId = _copyCancelOrderId(action);
|
|
100941
|
+
if (orderId == null) {
|
|
100623
100942
|
throw new Error("Copy Trading cancel action is missing a valid destination order id.");
|
|
100624
100943
|
}
|
|
100625
100944
|
await executeClientCancelOrder({
|
|
@@ -100631,7 +100950,8 @@ var init_runtime_execution = __esm({
|
|
|
100631
100950
|
destinationOrderId: String(orderId),
|
|
100632
100951
|
destinationOrderState: null,
|
|
100633
100952
|
orderMemberResults: null,
|
|
100634
|
-
message: "Copy Trading order cancellation executed."
|
|
100953
|
+
message: "Copy Trading order cancellation executed.",
|
|
100954
|
+
...await cancelledOrderStatusEvidence(orderId)
|
|
100635
100955
|
};
|
|
100636
100956
|
}
|
|
100637
100957
|
const size = Number(action.destination_size);
|
|
@@ -100725,7 +101045,8 @@ var init_runtime_execution = __esm({
|
|
|
100725
101045
|
destinationOrderId: action.previous_destination_order_id ?? action.destination_order_id ?? null,
|
|
100726
101046
|
destinationOrderState: null,
|
|
100727
101047
|
orderMemberResults: null,
|
|
100728
|
-
message: "Copy Trading order was already terminal."
|
|
101048
|
+
message: "Copy Trading order was already terminal.",
|
|
101049
|
+
...await cancelledOrderStatusEvidence(_copyCancelOrderId(action))
|
|
100729
101050
|
};
|
|
100730
101051
|
}
|
|
100731
101052
|
return {
|
|
@@ -112863,8 +113184,11 @@ ${reviewOutputContract}`;
|
|
|
112863
113184
|
startPosition: fill.start_position
|
|
112864
113185
|
}))
|
|
112865
113186
|
);
|
|
112866
|
-
const perSymbolCap =
|
|
112867
|
-
|
|
113187
|
+
const perSymbolCap = Number(input.maxFillsPerSymbol);
|
|
113188
|
+
if (!Number.isInteger(perSymbolCap) || perSymbolCap < 1) {
|
|
113189
|
+
throw new Error("Missing required behavior memory max_fills_per_symbol configuration.");
|
|
113190
|
+
}
|
|
113191
|
+
const totalCap = perSymbolCap * Math.max(selectedSymbols.size, 1);
|
|
112868
113192
|
const behaviorMemoryEnabled = input.behaviorMemoryEnabled ?? false;
|
|
112869
113193
|
const rawPerSymbolCounts = /* @__PURE__ */ new Map();
|
|
112870
113194
|
for (const fill of fillsDescending) {
|
|
@@ -114722,6 +115046,7 @@ ${behaviorJson}
|
|
|
114722
115046
|
behaviorInstructions: promptBehaviorInstructions,
|
|
114723
115047
|
lastTrades: asRecord(derivedContext.behavior_last_trades),
|
|
114724
115048
|
behaviorMemoryEnabled,
|
|
115049
|
+
maxFillsPerSymbol: config2.behavior_memory_max_fills_per_symbol,
|
|
114725
115050
|
decisionMemory: asRecord(derivedContext.behavior_decision_memory),
|
|
114726
115051
|
cycleCutoffMs: behaviorMemoryCutoffMs,
|
|
114727
115052
|
fillHistoryCoverage: behaviorFillCoverage
|
|
@@ -116097,7 +116422,7 @@ ${reviewOutputContract}`;
|
|
|
116097
116422
|
});
|
|
116098
116423
|
|
|
116099
116424
|
// lib/runtime/engine.ts
|
|
116100
|
-
var localAnalysis, getExchangeFailureDiagnostics, getRuntimeFallbackAttempts, sentInvocationAttemptCount, boundRuntimeFallbackAttempts, isProviderFailureDiagnosticsCandidate, getEventBoundProviderLabel, getEventBoundProviderTraceId, getRecentProviderFailureDiagnostics, getClientRuntimeErrorProvenance, getRuntimeProviderSetupDiagnostics, buildProviderSetupErrorDiagnosticFields, buildClientRuntimeErrorProvenanceDiagnosticFields, buildRuntimeRequestErrorDiagnosticFields, getCycleErrorModelCalls, isReturnedModelCall, hasEventBoundProviderFailureEvidence, endsWithNeverSentAttempt, classifyRuntimeErrorStage, buildHyperliquidPublicReadDiagnosticFields, buildRuntimeErrorDiagnostics, positiveNumber, resolveRuntimeEngineOptions, withServerPositionEvents, CLIENT_KILLSWITCH_BLOCK_STORAGE_PREFIX, getClientKillswitchBlockStorageKey, persistClientRuntimeKillswitchBlock, clearClientRuntimeKillswitchBlock, hashRuntimeDebugText2, createRuntimeUuid2, getRuntimeContractIdentityToken, getRuntimeStatusContractIdentityToken, getRuntimeContractBindingTokenFromCycleResult, getRuntimeContractBindingTupleToken, getRuntimeStatusContractBindingTupleToken, isTransientRuntimeConflictError, createRuntimeStartCancelledError, isRuntimeContractMismatchError, isClientExecutionModeMismatchError, isClientRuntimeSessionStoppedError, isClientRuntimeLeaseAuthError, isClientRuntimeReleasedError, deriveFailedStartCleanupOwnershipLossReason, isRuntimeAbortError, isExplicitClientExecutionMode, createStopAbortError, isRuntimeContractIdentityAdvancedAbort, CLIENT_RUNTIME_NO_DECISION_RECOVERY_REASON, sanitizeSettingsSnapshotForFallback, preflightClientRuntime, ClientExecutionEngine, createStoppedRuntimeSnapshot, ClientRuntimeRegistry, botEngine;
|
|
116425
|
+
var localAnalysis, getExchangeFailureDiagnostics, getRuntimeFallbackAttempts, sentInvocationAttemptCount, boundRuntimeFallbackAttempts, isProviderFailureDiagnosticsCandidate, getEventBoundProviderLabel, getEventBoundProviderTraceId, getRecentProviderFailureDiagnostics, getClientRuntimeErrorProvenance, getRuntimeProviderSetupDiagnostics, buildProviderSetupErrorDiagnosticFields, buildClientRuntimeErrorProvenanceDiagnosticFields, buildRuntimeRequestErrorDiagnosticFields, getCycleErrorModelCalls, isReturnedModelCall, hasEventBoundProviderFailureEvidence, endsWithNeverSentAttempt, classifyRuntimeErrorStage, buildHyperliquidPublicReadDiagnosticFields, buildRuntimeErrorDiagnostics, positiveNumber, resolveRuntimeEngineOptions, withServerPositionEvents, CLIENT_KILLSWITCH_BLOCK_STORAGE_PREFIX, getClientKillswitchBlockStorageKey, isClientRuntimeKillswitchBlocked, persistClientRuntimeKillswitchBlock, clearClientRuntimeKillswitchBlock, hashRuntimeDebugText2, createRuntimeUuid2, getRuntimeContractIdentityToken, getRuntimeStatusContractIdentityToken, getRuntimeContractBindingTokenFromCycleResult, getRuntimeContractBindingTupleToken, getRuntimeStatusContractBindingTupleToken, isTransientRuntimeConflictError, createRuntimeStartCancelledError, isRuntimeContractMismatchError, isClientExecutionModeMismatchError, isClientRuntimeSessionStoppedError, isClientRuntimeLeaseAuthError, isClientRuntimeReleasedError, deriveFailedStartCleanupOwnershipLossReason, isRuntimeAbortError, isExplicitClientExecutionMode, createStopAbortError, isRuntimeContractIdentityAdvancedAbort, CLIENT_RUNTIME_NO_DECISION_RECOVERY_REASON, sanitizeSettingsSnapshotForFallback, preflightClientRuntime, ClientExecutionEngine, createStoppedRuntimeSnapshot, ClientRuntimeRegistry, botEngine;
|
|
116101
116426
|
var init_engine = __esm({
|
|
116102
116427
|
"lib/runtime/engine.ts"() {
|
|
116103
116428
|
"use strict";
|
|
@@ -116136,6 +116461,7 @@ var init_engine = __esm({
|
|
|
116136
116461
|
init_api2();
|
|
116137
116462
|
init_history_evidence();
|
|
116138
116463
|
init_portfolio_evidence();
|
|
116464
|
+
init_copy_trading_evidence();
|
|
116139
116465
|
getExchangeFailureDiagnostics = (error48) => {
|
|
116140
116466
|
if (error48 instanceof HyperliquidExchangeRejectionError) {
|
|
116141
116467
|
return {
|
|
@@ -116545,6 +116871,13 @@ var init_engine = __esm({
|
|
|
116545
116871
|
});
|
|
116546
116872
|
CLIENT_KILLSWITCH_BLOCK_STORAGE_PREFIX = "vtx_client_runtime_killswitch_block_v1:";
|
|
116547
116873
|
getClientKillswitchBlockStorageKey = (profileId) => `${CLIENT_KILLSWITCH_BLOCK_STORAGE_PREFIX}${profileId.trim()}`;
|
|
116874
|
+
isClientRuntimeKillswitchBlocked = (profileId) => {
|
|
116875
|
+
const storage3 = runtimeHostStorage();
|
|
116876
|
+
if (!storage3 || !profileId.trim()) {
|
|
116877
|
+
return false;
|
|
116878
|
+
}
|
|
116879
|
+
return storage3.getItem(getClientKillswitchBlockStorageKey(profileId)) !== null;
|
|
116880
|
+
};
|
|
116548
116881
|
persistClientRuntimeKillswitchBlock = (profileId) => {
|
|
116549
116882
|
const storage3 = runtimeHostStorage();
|
|
116550
116883
|
if (!storage3 || !profileId.trim()) {
|
|
@@ -120357,7 +120690,7 @@ var init_engine = __esm({
|
|
|
120357
120690
|
if (this._analysisRequestId === requestId) {
|
|
120358
120691
|
this._analysisRequestId = null;
|
|
120359
120692
|
this._analysisStartedAtMs = null;
|
|
120360
|
-
if (this.
|
|
120693
|
+
if (this._state === "running") void this.sendHeartbeat();
|
|
120361
120694
|
}
|
|
120362
120695
|
const silentEmptyAgentPoll = cycleOutcome === "skipped" && (cycleReason === "agent_instruction_poll_empty" || cycleReason === "ai_schedule_paused" || cycleReason === "ai_schedule_check") && !cycleStartEmitted;
|
|
120363
120696
|
if (this._state === "running" && this._sessionId === sessionId) {
|
|
@@ -120820,9 +121153,11 @@ var init_engine = __esm({
|
|
|
120820
121153
|
analysisRunId: heartbeatAnalysisRunId,
|
|
120821
121154
|
isAnalyzing: heartbeatIsAnalyzing,
|
|
120822
121155
|
isExecuting: heartbeatIsExecuting,
|
|
120823
|
-
// Beats may arrive out of order: the server keeps
|
|
120824
|
-
// analyzing observation
|
|
120825
|
-
|
|
121156
|
+
// Beats may arrive out of order: the server keeps the owner's newest
|
|
121157
|
+
// analyzing observation (a node bot's status; a Client runtime's
|
|
121158
|
+
// handback to its home device), so a cycle's end is never undone by
|
|
121159
|
+
// its start.
|
|
121160
|
+
analyzingObservedAtMs: heartbeatObservedAtMs
|
|
120826
121161
|
});
|
|
120827
121162
|
if (Number(response.protective_actions_pending ?? 0) > 0) {
|
|
120828
121163
|
notifyClientProtectiveActionsPending(heartbeatProfileId);
|
|
@@ -121366,22 +121701,66 @@ var init_engine = __esm({
|
|
|
121366
121701
|
try {
|
|
121367
121702
|
const persistedLease = getPersistedClientRuntimeServerLease(input.profileId);
|
|
121368
121703
|
const runtimeLeaseToken = persistedLease?.runtimeSessionId === input.runtimeSessionId && persistedLease.deviceId === input.runtimeDeviceId && persistedLease.mode === "trader" ? persistedLease.runtimeLeaseToken : null;
|
|
121369
|
-
const
|
|
121704
|
+
const pollOptions = {
|
|
121370
121705
|
runtimeLeaseToken: runtimeLeaseToken ?? void 0,
|
|
121371
121706
|
schedulerInstanceId: this._instanceId,
|
|
121372
121707
|
signal: input.signal
|
|
121373
|
-
}
|
|
121374
|
-
|
|
121375
|
-
|
|
121376
|
-
|
|
121377
|
-
|
|
121378
|
-
|
|
121379
|
-
|
|
121380
|
-
|
|
121381
|
-
|
|
121708
|
+
};
|
|
121709
|
+
const logPoll = (response) => {
|
|
121710
|
+
if (response.result.recorded_count > 0 || response.result.skipped_count > 0 || response.result.error_code) {
|
|
121711
|
+
appendRuntimeDebugEvent({
|
|
121712
|
+
label: "copy_trading_source_polled",
|
|
121713
|
+
note: `observed=${response.result.observed_count} recorded=${response.result.recorded_count} skipped=${response.result.skipped_count} status=${response.result.latest_status || "none"} reason=${response.result.latest_skip_reason || response.result.error_code || "none"}`,
|
|
121714
|
+
outcome: response.result.error_code ? "error" : "ok"
|
|
121715
|
+
});
|
|
121716
|
+
}
|
|
121717
|
+
};
|
|
121718
|
+
let trustedWalletRead = null;
|
|
121719
|
+
const readTrustedWallet = () => {
|
|
121720
|
+
trustedWalletRead ??= getFreshPreferences(
|
|
121721
|
+
void 0,
|
|
121722
|
+
Number(input.profileId),
|
|
121723
|
+
input.signal,
|
|
121724
|
+
false,
|
|
121725
|
+
{
|
|
121726
|
+
runtimeLeaseToken: runtimeLeaseToken ?? void 0,
|
|
121727
|
+
schedulerInstanceId: this._instanceId
|
|
121728
|
+
}
|
|
121729
|
+
).then((preferences) => String(
|
|
121730
|
+
preferences.preferences?.hyperliquid_wallet_address || ""
|
|
121731
|
+
).trim() || null);
|
|
121732
|
+
return trustedWalletRead;
|
|
121733
|
+
};
|
|
121734
|
+
let pollResponse = await pollCopyTradingRuntimeSource(Number(input.profileId), pollOptions);
|
|
121735
|
+
logPoll(pollResponse);
|
|
121382
121736
|
if (pollResponse.result.error_code === "self_copy_blocked") {
|
|
121383
121737
|
return;
|
|
121384
121738
|
}
|
|
121739
|
+
if (pollResponse.account_evidence_request) {
|
|
121740
|
+
if (this._windowHandoffRequested) {
|
|
121741
|
+
return;
|
|
121742
|
+
}
|
|
121743
|
+
const followUp = await this._sendClientCopyTradingAccountEvidence({
|
|
121744
|
+
profileId: input.profileId,
|
|
121745
|
+
request: pollResponse.account_evidence_request,
|
|
121746
|
+
// Unread preferences leave no trusted wallet: no evidence is read.
|
|
121747
|
+
trustedWalletAddress: await readTrustedWallet().catch((error48) => {
|
|
121748
|
+
if (input.signal.aborted) throw error48;
|
|
121749
|
+
return null;
|
|
121750
|
+
}),
|
|
121751
|
+
config: input.config,
|
|
121752
|
+
signal: input.signal,
|
|
121753
|
+
pollOptions
|
|
121754
|
+
});
|
|
121755
|
+
if (followUp) {
|
|
121756
|
+
pollResponse = followUp;
|
|
121757
|
+
logPoll(pollResponse);
|
|
121758
|
+
if (pollResponse.result.error_code === "self_copy_blocked") {
|
|
121759
|
+
return;
|
|
121760
|
+
}
|
|
121761
|
+
}
|
|
121762
|
+
}
|
|
121763
|
+
const copySourceUnavailable = pollResponse.result.error_code === "copy_trading_disabled" || pollResponse.result.error_code === "copy_trading_source_missing";
|
|
121385
121764
|
const copyOrderActions = copySourceUnavailable ? [] : await getPendingClientCopyTradingOrderActions(Number(input.profileId), {
|
|
121386
121765
|
runtimeLeaseToken: runtimeLeaseToken ?? void 0,
|
|
121387
121766
|
schedulerInstanceId: this._instanceId,
|
|
@@ -121397,19 +121776,7 @@ var init_engine = __esm({
|
|
|
121397
121776
|
) : pendingCopyIntents;
|
|
121398
121777
|
let expectedWalletAddress = null;
|
|
121399
121778
|
if (copyOrderActions.length > 0 || copyIntents.length > 0) {
|
|
121400
|
-
|
|
121401
|
-
void 0,
|
|
121402
|
-
Number(input.profileId),
|
|
121403
|
-
input.signal,
|
|
121404
|
-
false,
|
|
121405
|
-
{
|
|
121406
|
-
runtimeLeaseToken: runtimeLeaseToken ?? void 0,
|
|
121407
|
-
schedulerInstanceId: this._instanceId
|
|
121408
|
-
}
|
|
121409
|
-
);
|
|
121410
|
-
expectedWalletAddress = String(
|
|
121411
|
-
referencePreferences.preferences?.hyperliquid_wallet_address || ""
|
|
121412
|
-
).trim() || null;
|
|
121779
|
+
expectedWalletAddress = await readTrustedWallet();
|
|
121413
121780
|
if (!expectedWalletAddress) {
|
|
121414
121781
|
throw new Error(
|
|
121415
121782
|
"runtime_wallet_assignment_mismatch: copy trading has no trusted wallet assignment"
|
|
@@ -121456,7 +121823,8 @@ var init_engine = __esm({
|
|
|
121456
121823
|
order_id: actionResult.destinationOrderId,
|
|
121457
121824
|
order_state: actionResult.destinationOrderState,
|
|
121458
121825
|
order_member_results: actionResult.orderMemberResults,
|
|
121459
|
-
error_message: actionResult.status === "executed" ? null : actionResult.message
|
|
121826
|
+
error_message: actionResult.status === "executed" ? null : actionResult.message,
|
|
121827
|
+
...actionResult.orderStatusEvidence ? { order_status_evidence: orderStatusEvidenceForAck(actionResult.orderStatusEvidence) } : {}
|
|
121460
121828
|
},
|
|
121461
121829
|
{
|
|
121462
121830
|
runtimeLeaseToken: runtimeLeaseToken ?? void 0,
|
|
@@ -121540,6 +121908,55 @@ var init_engine = __esm({
|
|
|
121540
121908
|
});
|
|
121541
121909
|
}
|
|
121542
121910
|
}
|
|
121911
|
+
/**
|
|
121912
|
+
* Read the follower account evidence a copy poll asked for and send it on
|
|
121913
|
+
* one follow-up poll. Fails closed: when any read fails or the wallet is not
|
|
121914
|
+
* the trusted one, nothing is sent and the check-in continues on the first
|
|
121915
|
+
* poll (null). A report the server cannot use still answers the poll, with
|
|
121916
|
+
* its reason in account_evidence_status, which is logged here.
|
|
121917
|
+
*/
|
|
121918
|
+
async _sendClientCopyTradingAccountEvidence(input) {
|
|
121919
|
+
const requestId = String(input.request.request_id ?? "").trim().slice(0, 80) || "none";
|
|
121920
|
+
const evidence = await readClientCopyTradingAccountEvidence({
|
|
121921
|
+
request: input.request,
|
|
121922
|
+
trustedWalletAddress: input.trustedWalletAddress,
|
|
121923
|
+
config: input.config,
|
|
121924
|
+
signal: input.signal
|
|
121925
|
+
});
|
|
121926
|
+
if (!evidence.ok) {
|
|
121927
|
+
appendRuntimeDebugEvent({
|
|
121928
|
+
label: "copy_trading_account_evidence_skipped",
|
|
121929
|
+
note: `profile_id=${input.profileId} request_id=${requestId} reason=${evidence.reason}`,
|
|
121930
|
+
outcome: "error"
|
|
121931
|
+
});
|
|
121932
|
+
return null;
|
|
121933
|
+
}
|
|
121934
|
+
try {
|
|
121935
|
+
const response = await pollCopyTradingRuntimeSource(Number(input.profileId), {
|
|
121936
|
+
...input.pollOptions,
|
|
121937
|
+
accountEvidence: accountEvidenceForUpload(evidence.read)
|
|
121938
|
+
});
|
|
121939
|
+
const status = response.account_evidence_status ?? null;
|
|
121940
|
+
if (status !== "applied") {
|
|
121941
|
+
appendRuntimeDebugEvent({
|
|
121942
|
+
label: "copy_trading_account_evidence_rejected",
|
|
121943
|
+
note: `profile_id=${input.profileId} request_id=${requestId} reason=${String(status ?? "missing").slice(0, 80)}`,
|
|
121944
|
+
outcome: "error"
|
|
121945
|
+
});
|
|
121946
|
+
}
|
|
121947
|
+
return response;
|
|
121948
|
+
} catch (error48) {
|
|
121949
|
+
if (input.signal.aborted) {
|
|
121950
|
+
throw error48;
|
|
121951
|
+
}
|
|
121952
|
+
appendRuntimeDebugEvent({
|
|
121953
|
+
label: "copy_trading_account_evidence_rejected",
|
|
121954
|
+
note: `profile_id=${input.profileId} request_id=${requestId} error=${getSanitizedRuntimeErrorMessage(error48) || "unknown"}`,
|
|
121955
|
+
outcome: "error"
|
|
121956
|
+
});
|
|
121957
|
+
return null;
|
|
121958
|
+
}
|
|
121959
|
+
}
|
|
121543
121960
|
_resetRuntimeState(options) {
|
|
121544
121961
|
this._clearExecutionLoopTimer();
|
|
121545
121962
|
this._clearClientKillswitchMonitor();
|
|
@@ -121952,6 +122369,99 @@ var init_reconcile = __esm({
|
|
|
121952
122369
|
}
|
|
121953
122370
|
});
|
|
121954
122371
|
|
|
122372
|
+
// lib/runtime/host/local-ai-preflight.ts
|
|
122373
|
+
var normalizeModelSource, isLocalModelSource2, getLocalAiBaseUrlFromPreferences, canReachLocalAiEndpoint;
|
|
122374
|
+
var init_local_ai_preflight = __esm({
|
|
122375
|
+
"lib/runtime/host/local-ai-preflight.ts"() {
|
|
122376
|
+
"use strict";
|
|
122377
|
+
init_define_VTX_EXO_POLICY();
|
|
122378
|
+
init_define_VTX_GROK_POLICY();
|
|
122379
|
+
init_define_VTX_PI_MODEL_POLICY();
|
|
122380
|
+
init_api2();
|
|
122381
|
+
init_local_ai();
|
|
122382
|
+
init_vault();
|
|
122383
|
+
normalizeModelSource = (value) => String(value ?? "").trim().toLowerCase();
|
|
122384
|
+
isLocalModelSource2 = (value) => {
|
|
122385
|
+
const normalized = normalizeModelSource(value);
|
|
122386
|
+
return normalized === "local" || normalized === "localai" || normalized === "local ai" || normalized === "local-ai" || normalized === "local_ai";
|
|
122387
|
+
};
|
|
122388
|
+
getLocalAiBaseUrlFromPreferences = (preferences) => {
|
|
122389
|
+
const record5 = preferences && typeof preferences === "object" && !Array.isArray(preferences) ? preferences : {};
|
|
122390
|
+
const direct = typeof record5.local_ai_base_url === "string" ? record5.local_ai_base_url.trim() : "";
|
|
122391
|
+
if (direct) {
|
|
122392
|
+
return direct;
|
|
122393
|
+
}
|
|
122394
|
+
const localAi = record5.local_ai && typeof record5.local_ai === "object" && !Array.isArray(record5.local_ai) ? record5.local_ai : null;
|
|
122395
|
+
const remembered = Array.isArray(localAi?.remembered_endpoints) ? localAi.remembered_endpoints : [];
|
|
122396
|
+
for (const endpoint of remembered) {
|
|
122397
|
+
if (!endpoint || typeof endpoint !== "object" || Array.isArray(endpoint)) {
|
|
122398
|
+
continue;
|
|
122399
|
+
}
|
|
122400
|
+
const baseUrl = typeof endpoint.baseUrl === "string" ? String(endpoint.baseUrl).trim() : "";
|
|
122401
|
+
if (baseUrl) {
|
|
122402
|
+
return baseUrl;
|
|
122403
|
+
}
|
|
122404
|
+
}
|
|
122405
|
+
return null;
|
|
122406
|
+
};
|
|
122407
|
+
canReachLocalAiEndpoint = async (preferences, profileId, timeoutMs, signal) => {
|
|
122408
|
+
const baseUrl = getLocalAiBaseUrlFromPreferences(preferences);
|
|
122409
|
+
if (!baseUrl) {
|
|
122410
|
+
return { ok: false, detail: "local_ai_endpoint_missing" };
|
|
122411
|
+
}
|
|
122412
|
+
let rawServerType = resolveLocalAiServerTypeInput(preferences);
|
|
122413
|
+
if (!rawServerType) {
|
|
122414
|
+
try {
|
|
122415
|
+
const secrets = await ClientVault.getSecrets(String(profileId));
|
|
122416
|
+
rawServerType = resolveLocalAiServerTypeInput(preferences, secrets?.localAi?.serverType);
|
|
122417
|
+
} catch {
|
|
122418
|
+
return { ok: false, detail: "local_ai_settings_unavailable" };
|
|
122419
|
+
}
|
|
122420
|
+
}
|
|
122421
|
+
const serverType = rawServerType ? normalizeLocalAiServerType(rawServerType) : "openai-compatible";
|
|
122422
|
+
if (!serverType) {
|
|
122423
|
+
return { ok: false, detail: "local_ai_reconnect_required" };
|
|
122424
|
+
}
|
|
122425
|
+
const endpoint = buildLocalAiModelsEndpointForServerType(baseUrl, serverType);
|
|
122426
|
+
if (!endpoint) {
|
|
122427
|
+
return { ok: false, detail: "local_ai_endpoint_missing" };
|
|
122428
|
+
}
|
|
122429
|
+
const headers = { Accept: "application/json" };
|
|
122430
|
+
try {
|
|
122431
|
+
const secret = await getLocalAiEndpointSecret(baseUrl, profileId, signal);
|
|
122432
|
+
const apiKey = typeof secret?.api_key === "string" ? secret.api_key.trim() : "";
|
|
122433
|
+
if (secret?.found && apiKey) {
|
|
122434
|
+
headers.Authorization = `Bearer ${apiKey}`;
|
|
122435
|
+
}
|
|
122436
|
+
} catch {
|
|
122437
|
+
}
|
|
122438
|
+
const controller = new AbortController();
|
|
122439
|
+
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
122440
|
+
const onAbort = () => controller.abort();
|
|
122441
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
122442
|
+
try {
|
|
122443
|
+
const response = await fetch(endpoint, {
|
|
122444
|
+
method: "GET",
|
|
122445
|
+
headers,
|
|
122446
|
+
signal: controller.signal
|
|
122447
|
+
});
|
|
122448
|
+
return {
|
|
122449
|
+
ok: response.ok,
|
|
122450
|
+
detail: response.ok ? "ok" : `status_${response.status}`
|
|
122451
|
+
};
|
|
122452
|
+
} catch (error48) {
|
|
122453
|
+
return {
|
|
122454
|
+
ok: false,
|
|
122455
|
+
detail: error48 instanceof Error && error48.name === "AbortError" ? "timeout" : "fetch_failed"
|
|
122456
|
+
};
|
|
122457
|
+
} finally {
|
|
122458
|
+
clearTimeout(timeout);
|
|
122459
|
+
signal?.removeEventListener("abort", onAbort);
|
|
122460
|
+
}
|
|
122461
|
+
};
|
|
122462
|
+
}
|
|
122463
|
+
});
|
|
122464
|
+
|
|
121955
122465
|
// lib/agent-core/headless-runtime.ts
|
|
121956
122466
|
import { randomUUID as randomUUID15 } from "node:crypto";
|
|
121957
122467
|
import { setTimeout as sleep3 } from "node:timers/promises";
|
|
@@ -122195,6 +122705,11 @@ async function runHeadlessRuntime(options) {
|
|
|
122195
122705
|
if (stored && stored.runtimeSessionId !== identity2.sessionId) return;
|
|
122196
122706
|
await clearRuntimeState(options.statePath);
|
|
122197
122707
|
};
|
|
122708
|
+
const readOwnStatus = async (signal = stopController.signal) => (await getClientRuntimeStatuses(
|
|
122709
|
+
[options.profileId],
|
|
122710
|
+
signal,
|
|
122711
|
+
{ runtimeViewer: { deviceId: identity2.deviceId, sessionId: identity2.sessionId } }
|
|
122712
|
+
)).statuses?.[String(options.profileId)] ?? null;
|
|
122198
122713
|
const stopRuntime = async (reason) => {
|
|
122199
122714
|
if (engine.active) await engine.stop({ skipRemote: true, reason });
|
|
122200
122715
|
try {
|
|
@@ -122210,6 +122725,8 @@ async function runHeadlessRuntime(options) {
|
|
|
122210
122725
|
requestTimeoutMs: options.stopRequestTimeoutMs ?? STOP_REQUEST_TIMEOUT_MS
|
|
122211
122726
|
});
|
|
122212
122727
|
} catch (error48) {
|
|
122728
|
+
const backupRuns = await readOwnStatus(AbortSignal.timeout(options.stopRequestTimeoutMs ?? STOP_REQUEST_TIMEOUT_MS)).then((status) => status?.server_backup?.active === true, () => false);
|
|
122729
|
+
if (backupRuns) return;
|
|
122213
122730
|
const detail = error48 instanceof Error ? error48.message : String(error48);
|
|
122214
122731
|
throw new Error(`VTX could not stop this profile's runtime on the server (${detail}); it may still be set to run.`);
|
|
122215
122732
|
}
|
|
@@ -122229,6 +122746,120 @@ async function runHeadlessRuntime(options) {
|
|
|
122229
122746
|
}
|
|
122230
122747
|
if (kind === "explicit") await clearOwnState().catch(() => void 0);
|
|
122231
122748
|
};
|
|
122749
|
+
const readyToTakeBack = async (status) => {
|
|
122750
|
+
const profileId = String(options.profileId);
|
|
122751
|
+
const desiredMode = String(status.desired_runtime_mode || "").trim().toLowerCase();
|
|
122752
|
+
if (desiredMode && desiredMode !== identity2.mode) return false;
|
|
122753
|
+
if (identity2.mode === "trader" && isClientRuntimeKillswitchBlocked(profileId)) return false;
|
|
122754
|
+
try {
|
|
122755
|
+
const [config2, preferences] = await Promise.all([
|
|
122756
|
+
getLLMConfig(void 0, options.profileId, stopController.signal),
|
|
122757
|
+
getPreferences(void 0, options.profileId, stopController.signal)
|
|
122758
|
+
]);
|
|
122759
|
+
if (config2.agent_headless_client_runtime_enabled !== true) return false;
|
|
122760
|
+
const prefs = preferences?.preferences;
|
|
122761
|
+
if (isLocalModelSource2(prefs?.preferred_model_source)) {
|
|
122762
|
+
return (await canReachLocalAiEndpoint(prefs, options.profileId, LOCAL_AI_PREFLIGHT_TIMEOUT_MS, stopController.signal)).ok;
|
|
122763
|
+
}
|
|
122764
|
+
return true;
|
|
122765
|
+
} catch {
|
|
122766
|
+
return false;
|
|
122767
|
+
}
|
|
122768
|
+
};
|
|
122769
|
+
const readWaitStatus = async () => {
|
|
122770
|
+
try {
|
|
122771
|
+
const response = await getClientRuntimeStatuses(
|
|
122772
|
+
[options.profileId],
|
|
122773
|
+
stopController.signal,
|
|
122774
|
+
{ runtimeViewer: { deviceId: identity2.deviceId, sessionId: identity2.sessionId } }
|
|
122775
|
+
);
|
|
122776
|
+
const status = response.statuses?.[String(options.profileId)];
|
|
122777
|
+
if (status) return { status };
|
|
122778
|
+
const error48 = String(response.errors?.[String(options.profileId)] ?? "");
|
|
122779
|
+
return !error48 || /temporarily unavailable/iu.test(error48) ? "retry" : "ended";
|
|
122780
|
+
} catch (error48) {
|
|
122781
|
+
return classifyReconcileRequestError(error48) === "transient" ? "retry" : { refused: error48 };
|
|
122782
|
+
}
|
|
122783
|
+
};
|
|
122784
|
+
const waitForServerBackup = async () => {
|
|
122785
|
+
if (options.once || stopController.signal.aborted) return "not_backup";
|
|
122786
|
+
let status = null;
|
|
122787
|
+
for (let attempt = 0; ; attempt += 1) {
|
|
122788
|
+
const read = await readWaitStatus();
|
|
122789
|
+
if (read === "ended" || typeof read === "object" && "refused" in read) return "not_backup";
|
|
122790
|
+
status = read === "retry" ? null : read.status;
|
|
122791
|
+
if (status || attempt >= BACKUP_FIRST_READ_RETRY_MS.length || stopController.signal.aborted) break;
|
|
122792
|
+
try {
|
|
122793
|
+
await sleep3(BACKUP_FIRST_READ_RETRY_MS[attempt], void 0, { signal: stopController.signal });
|
|
122794
|
+
} catch {
|
|
122795
|
+
break;
|
|
122796
|
+
}
|
|
122797
|
+
}
|
|
122798
|
+
if (!status?.server_backup?.active) return "not_backup";
|
|
122799
|
+
const stored = await readRuntimeState(options.statePath).catch(() => null);
|
|
122800
|
+
const ownDevices = new Set([identity2.deviceId, stored?.deviceId].filter(Boolean).map(String));
|
|
122801
|
+
let offered = false;
|
|
122802
|
+
const stopped = new Promise((resolve14) => {
|
|
122803
|
+
if (stopController.signal.aborted) resolve14(false);
|
|
122804
|
+
else stopController.signal.addEventListener("abort", () => resolve14(false), { once: true });
|
|
122805
|
+
});
|
|
122806
|
+
const withdraw = async () => {
|
|
122807
|
+
if (!offered) return;
|
|
122808
|
+
await reportServerBackupReadiness(
|
|
122809
|
+
options.profileId,
|
|
122810
|
+
false,
|
|
122811
|
+
identity2.deviceId,
|
|
122812
|
+
AbortSignal.timeout(options.stopRequestTimeoutMs ?? STOP_REQUEST_TIMEOUT_MS)
|
|
122813
|
+
).catch(() => void 0);
|
|
122814
|
+
};
|
|
122815
|
+
process.stderr.write("VTX CLI: Server Mode Backup runs this profile; waiting to take it back.\n");
|
|
122816
|
+
for (; ; ) {
|
|
122817
|
+
if (status) {
|
|
122818
|
+
const backup = status.server_backup;
|
|
122819
|
+
if (!backup?.active) {
|
|
122820
|
+
return String(status.execution_mode || "").trim().toLowerCase() === "client" ? "returned" : "not_backup";
|
|
122821
|
+
}
|
|
122822
|
+
if (backup.enabled && ownDevices.has(String(backup.return_device_id || "").trim())) {
|
|
122823
|
+
const ready = await Promise.race([readyToTakeBack(status), stopped]);
|
|
122824
|
+
if (!stopController.signal.aborted) {
|
|
122825
|
+
offered = true;
|
|
122826
|
+
await reportServerBackupReadiness(options.profileId, ready, identity2.deviceId, stopController.signal).catch(() => void 0);
|
|
122827
|
+
}
|
|
122828
|
+
}
|
|
122829
|
+
}
|
|
122830
|
+
if (options.shouldYieldForUpdate && await options.shouldYieldForUpdate()) {
|
|
122831
|
+
await withdraw();
|
|
122832
|
+
return "yielded_for_update";
|
|
122833
|
+
}
|
|
122834
|
+
try {
|
|
122835
|
+
await sleep3(options.serverBackupWaitMs ?? BACKUP_WAIT_TICK_MS, void 0, { signal: stopController.signal });
|
|
122836
|
+
} catch {
|
|
122837
|
+
await withdraw();
|
|
122838
|
+
return "stopped";
|
|
122839
|
+
}
|
|
122840
|
+
const read = await readWaitStatus();
|
|
122841
|
+
if (read === "ended") {
|
|
122842
|
+
await withdraw();
|
|
122843
|
+
return "not_backup";
|
|
122844
|
+
}
|
|
122845
|
+
if (typeof read === "object" && "refused" in read) {
|
|
122846
|
+
await withdraw();
|
|
122847
|
+
throw read.refused;
|
|
122848
|
+
}
|
|
122849
|
+
status = read === "retry" ? null : read.status;
|
|
122850
|
+
if (stopController.signal.aborted) {
|
|
122851
|
+
await withdraw();
|
|
122852
|
+
return "stopped";
|
|
122853
|
+
}
|
|
122854
|
+
}
|
|
122855
|
+
};
|
|
122856
|
+
const waitOutServerBackup = async () => {
|
|
122857
|
+
const waited = await waitForServerBackup();
|
|
122858
|
+
if (waited === "returned") return "resume";
|
|
122859
|
+
if (waited === "stopped") return result("stopped");
|
|
122860
|
+
if (waited === "yielded_for_update") return result("yielded_for_update");
|
|
122861
|
+
return null;
|
|
122862
|
+
};
|
|
122232
122863
|
let handoffLease = resume?.handoffLease ?? null;
|
|
122233
122864
|
const start = async (kind) => {
|
|
122234
122865
|
attached = false;
|
|
@@ -122275,11 +122906,21 @@ async function runHeadlessRuntime(options) {
|
|
|
122275
122906
|
await clearOwnState();
|
|
122276
122907
|
throw error48;
|
|
122277
122908
|
}
|
|
122278
|
-
if (!stopController.signal.aborted)
|
|
122279
|
-
|
|
122280
|
-
|
|
122909
|
+
if (!stopController.signal.aborted) {
|
|
122910
|
+
const waited = await waitOutServerBackup();
|
|
122911
|
+
if (waited === null && !stopController.signal.aborted) throw error48;
|
|
122912
|
+
if (waited !== null && waited !== "resume") return waited;
|
|
122913
|
+
if (waited === "resume") push({ kind: "resume", immediate: true });
|
|
122914
|
+
else {
|
|
122915
|
+
await stopRuntime("agent_cli:stop");
|
|
122916
|
+
return result("stopped");
|
|
122917
|
+
}
|
|
122918
|
+
} else {
|
|
122919
|
+
await stopRuntime("agent_cli:stop");
|
|
122920
|
+
return result("stopped");
|
|
122921
|
+
}
|
|
122281
122922
|
}
|
|
122282
|
-
stopProtection = firstAttached();
|
|
122923
|
+
if (attached) stopProtection = firstAttached();
|
|
122283
122924
|
}
|
|
122284
122925
|
let resumesWithoutCycle = 0;
|
|
122285
122926
|
let lastResumeError = null;
|
|
@@ -122312,6 +122953,18 @@ async function runHeadlessRuntime(options) {
|
|
|
122312
122953
|
if (event.kind === "engine_stopped") {
|
|
122313
122954
|
if (stopController.signal.aborted || !engineEnded()) continue;
|
|
122314
122955
|
if (snapshot.ownershipLossReason) {
|
|
122956
|
+
const waited = await waitOutServerBackup();
|
|
122957
|
+
if (waited === "resume") {
|
|
122958
|
+
resumesWithoutCycle = 0;
|
|
122959
|
+
lastResumeError = null;
|
|
122960
|
+
push({ kind: "resume", immediate: true });
|
|
122961
|
+
continue;
|
|
122962
|
+
}
|
|
122963
|
+
if (waited) return waited;
|
|
122964
|
+
if (stopController.signal.aborted) {
|
|
122965
|
+
await stopRuntime("agent_cli:stop");
|
|
122966
|
+
return result("stopped");
|
|
122967
|
+
}
|
|
122315
122968
|
await clearOwnState();
|
|
122316
122969
|
throw new Error(
|
|
122317
122970
|
`Client runtime ownership moved (${snapshot.ownershipLossReason})${snapshot.lastError ? `: ${snapshot.lastError}` : ""}.`
|
|
@@ -122352,6 +123005,18 @@ async function runHeadlessRuntime(options) {
|
|
|
122352
123005
|
await stopRuntime("agent_cli:stop");
|
|
122353
123006
|
return result("stopped");
|
|
122354
123007
|
}
|
|
123008
|
+
const waited = await waitOutServerBackup();
|
|
123009
|
+
if (waited !== null) {
|
|
123010
|
+
if (waited !== "resume") return waited;
|
|
123011
|
+
resumesWithoutCycle = 0;
|
|
123012
|
+
lastResumeError = null;
|
|
123013
|
+
push({ kind: "resume", immediate: true });
|
|
123014
|
+
continue;
|
|
123015
|
+
}
|
|
123016
|
+
if (stopController.signal.aborted) {
|
|
123017
|
+
await stopRuntime("agent_cli:stop");
|
|
123018
|
+
return result("stopped");
|
|
123019
|
+
}
|
|
122355
123020
|
if (classifyReconcileRequestError(error48) !== "transient") throw error48;
|
|
122356
123021
|
lastResumeError = error48;
|
|
122357
123022
|
push({ kind: "resume", immediate: false });
|
|
@@ -122372,7 +123037,7 @@ async function runHeadlessRuntime(options) {
|
|
|
122372
123037
|
}
|
|
122373
123038
|
}
|
|
122374
123039
|
}
|
|
122375
|
-
var HeadlessRuntimeTakeoverRequiredError, HEADLESS_RUNTIME_AGENT_SCOPES, DEFAULT_MAX_CLAIM_WAITS, STOP_REQUEST_TIMEOUT_MS, PROTECTION_IDLE_RECHECK_MS, PROTECTION_RETRY_MS, MAX_RESUMES_WITHOUT_A_CYCLE, RESUME_BACKOFF_MS;
|
|
123040
|
+
var HeadlessRuntimeTakeoverRequiredError, HEADLESS_RUNTIME_AGENT_SCOPES, DEFAULT_MAX_CLAIM_WAITS, STOP_REQUEST_TIMEOUT_MS, PROTECTION_IDLE_RECHECK_MS, PROTECTION_RETRY_MS, MAX_RESUMES_WITHOUT_A_CYCLE, RESUME_BACKOFF_MS, BACKUP_WAIT_TICK_MS, LOCAL_AI_PREFLIGHT_TIMEOUT_MS, BACKUP_FIRST_READ_RETRY_MS;
|
|
122376
123041
|
var init_headless_runtime = __esm({
|
|
122377
123042
|
"lib/agent-core/headless-runtime.ts"() {
|
|
122378
123043
|
"use strict";
|
|
@@ -122391,6 +123056,7 @@ var init_headless_runtime = __esm({
|
|
|
122391
123056
|
init_engine();
|
|
122392
123057
|
init_server_runtime_lease();
|
|
122393
123058
|
init_reconcile();
|
|
123059
|
+
init_local_ai_preflight();
|
|
122394
123060
|
HeadlessRuntimeTakeoverRequiredError = class extends Error {
|
|
122395
123061
|
constructor(response) {
|
|
122396
123062
|
const owner2 = objectOrNull2(response.owner);
|
|
@@ -122412,6 +123078,9 @@ var init_headless_runtime = __esm({
|
|
|
122412
123078
|
PROTECTION_RETRY_MS = 15e3;
|
|
122413
123079
|
MAX_RESUMES_WITHOUT_A_CYCLE = 5;
|
|
122414
123080
|
RESUME_BACKOFF_MS = [1e3, 5e3, 15e3, 3e4, 6e4];
|
|
123081
|
+
BACKUP_WAIT_TICK_MS = runtime_policy_generated_default2.trading.engine.client_runtime.reconcile.tick_interval_seconds * 1e3;
|
|
123082
|
+
LOCAL_AI_PREFLIGHT_TIMEOUT_MS = runtime_policy_generated_default2.trading.engine.client_runtime.reconcile.local_ai_preflight_timeout_ms;
|
|
123083
|
+
BACKUP_FIRST_READ_RETRY_MS = [1e3, 5e3];
|
|
122415
123084
|
}
|
|
122416
123085
|
});
|
|
122417
123086
|
|