@vtxmacro/cli 2026.8.50 → 2026.8.52

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.
Files changed (2) hide show
  1. package/bin/vtx.js +891 -137
  2. package/package.json +1 -1
package/bin/vtx.js CHANGED
@@ -5,11 +5,20 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __esm = (fn, res) => function __init() {
9
- return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
8
+ var __esm = (fn, res, err) => function __init() {
9
+ if (err) throw err[0];
10
+ try {
11
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
12
+ } catch (e) {
13
+ throw err = [e], e;
14
+ }
10
15
  };
11
16
  var __commonJS = (cb, mod2) => function __require() {
12
- return mod2 || (0, cb[__getOwnPropNames(cb)[0]])((mod2 = { exports: {} }).exports, mod2), mod2.exports;
17
+ try {
18
+ return mod2 || (0, cb[__getOwnPropNames(cb)[0]])((mod2 = { exports: {} }).exports, mod2), mod2.exports;
19
+ } catch (e) {
20
+ throw mod2 = 0, e;
21
+ }
13
22
  };
14
23
  var __export = (target, all) => {
15
24
  for (var name in all)
@@ -38,7 +47,7 @@ var init_agent_cli_release = __esm({
38
47
  "agent-cli-release.json"() {
39
48
  agent_cli_release_default = {
40
49
  package_name: "@vtxmacro/cli",
41
- package_version: "2026.8.50",
50
+ package_version: "2026.8.52",
42
51
  codex_package_name: "@openai/codex",
43
52
  codex_version: "0.147.0",
44
53
  copilot_sdk_package_name: "@github/copilot-sdk",
@@ -16535,6 +16544,25 @@ async function syncInferenceDirectory(path, platform = process.platform) {
16535
16544
  await handle.close();
16536
16545
  }
16537
16546
  }
16547
+ async function replaceAtomicInferencePrivateFile(temporaryPath, destinationPath, options = {}) {
16548
+ const platform = options.platform ?? process.platform;
16549
+ const renameFile = options.renameFile ?? rename;
16550
+ const sleep4 = options.sleep ?? ((milliseconds) => new Promise((resolve6) => setTimeout(resolve6, milliseconds)));
16551
+ const maxAttempts = Math.max(1, options.maxAttempts ?? 40);
16552
+ const retryDelayMs = Math.max(0, options.retryDelayMs ?? 25);
16553
+ for (let attempt = 0; attempt < maxAttempts; attempt += 1) {
16554
+ try {
16555
+ await renameFile(temporaryPath, destinationPath);
16556
+ return;
16557
+ } catch (error48) {
16558
+ const code = String(error48.code ?? "");
16559
+ if (platform !== "win32" || !WINDOWS_PRIVATE_FILE_REPLACE_ERROR_CODES.has(code) || attempt === maxAttempts - 1) {
16560
+ throw error48;
16561
+ }
16562
+ await sleep4(retryDelayMs);
16563
+ }
16564
+ }
16565
+ }
16538
16566
  async function writeAtomicInferencePrivateFile(path, contents, dependencies = {}) {
16539
16567
  const platform = dependencies.platform ?? process.platform;
16540
16568
  const runner = dependencies.runner ?? runWindowsPrivateAcl;
@@ -16571,7 +16599,13 @@ async function writeAtomicInferencePrivateFile(path, contents, dependencies = {}
16571
16599
  }
16572
16600
  try {
16573
16601
  invalidateWindowsAclCache(path);
16574
- await rename(temporary, path);
16602
+ await replaceAtomicInferencePrivateFile(temporary, path, {
16603
+ platform,
16604
+ renameFile: dependencies.renameFile,
16605
+ sleep: dependencies.sleep,
16606
+ maxAttempts: dependencies.replaceMaxAttempts,
16607
+ retryDelayMs: dependencies.replaceRetryDelayMs
16608
+ });
16575
16609
  if (platform === "win32" && hardenedIdentity) {
16576
16610
  await rebindHardenedWindowsAclAfterRename(
16577
16611
  temporary,
@@ -16838,7 +16872,7 @@ async function acquireInferenceHostProcessLock(path, dependencies = {}) {
16838
16872
  }
16839
16873
  };
16840
16874
  }
16841
- var INFERENCE_CREDENTIAL_NAMESPACE, MAX_INFERENCE_PRIVATE_FILE_BYTES, WINDOWS_PRIVATE_ACL_BROKER_SCRIPT, WINDOWS_IDENTITY_COMMAND_TIMEOUT_MS, WINDOWS_PRIVATE_ACL_BROKER_STARTUP_TIMEOUT_MS, SMALL_IDENTITY_COMMAND_TIMEOUT_MS, windowsPowerShellEnvironment, windowsPrivateAclBrokerInvocation, WindowsPrivateAclBroker, defaultWindowsPrivateAclBroker, runWindowsPrivateAcl, windowsAclCache, windowsAclIdentity, aclCacheKey, secureWindowsPrivatePath, invalidateWindowsAclCache, rebindHardenedWindowsAclAfterRename, rebindHardenedWindowsDirectoryAfterOwnedMutation, isDefaultWindowsPrivatePath, secureExistingWindowsPath, linuxProcessIdentity, windowsProcessIdentityInvocation, windowsBootIdentityInvocation, windowsProcessIdentity, darwinProcessIdentity, runSmallIdentityCommand, cachedSystemBootIdentity, readInferenceSystemBootIdentity, defaultProcessIdentity, defaultCurrentProcessIdentity, processLockObservationCache, inferenceProcessIdentitiesMatch, DEFAULT_INFERENCE_HOST_INSTANCE, SAFE_INFERENCE_HOST_INSTANCE, requireNamedInstancePath, credentialStoreIdentity, inferenceHostCredentialContextPath, inferenceHostCredentialContextTransitionPath, credentialContextForConfig;
16875
+ var INFERENCE_CREDENTIAL_NAMESPACE, MAX_INFERENCE_PRIVATE_FILE_BYTES, WINDOWS_PRIVATE_ACL_BROKER_SCRIPT, WINDOWS_IDENTITY_COMMAND_TIMEOUT_MS, WINDOWS_PRIVATE_ACL_BROKER_STARTUP_TIMEOUT_MS, SMALL_IDENTITY_COMMAND_TIMEOUT_MS, windowsPowerShellEnvironment, windowsPrivateAclBrokerInvocation, WindowsPrivateAclBroker, defaultWindowsPrivateAclBroker, runWindowsPrivateAcl, windowsAclCache, windowsAclIdentity, aclCacheKey, secureWindowsPrivatePath, invalidateWindowsAclCache, rebindHardenedWindowsAclAfterRename, rebindHardenedWindowsDirectoryAfterOwnedMutation, isDefaultWindowsPrivatePath, secureExistingWindowsPath, linuxProcessIdentity, windowsProcessIdentityInvocation, windowsBootIdentityInvocation, windowsProcessIdentity, darwinProcessIdentity, runSmallIdentityCommand, cachedSystemBootIdentity, readInferenceSystemBootIdentity, defaultProcessIdentity, defaultCurrentProcessIdentity, processLockObservationCache, inferenceProcessIdentitiesMatch, DEFAULT_INFERENCE_HOST_INSTANCE, SAFE_INFERENCE_HOST_INSTANCE, requireNamedInstancePath, credentialStoreIdentity, inferenceHostCredentialContextPath, inferenceHostCredentialContextTransitionPath, credentialContextForConfig, WINDOWS_PRIVATE_FILE_REPLACE_ERROR_CODES;
16842
16876
  var init_config = __esm({
16843
16877
  "lib/inference-host/config.ts"() {
16844
16878
  "use strict";
@@ -17413,6 +17447,13 @@ while(($line=[Console]::In.ReadLine()) -ne $null) {
17413
17447
  credential_store_mode: config2.credentialStoreMode,
17414
17448
  credential_file_path: config2.credentialStoreMode === "file" ? resolve(config2.credentialFilePath) : null
17415
17449
  });
17450
+ WINDOWS_PRIVATE_FILE_REPLACE_ERROR_CODES = /* @__PURE__ */ new Set([
17451
+ "EACCES",
17452
+ "EBUSY",
17453
+ "EEXIST",
17454
+ "ENOTEMPTY",
17455
+ "EPERM"
17456
+ ]);
17416
17457
  }
17417
17458
  });
17418
17459
 
@@ -18058,7 +18099,7 @@ ${body}`;
18058
18099
  });
18059
18100
 
18060
18101
  // lib/inference-host/mcp-client.ts
18061
- var EXTERNAL_INFERENCE_MCP_PROTOCOL_VERSION, EXTERNAL_INFERENCE_AUTOMATED_HOST_TOOLS, EXTERNAL_INFERENCE_OPERATIONAL_TOOLS, ExternalInferenceMcpError, DEFAULT_REQUEST_TIMEOUT_MS, MAX_RETRY_AFTER_MS, parseRetryAfterMs, identifierSchema2, safeCodeSchema2, hostMutationResultSchema, attemptStartResultSchema, agentConnectResultSchema, agentHeartbeatResultSchema, timestampSchema2, positiveGenerationSchema, jsonObjectSchema, agentAssignmentNextArgumentsSchema, agentAssignmentNextResultSchema, agentAssignmentHeartbeatArgumentsSchema, agentAssignmentHeartbeatResultSchema, agentDataCallArgumentsSchema, agentDataCallResultSchema, agentDecisionSubmitArgumentsSchema, agentDecisionSubmitResultSchema, agentDecisionStatusArgumentsSchema, agentDecisionStatusResultSchema, agentAssignmentReleaseArgumentsSchema, agentAssignmentReleaseResultSchema, jobCompletionResultSchema, jobFailureResultSchema, toolContracts, discoveryResultSchema, toolListResultSchema, inlineStructuredContentSchema, protocolMeta, parseJsonDocument, parseSseDocuments, parseResponseDocuments, exactOperationalInventory, exactJson, invalidBoundResult, verifyToolResult, ExternalInferenceMcpClient;
18102
+ var EXTERNAL_INFERENCE_MCP_PROTOCOL_VERSION, EXTERNAL_INFERENCE_AUTOMATED_HOST_TOOLS, EXTERNAL_INFERENCE_OPERATIONAL_TOOLS, ExternalInferenceMcpError, DEFAULT_REQUEST_TIMEOUT_MS, MAX_RETRY_AFTER_MS, parseRetryAfterMs, identifierSchema2, safeCodeSchema2, hostMutationResultSchema, attemptStartResultSchema, agentConnectResultSchema, agentHeartbeatResultSchema, timestampSchema2, positiveGenerationSchema, jsonObjectSchema, agentAssignmentNextArgumentsSchema, agentDataCapabilityDescriptorSchema, agentAssignmentNextResultSchema, agentAssignmentHeartbeatArgumentsSchema, agentAssignmentHeartbeatResultSchema, agentDataCallArgumentsSchema, agentDataCallResultSchema, agentDecisionSubmitArgumentsSchema, agentDecisionSubmitResultSchema, agentDecisionStatusArgumentsSchema, agentDecisionStatusResultSchema, agentAssignmentReleaseArgumentsSchema, agentAssignmentReleaseResultSchema, jobCompletionResultSchema, jobFailureResultSchema, toolContracts, discoveryResultSchema, toolListResultSchema, inlineStructuredContentSchema, protocolMeta, parseJsonDocument, parseSseDocuments, parseResponseDocuments, exactOperationalInventory, exactJson, invalidBoundResult, verifyToolResult, ExternalInferenceMcpClient;
18062
18103
  var init_mcp_client = __esm({
18063
18104
  "lib/inference-host/mcp-client.ts"() {
18064
18105
  "use strict";
@@ -18156,7 +18197,25 @@ var init_mcp_client = __esm({
18156
18197
  agentAssignmentNextArgumentsSchema = external_exports.strictObject({
18157
18198
  operation_id: identifierSchema2,
18158
18199
  host_id: identifierSchema2,
18159
- requested_at: timestampSchema2
18200
+ requested_at: timestampSchema2,
18201
+ contract_version: external_exports.literal("agent_assignment_v2"),
18202
+ assignment_id: identifierSchema2.optional(),
18203
+ assignment_generation: positiveGenerationSchema.optional()
18204
+ }).superRefine((value, context) => {
18205
+ if (value.assignment_id === void 0 !== (value.assignment_generation === void 0)) {
18206
+ context.addIssue({
18207
+ code: "custom",
18208
+ message: "Agent recovery assignment identity is incomplete.",
18209
+ path: ["assignment_id"]
18210
+ });
18211
+ }
18212
+ });
18213
+ agentDataCapabilityDescriptorSchema = external_exports.strictObject({
18214
+ id: external_exports.string().min(1).max(128),
18215
+ title: external_exports.string().min(1),
18216
+ description: external_exports.string().min(1),
18217
+ input_schema: jsonObjectSchema,
18218
+ input_schema_sha256: external_exports.string().regex(/^[0-9a-f]{64}$/u)
18160
18219
  });
18161
18220
  agentAssignmentNextResultSchema = external_exports.discriminatedUnion("claim_state", [
18162
18221
  external_exports.strictObject({
@@ -18172,6 +18231,11 @@ var init_mcp_client = __esm({
18172
18231
  model_id: identifierSchema2,
18173
18232
  reasoning_effort: safeCodeSchema2,
18174
18233
  allowed_symbols: external_exports.array(external_exports.string().min(1)).min(1),
18234
+ contract_version: external_exports.literal("agent_assignment_v2"),
18235
+ data_contract: external_exports.array(agentDataCapabilityDescriptorSchema).min(1).refine(
18236
+ (value) => new Set(value.map((descriptor) => descriptor.id)).size === value.length,
18237
+ { message: "Agent data capability descriptors must be unique." }
18238
+ ),
18175
18239
  output_schema_version: external_exports.string().min(1),
18176
18240
  output_schema: jsonObjectSchema,
18177
18241
  minimum_wake_seconds: external_exports.number().int().positive().max(Number.MAX_SAFE_INTEGER),
@@ -19743,19 +19807,42 @@ var init_agent_state = __esm({
19743
19807
  "updated_at"
19744
19808
  ])) throw new Error(message);
19745
19809
  const assignment = assertPlainObject(state.assignment, message);
19746
- if (state.schema_version !== "vtx_codex_agent_runtime_v1" || typeof state.host_id !== "string" || !state.host_id || !isIsoTimestamp(state.next_wake_at) || !isIsoTimestamp(state.updated_at) || !hasExactKeys(assignment, [
19747
- "assignment_id",
19748
- "assignment_generation",
19749
- "model_id",
19750
- "reasoning_effort",
19751
- "bot_mode",
19752
- "execution_mode",
19753
- "allowed_symbols",
19754
- "output_schema",
19755
- "minimum_wake_seconds",
19756
- "maximum_wake_seconds",
19757
- "lease_expires_at"
19758
- ]) || typeof assignment.assignment_id !== "string" || !assignment.assignment_id || !Number.isSafeInteger(assignment.assignment_generation) || Number(assignment.assignment_generation) < 1 || typeof assignment.model_id !== "string" || !assignment.model_id || typeof assignment.reasoning_effort !== "string" || !assignment.reasoning_effort || !["trader", "assistant"].includes(String(assignment.bot_mode)) || !["server", "client"].includes(String(assignment.execution_mode)) || !Array.isArray(assignment.allowed_symbols) || assignment.allowed_symbols.some((symbol2) => typeof symbol2 !== "string" || !symbol2) || !assignment.output_schema || typeof assignment.output_schema !== "object" || Array.isArray(assignment.output_schema) || !Number.isSafeInteger(assignment.minimum_wake_seconds) || Number(assignment.minimum_wake_seconds) < 1 || !Number.isSafeInteger(assignment.maximum_wake_seconds) || Number(assignment.maximum_wake_seconds) < Number(assignment.minimum_wake_seconds) || !isIsoTimestamp(assignment.lease_expires_at)) throw new Error(message);
19810
+ if (!["vtx_codex_agent_runtime_v1", "vtx_codex_agent_runtime_v2"].includes(
19811
+ String(state.schema_version)
19812
+ ) || typeof state.host_id !== "string" || !state.host_id || !isIsoTimestamp(state.next_wake_at) || !isIsoTimestamp(state.updated_at) || !hasExactKeys(
19813
+ assignment,
19814
+ [
19815
+ "assignment_id",
19816
+ "assignment_generation",
19817
+ "model_id",
19818
+ "reasoning_effort",
19819
+ "bot_mode",
19820
+ "execution_mode",
19821
+ "allowed_symbols",
19822
+ "output_schema",
19823
+ "minimum_wake_seconds",
19824
+ "maximum_wake_seconds",
19825
+ "lease_expires_at",
19826
+ ...state.schema_version === "vtx_codex_agent_runtime_v2" ? ["data_contract"] : []
19827
+ ]
19828
+ ) || typeof assignment.assignment_id !== "string" || !assignment.assignment_id || !Number.isSafeInteger(assignment.assignment_generation) || Number(assignment.assignment_generation) < 1 || typeof assignment.model_id !== "string" || !assignment.model_id || typeof assignment.reasoning_effort !== "string" || !assignment.reasoning_effort || !["trader", "assistant"].includes(String(assignment.bot_mode)) || !["server", "client"].includes(String(assignment.execution_mode)) || !Array.isArray(assignment.allowed_symbols) || assignment.allowed_symbols.some((symbol2) => typeof symbol2 !== "string" || !symbol2) || !assignment.output_schema || typeof assignment.output_schema !== "object" || Array.isArray(assignment.output_schema) || !Number.isSafeInteger(assignment.minimum_wake_seconds) || Number(assignment.minimum_wake_seconds) < 1 || !Number.isSafeInteger(assignment.maximum_wake_seconds) || Number(assignment.maximum_wake_seconds) < Number(assignment.minimum_wake_seconds) || !isIsoTimestamp(assignment.lease_expires_at)) throw new Error(message);
19829
+ if (state.schema_version === "vtx_codex_agent_runtime_v2") {
19830
+ if (!Array.isArray(assignment.data_contract) || assignment.data_contract.length === 0) {
19831
+ throw new Error(message);
19832
+ }
19833
+ const capabilityIds = assignment.data_contract.map((value2) => {
19834
+ const descriptor = assertPlainObject(value2, message);
19835
+ if (!hasExactKeys(descriptor, [
19836
+ "id",
19837
+ "title",
19838
+ "description",
19839
+ "input_schema",
19840
+ "input_schema_sha256"
19841
+ ]) || typeof descriptor.id !== "string" || !descriptor.id || typeof descriptor.title !== "string" || !descriptor.title || typeof descriptor.description !== "string" || !descriptor.description || !descriptor.input_schema || typeof descriptor.input_schema !== "object" || Array.isArray(descriptor.input_schema) || typeof descriptor.input_schema_sha256 !== "string" || !/^[0-9a-f]{64}$/u.test(descriptor.input_schema_sha256)) throw new Error(message);
19842
+ return descriptor.id;
19843
+ });
19844
+ if (new Set(capabilityIds).size !== capabilityIds.length) throw new Error(message);
19845
+ }
19759
19846
  if (state.thread !== null) {
19760
19847
  const thread = assertPlainObject(state.thread, message);
19761
19848
  if (!hasExactKeys(thread, [
@@ -19909,7 +19996,7 @@ async function logoutCodexSubscription(options) {
19909
19996
  await session.close();
19910
19997
  }
19911
19998
  }
19912
- var CODEX_INFERENCE_PERMISSION_PROFILE, CODEX_AGENT_PERMISSION_PROFILE, CODEX_REASONING_CONTENT_MAX_UTF8_BYTES, CODEX_REASONING_SUMMARY_MAX_UTF8_BYTES, CODEX_ACCOUNT_PLAN_TYPES, CODEX_AGENT_DYNAMIC_TOOLS, CodexAppServerError, objectOrNull, finiteToken, tokenUsageFromBreakdown, usageFromNotification, validPlanType, nonnegativeSafeIntegerOrNull, nonnegativeFiniteNumberOrNull, parseRateLimitWindow, RATE_LIMIT_REACHED_TYPES, DEFAULT_CODEX_QUOTA_COOLDOWN_MS, MAX_CODEX_QUOTA_COOLDOWN_MS, CODEX_TRANSIENT_RATE_LIMIT_COOLDOWN_MS, parseRateLimitSnapshot, codexRateLimitRetryAtMs, codexAccountRateLimitReached, forbiddenMethod, forbiddenTerminalItem, forbiddenAgentMethod, forbiddenAgentTerminalItem, CODEX_AGENT_TOOL_SPECS, classifyCodexTurnFailure, scrubbedCodexEnvironment, killWindowsProcessTree, appServerArgs, GUARDIAN_SCRIPT, WINDOWS_RECEIPT_REPLACE_ERROR_CODES, MAX_RETIRED_RESPONSE_IDS, LATE_RESPONSE_SAFE_METHODS, replaceCodexGuardianReceiptFile, writeCodexGuardianSpawnIntent, parseGuardianReceipt, readCodexGuardianReceipt, waitForCodexGuardianState, defaultSpawn, CodexAppServerSession;
19999
+ var CODEX_INFERENCE_PERMISSION_PROFILE, CODEX_AGENT_PERMISSION_PROFILE, CODEX_REASONING_CONTENT_MAX_UTF8_BYTES, CODEX_REASONING_SUMMARY_MAX_UTF8_BYTES, CODEX_ACCOUNT_PLAN_TYPES, CODEX_AGENT_DYNAMIC_TOOLS, CodexAppServerError, objectOrNull, finiteToken, tokenUsageFromBreakdown, usageFromNotification, validPlanType, nonnegativeSafeIntegerOrNull, nonnegativeFiniteNumberOrNull, parseRateLimitWindow, RATE_LIMIT_REACHED_TYPES, DEFAULT_CODEX_QUOTA_COOLDOWN_MS, MAX_CODEX_QUOTA_COOLDOWN_MS, CODEX_TRANSIENT_RATE_LIMIT_COOLDOWN_MS, parseRateLimitSnapshot, codexRateLimitRetryAtMs, codexAccountRateLimitReached, forbiddenMethod, forbiddenTerminalItem, forbiddenAgentMethod, forbiddenAgentTerminalItem, createCodexAgentToolSpecs, classifyCodexTurnFailure, scrubbedCodexEnvironment, killWindowsProcessTree, appServerArgs, GUARDIAN_SCRIPT, WINDOWS_RECEIPT_REPLACE_ERROR_CODES, MAX_RETIRED_RESPONSE_IDS, LATE_RESPONSE_SAFE_METHODS, replaceCodexGuardianReceiptFile, writeCodexGuardianSpawnIntent, parseGuardianReceipt, readCodexGuardianReceipt, waitForCodexGuardianState, defaultSpawn, CodexAppServerSession;
19913
20000
  var init_codex_app_server = __esm({
19914
20001
  "lib/inference-host/codex-app-server.ts"() {
19915
20002
  "use strict";
@@ -20074,41 +20161,62 @@ var init_codex_app_server = __esm({
20074
20161
  "webSearch",
20075
20162
  "contextCompaction"
20076
20163
  ].includes(String(item.type || ""));
20077
- CODEX_AGENT_TOOL_SPECS = [
20078
- {
20079
- name: "vtx_get_data",
20080
- description: "Request assignment-scoped VTX data. Choose the capability and only the arguments needed for this decision.",
20081
- inputSchema: {
20082
- type: "object",
20083
- additionalProperties: false,
20084
- required: ["capability", "arguments"],
20085
- properties: {
20086
- capability: { type: "string", minLength: 1 },
20087
- arguments: { type: "object" }
20088
- }
20089
- }
20090
- },
20091
- {
20092
- name: "vtx_submit_decision",
20093
- description: "Submit one VTX structured trading decision candidate using the assignment decision schema.",
20094
- inputSchema: {
20095
- type: "object",
20096
- additionalProperties: false,
20097
- required: ["candidate"],
20098
- properties: { candidate: { type: "object" } }
20164
+ createCodexAgentToolSpecs = (dataContract, decisionSchema) => {
20165
+ if (dataContract.length === 0 || Object.keys(decisionSchema).length === 0) {
20166
+ throw new CodexAppServerError({
20167
+ message: "Codex Agent data contract is unavailable.",
20168
+ category: "schema",
20169
+ code: "invalid_agent_data_contract",
20170
+ retryable: false
20171
+ });
20172
+ }
20173
+ const dataRequestBranches = dataContract.map((descriptor) => ({
20174
+ type: "object",
20175
+ additionalProperties: false,
20176
+ required: ["capability", "arguments"],
20177
+ description: descriptor.description,
20178
+ properties: {
20179
+ capability: {
20180
+ type: "string",
20181
+ const: descriptor.id,
20182
+ title: descriptor.title
20183
+ },
20184
+ arguments: descriptor.input_schema
20099
20185
  }
20100
- },
20101
- {
20102
- name: "vtx_decision_status",
20103
- description: "Resolve the durable status of a previously attempted decision operation.",
20104
- inputSchema: {
20105
- type: "object",
20106
- additionalProperties: false,
20107
- required: ["operation_id"],
20108
- properties: { operation_id: { type: "string", minLength: 1 } }
20186
+ }));
20187
+ return [
20188
+ {
20189
+ type: "function",
20190
+ name: "vtx_get_data",
20191
+ description: "Request assignment-scoped VTX data using one exact canonical capability schema.",
20192
+ inputSchema: {
20193
+ oneOf: dataRequestBranches
20194
+ }
20195
+ },
20196
+ {
20197
+ type: "function",
20198
+ name: "vtx_submit_decision",
20199
+ description: "Submit one VTX structured trading decision candidate using the assignment decision schema.",
20200
+ inputSchema: {
20201
+ type: "object",
20202
+ additionalProperties: false,
20203
+ required: ["candidate"],
20204
+ properties: { candidate: decisionSchema }
20205
+ }
20206
+ },
20207
+ {
20208
+ type: "function",
20209
+ name: "vtx_decision_status",
20210
+ description: "Resolve the durable status of a previously attempted decision operation.",
20211
+ inputSchema: {
20212
+ type: "object",
20213
+ additionalProperties: false,
20214
+ required: ["operation_id"],
20215
+ properties: { operation_id: { type: "string", minLength: 1 } }
20216
+ }
20109
20217
  }
20110
- }
20111
- ];
20218
+ ];
20219
+ };
20112
20220
  classifyCodexTurnFailure = (codexErrorInfo, terminalStatus) => {
20113
20221
  if (terminalStatus === "interrupted") {
20114
20222
  return { code: "cancelled", category: "cancelled", retryable: false, httpStatusCode: null };
@@ -20272,7 +20380,7 @@ var init_codex_app_server = __esm({
20272
20380
  });
20273
20381
  });
20274
20382
  };
20275
- appServerArgs = () => {
20383
+ appServerArgs = (enableAgentCodeModeHost = false) => {
20276
20384
  const args = [
20277
20385
  "app-server",
20278
20386
  "--stdio",
@@ -20295,8 +20403,9 @@ var init_codex_app_server = __esm({
20295
20403
  "memories",
20296
20404
  "image_generation",
20297
20405
  "multi_agent",
20298
- "code_mode_host"
20406
+ ...enableAgentCodeModeHost ? [] : ["code_mode_host"]
20299
20407
  ]) args.push("--disable", feature);
20408
+ if (enableAgentCodeModeHost) args.push("--enable", "code_mode_host");
20300
20409
  return args;
20301
20410
  };
20302
20411
  GUARDIAN_SCRIPT = String.raw`
@@ -20641,7 +20750,9 @@ child.once('close', async (code, signal) => {
20641
20750
  });
20642
20751
  }
20643
20752
  }
20644
- const child = spawnProcess(options.binary.path, appServerArgs(), {
20753
+ const child = spawnProcess(options.binary.path, appServerArgs(
20754
+ options.enableAgentCodeModeHost === true
20755
+ ), {
20645
20756
  env: scrubbedCodexEnvironment(options.codexHome),
20646
20757
  stdio: ["pipe", "pipe", "pipe"],
20647
20758
  windowsHide: true,
@@ -21445,7 +21556,7 @@ child.once('close', async (code, signal) => {
21445
21556
  ephemeral: false,
21446
21557
  historyMode: "legacy",
21447
21558
  environments: [],
21448
- dynamicTools: CODEX_AGENT_TOOL_SPECS,
21559
+ dynamicTools: createCodexAgentToolSpecs(options.dataContract, options.decisionSchema),
21449
21560
  selectedCapabilityRoots: [],
21450
21561
  experimentalRawEvents: false,
21451
21562
  developerInstructions: options.systemPrompt,
@@ -21457,9 +21568,9 @@ child.once('close', async (code, signal) => {
21457
21568
  web_search: "live",
21458
21569
  features: {
21459
21570
  apps: false,
21460
- code_mode: false,
21571
+ code_mode: true,
21461
21572
  code_mode_buffered_exec: false,
21462
- code_mode_host: false,
21573
+ code_mode_host: true,
21463
21574
  code_mode_only: false,
21464
21575
  in_app_browser: false,
21465
21576
  js_repl: false,
@@ -23648,6 +23759,7 @@ var init_codex_adapter = __esm({
23648
23759
  deadlineAtMs,
23649
23760
  signal,
23650
23761
  spawnProcess: this.dependencies.spawnProcess,
23762
+ enableAgentCodeModeHost: true,
23651
23763
  guardian: this.guardianProcessToken && this.guardianReceiptPath ? {
23652
23764
  processToken: this.guardianProcessToken,
23653
23765
  receiptPath: this.guardianReceiptPath
@@ -23695,6 +23807,8 @@ var init_codex_adapter = __esm({
23695
23807
  systemPrompt: input.systemPrompt,
23696
23808
  requestedModel: input.requestedModel,
23697
23809
  requestedReasoningEffort: input.requestedReasoningEffort,
23810
+ dataContract: input.dataContract,
23811
+ decisionSchema: input.decisionSchema,
23698
23812
  deadlineAtMs: input.deadlineAtMs,
23699
23813
  signal: input.signal
23700
23814
  });
@@ -23707,6 +23821,8 @@ var init_codex_adapter = __esm({
23707
23821
  systemPrompt: input.systemPrompt,
23708
23822
  requestedModel: input.requestedModel,
23709
23823
  requestedReasoningEffort: input.requestedReasoningEffort,
23824
+ dataContract: input.dataContract,
23825
+ decisionSchema: input.decisionSchema,
23710
23826
  deadlineAtMs: input.deadlineAtMs,
23711
23827
  signal: input.signal
23712
23828
  });
@@ -33015,7 +33131,10 @@ var init_runner = __esm({
33015
33131
  };
33016
33132
  createCodexAgentControlClient = (mcp) => ({
33017
33133
  nextAssignment: async (request, options) => {
33018
- const result2 = await mcp.callTool("inference.agent.assignment.next", request, options);
33134
+ const result2 = await mcp.callTool("inference.agent.assignment.next", {
33135
+ ...request,
33136
+ contract_version: "agent_assignment_v2"
33137
+ }, options);
33019
33138
  if (result2.claim_state === "empty") return null;
33020
33139
  return {
33021
33140
  assignment_id: result2.assignment_id,
@@ -33025,6 +33144,7 @@ var init_runner = __esm({
33025
33144
  bot_mode: result2.bot_mode,
33026
33145
  execution_mode: result2.execution_mode,
33027
33146
  allowed_symbols: result2.allowed_symbols,
33147
+ data_contract: result2.data_contract,
33028
33148
  output_schema: result2.output_schema,
33029
33149
  minimum_wake_seconds: result2.minimum_wake_seconds,
33030
33150
  maximum_wake_seconds: result2.maximum_wake_seconds,
@@ -33119,13 +33239,20 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33119
33239
  }
33120
33240
  async runOnce(signal) {
33121
33241
  const nowIso = () => new Date(this.now()).toISOString();
33122
- let state = await readCodexAgentRuntimeState(this.options.statePath);
33123
- if (state && state.host_id !== this.options.hostId) {
33242
+ const recoveredState = await readCodexAgentRuntimeState(this.options.statePath);
33243
+ if (recoveredState && recoveredState.host_id !== this.options.hostId) {
33124
33244
  throw new InferenceHostRunnerError(
33125
33245
  "agent_recovery_scope_mismatch",
33126
33246
  "Codex Agent recovery state belongs to another host."
33127
33247
  );
33128
33248
  }
33249
+ let state;
33250
+ if (recoveredState?.schema_version === "vtx_codex_agent_runtime_v1") {
33251
+ state = await this.upgradeLegacyRuntimeState(recoveredState, signal);
33252
+ if (!state) return this.now() + (this.options.idlePollMs ?? 5e3);
33253
+ } else {
33254
+ state = recoveredState ?? null;
33255
+ }
33129
33256
  if (!state) {
33130
33257
  const assignment2 = await this.options.controlClient.nextAssignment({
33131
33258
  operation_id: randomUUID(),
@@ -33134,7 +33261,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33134
33261
  }, { signal });
33135
33262
  if (!assignment2) return this.now() + (this.options.idlePollMs ?? 5e3);
33136
33263
  state = {
33137
- schema_version: "vtx_codex_agent_runtime_v1",
33264
+ schema_version: "vtx_codex_agent_runtime_v2",
33138
33265
  host_id: this.options.hostId,
33139
33266
  assignment: assignment2,
33140
33267
  thread: null,
@@ -33150,8 +33277,11 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33150
33277
  if (wakeOutcome !== "ready") {
33151
33278
  return this.now() + (this.options.idlePollMs ?? 5e3);
33152
33279
  }
33153
- state = await readCodexAgentRuntimeState(this.options.statePath);
33154
- if (!state) return this.now() + (this.options.idlePollMs ?? 5e3);
33280
+ const rereadState = await readCodexAgentRuntimeState(this.options.statePath);
33281
+ if (rereadState?.schema_version !== "vtx_codex_agent_runtime_v2") {
33282
+ return this.now() + (this.options.idlePollMs ?? 5e3);
33283
+ }
33284
+ state = rereadState;
33155
33285
  }
33156
33286
  }
33157
33287
  state = await this.resolvePendingDecision(state, signal);
@@ -33213,6 +33343,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33213
33343
  bot_mode: assignment.bot_mode,
33214
33344
  execution_mode: assignment.execution_mode,
33215
33345
  allowed_symbols: assignment.allowed_symbols,
33346
+ data_capability_ids: assignment.data_contract.map((descriptor) => descriptor.id),
33216
33347
  output_schema: assignment.output_schema,
33217
33348
  wake_bounds_seconds: {
33218
33349
  minimum: assignment.minimum_wake_seconds,
@@ -33220,6 +33351,8 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33220
33351
  }
33221
33352
  }),
33222
33353
  outputSchema: CODEX_AGENT_WAKE_SCHEMA,
33354
+ dataContract: assignment.data_contract,
33355
+ decisionSchema: assignment.output_schema,
33223
33356
  requestedModel: assignment.model_id,
33224
33357
  requestedReasoningEffort: assignment.reasoning_effort,
33225
33358
  deadlineAtMs,
@@ -33232,7 +33365,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33232
33365
  if (call.tool === "vtx_get_data") {
33233
33366
  const capability = typeof call.arguments.capability === "string" ? call.arguments.capability.trim() : "";
33234
33367
  const args = call.arguments.arguments;
33235
- if (!capability || !args || typeof args !== "object" || Array.isArray(args)) {
33368
+ if (!capability || !assignment.data_contract.some((descriptor) => descriptor.id === capability) || !args || typeof args !== "object" || Array.isArray(args)) {
33236
33369
  return { success: false, value: { error: "invalid_data_request" } };
33237
33370
  }
33238
33371
  const value = await this.options.controlClient.dataCall({
@@ -33368,6 +33501,40 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33368
33501
  await heartbeatTask.catch(() => void 0);
33369
33502
  }
33370
33503
  }
33504
+ async upgradeLegacyRuntimeState(legacyState, signal) {
33505
+ const state = await this.resolveLegacyPendingDecision(legacyState, signal);
33506
+ if (state.pending_decision) return null;
33507
+ if (state.thread) {
33508
+ await this.options.adapter.releaseThread(state.thread).catch(() => void 0);
33509
+ }
33510
+ await clearCodexAgentRuntimeState(this.options.statePath);
33511
+ return null;
33512
+ }
33513
+ async resolveLegacyPendingDecision(state, signal) {
33514
+ const pending = state.pending_decision;
33515
+ if (!pending) return state;
33516
+ const checkedAt = new Date(this.now()).toISOString();
33517
+ const checking = {
33518
+ ...state,
33519
+ pending_decision: { ...pending, last_status_check_at: checkedAt },
33520
+ updated_at: checkedAt
33521
+ };
33522
+ await writeCodexAgentRuntimeState(this.options.statePath, checking);
33523
+ const status = await this.options.controlClient.decisionStatus({
33524
+ host_id: this.options.hostId,
33525
+ assignment_id: state.assignment.assignment_id,
33526
+ assignment_generation: state.assignment.assignment_generation,
33527
+ operation_id: pending.operation_id
33528
+ }, { signal });
33529
+ if (status.status !== "applied" && status.status !== "not_applied") return checking;
33530
+ const resolved = {
33531
+ ...checking,
33532
+ pending_decision: null,
33533
+ updated_at: new Date(this.now()).toISOString()
33534
+ };
33535
+ await writeCodexAgentRuntimeState(this.options.statePath, resolved);
33536
+ return resolved;
33537
+ }
33371
33538
  async resolvePendingDecision(state, signal) {
33372
33539
  const pending = state.pending_decision;
33373
33540
  if (!pending) return state;
@@ -33415,7 +33582,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33415
33582
  if (this.stopped || signal?.aborted) return "stopped";
33416
33583
  if (this.now() >= nextWakeAtMs) return "ready";
33417
33584
  const state = await readCodexAgentRuntimeState(this.options.statePath);
33418
- if (!state) return "cancelled";
33585
+ if (state?.schema_version !== "vtx_codex_agent_runtime_v2") return "cancelled";
33419
33586
  const requestedAt = new Date(this.now()).toISOString();
33420
33587
  const heartbeat = await this.options.controlClient.heartbeat({
33421
33588
  operation_id: randomUUID(),
@@ -33443,7 +33610,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33443
33610
  let state = await readCodexAgentRuntimeState(this.options.statePath);
33444
33611
  if (!state) return;
33445
33612
  try {
33446
- state = await this.resolvePendingDecision(state);
33613
+ state = state.schema_version === "vtx_codex_agent_runtime_v1" ? await this.resolveLegacyPendingDecision(state) : await this.resolvePendingDecision(state);
33447
33614
  } catch {
33448
33615
  return;
33449
33616
  }
@@ -38094,7 +38261,18 @@ var init_sort_utils = __esm({
38094
38261
  });
38095
38262
 
38096
38263
  // lib/runtime/hyperliquid-account-mode-contract.ts
38097
- var UNIFIED_MODE_ALIASES, normalizeAccountMode, extractAccountModeFromPayload, extractAccountModeCandidateFromPayload, isUnifiedAccountMode;
38264
+ function resolveExactHyperliquidAccountMode(userAbstraction, ...dexEvidence) {
38265
+ const mode = extractCanonicalHyperliquidAccountMode(userAbstraction);
38266
+ if (!mode) {
38267
+ throw new Error("Exact Hyperliquid userAbstraction response is invalid.");
38268
+ }
38269
+ if (mode !== "default" && mode !== "disabled") return mode;
38270
+ if (dexEvidence.length < 1) {
38271
+ throw new Error("Exact Hyperliquid userDexAbstraction response is unavailable.");
38272
+ }
38273
+ return parseExactDexAbstractionEnabled(dexEvidence[0]) ? "dexAbstraction" : mode;
38274
+ }
38275
+ var UNIFIED_MODE_ALIASES, CANONICAL_ACCOUNT_MODE_ALIASES, EXACT_MODE_KEYS, EXACT_MODE_BOOLEAN_KEYS, isExactTruthyFlag, normalizeCanonicalHyperliquidAccountMode, extractCanonicalHyperliquidAccountMode, parseExactDexAbstractionEnabled, normalizeAccountMode, extractAccountModeFromPayload, extractAccountModeCandidateFromPayload, isUnifiedAccountMode;
38098
38276
  var init_hyperliquid_account_mode_contract = __esm({
38099
38277
  "lib/runtime/hyperliquid-account-mode-contract.ts"() {
38100
38278
  "use strict";
@@ -38105,6 +38283,89 @@ var init_hyperliquid_account_mode_contract = __esm({
38105
38283
  "unified",
38106
38284
  "pm"
38107
38285
  ]);
38286
+ CANONICAL_ACCOUNT_MODE_ALIASES = /* @__PURE__ */ new Map([
38287
+ ["default", "default"],
38288
+ ["standard", "default"],
38289
+ ["classic", "default"],
38290
+ ["disabled", "disabled"],
38291
+ ["unifiedaccount", "unifiedAccount"],
38292
+ ["unified", "unifiedAccount"],
38293
+ ["portfoliomargin", "portfolioMargin"],
38294
+ ["pm", "portfolioMargin"],
38295
+ ["dexabstraction", "dexAbstraction"]
38296
+ ]);
38297
+ EXACT_MODE_KEYS = [
38298
+ "accountMode",
38299
+ "account_mode",
38300
+ "accountType",
38301
+ "account_type",
38302
+ "accountUnificationMode",
38303
+ "account_unification_mode",
38304
+ "abstractionMode",
38305
+ "abstraction_mode",
38306
+ "abstraction",
38307
+ "abstractionState",
38308
+ "dexAbstractionState",
38309
+ "marginMode",
38310
+ "state",
38311
+ "mode",
38312
+ "value"
38313
+ ];
38314
+ EXACT_MODE_BOOLEAN_KEYS = [
38315
+ ["unifiedAccount", ["isUnifiedAccount", "unifiedAccount", "isUnified", "unified", "is_unified_account"]],
38316
+ ["portfolioMargin", ["isPortfolioMargin", "portfolioMargin", "isPm", "pm", "is_portfolio_margin"]],
38317
+ ["dexAbstraction", ["isDexAbstraction", "dexAbstraction", "dexAbstractionEnabled", "is_dex_abstraction"]],
38318
+ ["default", ["isClassic", "classic", "isStandard", "standard"]]
38319
+ ];
38320
+ isExactTruthyFlag = (value) => value === true || value === 1 || typeof value === "string" && value.trim().toLowerCase() === "true";
38321
+ normalizeCanonicalHyperliquidAccountMode = (value) => {
38322
+ if (typeof value !== "string") return null;
38323
+ const key = value.trim().replace(/[_\s-]/g, "").toLowerCase();
38324
+ return CANONICAL_ACCOUNT_MODE_ALIASES.get(key) ?? null;
38325
+ };
38326
+ extractCanonicalHyperliquidAccountMode = (payload, depth = 0) => {
38327
+ if (depth > 6) return null;
38328
+ const direct = normalizeCanonicalHyperliquidAccountMode(payload);
38329
+ if (direct) return direct;
38330
+ if (Array.isArray(payload)) {
38331
+ for (const item of payload) {
38332
+ const mode = extractCanonicalHyperliquidAccountMode(item, depth + 1);
38333
+ if (mode) return mode;
38334
+ }
38335
+ return null;
38336
+ }
38337
+ if (!payload || typeof payload !== "object") return null;
38338
+ const source = payload;
38339
+ for (const key of EXACT_MODE_KEYS) {
38340
+ if (!(key in source)) continue;
38341
+ const mode = normalizeCanonicalHyperliquidAccountMode(source[key]);
38342
+ if (mode) return mode;
38343
+ }
38344
+ for (const [mode, keys] of EXACT_MODE_BOOLEAN_KEYS) {
38345
+ for (const key of keys) {
38346
+ if (isExactTruthyFlag(source[key])) return mode;
38347
+ }
38348
+ }
38349
+ for (const value of Object.values(source)) {
38350
+ const mode = extractCanonicalHyperliquidAccountMode(value, depth + 1);
38351
+ if (mode) return mode;
38352
+ }
38353
+ return null;
38354
+ };
38355
+ parseExactDexAbstractionEnabled = (payload) => {
38356
+ if (payload == null || payload === false) return false;
38357
+ if (payload === true) return true;
38358
+ if (typeof payload === "string") {
38359
+ const normalized = payload.trim().toLowerCase();
38360
+ if (normalized === "true") return true;
38361
+ if (normalized === "false") return false;
38362
+ }
38363
+ if (typeof payload === "number" && Number.isFinite(payload)) {
38364
+ if (payload === 1) return true;
38365
+ if (payload === 0) return false;
38366
+ }
38367
+ throw new Error("Exact Hyperliquid userDexAbstraction response is invalid.");
38368
+ };
38108
38369
  normalizeAccountMode = (mode) => String(mode ?? "").trim().toLowerCase().replace(/[_\s-]/g, "");
38109
38370
  extractAccountModeFromPayload = (payload) => {
38110
38371
  const candidate = extractAccountModeCandidateFromPayload(payload);
@@ -38329,6 +38590,229 @@ var init_hyperliquid_active_asset_contract = __esm({
38329
38590
  }
38330
38591
  });
38331
38592
 
38593
+ // lib/runtime/server-prompt-rescue-account-contract.ts
38594
+ var STABLE_SYMBOLS, toNumber2, firstNumber2, firstTruthy, spotContainers, extractCanonicalSpotMetrics, sumBalanceValueUsd, approximatelyEqual, balancesMirrorUnifiedAccountValue, computeEffectiveAccountValue, equityFormula, buildServerPromptRescueAccountSummary;
38595
+ var init_server_prompt_rescue_account_contract = __esm({
38596
+ "lib/runtime/server-prompt-rescue-account-contract.ts"() {
38597
+ "use strict";
38598
+ init_hyperliquid_account_mode_contract();
38599
+ STABLE_SYMBOLS = /* @__PURE__ */ new Set(["USDC", "USD", "USDT"]);
38600
+ toNumber2 = (value, fallback = 0) => {
38601
+ const numeric = Number(value);
38602
+ return Number.isFinite(numeric) ? numeric : fallback;
38603
+ };
38604
+ firstNumber2 = (values, fallback = 0) => {
38605
+ for (const value of values) {
38606
+ if (value == null || value === "") continue;
38607
+ const numeric = Number(value);
38608
+ if (Number.isFinite(numeric)) return numeric;
38609
+ }
38610
+ return fallback;
38611
+ };
38612
+ firstTruthy = (values, fallback) => {
38613
+ for (const value of values) {
38614
+ if (value) return value;
38615
+ }
38616
+ return fallback;
38617
+ };
38618
+ spotContainers = (spotResponse) => {
38619
+ if (!spotResponse || typeof spotResponse !== "object" || Array.isArray(spotResponse)) return [];
38620
+ const response = spotResponse;
38621
+ const containers = [response];
38622
+ for (const key of ["spotState", "userState", "clearinghouseState", "state", "data"]) {
38623
+ const child = response[key];
38624
+ if (child && typeof child === "object" && !Array.isArray(child)) containers.push(child);
38625
+ }
38626
+ return containers;
38627
+ };
38628
+ extractCanonicalSpotMetrics = (spotResponse) => {
38629
+ const response = spotResponse && typeof spotResponse === "object" && !Array.isArray(spotResponse) ? spotResponse : {};
38630
+ const containers = spotContainers(response);
38631
+ let accountValue = 0;
38632
+ let totalMarginUsed = 0;
38633
+ let withdrawable = 0;
38634
+ for (const container of containers) {
38635
+ const marginSummary = container.marginSummary && typeof container.marginSummary === "object" && !Array.isArray(container.marginSummary) ? container.marginSummary : {};
38636
+ accountValue = Math.max(accountValue, toNumber2(marginSummary.accountValue));
38637
+ totalMarginUsed = Math.max(totalMarginUsed, toNumber2(marginSummary.totalMarginUsed));
38638
+ withdrawable = Math.max(withdrawable, toNumber2(container.withdrawable));
38639
+ }
38640
+ if (accountValue <= 0) {
38641
+ for (const key of ["accountValue", "totalValue", "equity", "totalRawUsd", "usdValue", "usdcValue"]) {
38642
+ accountValue = Math.max(accountValue, toNumber2(response[key]));
38643
+ }
38644
+ }
38645
+ const balances = [];
38646
+ const listKeys = ["balances", "tokenBalances", "spotBalances", "assets"];
38647
+ for (const container of containers) {
38648
+ for (const listKey of listKeys) {
38649
+ const bucket = container[listKey];
38650
+ if (!Array.isArray(bucket)) continue;
38651
+ let stableTotal = 0;
38652
+ let anyTotal = 0;
38653
+ for (const rawEntry of bucket) {
38654
+ if (!rawEntry || typeof rawEntry !== "object" || Array.isArray(rawEntry)) continue;
38655
+ const entry = rawEntry;
38656
+ const coin = String(firstTruthy([
38657
+ entry.coin,
38658
+ entry.token,
38659
+ entry.asset,
38660
+ entry.symbol
38661
+ ], "")).trim().toUpperCase();
38662
+ if (!coin) continue;
38663
+ const total = toNumber2(firstTruthy([entry.total, entry.balance, entry.amount], "0"));
38664
+ const hold = toNumber2(firstTruthy([entry.hold, entry.locked], "0"));
38665
+ const available = Math.max(
38666
+ 0,
38667
+ toNumber2(firstTruthy([entry.available, entry.free, total - hold], "0"))
38668
+ );
38669
+ let valueUsd = toNumber2(firstTruthy([entry.usdValue, entry.usdcValue], "0"));
38670
+ if (valueUsd <= 0 && STABLE_SYMBOLS.has(coin)) {
38671
+ valueUsd = available > 0 ? available : total;
38672
+ }
38673
+ balances.push({ coin, total, hold, available, value_usd: valueUsd });
38674
+ const entryValue = valueUsd > 0 ? valueUsd : total;
38675
+ if (entryValue > 0) {
38676
+ anyTotal += entryValue;
38677
+ if (STABLE_SYMBOLS.has(coin)) stableTotal += entryValue;
38678
+ }
38679
+ }
38680
+ if (accountValue <= 0) {
38681
+ if (stableTotal > 0) accountValue = stableTotal;
38682
+ else if (anyTotal > 0) accountValue = anyTotal;
38683
+ }
38684
+ }
38685
+ if (balances.length > 0) break;
38686
+ }
38687
+ return { accountValue, totalMarginUsed, withdrawable, balances };
38688
+ };
38689
+ sumBalanceValueUsd = (balances) => balances.reduce((total, balance) => {
38690
+ let valueUsd = toNumber2(balance.value_usd);
38691
+ if (valueUsd <= 0 && STABLE_SYMBOLS.has(String(balance.coin || "").trim().toUpperCase())) {
38692
+ valueUsd = toNumber2(balance.total);
38693
+ }
38694
+ return total + Math.max(valueUsd, 0);
38695
+ }, 0);
38696
+ approximatelyEqual = (left, right, absoluteToleranceUsd, relativeTolerance) => {
38697
+ const reference = Math.max(Math.abs(left), Math.abs(right), 1);
38698
+ return Math.abs(left - right) <= Math.max(absoluteToleranceUsd, reference * relativeTolerance);
38699
+ };
38700
+ balancesMirrorUnifiedAccountValue = (input) => input.perpsEquity > 0 && input.spotEquity > 0 && input.balancesEquity > 0 && approximatelyEqual(
38701
+ input.perpsEquity,
38702
+ input.spotEquity,
38703
+ input.absoluteToleranceUsd,
38704
+ input.relativeTolerance
38705
+ ) && approximatelyEqual(
38706
+ input.spotEquity,
38707
+ input.balancesEquity,
38708
+ input.absoluteToleranceUsd,
38709
+ input.relativeTolerance
38710
+ );
38711
+ computeEffectiveAccountValue = (input) => {
38712
+ if (!input.unifiedLike) return input.perpsEquity;
38713
+ if (input.balancesEquity > 0) {
38714
+ if (input.mirrored) {
38715
+ return Math.max(input.perpsEquity, input.spotEquity, input.balancesEquity);
38716
+ }
38717
+ return Math.max(
38718
+ input.perpsEquity + input.balancesEquity,
38719
+ input.spotEquity,
38720
+ input.balancesEquity
38721
+ );
38722
+ }
38723
+ return Math.max(input.perpsEquity, input.spotEquity);
38724
+ };
38725
+ equityFormula = (input) => {
38726
+ if (!input.unifiedLike) return "perps_account_value";
38727
+ if (input.balancesEquity > 0) {
38728
+ if (input.mirrored) return "unified_mirrored_balances_equity";
38729
+ if (input.perpsEquity + input.balancesEquity >= Math.max(input.spotEquity, input.balancesEquity)) return "unified_perps_plus_balances";
38730
+ if (input.spotEquity >= input.balancesEquity) return "unified_spot_account_value";
38731
+ return "unified_balances_equity";
38732
+ }
38733
+ return input.perpsEquity >= input.spotEquity ? "unified_perps_account_value" : "unified_spot_account_value";
38734
+ };
38735
+ buildServerPromptRescueAccountSummary = (perpsResponse, spotResponse, accountMode, options = {}) => {
38736
+ const perps = perpsResponse && typeof perpsResponse === "object" && !Array.isArray(perpsResponse) ? perpsResponse : {};
38737
+ const marginSummary = perps.marginSummary && typeof perps.marginSummary === "object" && !Array.isArray(perps.marginSummary) ? perps.marginSummary : {};
38738
+ const crossMarginSummary = perps.crossMarginSummary && typeof perps.crossMarginSummary === "object" && !Array.isArray(perps.crossMarginSummary) ? perps.crossMarginSummary : {};
38739
+ const rawPerpsAccountValue = toNumber2(marginSummary.accountValue);
38740
+ const perpsAccountValue = Math.max(0, rawPerpsAccountValue);
38741
+ const crossMarginAccountValue = toNumber2(crossMarginSummary.accountValue);
38742
+ let totalMarginUsed = toNumber2(marginSummary.totalMarginUsed);
38743
+ let withdrawable = toNumber2(perps.withdrawable);
38744
+ const spot = accountMode === "disabled" ? { accountValue: 0, totalMarginUsed: 0, withdrawable: 0, balances: [] } : extractCanonicalSpotMetrics(spotResponse);
38745
+ const balances = spot.balances;
38746
+ const balancesEquity = sumBalanceValueUsd(balances);
38747
+ const unifiedLike = isUnifiedAccountMode(accountMode);
38748
+ if (unifiedLike) {
38749
+ totalMarginUsed = Math.max(totalMarginUsed, spot.totalMarginUsed);
38750
+ withdrawable = Math.max(withdrawable, spot.withdrawable);
38751
+ }
38752
+ const absoluteToleranceUsd = firstNumber2([
38753
+ options.mirroredAccountValueAbsoluteToleranceUsd,
38754
+ options.mirrored_account_value_absolute_tolerance_usd
38755
+ ]);
38756
+ const relativeTolerance = firstNumber2([
38757
+ options.mirroredAccountValueRelativeTolerance,
38758
+ options.mirrored_account_value_relative_tolerance
38759
+ ]);
38760
+ const mirrored = balancesMirrorUnifiedAccountValue({
38761
+ perpsEquity: perpsAccountValue,
38762
+ spotEquity: Math.max(spot.accountValue, 0),
38763
+ balancesEquity,
38764
+ absoluteToleranceUsd,
38765
+ relativeTolerance
38766
+ });
38767
+ const formulaInput = {
38768
+ perpsEquity: perpsAccountValue,
38769
+ spotEquity: Math.max(spot.accountValue, 0),
38770
+ balancesEquity,
38771
+ unifiedLike,
38772
+ mirrored
38773
+ };
38774
+ const accountValue = computeEffectiveAccountValue(formulaInput);
38775
+ const maintenanceMargin = toNumber2(perps.crossMaintenanceMarginUsed);
38776
+ const calculatedAvailable = accountValue - totalMarginUsed;
38777
+ const availableMargin = maintenanceMargin > 0 ? Math.max(
38778
+ calculatedAvailable,
38779
+ Math.max(0, accountValue - 4 * maintenanceMargin),
38780
+ withdrawable
38781
+ ) : Math.max(calculatedAvailable, withdrawable);
38782
+ let totalNotional = 0;
38783
+ let totalUnrealizedPnl = 0;
38784
+ const positions = Array.isArray(perps.assetPositions) ? perps.assetPositions : [];
38785
+ for (const entry of positions) {
38786
+ const position = entry && typeof entry === "object" && !Array.isArray(entry) ? entry.position : null;
38787
+ if (!position || typeof position !== "object" || Array.isArray(position)) continue;
38788
+ const size = toNumber2(position.szi);
38789
+ const unrealizedPnl = toNumber2(position.unrealizedPnl);
38790
+ totalUnrealizedPnl += unrealizedPnl;
38791
+ totalNotional += Math.abs(size * toNumber2(position.entryPx) + unrealizedPnl);
38792
+ }
38793
+ return {
38794
+ account_value: accountValue,
38795
+ total_margin_used: totalMarginUsed,
38796
+ available_margin: availableMargin,
38797
+ withdrawable,
38798
+ cross_margin_ratio: accountValue > 0 ? maintenanceMargin / accountValue : 0,
38799
+ maintenance_margin: maintenanceMargin,
38800
+ cross_account_leverage: accountValue > 0 ? totalNotional / accountValue : 0,
38801
+ total_unrealized_pnl: totalUnrealizedPnl,
38802
+ account_mode: accountMode,
38803
+ mode_source: "canonical",
38804
+ balances,
38805
+ raw_account_value: rawPerpsAccountValue,
38806
+ cross_margin_account_value: crossMarginAccountValue,
38807
+ spot_account_value: spot.accountValue,
38808
+ balances_equity: balancesEquity,
38809
+ equity_formula: equityFormula(formulaInput),
38810
+ balance_trust_classification: "trusted_canonical"
38811
+ };
38812
+ };
38813
+ }
38814
+ });
38815
+
38332
38816
  // lib/runtime/abort.ts
38333
38817
  var ABORT_MESSAGE_TOKENS, readAbortLikeMessage, isAbortLikeError;
38334
38818
  var init_abort = __esm({
@@ -38895,6 +39379,8 @@ var init_hyperliquid_account_state_adapter = __esm({
38895
39379
  init_sort_utils();
38896
39380
  init_hyperliquid_account_contract();
38897
39381
  init_hyperliquid_active_asset_contract();
39382
+ init_hyperliquid_account_mode_contract();
39383
+ init_server_prompt_rescue_account_contract();
38898
39384
  init_hyperliquid_market_symbol();
38899
39385
  init_network_debug();
38900
39386
  unsupportedUserActiveAssetCache = /* @__PURE__ */ new Set();
@@ -39010,13 +39496,15 @@ var init_hyperliquid_account_state_adapter = __esm({
39010
39496
  buildUserFillsStorageKey = (cacheKey) => {
39011
39497
  return `${USER_FILLS_CACHE_STORAGE_PREFIX}${cacheKey}`;
39012
39498
  };
39013
- buildAccountStateCacheKey = (apiUrl, walletAddress, symbol2, aggregatePerpDexs, dexNames, includeEffectiveTakerRate) => {
39499
+ buildAccountStateCacheKey = (apiUrl, walletAddress, symbol2, aggregatePerpDexs, dexNames, includeEffectiveTakerRate, includeExactAccountMode, includeActiveAssetData) => {
39014
39500
  return [
39015
39501
  apiUrl.replace(/\/$/, "").toLowerCase(),
39016
39502
  walletAddress.trim().toLowerCase(),
39017
39503
  normalizeHyperliquidMarketSymbol(symbol2),
39018
39504
  aggregatePerpDexs ? "aggregate" : "selected",
39019
39505
  includeEffectiveTakerRate ? "with-effective-taker-rate" : "without-effective-taker-rate",
39506
+ includeExactAccountMode ? "with-exact-account-mode" : "without-exact-account-mode",
39507
+ includeActiveAssetData ? "with-active-asset" : "without-active-asset",
39020
39508
  ...dexNames.map(normalizePerpDexName).sort()
39021
39509
  ].join("::");
39022
39510
  };
@@ -39226,7 +39714,8 @@ var init_hyperliquid_account_state_adapter = __esm({
39226
39714
  accountSummary: { ...result2.accountSummary },
39227
39715
  availableToTrade: { ...result2.availableToTrade },
39228
39716
  positions: result2.positions.map((position) => ({ ...position })),
39229
- ...result2.takerRate == null ? {} : { takerRate: result2.takerRate }
39717
+ ...result2.takerRate == null ? {} : { takerRate: result2.takerRate },
39718
+ ...result2.promptRescueEvidence == null ? {} : { promptRescueEvidence: { ...result2.promptRescueEvidence } }
39230
39719
  });
39231
39720
  readBrowserAccountStateCache = (cacheKey) => {
39232
39721
  const memoryEntry = browserAccountStateCache.get(cacheKey);
@@ -39256,7 +39745,8 @@ var init_hyperliquid_account_state_adapter = __esm({
39256
39745
  accountSummary: { ...result2.accountSummary || {} },
39257
39746
  availableToTrade: { ...result2.availableToTrade || {} },
39258
39747
  positions: Array.isArray(result2.positions) ? result2.positions.filter((position) => position !== null && typeof position === "object" && !Array.isArray(position)).map((position) => ({ ...position })) : [],
39259
- ...result2.takerRate == null ? {} : { takerRate: Number(result2.takerRate) }
39748
+ ...result2.takerRate == null ? {} : { takerRate: Number(result2.takerRate) },
39749
+ ...result2.promptRescueEvidence == null ? {} : { promptRescueEvidence: { ...result2.promptRescueEvidence } }
39260
39750
  }
39261
39751
  };
39262
39752
  if (entry.result.takerRate != null && (!Number.isFinite(entry.result.takerRate) || entry.result.takerRate < 0 || entry.result.takerRate >= 1)) {
@@ -39684,6 +40174,8 @@ var init_hyperliquid_account_state_adapter = __esm({
39684
40174
  const activeAssetRequestTypes = getBrowserActiveAssetTypeCandidates(apiUrl, walletAddress, symbol2);
39685
40175
  const aggregatePerpDexs = input.aggregatePerpDexs !== false;
39686
40176
  const includeEffectiveTakerRate = input.includeEffectiveTakerRate === true;
40177
+ const includeExactAccountMode = input.includeExactAccountMode === true;
40178
+ const includeActiveAssetData = input.includeActiveAssetData !== false;
39687
40179
  const dexNames = listPerpDexsForAccountState(input.config, dex, aggregatePerpDexs);
39688
40180
  const cacheKey = buildAccountStateCacheKey(
39689
40181
  apiUrl,
@@ -39691,7 +40183,9 @@ var init_hyperliquid_account_state_adapter = __esm({
39691
40183
  symbol2,
39692
40184
  aggregatePerpDexs,
39693
40185
  dexNames,
39694
- includeEffectiveTakerRate
40186
+ includeEffectiveTakerRate,
40187
+ includeExactAccountMode,
40188
+ includeActiveAssetData
39695
40189
  );
39696
40190
  const now = Date.now();
39697
40191
  const cached2 = readBrowserAccountStateCache(cacheKey);
@@ -39702,7 +40196,8 @@ var init_hyperliquid_account_state_adapter = __esm({
39702
40196
  "clearinghouseState",
39703
40197
  "spotClearinghouseState",
39704
40198
  ...includeEffectiveTakerRate ? ["userFees"] : [],
39705
- ...activeAssetRequestTypes
40199
+ ...includeExactAccountMode ? ["userAbstraction", "userDexAbstraction"] : [],
40200
+ ...includeActiveAssetData ? activeAssetRequestTypes : []
39706
40201
  ], now)) {
39707
40202
  return cloneBrowserAccountStateResult(cached2.result);
39708
40203
  }
@@ -39780,20 +40275,29 @@ var init_hyperliquid_account_state_adapter = __esm({
39780
40275
  return prefixHip3PositionCoins(response, dexName);
39781
40276
  })
39782
40277
  );
39783
- return aggregateClearinghouseResponses([defaultResponse, ...dexResponses]);
40278
+ return {
40279
+ payload: aggregateClearinghouseResponses([defaultResponse, ...dexResponses]),
40280
+ capturedAt: (/* @__PURE__ */ new Date()).toISOString()
40281
+ };
39784
40282
  })();
39785
- const spotPromise = fetchHyperliquidInfoPayload(
39786
- apiUrl,
39787
- { type: "spotClearinghouseState", user: walletAddress },
39788
- input.signal
39789
- ).catch((error48) => {
39790
- recordInfoRateLimitCooldownFromError(apiUrl, error48, staleIf429MaxAgeMs);
39791
- if (input.forceRefresh || input.includeEffectiveTakerRate === true) {
39792
- throw error48;
40283
+ const spotPromise = (async () => {
40284
+ let payload;
40285
+ try {
40286
+ payload = await fetchHyperliquidInfoPayload(
40287
+ apiUrl,
40288
+ { type: "spotClearinghouseState", user: walletAddress },
40289
+ input.signal
40290
+ );
40291
+ } catch (error48) {
40292
+ recordInfoRateLimitCooldownFromError(apiUrl, error48, staleIf429MaxAgeMs);
40293
+ if (input.forceRefresh || input.includeEffectiveTakerRate === true) {
40294
+ throw error48;
40295
+ }
40296
+ payload = {};
39793
40297
  }
39794
- return {};
39795
- });
39796
- const activeAssetPromise = (async () => {
40298
+ return { payload, capturedAt: (/* @__PURE__ */ new Date()).toISOString() };
40299
+ })();
40300
+ const activeAssetPromise = input.includeActiveAssetData === false ? Promise.resolve(null) : (async () => {
39797
40301
  let lastError = null;
39798
40302
  for (const typeName of activeAssetRequestTypes) {
39799
40303
  try {
@@ -39813,17 +40317,50 @@ var init_hyperliquid_account_state_adapter = __esm({
39813
40317
  }
39814
40318
  throw lastError instanceof Error ? lastError : new Error("Failed to fetch browser active asset data.");
39815
40319
  })();
39816
- const userFeesPromise = input.includeEffectiveTakerRate === true ? fetchHyperliquidInfoPayload(
39817
- apiUrl,
39818
- { type: "userFees", user: walletAddress },
39819
- input.signal
39820
- ) : Promise.resolve(null);
39821
- const [perpsResponse, spotResponse, activeAssetResult, userFeesResponse] = await Promise.all([
40320
+ const userFeesPromise = input.includeEffectiveTakerRate === true ? (async () => ({
40321
+ payload: await fetchHyperliquidInfoPayload(
40322
+ apiUrl,
40323
+ { type: "userFees", user: walletAddress },
40324
+ input.signal
40325
+ ),
40326
+ capturedAt: (/* @__PURE__ */ new Date()).toISOString()
40327
+ }))() : Promise.resolve(null);
40328
+ const exactAccountModePromise = input.includeExactAccountMode === true ? (async () => {
40329
+ const userAbstraction = await fetchHyperliquidInfoPayload(
40330
+ apiUrl,
40331
+ { type: "userAbstraction", user: walletAddress },
40332
+ input.signal
40333
+ );
40334
+ const preliminaryMode = extractCanonicalHyperliquidAccountMode(userAbstraction);
40335
+ if (!preliminaryMode) {
40336
+ throw new Error("Exact Hyperliquid userAbstraction response is invalid.");
40337
+ }
40338
+ let userDexAbstraction;
40339
+ if (preliminaryMode === "default" || preliminaryMode === "disabled") {
40340
+ userDexAbstraction = await fetchHyperliquidInfoPayload(
40341
+ apiUrl,
40342
+ { type: "userDexAbstraction", user: walletAddress },
40343
+ input.signal
40344
+ );
40345
+ }
40346
+ return {
40347
+ accountMode: resolveExactHyperliquidAccountMode(
40348
+ userAbstraction,
40349
+ userDexAbstraction
40350
+ ),
40351
+ capturedAt: (/* @__PURE__ */ new Date()).toISOString()
40352
+ };
40353
+ })() : Promise.resolve(null);
40354
+ const [perpsResult, spotResult, activeAssetResult, userFeesResult, exactAccountMode] = await Promise.all([
39822
40355
  perpsPromise,
39823
40356
  spotPromise,
39824
40357
  activeAssetPromise,
39825
- userFeesPromise
40358
+ userFeesPromise,
40359
+ exactAccountModePromise
39826
40360
  ]);
40361
+ const perpsResponse = perpsResult.payload;
40362
+ const spotResponse = spotResult.payload;
40363
+ const userFeesResponse = userFeesResult?.payload ?? null;
39827
40364
  if (input.includeEffectiveTakerRate === true) {
39828
40365
  requirePromptSpotState(spotResponse);
39829
40366
  }
@@ -39843,20 +40380,32 @@ var init_hyperliquid_account_state_adapter = __esm({
39843
40380
  takerRate = parsedUserCrossRate;
39844
40381
  }
39845
40382
  const accountStateConfig = input.config.client_runtime_hyperliquid_account_state;
39846
- const normalizedSummary = buildAccountSummaryFromInfoResponses(perpsResponse, spotResponse, {
40383
+ const summaryPerpsResponse = exactAccountMode ? { ...perpsResponse, accountMode: exactAccountMode.accountMode } : perpsResponse;
40384
+ const accountSummaryOptions = {
39847
40385
  spotDominatesMinTotalUsd: accountStateConfig?.spot_dominates_min_total_usd,
39848
40386
  spotDominatesPerpsMultiplier: accountStateConfig?.spot_dominates_perps_multiplier,
39849
40387
  mirroredAccountValueAbsoluteToleranceUsd: accountStateConfig?.mirrored_account_value_absolute_tolerance_usd,
39850
40388
  mirroredAccountValueRelativeTolerance: accountStateConfig?.mirrored_account_value_relative_tolerance
39851
- });
40389
+ };
40390
+ const normalizedSummary = exactAccountMode ? buildServerPromptRescueAccountSummary(
40391
+ perpsResponse,
40392
+ spotResponse,
40393
+ exactAccountMode.accountMode,
40394
+ accountSummaryOptions
40395
+ ) : buildAccountSummaryFromInfoResponses(
40396
+ summaryPerpsResponse,
40397
+ spotResponse,
40398
+ accountSummaryOptions
40399
+ );
39852
40400
  const accountSummary = {
39853
40401
  ...normalizedSummary,
40402
+ ...exactAccountMode == null ? {} : { account_mode: exactAccountMode.accountMode, mode_source: "canonical" },
39854
40403
  address: walletAddress,
39855
40404
  dex: "all",
39856
40405
  market_type: "perp"
39857
40406
  };
39858
- const activeAssetPayload = activeAssetResult.payload;
39859
- const activeAssetType = activeAssetResult.type;
40407
+ const activeAssetPayload = activeAssetResult?.payload ?? null;
40408
+ const activeAssetType = activeAssetResult?.type ?? "promptAccountState";
39860
40409
  const normalizedActiveAsset = normalizeActiveAssetData(activeAssetPayload, symbol2);
39861
40410
  const markPrice = toPositiveFinite(normalizedActiveAsset.mark_price, toPositiveFinite(input.tickerPrice));
39862
40411
  const fallbackLeverage = toPositiveFinite(input.leverage, 1);
@@ -39874,7 +40423,17 @@ var init_hyperliquid_account_state_adapter = __esm({
39874
40423
  accountSummary,
39875
40424
  availableToTrade,
39876
40425
  positions: parseInfoPositions(perpsResponse),
39877
- ...takerRate == null ? {} : { takerRate }
40426
+ ...takerRate == null ? {} : { takerRate },
40427
+ ...exactAccountMode == null || userFeesResult == null ? {} : {
40428
+ promptRescueEvidence: {
40429
+ capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
40430
+ perpsCapturedAt: perpsResult.capturedAt,
40431
+ spotCapturedAt: spotResult.capturedAt,
40432
+ feesCapturedAt: userFeesResult.capturedAt,
40433
+ accountModeCapturedAt: exactAccountMode.capturedAt,
40434
+ accountModeSource: "canonical"
40435
+ }
40436
+ }
39878
40437
  };
39879
40438
  };
39880
40439
  fetchBrowserUserFills = async (input) => {
@@ -51032,6 +51591,145 @@ var init_runtime_handoff = __esm({
51032
51591
  }
51033
51592
  });
51034
51593
 
51594
+ // lib/runtime/status-contract.ts
51595
+ var init_status_contract = __esm({
51596
+ "lib/runtime/status-contract.ts"() {
51597
+ "use strict";
51598
+ }
51599
+ });
51600
+
51601
+ // lib/runtime/error-surface-contract.ts
51602
+ var SENSITIVE_DB_TOKENS, SCHEMA_DISCLOSURE_TOKENS, SQL_STATEMENT_PATTERN, TRACEBACK_PATTERN, DB_SESSION_STATE_PATTERNS, isSensitiveRuntimeErrorDetail, EXECUTION_ERROR_DEFAULTS, isExecutionErrorReasonCode, RuntimeExecutionError, projectExecutionErrorContract;
51603
+ var init_error_surface_contract = __esm({
51604
+ "lib/runtime/error-surface-contract.ts"() {
51605
+ "use strict";
51606
+ init_status_contract();
51607
+ init_runtime_redaction();
51608
+ SENSITIVE_DB_TOKENS = [
51609
+ "sqlalchemy",
51610
+ "asyncpg",
51611
+ "psycopg",
51612
+ "dbapi",
51613
+ "programmingerror",
51614
+ "undefinedcolumnerror",
51615
+ "integrityerror",
51616
+ "statementerror",
51617
+ "queuepool",
51618
+ "postgresql",
51619
+ "sqlite"
51620
+ ];
51621
+ SCHEMA_DISCLOSURE_TOKENS = [
51622
+ " column ",
51623
+ " table ",
51624
+ " schema ",
51625
+ " relation ",
51626
+ " constraint "
51627
+ ];
51628
+ SQL_STATEMENT_PATTERN = /\b(select|insert|update|delete)\b[\s\S]{0,300}\bfrom\b/i;
51629
+ TRACEBACK_PATTERN = /traceback \(most recent call last\):/i;
51630
+ DB_SESSION_STATE_PATTERNS = [
51631
+ /\bthis session is in ['"]?\w+['"]? state\b/i,
51632
+ /\bno further sql can be emitted within this transaction\b/i,
51633
+ /\bcan(?:not|'t) reconnect until (?:the )?invalid transaction is rolled back\b/i,
51634
+ /\bthis session(?:'s)? transaction has been rolled back due to a previous exception\b/i,
51635
+ /\bthis transaction is (?:closed|inactive)\b/i,
51636
+ /\bthis session is provisioning a new connection; concurrent operations are not permitted\b/i,
51637
+ /\bthis session has been permanently closed\b/i,
51638
+ /\binvalid savepoint transaction\b/i
51639
+ ];
51640
+ isSensitiveRuntimeErrorDetail = (error48) => {
51641
+ const message = String(error48 || "").trim();
51642
+ if (!message) {
51643
+ return false;
51644
+ }
51645
+ const lowered = message.toLowerCase();
51646
+ if (TRACEBACK_PATTERN.test(lowered) || lowered.includes("[sql:")) {
51647
+ return true;
51648
+ }
51649
+ if (SENSITIVE_DB_TOKENS.some((token) => lowered.includes(token))) {
51650
+ return true;
51651
+ }
51652
+ if (DB_SESSION_STATE_PATTERNS.some((pattern) => pattern.test(message))) {
51653
+ return true;
51654
+ }
51655
+ return SQL_STATEMENT_PATTERN.test(lowered) && SCHEMA_DISCLOSURE_TOKENS.some((token) => ` ${lowered} `.includes(token));
51656
+ };
51657
+ EXECUTION_ERROR_DEFAULTS = {
51658
+ private_node_stale: ["preflight", "not_dispatched"],
51659
+ signer_validation_unavailable: ["preflight", "not_dispatched"],
51660
+ wallet_not_authorized: ["preflight", "not_dispatched"],
51661
+ credentials_missing: ["preflight", "not_dispatched"],
51662
+ local_safety_block: ["preflight", "not_dispatched"],
51663
+ redis_unavailable: ["coordination", "not_dispatched"],
51664
+ exchange_rejected: ["exchange_response", "confirmed_dispatched"],
51665
+ outcome_unknown: ["transport", "outcome_unknown"],
51666
+ internal_execution_error: ["execution", "unknown"]
51667
+ };
51668
+ isExecutionErrorReasonCode = (value) => Object.prototype.hasOwnProperty.call(EXECUTION_ERROR_DEFAULTS, value);
51669
+ RuntimeExecutionError = class extends Error {
51670
+ constructor(message, reasonCode) {
51671
+ super(message);
51672
+ this.name = "RuntimeExecutionError";
51673
+ this.reasonCode = reasonCode;
51674
+ this.executionStage = EXECUTION_ERROR_DEFAULTS[reasonCode][0];
51675
+ this.dispatchOutcome = EXECUTION_ERROR_DEFAULTS[reasonCode][1];
51676
+ }
51677
+ };
51678
+ projectExecutionErrorContract = (input) => {
51679
+ const {
51680
+ error: error48,
51681
+ symbol: symbol2 = null,
51682
+ reasonCode = null
51683
+ } = input;
51684
+ const typed = error48;
51685
+ const rawReason = String(reasonCode || typed?.reasonCode || "internal_execution_error").trim().toLowerCase();
51686
+ const resolvedReason = isExecutionErrorReasonCode(rawReason) ? rawReason : "internal_execution_error";
51687
+ const defaults = EXECUTION_ERROR_DEFAULTS[resolvedReason];
51688
+ const resolvedStage = defaults[0];
51689
+ const resolvedDispatch = defaults[1];
51690
+ const normalizedSymbol = String(symbol2 || "").trim();
51691
+ const orderLabel = normalizedSymbol ? `${normalizedSymbol} order` : "order";
51692
+ const rawMessage = sanitizeRuntimeDiagnosticValue(
51693
+ error48 instanceof Error ? error48.message : String(error48 || "").trim()
51694
+ );
51695
+ let message;
51696
+ if (resolvedReason === "private_node_stale") {
51697
+ message = `\u26A0\uFE0F The ${orderLabel} was not sent: Hyperliquid private account data was too stale to validate the signing key.`;
51698
+ } else if (resolvedReason === "signer_validation_unavailable") {
51699
+ message = `\u26A0\uFE0F The ${orderLabel} was not sent: Hyperliquid's private account service could not validate the signing key.`;
51700
+ } else if (resolvedReason === "wallet_not_authorized") {
51701
+ message = `\u26A0\uFE0F The ${orderLabel} was not sent: the signing key is not authorized for the configured wallet.`;
51702
+ } else if (resolvedReason === "credentials_missing") {
51703
+ message = `\u26A0\uFE0F The ${orderLabel} was not sent: a wallet address and authorized signing key are required for trading.`;
51704
+ } else if (resolvedReason === "local_safety_block") {
51705
+ const detail = isSensitiveRuntimeErrorDetail(rawMessage) ? "Local preflight validation failed." : rawMessage || "Local preflight validation failed.";
51706
+ const canonicalDetail = detail.replace(/^⚠️?\s*The (?:.+ )?order was not sent before exchange dispatch:\s*/i, "").trim() || "Local preflight validation failed.";
51707
+ message = `\u26A0\uFE0F The ${orderLabel} was not sent before exchange dispatch: ${canonicalDetail}`;
51708
+ } else if (resolvedReason === "redis_unavailable") {
51709
+ message = `\u26A0\uFE0F The ${orderLabel} was not sent because execution coordination was unavailable.`;
51710
+ } else if (resolvedReason === "exchange_rejected") {
51711
+ let detail = isSensitiveRuntimeErrorDetail(rawMessage) ? "The exchange did not provide safe rejection details." : rawMessage || "The exchange did not provide safe rejection details.";
51712
+ detail = detail.replace(/^⚠️?\s*Hyperliquid rejected the (?:.+ )?order:\s*/i, "").trim();
51713
+ detail = detail.replace(/^(?:Hyperliquid rejected order:|Order execution failed:|order execution failed:)\s*/, "");
51714
+ detail = detail.replace(/\s+asset=\d+\b\.?/g, "").trim() || "The exchange did not provide safe rejection details.";
51715
+ message = `\u26A0\uFE0F Hyperliquid rejected the ${orderLabel}: ${detail}`;
51716
+ } else if (resolvedReason === "outcome_unknown") {
51717
+ message = `\u26A0\uFE0F VTX could not confirm whether the ${orderLabel} was applied. Check open orders and the current position before retrying.`;
51718
+ } else {
51719
+ const detail = isSensitiveRuntimeErrorDetail(rawMessage) ? "VTX could not complete the exchange operation." : rawMessage || "VTX could not complete the exchange operation.";
51720
+ const canonicalDetail = detail.replace(/^⚠️?\s*VTX could not complete the (?:.+ )?order:\s*/i, "").trim() || "VTX could not complete the exchange operation.";
51721
+ message = `\u26A0\uFE0F VTX could not complete the ${orderLabel}: ${canonicalDetail}`;
51722
+ }
51723
+ return {
51724
+ reason_code: resolvedReason,
51725
+ execution_stage: resolvedStage,
51726
+ dispatch_outcome: resolvedDispatch,
51727
+ message
51728
+ };
51729
+ };
51730
+ }
51731
+ });
51732
+
51035
51733
  // lib/runtime/hyperliquid-client.ts
51036
51734
  var HyperliquidExchangeRejectionError, durableMutationAuthorityArgs, assertFreshPreparedExecutionContext, HYPERLIQUID_TERMINAL_ORDER_STATUSES, normalizeSymbol, HYPERLIQUID_NONCE_STORAGE_KEY, HYPERLIQUID_NONCE_LOCK_NAME, lastGeneratedNonce, readBrowserStoredHyperliquidNonce, writeBrowserStoredHyperliquidNonce, browserNonceCoordinator, allocateHyperliquidNonce, generateHyperliquidNonce, roundToSigFigs, normalizeDecimalString, toPlainDecimalString, roundDirectionalDecimalString, formatHyperliquidPerpPriceWire, formatHyperliquidTriggerPriceWire, countSignificantDigits, countDecimalPlaces, validateHyperliquidPerpPriceWire, validateHyperliquidSizeWire, formatSizeWire, inferApiUrl, inferIsTestnet, postHyperliquidInfo, toFiniteNumber, OPEN_ORDER_NUMERIC_STRING, OPEN_ORDER_ID_STRING, parseCanonicalOpenOrderId, parseOpenOrderFiniteNumber, parseOpenOrderPositiveNumber, parseOpenOrderPresentationNumber, readOpenOrderField, firstFiniteNumber2, parseFundingUsdcFromInfoPosition2, isExchangeIsolatedOnly, computeHip3AssetId, getPerpDexIndexMap, buildAssetInfosFromMetaResponse, requireWalletAddress2, assertPositiveInteger, assertPositiveNumber, normalizeOrderSide, normalizeHyperliquidClientOrderId, resolveAssets, findResolvedAsset, normalizeExecutionAssetMetadata, resolveHyperliquidAsset, resolveHyperliquidAssetIndex, fetchBrowserAvailableAssets, fetchBrowserAllMids, fetchBrowserSymbolMidPrice, fetchBrowserOpenOrders, parseCanonicalHyperliquidOrderStatusEvidence, fetchBrowserOrderStatusEvidence, fetchBrowserUserRole, fetchBrowserAccountState2, fetchBrowserPosition, buildHyperliquidOrderWire, buildHyperliquidTriggerOrderWire, signHyperliquidPayload, buildHyperliquidCancelPayload, buildHyperliquidUpdateLeveragePayload, buildHyperliquidMarketOrderPayload, buildHyperliquidTriggerOrderPayload, buildHyperliquidOrderBatchPayload, buildHyperliquidModifyOrderPayload, extractHyperliquidExchangeError, isDefinitiveHyperliquidExchangeResponse, extractDefinitiveHyperliquidOrderId, CANONICAL_POSITIVE_DECIMAL_PATTERN, extractCanonicalHyperliquidOrderStateAcknowledgement, extractCanonicalHyperliquidOrderStateAcknowledgements, extractCanonicalHyperliquidFilledOrderAcknowledgement, extractDefinitiveHyperliquidOrderMemberResults, buildHyperliquidOrderDiagnostics, loadClientExecutionReferenceEvidence, sha256Hex, extractSignedPayloadClientOrderId, extractSignedPayloadMutationCorrelation, assertDurableMutationMatchesSignedAction, submitHyperliquidExchangePayload;
51037
51735
  var init_hyperliquid_client = __esm({
@@ -51045,9 +51743,10 @@ var init_hyperliquid_client = __esm({
51045
51743
  init_runtime_redaction();
51046
51744
  init_exchange_mutation_fence();
51047
51745
  init_runtime_handoff();
51048
- HyperliquidExchangeRejectionError = class extends Error {
51746
+ init_error_surface_contract();
51747
+ HyperliquidExchangeRejectionError = class extends RuntimeExecutionError {
51049
51748
  constructor(message, orderDiagnostics, clientMutationId = null) {
51050
- super(message);
51749
+ super(message, "exchange_rejected");
51051
51750
  this.name = "HyperliquidExchangeRejectionError";
51052
51751
  this.orderDiagnostics = orderDiagnostics;
51053
51752
  this.clientMutationId = clientMutationId;
@@ -52745,8 +53444,9 @@ var init_hyperliquid_client = __esm({
52745
53444
  ...durableMutationAuthorityArgs(durableMutation)
52746
53445
  );
52747
53446
  if (beginResult.dispatch_authorized !== true) {
52748
- throw new Error(
52749
- "This exchange mutation was already recorded and will not be dispatched again. Durable reconciliation is required before retrying."
53447
+ throw new RuntimeExecutionError(
53448
+ "This exchange mutation was already recorded and will not be dispatched again. Durable reconciliation is required before retrying.",
53449
+ "local_safety_block"
52750
53450
  );
52751
53451
  }
52752
53452
  }
@@ -52769,8 +53469,9 @@ var init_hyperliquid_client = __esm({
52769
53469
  ...durableMutationAuthorityArgs(durableMutation)
52770
53470
  );
52771
53471
  } catch {
52772
- throw new Error(
52773
- "Exchange submission may have completed; durable reconciliation is pending."
53472
+ throw new RuntimeExecutionError(
53473
+ "Exchange submission may have completed; durable reconciliation is pending.",
53474
+ "outcome_unknown"
52774
53475
  );
52775
53476
  }
52776
53477
  };
@@ -52854,7 +53555,10 @@ var init_hyperliquid_client = __esm({
52854
53555
  assertFreshPreparedExecutionContext(input.preparedContext);
52855
53556
  } catch (preparedContextError) {
52856
53557
  await settleDurableMutation("rejected");
52857
- throw preparedContextError;
53558
+ throw new RuntimeExecutionError(
53559
+ preparedContextError instanceof Error ? preparedContextError.message : "Prepared exchange context expired before dispatch.",
53560
+ "local_safety_block"
53561
+ );
52858
53562
  }
52859
53563
  if (input.signal?.aborted) {
52860
53564
  await settleDurableMutation("rejected");
@@ -52886,8 +53590,9 @@ var init_hyperliquid_client = __esm({
52886
53590
  const payload = await response.json().catch(() => ({}));
52887
53591
  if (!response.ok) {
52888
53592
  await settleDurableMutation("transport_ambiguous");
52889
- throw new Error(
52890
- "Exchange submission may have completed; durable reconciliation is pending."
53593
+ throw new RuntimeExecutionError(
53594
+ "Exchange submission may have completed; durable reconciliation is pending.",
53595
+ "outcome_unknown"
52891
53596
  );
52892
53597
  }
52893
53598
  const exchangeError = extractHyperliquidExchangeError(payload);
@@ -52896,8 +53601,9 @@ var init_hyperliquid_client = __esm({
52896
53601
  exchangeError.partial ? "transport_ambiguous" : "rejected"
52897
53602
  );
52898
53603
  if (exchangeError.partial) {
52899
- throw new Error(
52900
- "Hyperliquid returned a partially applied exchange response; durable reconciliation is pending."
53604
+ throw new RuntimeExecutionError(
53605
+ "Hyperliquid returned a partially applied exchange response; durable reconciliation is pending.",
53606
+ "outcome_unknown"
52901
53607
  );
52902
53608
  }
52903
53609
  throw new HyperliquidExchangeRejectionError(
@@ -52911,8 +53617,9 @@ var init_hyperliquid_client = __esm({
52911
53617
  input.payload.action
52912
53618
  )) {
52913
53619
  await settleDurableMutation("transport_ambiguous");
52914
- throw new Error(
52915
- "Hyperliquid returned an incomplete exchange response; durable reconciliation is pending."
53620
+ throw new RuntimeExecutionError(
53621
+ "Hyperliquid returned an incomplete exchange response; durable reconciliation is pending.",
53622
+ "outcome_unknown"
52916
53623
  );
52917
53624
  }
52918
53625
  const exactExchangeOrderId = durableMutation?.operationKind === "order" ? extractDefinitiveHyperliquidOrderId(payload, input.payload.action) : null;
@@ -52934,12 +53641,14 @@ var init_hyperliquid_client = __esm({
52934
53641
  try {
52935
53642
  await settleDurableMutation("transport_ambiguous");
52936
53643
  } catch {
52937
- throw new Error(
52938
- "Exchange submission may have completed; durable reconciliation is pending."
53644
+ throw new RuntimeExecutionError(
53645
+ "Exchange submission may have completed; durable reconciliation is pending.",
53646
+ "outcome_unknown"
52939
53647
  );
52940
53648
  }
52941
- throw new Error(
52942
- "Exchange submission may have completed; durable reconciliation is pending."
53649
+ throw new RuntimeExecutionError(
53650
+ "Exchange submission may have completed; durable reconciliation is pending.",
53651
+ "outcome_unknown"
52943
53652
  );
52944
53653
  }
52945
53654
  throw error48;
@@ -52961,6 +53670,7 @@ var init_hyperliquid_signer_binding = __esm({
52961
53670
  "use strict";
52962
53671
  init_lib2();
52963
53672
  init_hyperliquid_client();
53673
+ init_error_surface_contract();
52964
53674
  normalizeAddress = (value, label) => {
52965
53675
  const normalized = String(value || "").trim().toLowerCase();
52966
53676
  if (!/^0x[0-9a-f]{40}$/.test(normalized)) {
@@ -52983,7 +53693,15 @@ var init_hyperliquid_signer_binding = __esm({
52983
53693
  return null;
52984
53694
  };
52985
53695
  assertBrowserHyperliquidSignerWalletBinding = async (input) => {
52986
- const walletAddress = normalizeAddress(input.walletAddress, "wallet address");
53696
+ let walletAddress;
53697
+ try {
53698
+ walletAddress = normalizeAddress(input.walletAddress, "wallet address");
53699
+ } catch {
53700
+ throw new RuntimeExecutionError(
53701
+ "A valid Hyperliquid wallet address is required for trading.",
53702
+ "credentials_missing"
53703
+ );
53704
+ }
52987
53705
  let signerAddress;
52988
53706
  try {
52989
53707
  signerAddress = normalizeAddress(
@@ -52991,13 +53709,25 @@ var init_hyperliquid_signer_binding = __esm({
52991
53709
  "signer address"
52992
53710
  );
52993
53711
  } catch {
52994
- throw new Error("Invalid Hyperliquid signing key.");
53712
+ throw new RuntimeExecutionError(
53713
+ "Invalid Hyperliquid signing key.",
53714
+ "credentials_missing"
53715
+ );
53716
+ }
53717
+ let roleResponse;
53718
+ try {
53719
+ roleResponse = await fetchBrowserUserRole({
53720
+ config: input.config ?? null,
53721
+ walletAddress: signerAddress,
53722
+ signal: input.signal
53723
+ });
53724
+ } catch (error48) {
53725
+ if (input.signal?.aborted) throw error48;
53726
+ throw new RuntimeExecutionError(
53727
+ "Hyperliquid's private account service could not validate the signing key.",
53728
+ "signer_validation_unavailable"
53729
+ );
52995
53730
  }
52996
- const roleResponse = await fetchBrowserUserRole({
52997
- config: input.config ?? null,
52998
- walletAddress: signerAddress,
52999
- signal: input.signal
53000
- });
53001
53731
  const signerRole = String(roleResponse.role || "").trim().toLowerCase();
53002
53732
  if (signerRole === "user" && signerAddress === walletAddress) {
53003
53733
  return {
@@ -53019,8 +53749,9 @@ var init_hyperliquid_signer_binding = __esm({
53019
53749
  };
53020
53750
  }
53021
53751
  }
53022
- throw new Error(
53023
- "The device Hyperliquid signing key is not authorized for this profile wallet. Stop the runtime and reconnect the wallet."
53752
+ throw new RuntimeExecutionError(
53753
+ "The device Hyperliquid signing key is not authorized for this profile wallet. Stop the runtime and reconnect the wallet.",
53754
+ "wallet_not_authorized"
53024
53755
  );
53025
53756
  };
53026
53757
  }
@@ -53755,6 +54486,7 @@ var init_browser_trading = __esm({
53755
54486
  "use strict";
53756
54487
  init_hyperliquid_client();
53757
54488
  init_hyperliquid_signer_binding();
54489
+ init_error_surface_contract();
53758
54490
  init_vault();
53759
54491
  resolveProfileId = (value) => {
53760
54492
  const profileId = String(value).trim();
@@ -53840,7 +54572,10 @@ var init_browser_trading = __esm({
53840
54572
  }
53841
54573
  }
53842
54574
  if (!signingKey) {
53843
- throw new Error("Missing required device-local Hyperliquid signing key for this profile. Configure it in System for this device.");
54575
+ throw new RuntimeExecutionError(
54576
+ "Missing required device-local Hyperliquid signing key for this profile. Configure it in System for this device.",
54577
+ "credentials_missing"
54578
+ );
53844
54579
  }
53845
54580
  return signingKey;
53846
54581
  };
@@ -53849,7 +54584,10 @@ var init_browser_trading = __esm({
53849
54584
  const signingKey = explicit || await loadSigningKey(resolveProfileId(input.profileId));
53850
54585
  const walletAddress = String(input.walletAddress || "").trim();
53851
54586
  if (!walletAddress) {
53852
- throw new Error("Missing wallet address for client Hyperliquid signing.");
54587
+ throw new RuntimeExecutionError(
54588
+ "Missing wallet address for client Hyperliquid signing.",
54589
+ "credentials_missing"
54590
+ );
53853
54591
  }
53854
54592
  await assertBrowserHyperliquidSignerWalletBinding({
53855
54593
  signingKey,
@@ -54358,6 +55096,7 @@ var init_runtime_execution = __esm({
54358
55096
  init_hyperliquid_market_symbol();
54359
55097
  init_network_debug();
54360
55098
  init_runtime_redaction();
55099
+ init_error_surface_contract();
54361
55100
  init_runtime_handoff();
54362
55101
  fetchClientRuntimeOpenOrders = async (request) => {
54363
55102
  const normalizedSymbol = normalizeHyperliquidMarketSymbol(
@@ -55835,6 +56574,7 @@ var init_runtime_execution = __esm({
55835
56574
  }
55836
56575
  }
55837
56576
  for (const candidate of candidates) {
56577
+ const rejectionProjection = error48 instanceof HyperliquidExchangeRejectionError ? projectExecutionErrorContract({ error: error48, symbol: symbol2 }) : null;
55838
56578
  reports.push({
55839
56579
  order_id: null,
55840
56580
  client_mutation_id: error48 instanceof HyperliquidExchangeRejectionError ? error48.clientMutationId ?? candidate.mutationId : candidate.mutationId,
@@ -55842,10 +56582,12 @@ var init_runtime_execution = __esm({
55842
56582
  action: candidate.kind === "sl" ? "AUTO_SL" : "AUTO_TP",
55843
56583
  status: error48 instanceof HyperliquidExchangeRejectionError ? "failed" : "blocked",
55844
56584
  execution_metadata: {
55845
- reason_code: error48 instanceof HyperliquidExchangeRejectionError ? "execution_error" : "protective_trigger_ack_unresolved",
55846
- error: getSanitizedRuntimeErrorMessage(error48) || "Protective trigger submission is unresolved.",
56585
+ reason_code: error48 instanceof HyperliquidExchangeRejectionError ? rejectionProjection?.reason_code : "protective_trigger_ack_unresolved",
56586
+ error: rejectionProjection?.message ?? getSanitizedRuntimeErrorMessage(error48) ?? "Protective trigger submission is unresolved.",
55847
56587
  ...error48 instanceof HyperliquidExchangeRejectionError ? {
55848
- execution_stage: "protective_trigger_order",
56588
+ execution_stage: rejectionProjection?.execution_stage,
56589
+ dispatch_outcome: rejectionProjection?.dispatch_outcome,
56590
+ operation_stage: "protective_trigger_order",
55849
56591
  entry_order_id: fill.orderId,
55850
56592
  order_diagnostics: error48.orderDiagnostics
55851
56593
  } : {}
@@ -58904,15 +59646,21 @@ var init_runtime_execution = __esm({
58904
59646
  execution_metadata: _toExecutionMetadata(marketOrderResponse)
58905
59647
  });
58906
59648
  const appendPostEntryProtectionFailure = (error48) => {
58907
- const message = getSanitizedRuntimeErrorMessage(error48) || "Unknown post-entry protection error.";
59649
+ const projection = projectExecutionErrorContract({
59650
+ error: error48,
59651
+ symbol: input.executionContext.symbol
59652
+ });
59653
+ const message = projection.message;
58908
59654
  executionReports.push({
58909
59655
  order_id: null,
58910
59656
  symbol: input.executionContext.symbol,
58911
59657
  action: "PROTECTIVE_RECONCILIATION",
58912
59658
  status: "failed",
58913
59659
  execution_metadata: {
58914
- reason_code: "execution_error",
58915
- execution_stage: "post_entry_protection",
59660
+ reason_code: projection.reason_code,
59661
+ execution_stage: projection.execution_stage,
59662
+ dispatch_outcome: projection.dispatch_outcome,
59663
+ operation_stage: "post_entry_protection",
58916
59664
  entry_order_id: _extractOrderId(marketOrderResponse),
58917
59665
  error: message
58918
59666
  }
@@ -59317,7 +60065,11 @@ var init_runtime_execution = __esm({
59317
60065
  );
59318
60066
  }
59319
60067
  } catch (triggerError) {
59320
- const message = getSanitizedRuntimeErrorMessage(triggerError) || "Unknown protective trigger order error.";
60068
+ const projection = projectExecutionErrorContract({
60069
+ error: triggerError,
60070
+ symbol: input.executionContext.symbol
60071
+ });
60072
+ const message = projection.message;
59321
60073
  const rejection = triggerError instanceof HyperliquidExchangeRejectionError ? triggerError : null;
59322
60074
  executionReports.push({
59323
60075
  order_id: null,
@@ -59328,8 +60080,10 @@ var init_runtime_execution = __esm({
59328
60080
  execution_metadata: {
59329
60081
  trigger_price: triggerInput.triggerPrice,
59330
60082
  is_take_profit: triggerInput.isTakeProfit,
59331
- reason_code: "execution_error",
59332
- execution_stage: "protective_trigger_order",
60083
+ reason_code: projection.reason_code,
60084
+ execution_stage: projection.execution_stage,
60085
+ dispatch_outcome: projection.dispatch_outcome,
60086
+ operation_stage: "protective_trigger_order",
59333
60087
  entry_order_id: _extractOrderId(marketOrderResponse),
59334
60088
  error: message,
59335
60089
  ...rejection ? { order_diagnostics: rejection.orderDiagnostics } : {}