@vtxmacro/cli 2026.9.52 → 2026.9.54

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.js CHANGED
@@ -77,9 +77,9 @@ var init_agent_cli_release = __esm({
77
77
  "agent-cli-release.json"() {
78
78
  agent_cli_release_default = {
79
79
  package_name: "@vtxmacro/cli",
80
- package_version: "2026.9.52",
80
+ package_version: "2026.9.54",
81
81
  codex_package_name: "@openai/codex",
82
- codex_version: "0.153.3",
82
+ codex_version: "0.155.0",
83
83
  copilot_sdk_package_name: "@github/copilot-sdk",
84
84
  copilot_sdk_version: "1.0.0-beta.8",
85
85
  copilot_cli_package_name: "@github/copilot",
@@ -143,13 +143,13 @@ var init_agent_cli_release = __esm({
143
143
  package_name: "@openai/codex-linux-x64",
144
144
  target: "x86_64-unknown-linux-musl",
145
145
  binary_name: "codex",
146
- sha256: "f9d4eab23d0e0726340e084ed22d668885c1dcabeb29ec508b8962e5e29b8dc6"
146
+ sha256: "660e159a49e823ac8e5986cb238f73158ce4b957d40d9292f8de90862644b501"
147
147
  },
148
148
  "win32-x64": {
149
149
  package_name: "@openai/codex-win32-x64",
150
150
  target: "x86_64-pc-windows-msvc",
151
151
  binary_name: "codex.exe",
152
- sha256: "e5ef3c4b81d2fb861f3731c91a773d45a1973c6a0b480d6449f80bc8fd749e96"
152
+ sha256: "e4c11374bd9de8ad5c3b7617fd4654bb7839901edb0863f9930666863c7a021b"
153
153
  }
154
154
  },
155
155
  pi_coding_agent_package_name: "@earendil-works/pi-coding-agent",
@@ -20541,6 +20541,14 @@ var init_runtime_policy_generated = __esm({
20541
20541
  host_liveness_heartbeat_interval_ms: 3e4,
20542
20542
  host_liveness_recovery_nudge_ttl_ms: 1e4
20543
20543
  }
20544
+ },
20545
+ server_runtime: {
20546
+ prompt_rescue: {
20547
+ client_long_poll_seconds: 20,
20548
+ client_claim_http_timeout_milliseconds: 25e3,
20549
+ client_presence_heartbeat_interval_milliseconds: 3e4,
20550
+ client_presence_http_timeout_milliseconds: 5e3
20551
+ }
20544
20552
  }
20545
20553
  }
20546
20554
  },
@@ -20585,7 +20593,7 @@ var init_runtime_policy_generated = __esm({
20585
20593
  exchange: {
20586
20594
  hyperliquid: {
20587
20595
  client_public_read_budget: {
20588
- max_weight: 900,
20596
+ max_weight: 1200,
20589
20597
  window_seconds: 60,
20590
20598
  cooldown_seconds: 60,
20591
20599
  metadata_ttl_seconds: 300,
@@ -20596,6 +20604,7 @@ var init_runtime_policy_generated = __esm({
20596
20604
  },
20597
20605
  read_budget: {
20598
20606
  weights: {
20607
+ exchange: 1,
20599
20608
  exchangeStatus: 2,
20600
20609
  clearinghouseState: 2,
20601
20610
  spotClearinghouseState: 2,
@@ -20626,7 +20635,8 @@ var init_runtime_policy_generated = __esm({
20626
20635
  authorizedAgents: 20,
20627
20636
  agents: 20,
20628
20637
  apiWallets: 20
20629
- }
20638
+ },
20639
+ exchange_action_batch_size: 40
20630
20640
  }
20631
20641
  }
20632
20642
  }
@@ -40287,10 +40297,10 @@ var init_grok_transport_proxy = __esm({
40287
40297
 
40288
40298
  // lib/inference-host/grok-runtime.ts
40289
40299
  import { spawn as spawn7 } from "node:child_process";
40290
- import { randomBytes as randomBytes7 } from "node:crypto";
40300
+ import { randomBytes as randomBytes7, randomUUID as randomUUID7 } from "node:crypto";
40291
40301
  import { createServer as createServer4 } from "node:http";
40292
40302
  import { join as join9 } from "node:path";
40293
- import { lstat as lstat6 } from "node:fs/promises";
40303
+ import { link, lstat as lstat6, rm as rm8 } from "node:fs/promises";
40294
40304
  var grokObject, grokRuntimeEnvironment, prepareGrokHome, GrokAcpSession, createGrokToolServer;
40295
40305
  var init_grok_runtime = __esm({
40296
40306
  "lib/inference-host/grok-runtime.ts"() {
@@ -40357,6 +40367,28 @@ var init_grok_runtime = __esm({
40357
40367
  env.XDG_STATE_HOME,
40358
40368
  env.XDG_CACHE_HOME
40359
40369
  ]) await ensureInferencePrivateDirectory(path);
40370
+ const agentIdPath = join9(grokHome, "agent_id");
40371
+ let needsAgentId = false;
40372
+ try {
40373
+ await lstat6(agentIdPath);
40374
+ } catch (error48) {
40375
+ if (error48.code !== "ENOENT") throw error48;
40376
+ needsAgentId = true;
40377
+ }
40378
+ if (needsAgentId) {
40379
+ const temporary = join9(grokHome, `.agent-id-${randomUUID7()}.tmp`);
40380
+ try {
40381
+ await writeAtomicInferencePrivateFile(temporary, `${randomUUID7()}
40382
+ `);
40383
+ try {
40384
+ await link(temporary, agentIdPath);
40385
+ } catch (error48) {
40386
+ if (error48.code !== "EEXIST") throw error48;
40387
+ }
40388
+ } finally {
40389
+ await rm8(temporary, { force: true });
40390
+ }
40391
+ }
40360
40392
  await writeAtomicInferencePrivateFile(join9(grokHome, "config.toml"), "[claude_compat]\nimported = true\n");
40361
40393
  await writeAtomicInferencePrivateFile(join9(grokHome, "requirements.toml"), [
40362
40394
  "[auth]",
@@ -40576,7 +40608,7 @@ var init_grok_runtime = __esm({
40576
40608
 
40577
40609
  // lib/inference-host/grok-state.ts
40578
40610
  import { constants as constants2 } from "node:fs";
40579
- import { lstat as lstat7, mkdtemp as mkdtemp4, open as open3, readdir as readdir3, realpath as realpath6, rm as rm8, rmdir, unlink, writeFile as writeFile3 } from "node:fs/promises";
40611
+ import { lstat as lstat7, mkdtemp as mkdtemp4, open as open3, readdir as readdir3, realpath as realpath6, rm as rm9, rmdir, unlink, writeFile as writeFile3 } from "node:fs/promises";
40580
40612
  import { basename as basename3, dirname as dirname8, join as join10, resolve as resolve6 } from "node:path";
40581
40613
  var markerName, ownedName, invalid, missing, sessionIdValid, directory, nativeDirectory, roots, owner, nativeFile, encodedCwd, nativeSession, removeEmptyNativeGroup, createGrokOwnedWorkspace, bindGrokOwnedSession, validateGrokOwnedThread, releaseGrokOwnedWorkspace, cleanupGrokOwnedState;
40582
40614
  var init_grok_state = __esm({
@@ -40745,7 +40777,7 @@ var init_grok_state = __esm({
40745
40777
  await writeAtomicInferencePrivateFile(join10(workspace, markerName), JSON.stringify(value));
40746
40778
  return workspace;
40747
40779
  } catch (error48) {
40748
- await rm8(workspace, { recursive: true, force: true });
40780
+ await rm9(workspace, { recursive: true, force: true });
40749
40781
  throw error48;
40750
40782
  }
40751
40783
  };
@@ -40778,11 +40810,11 @@ var init_grok_state = __esm({
40778
40810
  if (session) {
40779
40811
  await owner(options, workspace);
40780
40812
  if (await nativeSession(value, false) !== session) throw invalid();
40781
- await rm8(session, { recursive: true, force: true });
40813
+ await rm9(session, { recursive: true, force: true });
40782
40814
  await removeEmptyNativeGroup(dirname8(session), workspace);
40783
40815
  }
40784
40816
  await owner(options, workspace);
40785
- await rm8(workspace, { recursive: true, force: true });
40817
+ await rm9(workspace, { recursive: true, force: true });
40786
40818
  };
40787
40819
  cleanupGrokOwnedState = async (options) => {
40788
40820
  let scope;
@@ -40814,7 +40846,7 @@ var init_grok_state = __esm({
40814
40846
  });
40815
40847
 
40816
40848
  // lib/inference-host/grok-adapter.ts
40817
- import { randomUUID as randomUUID7 } from "node:crypto";
40849
+ import { randomUUID as randomUUID8 } from "node:crypto";
40818
40850
  import { join as join11 } from "node:path";
40819
40851
  var unwrap, list, nonempty, integer2, grokModelCapabilities, grokPromptUsage, agentProfile, modelState, assertSelection, GrokBuildAdapter;
40820
40852
  var init_grok_adapter = __esm({
@@ -41080,7 +41112,7 @@ var init_grok_adapter = __esm({
41080
41112
  activeThread = { ...activeThread, effectiveModel: observedModel };
41081
41113
  await agent.onThreadReady?.(activeThread);
41082
41114
  }
41083
- const callId = randomUUID7();
41115
+ const callId = randomUUID8();
41084
41116
  const tool = name;
41085
41117
  const result3 = await agent.executeTool({ callId, tool, arguments: args });
41086
41118
  evidence.push({ callId, tool, arguments: args, success: result3.success });
@@ -41186,7 +41218,7 @@ var init_grok_adapter = __esm({
41186
41218
  if (update.sessionUpdate === "agent_message_chunk" && firstToken === null) firstToken = Date.now() - startedAt;
41187
41219
  if (update.sessionUpdate === "agent_thought_chunk" && Buffer.byteLength(thought) + Buffer.byteLength(text2) <= 3e5) thought += text2;
41188
41220
  };
41189
- const promptId = randomUUID7();
41221
+ const promptId = randomUUID8();
41190
41222
  const result2 = await session.request("session/prompt", {
41191
41223
  sessionId,
41192
41224
  prompt: [{ type: "text", text: input.userPrompt }],
@@ -41365,9 +41397,9 @@ var init_grok_auth = __esm({
41365
41397
 
41366
41398
  // lib/inference-host/exo-adapter.ts
41367
41399
  import { spawn as spawn9 } from "node:child_process";
41368
- import { randomUUID as randomUUID8, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
41400
+ import { randomUUID as randomUUID9, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
41369
41401
  import { createServer as createServer5 } from "node:http";
41370
- import { access as access3, lstat as lstat8, readdir as readdir4, realpath as realpath7, rm as rm9 } from "node:fs/promises";
41402
+ import { access as access3, lstat as lstat8, readdir as readdir4, realpath as realpath7, rm as rm10 } from "node:fs/promises";
41371
41403
  import { basename as basename4, dirname as dirname9, join as join12, resolve as resolve7 } from "node:path";
41372
41404
  import { fileURLToPath as fileURLToPath2 } from "node:url";
41373
41405
  var import_ajv3, failure, object4, validModel, receiptUsage, assertOwnedRuntime, cleanupExoOwnedState, ExoForegroundAdapter;
@@ -41429,7 +41461,7 @@ var init_exo_adapter = __esm({
41429
41461
  if (!match || !entry.isDirectory() || entry.isSymbolicLink()) throw failure("exo_state_not_owned");
41430
41462
  await assertOwnedRuntime(join12(root, entry.name), match[1]);
41431
41463
  }
41432
- await rm9(root, { recursive: true, force: true });
41464
+ await rm10(root, { recursive: true, force: true });
41433
41465
  };
41434
41466
  ExoForegroundAdapter = class {
41435
41467
  constructor(options) {
@@ -41549,7 +41581,7 @@ var init_exo_adapter = __esm({
41549
41581
  const credential = await this.options.credentialStore.read(input.signal);
41550
41582
  const provider = selected.model.split("/")[0];
41551
41583
  if (!credential || credential.provider !== provider) throw failure("exo_credential_required", false, "auth");
41552
- const id2 = agent?.durableThread?.threadId ?? randomUUID8();
41584
+ const id2 = agent?.durableThread?.threadId ?? randomUUID9();
41553
41585
  const runtimeRoot = agent?.durableThread ? await this.ownedRoot(agent.durableThread) : join12(await realpath7(this.options.stateRoot), `${agent ? "agent" : "attempt"}-${id2}`);
41554
41586
  let thread = { threadId: id2, threadPath: runtimeRoot, effectiveModel: input.requestedModel, effectiveReasoningEffort: input.requestedReasoningEffort };
41555
41587
  const owner2 = agent?.durableThread ? await assertOwnedRuntime(runtimeRoot, id2) : null;
@@ -41563,7 +41595,7 @@ var init_exo_adapter = __esm({
41563
41595
  const relay = () => abort.abort();
41564
41596
  input.signal?.addEventListener("abort", relay, { once: true });
41565
41597
  const timer = setTimeout(relay, Math.max(0, input.deadlineAtMs - started));
41566
- const token = randomUUID8();
41598
+ const token = randomUUID9();
41567
41599
  let dispatched = false;
41568
41600
  let terminal = null;
41569
41601
  let workerFailure = null;
@@ -41689,7 +41721,7 @@ var init_exo_adapter = __esm({
41689
41721
  }
41690
41722
  await agent?.onThreadReady?.(thread);
41691
41723
  try {
41692
- await this.command([...args, "conversation", "send", "vtx", "trading", randomUUID8()], env, abort.signal);
41724
+ await this.command([...args, "conversation", "send", "vtx", "trading", randomUUID9()], env, abort.signal);
41693
41725
  } catch (error48) {
41694
41726
  if (!terminal) throw error48;
41695
41727
  }
@@ -41761,11 +41793,11 @@ var init_exo_adapter = __esm({
41761
41793
  this.active.delete(abort);
41762
41794
  server.closeAllConnections();
41763
41795
  await new Promise((done) => server.close(() => done()));
41764
- if (!agent) await rm9(runtimeRoot, { recursive: true, force: true });
41796
+ if (!agent) await rm10(runtimeRoot, { recursive: true, force: true });
41765
41797
  }
41766
41798
  }
41767
41799
  async releaseThread(thread) {
41768
- await rm9(await this.ownedRoot(thread), { recursive: true, force: true });
41800
+ await rm10(await this.ownedRoot(thread), { recursive: true, force: true });
41769
41801
  }
41770
41802
  async close() {
41771
41803
  this.closing = true;
@@ -42364,7 +42396,7 @@ var init_durable_adapter = __esm({
42364
42396
  });
42365
42397
 
42366
42398
  // lib/inference-host/service-launcher-state.ts
42367
- import { access as access4, readFile as readFile9, rm as rm10 } from "node:fs/promises";
42399
+ import { access as access4, readFile as readFile9, rm as rm11 } from "node:fs/promises";
42368
42400
  import { dirname as dirname12, isAbsolute as isAbsolute5, join as join13, relative as relative3, resolve as resolve10 } from "node:path";
42369
42401
  var launcherSibling, within, launcherSelection, readLauncherSelection, readLauncherState, writeLauncherState, targetForSelection;
42370
42402
  var init_service_launcher_state = __esm({
@@ -42519,6 +42551,14 @@ var init_runtime_policy_generated2 = __esm({
42519
42551
  host_liveness_heartbeat_interval_ms: 3e4,
42520
42552
  host_liveness_recovery_nudge_ttl_ms: 1e4
42521
42553
  }
42554
+ },
42555
+ server_runtime: {
42556
+ prompt_rescue: {
42557
+ client_long_poll_seconds: 20,
42558
+ client_claim_http_timeout_milliseconds: 25e3,
42559
+ client_presence_heartbeat_interval_milliseconds: 3e4,
42560
+ client_presence_http_timeout_milliseconds: 5e3
42561
+ }
42522
42562
  }
42523
42563
  }
42524
42564
  },
@@ -42563,7 +42603,7 @@ var init_runtime_policy_generated2 = __esm({
42563
42603
  exchange: {
42564
42604
  hyperliquid: {
42565
42605
  client_public_read_budget: {
42566
- max_weight: 900,
42606
+ max_weight: 1200,
42567
42607
  window_seconds: 60,
42568
42608
  cooldown_seconds: 60,
42569
42609
  metadata_ttl_seconds: 300,
@@ -42574,6 +42614,7 @@ var init_runtime_policy_generated2 = __esm({
42574
42614
  },
42575
42615
  read_budget: {
42576
42616
  weights: {
42617
+ exchange: 1,
42577
42618
  exchangeStatus: 2,
42578
42619
  clearinghouseState: 2,
42579
42620
  spotClearinghouseState: 2,
@@ -42604,7 +42645,8 @@ var init_runtime_policy_generated2 = __esm({
42604
42645
  authorizedAgents: 20,
42605
42646
  agents: 20,
42606
42647
  apiWallets: 20
42607
- }
42648
+ },
42649
+ exchange_action_batch_size: 40
42608
42650
  }
42609
42651
  }
42610
42652
  }
@@ -42614,9 +42656,9 @@ var init_runtime_policy_generated2 = __esm({
42614
42656
 
42615
42657
  // lib/inference-host/service.ts
42616
42658
  import { spawn as spawn10 } from "node:child_process";
42617
- import { randomUUID as randomUUID9 } from "node:crypto";
42659
+ import { randomUUID as randomUUID10 } from "node:crypto";
42618
42660
  import { createWriteStream, readFileSync as readFileSync2 } from "node:fs";
42619
- import { access as access5, chmod as chmod3, mkdir as mkdir3, readFile as readFile10, rm as rm11, writeFile as writeFile4 } from "node:fs/promises";
42661
+ import { access as access5, chmod as chmod3, mkdir as mkdir3, readFile as readFile10, rm as rm12, writeFile as writeFile4 } from "node:fs/promises";
42620
42662
  import { homedir as homedir2 } from "node:os";
42621
42663
  import { dirname as dirname13, join as join14, resolve as resolve11 } from "node:path";
42622
42664
  var SERVICE_NAME, SYSTEMD_UNIT, LAUNCHD_LABEL, SERVICE_COOPERATIVE_STOP_SECONDS, SERVICE_UPDATE_STARTUP_SECONDS, INFERENCE_HOST_SERVICE_DRAIN_COMMAND, INFERENCE_HOST_SERVICE_QUIESCE_COMMAND, InferenceHostBootstrapRestartRequiredError, inferenceHostServiceChildEnvironment, isWindowsSubsystemForLinux, inferenceHostServiceManifestPath, inferenceHostServiceDesiredPath, inferenceHostServiceLogPath, inferenceHostServiceRuntimePath, xmlEscape, plistEscape, systemdQuote, defaultRunCommand, probeInferenceHostLauncher, managerName, assertRuntimeEnvironment, withoutConcurrencyLimit, assertServicePath, manifestGeneration, assertWorker, assertManifest, assertServiceRuntimeState, assertDesiredState, readInferenceHostServiceManifest, readManifestAcrossAtomicReplacement, readInferenceHostServiceRuntime, readRuntimeAcrossAtomicReplacement, readInferenceHostServiceDesired, readDesiredAcrossAtomicReplacement, writeDesired, runtimeEnvironment, serviceBootstrapArguments, windowsOwnedCommandLine, vbScriptString, windowsServiceLauncher, windowsTaskXml, systemdUnit, launchAgentPlist, sameWorker, sameServiceDefinition, sameWorkerSet, InferenceHostServiceManager, appendServiceLog, spawnInferenceHostServiceChild, runInferenceHostServiceSupervisor;
@@ -42693,7 +42735,7 @@ var init_service = __esm({
42693
42735
  }));
42694
42736
  });
42695
42737
  probeInferenceHostLauncher = async (executable, destination, bytes3, runCommand = defaultRunCommand) => {
42696
- const probe = `${destination}.${randomUUID9()}.probe.js`;
42738
+ const probe = `${destination}.${randomUUID10()}.probe.js`;
42697
42739
  try {
42698
42740
  await writeAtomicInferencePrivateFile(probe, bytes3);
42699
42741
  const result2 = await runCommand(executable, [probe]);
@@ -42701,7 +42743,7 @@ var init_service = __esm({
42701
42743
  throw new Error("Copied service launcher failed its isolated startup check.");
42702
42744
  }
42703
42745
  } finally {
42704
- await rm11(probe, { force: true });
42746
+ await rm12(probe, { force: true });
42705
42747
  }
42706
42748
  };
42707
42749
  managerName = (platform) => {
@@ -43197,7 +43239,7 @@ WantedBy=default.target
43197
43239
  const previousRuntimeUpdatedAt = previousRuntime?.manifest_generation === manifest.generation ? Date.parse(previousRuntime.updated_at) : Number.NaN;
43198
43240
  const restoredManifest = preserveGeneration ? manifest : assertManifest({
43199
43241
  ...manifest,
43200
- generation: randomUUID9(),
43242
+ generation: randomUUID10(),
43201
43243
  installed_at: this.now().toISOString()
43202
43244
  });
43203
43245
  await writeAtomicInferencePrivateFile(
@@ -43354,16 +43396,16 @@ ${cleanup.stderr}`)) {
43354
43396
  );
43355
43397
  }
43356
43398
  }
43357
- await rm11(this.definitionPath(), { force: true }).catch(() => void 0);
43399
+ await rm12(this.definitionPath(), { force: true }).catch(() => void 0);
43358
43400
  if (this.platform === "win32") {
43359
- await rm11(this.windowsLauncherPath(), { force: true }).catch(() => void 0);
43401
+ await rm12(this.windowsLauncherPath(), { force: true }).catch(() => void 0);
43360
43402
  }
43361
- await rm11(this.manifestPath(), { force: true }).catch(() => void 0);
43362
- await rm11(this.desiredPath(), { force: true }).catch(() => void 0);
43363
- await rm11(this.runtimePath(), { force: true }).catch(() => void 0);
43364
- if (!existingRecovery) await rm11(this.serviceBootstrapPath(), { force: true }).catch(() => void 0);
43403
+ await rm12(this.manifestPath(), { force: true }).catch(() => void 0);
43404
+ await rm12(this.desiredPath(), { force: true }).catch(() => void 0);
43405
+ await rm12(this.runtimePath(), { force: true }).catch(() => void 0);
43406
+ if (!existingRecovery) await rm12(this.serviceBootstrapPath(), { force: true }).catch(() => void 0);
43365
43407
  for (const suffix of [".service-launcher.json", ".service-bootstrap.previous.js"]) {
43366
- if (!existingRecovery) await rm11(launcherSibling(this.manifestPath(), suffix), { force: true }).catch(() => void 0);
43408
+ if (!existingRecovery) await rm12(launcherSibling(this.manifestPath(), suffix), { force: true }).catch(() => void 0);
43367
43409
  }
43368
43410
  if (this.platform === "linux") {
43369
43411
  await this.runCommand("systemctl", ["--user", "daemon-reload"]).catch(() => void 0);
@@ -43515,7 +43557,7 @@ ${cleanup.stderr}`)) {
43515
43557
  ].sort((left, right) => left.instance_name.localeCompare(right.instance_name));
43516
43558
  const manifest = assertManifest({
43517
43559
  schema_version: "vtx_inference_service_v3",
43518
- generation: randomUUID9(),
43560
+ generation: randomUUID10(),
43519
43561
  installed_at: this.now().toISOString(),
43520
43562
  executable: this.executable,
43521
43563
  script: this.script,
@@ -43738,7 +43780,7 @@ ${result2.stderr}`)) {
43738
43780
  if (remaining.length === 0) return await this.uninstallUnlocked();
43739
43781
  return await this.replaceManifestUnlocked({
43740
43782
  ...manifest,
43741
- generation: randomUUID9(),
43783
+ generation: randomUUID10(),
43742
43784
  installed_at: this.now().toISOString(),
43743
43785
  workers: remaining
43744
43786
  }, await readInferenceHostServiceDesired(this.desiredPath()));
@@ -43761,20 +43803,20 @@ ${result2.stderr}`)) {
43761
43803
  ${result2.stderr}`)) {
43762
43804
  throw new Error(`Background service uninstall failed: ${result2.stderr.trim()}`);
43763
43805
  }
43764
- await rm11(this.definitionPath(), { force: true });
43765
- if (this.platform === "win32") await rm11(this.windowsLauncherPath(), { force: true });
43806
+ await rm12(this.definitionPath(), { force: true });
43807
+ if (this.platform === "win32") await rm12(this.windowsLauncherPath(), { force: true });
43766
43808
  if (this.platform === "linux") await this.runCommand("systemctl", ["--user", "daemon-reload"]);
43767
- await rm11(this.manifestPath(), { force: true });
43768
- await rm11(this.desiredPath(), { force: true });
43769
- await rm11(this.runtimePath(), { force: true });
43809
+ await rm12(this.manifestPath(), { force: true });
43810
+ await rm12(this.desiredPath(), { force: true });
43811
+ await rm12(this.runtimePath(), { force: true });
43770
43812
  if (!preserveRecovery) {
43771
- await rm11(this.serviceBootstrapPath(), { force: true });
43813
+ await rm12(this.serviceBootstrapPath(), { force: true });
43772
43814
  for (const suffix of [".service-launcher.json", ".service-bootstrap.previous.js"]) {
43773
- await rm11(launcherSibling(this.manifestPath(), suffix), { force: true });
43815
+ await rm12(launcherSibling(this.manifestPath(), suffix), { force: true });
43774
43816
  }
43775
- await rm11(this.serviceReleasePath(), { force: true });
43776
- await rm11(this.serviceReleaseRejectionPath(), { force: true });
43777
- await rm11(this.serviceReleasesPath(), { recursive: true, force: true });
43817
+ await rm12(this.serviceReleasePath(), { force: true });
43818
+ await rm12(this.serviceReleaseRejectionPath(), { force: true });
43819
+ await rm12(this.serviceReleasesPath(), { recursive: true, force: true });
43778
43820
  }
43779
43821
  return {
43780
43822
  installed: false,
@@ -44237,9 +44279,9 @@ __export(cli_exports, {
44237
44279
  registerInferenceHostServiceControlInput: () => registerInferenceHostServiceControlInput,
44238
44280
  runInferenceHostCli: () => runInferenceHostCli
44239
44281
  });
44240
- import { createHash as createHash12, randomUUID as randomUUID10 } from "node:crypto";
44282
+ import { createHash as createHash12, randomUUID as randomUUID11 } from "node:crypto";
44241
44283
  import { spawn as spawn11 } from "node:child_process";
44242
- import { lstat as lstat9, realpath as realpath8, rm as rm12 } from "node:fs/promises";
44284
+ import { lstat as lstat9, realpath as realpath8, rm as rm13 } from "node:fs/promises";
44243
44285
  import { hostname as osHostname } from "node:os";
44244
44286
  import { join as join15, resolve as resolve12 } from "node:path";
44245
44287
  async function runInferenceHostCli(argv2, env = process.env, dependencies = {}) {
@@ -44878,7 +44920,7 @@ Durable service:
44878
44920
  runtimeReceiptPath(config2),
44879
44921
  "Inference host runtime receipt file"
44880
44922
  );
44881
- await rm12(codexGuardianReceiptRoot(config2), { recursive: true, force: true });
44923
+ await rm13(codexGuardianReceiptRoot(config2), { recursive: true, force: true });
44882
44924
  await clearInferencePrivateFile(
44883
44925
  codexRecoveryPath(config2),
44884
44926
  "Codex attempt recovery file"
@@ -45146,7 +45188,7 @@ Waiting for approval...
45146
45188
  await writeInferenceHostCredentialContextTransition(config2, previousCredentialContext);
45147
45189
  await writeInferenceHostCredentialContext(config2);
45148
45190
  const keyPair = generateExternalInferenceEnvelopeKeyPair();
45149
- const hostId = randomUUID10();
45191
+ const hostId = randomUUID11();
45150
45192
  const beginLogin = dependencies.beginLogin ?? beginInferenceOAuthLogin;
45151
45193
  const loginStore = {
45152
45194
  kind: store.kind,
@@ -46034,7 +46076,7 @@ Waiting for approval...
46034
46076
  }
46035
46077
  return record5;
46036
46078
  };
46037
- agentOperationId = (kind) => `${kind}-${randomUUID10()}`;
46079
+ agentOperationId = (kind) => `${kind}-${randomUUID11()}`;
46038
46080
  agentSession = async (config2, dependencies, warnings, signal) => {
46039
46081
  if (await readRevocationCheckpoint(config2)) {
46040
46082
  throw new Error("Inference host revocation recovery must finish first.");
@@ -47113,7 +47155,7 @@ Waiting for approval...
47113
47155
  if (recoveryRaw === null && existingTransaction?.phase !== "reconciled") {
47114
47156
  throw new Error("Codex recovery evidence changed before service recovery began.");
47115
47157
  }
47116
- const transactionId = existingTransaction?.transaction_id ?? randomUUID10();
47158
+ const transactionId = existingTransaction?.transaction_id ?? randomUUID11();
47117
47159
  const backupPath = existingTransaction?.recovery_backup_path ?? recoveryBackupPath(config2, transactionId);
47118
47160
  if (!existingTransaction) {
47119
47161
  await writeAtomicInferencePrivateFile(backupPath, recoveryRaw);
@@ -47261,7 +47303,7 @@ Waiting for approval...
47261
47303
  serviceRecoveryTransactionPath(config2),
47262
47304
  "Inference-host service recovery transaction"
47263
47305
  );
47264
- await rm12(backupPath, { force: true });
47306
+ await rm13(backupPath, { force: true });
47265
47307
  }
47266
47308
  }
47267
47309
  } finally {
@@ -47536,7 +47578,7 @@ Waiting for approval...
47536
47578
  });
47537
47579
 
47538
47580
  // lib/agent-core/config.ts
47539
- import { mkdir as mkdir5, readFile as readFile11, rm as rm13, writeFile as writeFile5 } from "node:fs/promises";
47581
+ import { mkdir as mkdir5, readFile as readFile11, rm as rm14, writeFile as writeFile5 } from "node:fs/promises";
47540
47582
  import { dirname as dirname14, join as join16 } from "node:path";
47541
47583
  import { homedir as homedir3 } from "node:os";
47542
47584
  function defaultBaseDir() {
@@ -47580,7 +47622,7 @@ async function writeStoredAgentAuth(path, auth) {
47580
47622
  `, { encoding: "utf8", mode: 384 });
47581
47623
  }
47582
47624
  async function clearStoredAgentAuth(path) {
47583
- await rm13(path, { force: true });
47625
+ await rm14(path, { force: true });
47584
47626
  }
47585
47627
  async function readRuntimeState(path) {
47586
47628
  try {
@@ -47615,7 +47657,7 @@ async function writeRuntimeState(path, state) {
47615
47657
  `, { encoding: "utf8", mode: 384 });
47616
47658
  }
47617
47659
  async function clearRuntimeState(path) {
47618
- await rm13(path, { force: true });
47660
+ await rm14(path, { force: true });
47619
47661
  }
47620
47662
  var init_config2 = __esm({
47621
47663
  "lib/agent-core/config.ts"() {
@@ -47647,7 +47689,7 @@ var init_types = __esm({
47647
47689
  });
47648
47690
 
47649
47691
  // lib/agent-core/client.ts
47650
- import { randomUUID as randomUUID11 } from "node:crypto";
47692
+ import { randomUUID as randomUUID12 } from "node:crypto";
47651
47693
  function normalizeApiUrl(value) {
47652
47694
  const parsed = String(value || "").trim();
47653
47695
  if (!parsed) {
@@ -47914,7 +47956,7 @@ var init_client = __esm({
47914
47956
  return this.request("/trading/ai/runtime/decision", {
47915
47957
  method: "POST",
47916
47958
  profileId,
47917
- idempotencyKey: randomUUID11(),
47959
+ idempotencyKey: randomUUID12(),
47918
47960
  headers: { "x-client-runtime-lease": leaseToken },
47919
47961
  body: payload
47920
47962
  });
@@ -47923,7 +47965,7 @@ var init_client = __esm({
47923
47965
  return this.request("/trading/ai/runtime/trade-sync", {
47924
47966
  method: "POST",
47925
47967
  profileId,
47926
- idempotencyKey: randomUUID11(),
47968
+ idempotencyKey: randomUUID12(),
47927
47969
  headers: { "x-client-runtime-lease": leaseToken },
47928
47970
  body: payload
47929
47971
  });
@@ -47932,7 +47974,7 @@ var init_client = __esm({
47932
47974
  return this.request("/trading/ai/runtime/error", {
47933
47975
  method: "POST",
47934
47976
  profileId,
47935
- idempotencyKey: randomUUID11(),
47977
+ idempotencyKey: randomUUID12(),
47936
47978
  headers: { "x-client-runtime-lease": leaseToken },
47937
47979
  body: payload
47938
47980
  });
@@ -47944,7 +47986,7 @@ var init_client = __esm({
47944
47986
  return this.request("/trading/market-order", {
47945
47987
  method: "POST",
47946
47988
  profileId,
47947
- idempotencyKey: randomUUID11(),
47989
+ idempotencyKey: randomUUID12(),
47948
47990
  body: payload
47949
47991
  });
47950
47992
  }
@@ -47952,7 +47994,7 @@ var init_client = __esm({
47952
47994
  return this.request("/trading/limit-order", {
47953
47995
  method: "POST",
47954
47996
  profileId,
47955
- idempotencyKey: randomUUID11(),
47997
+ idempotencyKey: randomUUID12(),
47956
47998
  body: payload
47957
47999
  });
47958
48000
  }
@@ -47960,7 +48002,7 @@ var init_client = __esm({
47960
48002
  return this.request("/trading/cancel-order", {
47961
48003
  method: "POST",
47962
48004
  profileId,
47963
- idempotencyKey: randomUUID11(),
48005
+ idempotencyKey: randomUUID12(),
47964
48006
  body: payload
47965
48007
  });
47966
48008
  }
@@ -47979,7 +48021,7 @@ var init_client = __esm({
47979
48021
  return this.request("/trading/ai/start", {
47980
48022
  method: "POST",
47981
48023
  profileId,
47982
- idempotencyKey: randomUUID11(),
48024
+ idempotencyKey: randomUUID12(),
47983
48025
  body: payload
47984
48026
  });
47985
48027
  }
@@ -47987,7 +48029,7 @@ var init_client = __esm({
47987
48029
  return this.request("/trading/ai/stop", {
47988
48030
  method: "POST",
47989
48031
  profileId,
47990
- idempotencyKey: randomUUID11(),
48032
+ idempotencyKey: randomUUID12(),
47991
48033
  body: {}
47992
48034
  });
47993
48035
  }
@@ -47995,7 +48037,7 @@ var init_client = __esm({
47995
48037
  return this.request("/trading/ai/assistant/start", {
47996
48038
  method: "POST",
47997
48039
  profileId,
47998
- idempotencyKey: randomUUID11(),
48040
+ idempotencyKey: randomUUID12(),
47999
48041
  body: {}
48000
48042
  });
48001
48043
  }
@@ -48003,7 +48045,7 @@ var init_client = __esm({
48003
48045
  return this.request("/trading/ai/assistant/stop", {
48004
48046
  method: "POST",
48005
48047
  profileId,
48006
- idempotencyKey: randomUUID11(),
48048
+ idempotencyKey: randomUUID12(),
48007
48049
  body: {}
48008
48050
  });
48009
48051
  }
@@ -48011,7 +48053,7 @@ var init_client = __esm({
48011
48053
  return this.request("/trading/ai/runtime/session/start", {
48012
48054
  method: "POST",
48013
48055
  profileId,
48014
- idempotencyKey: randomUUID11(),
48056
+ idempotencyKey: randomUUID12(),
48015
48057
  body: payload
48016
48058
  });
48017
48059
  }
@@ -48022,7 +48064,7 @@ var init_client = __esm({
48022
48064
  return this.request("/trading/ai/runtime/session/stop", {
48023
48065
  method: "POST",
48024
48066
  profileId,
48025
- idempotencyKey: randomUUID11(),
48067
+ idempotencyKey: randomUUID12(),
48026
48068
  body: payload
48027
48069
  });
48028
48070
  }
@@ -48039,7 +48081,7 @@ var init_client = __esm({
48039
48081
  }).request("/trading/ai/runtime/session/stop", {
48040
48082
  method: "POST",
48041
48083
  profileId,
48042
- idempotencyKey: randomUUID11(),
48084
+ idempotencyKey: randomUUID12(),
48043
48085
  body: payload
48044
48086
  });
48045
48087
  }
@@ -48056,7 +48098,7 @@ import {
48056
48098
  unlinkSync,
48057
48099
  writeFileSync
48058
48100
  } from "node:fs";
48059
- import { randomUUID as randomUUID12 } from "node:crypto";
48101
+ import { randomUUID as randomUUID13 } from "node:crypto";
48060
48102
  import { dirname as dirname15 } from "node:path";
48061
48103
  var parseStoredValues, FileBackedProtectionStorage, clientRuntimeProtectionStatePath;
48062
48104
  var init_protection_storage = __esm({
@@ -48116,7 +48158,7 @@ var init_protection_storage = __esm({
48116
48158
  mkdirSync(dirname15(this.path), { recursive: true, mode: 448 });
48117
48159
  const serialized = `${JSON.stringify(values)}
48118
48160
  `;
48119
- const temporaryPath = `${this.path}.${process.pid}.${randomUUID12()}.tmp`;
48161
+ const temporaryPath = `${this.path}.${process.pid}.${randomUUID13()}.tmp`;
48120
48162
  try {
48121
48163
  writeFileSync(temporaryPath, serialized, {
48122
48164
  encoding: "utf8",
@@ -48143,7 +48185,7 @@ var init_protection_storage = __esm({
48143
48185
  });
48144
48186
 
48145
48187
  // lib/agent-core/headless-runtime.ts
48146
- import { randomUUID as randomUUID13 } from "node:crypto";
48188
+ import { randomUUID as randomUUID14 } from "node:crypto";
48147
48189
  import { setTimeout as sleep } from "node:timers/promises";
48148
48190
  function objectOrNull2(value) {
48149
48191
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
@@ -48255,8 +48297,8 @@ async function runAndReportLocalWorkCycle(options, state, leaseToken, context) {
48255
48297
  return Boolean(result2.decision || tradeSync || result2.afterDecision);
48256
48298
  }
48257
48299
  async function startHeadlessRuntime(options) {
48258
- const runtimeSessionId = randomUUID13();
48259
- const deviceId = String(options.deviceId || "").trim() || randomUUID13();
48300
+ const runtimeSessionId = randomUUID14();
48301
+ const deviceId = String(options.deviceId || "").trim() || randomUUID14();
48260
48302
  const startResponse = await options.client.startRuntime(options.profileId, {
48261
48303
  session_id: runtimeSessionId,
48262
48304
  device_id: deviceId,
@@ -48546,7 +48588,7 @@ var init_runtime_redaction = __esm({
48546
48588
  });
48547
48589
 
48548
48590
  // lib/runtime/hyperliquid-public-read.ts
48549
- var policy, weights, budgets, unpersistedBudgets, cache, pending2, PREFIX, abortError2, checkAbort, wait, storage, loadBudget, saveBudget, withBudgetLock, admit, cooldown, reserveHyperliquidPublicReads, readHyperliquidPublicInfo;
48591
+ var policy, weights, budgets, unpersistedBudgets, cache, pending2, PREFIX, abortError2, checkAbort, wait, storage, loadBudget, saveBudget, withBudgetLock, HyperliquidPublicReadError, cooldownError, admit, cooldown, cacheTtlMs, eligibleCache, reserveHyperliquidPublicReads, releaseHyperliquidPublicReadReservation, admitHyperliquidExchangeRequest, recordHyperliquidExchangeResponse, readHyperliquidPublicInfo;
48550
48592
  var init_hyperliquid_public_read = __esm({
48551
48593
  "lib/runtime/hyperliquid-public-read.ts"() {
48552
48594
  "use strict";
@@ -48618,31 +48660,54 @@ var init_hyperliquid_public_read = __esm({
48618
48660
  }
48619
48661
  return work();
48620
48662
  };
48621
- admit = async (apiUrl, requestType, signal, bundleWeight, bundleId) => {
48663
+ HyperliquidPublicReadError = class extends Error {
48664
+ constructor(code, message, requestType, status, retryAfterMs, requiredWeight, usedWeight, maxWeight) {
48665
+ super(message);
48666
+ this.code = code;
48667
+ this.requestType = requestType;
48668
+ this.status = status;
48669
+ this.retryAfterMs = retryAfterMs;
48670
+ this.requiredWeight = requiredWeight;
48671
+ this.usedWeight = usedWeight;
48672
+ this.maxWeight = maxWeight;
48673
+ this.name = "HyperliquidPublicReadError";
48674
+ }
48675
+ };
48676
+ cooldownError = (requestType, until) => new HyperliquidPublicReadError(
48677
+ "public_cooldown_active",
48678
+ "Hyperliquid public request cooldown is active.",
48679
+ requestType,
48680
+ void 0,
48681
+ Math.max(0, until - Date.now())
48682
+ );
48683
+ admit = async (apiUrl, requestType, signal, bundleWeight, bundleId, deadlineMs) => {
48622
48684
  const key = `${PREFIX}${apiUrl}`;
48623
48685
  const weight = bundleWeight ?? weights[requestType] ?? policy.default_request_weight;
48624
- if (!(weight > 0 && weight <= policy.max_weight)) throw new Error("Invalid Hyperliquid public read weight.");
48686
+ if (!(weight > 0 && weight <= policy.max_weight)) throw new HyperliquidPublicReadError("public_budget_exhausted", "Hyperliquid public request exceeds the available allowance.", requestType, void 0, void 0, weight, void 0, policy.max_weight);
48625
48687
  for (; ; ) {
48626
48688
  checkAbort(signal);
48627
- const delay2 = await withBudgetLock(key, signal, () => {
48689
+ const { delay: delay2, usedWeight } = await withBudgetLock(key, signal, () => {
48628
48690
  const now = Date.now();
48629
48691
  const budget = loadBudget(key);
48630
48692
  budget.reservations = budget.reservations.filter((r) => r.at > now - policy.window_seconds * 1e3);
48631
- if (budget.cooldownUntil > now) throw Object.assign(new Error("Hyperliquid public read rate-limit cooldown."), { status: 429, requestType });
48693
+ if (budget.cooldownUntil > now) throw cooldownError(requestType, budget.cooldownUntil);
48632
48694
  let used = budget.reservations.reduce((sum, r) => sum + r.weight, 0);
48695
+ const usedWeight2 = used;
48633
48696
  if (used + weight <= policy.max_weight) {
48634
48697
  budget.reservations.push({ at: now, weight, ...bundleId ? { id: bundleId } : {} });
48635
48698
  saveBudget(key, budget);
48636
- return 0;
48699
+ return { delay: 0, usedWeight: usedWeight2 };
48637
48700
  }
48638
48701
  for (const reservation of budget.reservations) {
48639
48702
  used -= reservation.weight;
48640
- if (used + weight <= policy.max_weight) return Math.max(1, reservation.at + policy.window_seconds * 1e3 - now);
48703
+ if (used + weight <= policy.max_weight) return { delay: Math.max(1, reservation.at + policy.window_seconds * 1e3 - now), usedWeight: usedWeight2 };
48641
48704
  }
48642
48705
  throw new Error("Invalid Hyperliquid public read budget.");
48643
48706
  });
48644
48707
  if (!delay2) return;
48645
- if (bundleWeight != null) throw Object.assign(new Error("Hyperliquid public read bundle budget exhausted."), { code: "public_budget_exhausted" });
48708
+ if (bundleWeight != null || deadlineMs != null && Date.now() + delay2 >= deadlineMs) {
48709
+ throw new HyperliquidPublicReadError("public_budget_exhausted", "Hyperliquid local public request allowance is exhausted.", requestType, void 0, delay2, weight, usedWeight, policy.max_weight);
48710
+ }
48646
48711
  await wait(delay2, signal);
48647
48712
  }
48648
48713
  };
@@ -48657,29 +48722,70 @@ var init_hyperliquid_public_read = __esm({
48657
48722
  saveBudget(key, budget);
48658
48723
  });
48659
48724
  };
48660
- reserveHyperliquidPublicReads = async (endpoint, bodies, signal) => {
48725
+ cacheTtlMs = (body, options) => {
48726
+ const requestType = String(body.type);
48727
+ return (["meta", "spotMeta", "perpDexs"].includes(requestType) ? policy.metadata_ttl_seconds : requestType === "userFees" ? policy.user_fees_ttl_seconds : options.cacheAccountMode && ["userAbstraction", "userDexAbstraction"].includes(requestType) ? policy.account_mode_ttl_seconds : 0) * 1e3;
48728
+ };
48729
+ eligibleCache = (apiUrl, body, options) => {
48730
+ const ttl = cacheTtlMs(body, options);
48731
+ const existing = cache.get(`${apiUrl}:${JSON.stringify(body)}`);
48732
+ const horizon = Math.max(Date.now(), options.cacheValidUntilMs ?? Date.now());
48733
+ return ttl > 0 && existing && Date.now() >= existing.fetchedAtMs && horizon - existing.fetchedAtMs < ttl ? existing : void 0;
48734
+ };
48735
+ reserveHyperliquidPublicReads = async (endpoint, bodies, signal, options = {}) => {
48661
48736
  const apiUrl = endpoint.replace(/\/$/, "");
48662
- const weight = bodies.reduce((sum, body) => sum + (weights[String(body.type)] ?? policy.default_request_weight), 0);
48663
- const id2 = crypto.randomUUID();
48664
- const admittedAtMs = Date.now();
48665
- await admit(apiUrl, "bundle", signal, weight, id2);
48737
+ const cached2 = /* @__PURE__ */ new Map();
48666
48738
  const remaining = /* @__PURE__ */ new Map();
48739
+ let weight = 0;
48667
48740
  for (const body of bodies) {
48668
48741
  const key = JSON.stringify(body);
48742
+ const hit = eligibleCache(apiUrl, body, options);
48743
+ if (hit) {
48744
+ cached2.set(key, hit);
48745
+ continue;
48746
+ }
48669
48747
  remaining.set(key, (remaining.get(key) ?? 0) + 1);
48748
+ weight += weights[String(body.type)] ?? policy.default_request_weight;
48670
48749
  }
48671
- return { id: id2, endpoint: apiUrl, expiresAtMs: admittedAtMs + policy.window_seconds * 1e3, remaining };
48750
+ const id2 = crypto.randomUUID();
48751
+ const admittedAtMs = Date.now();
48752
+ if (weight) await admit(apiUrl, "bundle", signal, weight, id2, options.cacheValidUntilMs);
48753
+ return { id: id2, closed: false, endpoint: apiUrl, expiresAtMs: admittedAtMs + policy.window_seconds * 1e3, remaining, cached: cached2, cacheValidUntilMs: options.cacheValidUntilMs };
48754
+ };
48755
+ releaseHyperliquidPublicReadReservation = async (reservation) => {
48756
+ reservation.closed = true;
48757
+ const key = `${PREFIX}${reservation.endpoint}`;
48758
+ await withBudgetLock(key, void 0, () => {
48759
+ const budget = loadBudget(key);
48760
+ const row = budget.reservations.find((entry) => entry.id === reservation.id);
48761
+ if (row) {
48762
+ const unused = [...reservation.remaining].reduce((sum, [body, count4]) => sum + (weights[String(JSON.parse(body).type)] ?? policy.default_request_weight) * count4, 0);
48763
+ row.weight = Math.max(0, row.weight - unused);
48764
+ budget.reservations = budget.reservations.filter((entry) => entry.weight > 0);
48765
+ saveBudget(key, budget);
48766
+ }
48767
+ reservation.remaining.clear();
48768
+ });
48769
+ };
48770
+ admitHyperliquidExchangeRequest = async (endpoint, action, signal) => {
48771
+ const batchLength = Math.max(0, ...[action.orders, action.cancels, action.modifies].filter(Array.isArray).map((value) => value.length));
48772
+ const weight = weights.exchange + Math.floor(batchLength / runtime_policy_generated_default.exchange.hyperliquid.read_budget.exchange_action_batch_size);
48773
+ await admit(endpoint.replace(/\/$/, ""), "exchange", signal, weight);
48774
+ };
48775
+ recordHyperliquidExchangeResponse = async (endpoint, response) => {
48776
+ if (response.status === 429) await cooldown(endpoint.replace(/\/$/, ""), response.headers.get("Retry-After"));
48672
48777
  };
48673
48778
  readHyperliquidPublicInfo = async (endpoint, body, options = {}) => {
48674
48779
  const apiUrl = endpoint.replace(/\/$/, "");
48675
48780
  const requestType = String(body.type ?? "info");
48676
- const ttlSeconds = ["meta", "spotMeta", "perpDexs"].includes(requestType) ? policy.metadata_ttl_seconds : requestType === "userFees" ? policy.user_fees_ttl_seconds : options.cacheAccountMode && ["userAbstraction", "userDexAbstraction"].includes(requestType) ? policy.account_mode_ttl_seconds : 0;
48781
+ const cacheOptions = { ...options, cacheValidUntilMs: options.reservation?.cacheValidUntilMs ?? options.cacheValidUntilMs };
48782
+ const ttlMs = cacheTtlMs(body, cacheOptions);
48677
48783
  const key = `${apiUrl}:${JSON.stringify(body)}`;
48678
48784
  checkAbort(options.signal);
48679
- if (ttlSeconds) {
48785
+ if (ttlMs) {
48680
48786
  for (; ; ) {
48681
- const existing = cache.get(key);
48682
- if (existing && Date.now() - existing.fetchedAtMs >= 0 && Date.now() - existing.fetchedAtMs < ttlSeconds * 500) return existing;
48787
+ const existing = options.reservation?.cached.get(JSON.stringify(body)) ?? eligibleCache(apiUrl, body, cacheOptions);
48788
+ if (existing) return existing;
48683
48789
  const running = pending2.get(key);
48684
48790
  if (!running) break;
48685
48791
  await new Promise((resolve13, reject) => {
@@ -48697,26 +48803,31 @@ var init_hyperliquid_public_read = __esm({
48697
48803
  }
48698
48804
  }
48699
48805
  let settled;
48700
- if (ttlSeconds) pending2.set(key, new Promise((resolve13) => {
48806
+ if (ttlMs) pending2.set(key, new Promise((resolve13) => {
48701
48807
  settled = resolve13;
48702
48808
  }));
48703
48809
  try {
48704
48810
  const reservedKey = JSON.stringify(body);
48705
48811
  const remaining = options.reservation?.remaining.get(reservedKey) ?? 0;
48706
48812
  if (options.reservation?.endpoint === apiUrl && remaining > 0) {
48707
- if (Date.now() >= options.reservation.expiresAtMs) throw Object.assign(new Error("Hyperliquid public read reservation expired."), { code: "public_budget_exhausted" });
48813
+ if (Date.now() >= options.reservation.expiresAtMs) throw new HyperliquidPublicReadError("public_budget_exhausted", "Hyperliquid public read reservation expired.", requestType);
48708
48814
  await withBudgetLock(`${PREFIX}${apiUrl}`, options.signal, () => {
48815
+ if (options.reservation.closed) throw new HyperliquidPublicReadError("public_budget_exhausted", "Hyperliquid public read bundle is closed.", requestType);
48816
+ if ((options.reservation.remaining.get(reservedKey) ?? 0) <= 0) throw new HyperliquidPublicReadError("public_budget_exhausted", "Hyperliquid request is outside its admitted bundle.", requestType);
48709
48817
  const budget = loadBudget(`${PREFIX}${apiUrl}`);
48710
48818
  const row = budget.reservations.find((entry) => entry.id === options.reservation.id);
48711
- if (!row || Date.now() >= options.reservation.expiresAtMs) throw Object.assign(new Error("Hyperliquid public read reservation expired."), { code: "public_budget_exhausted" });
48819
+ if (!row || Date.now() >= options.reservation.expiresAtMs) throw new HyperliquidPublicReadError("public_budget_exhausted", "Hyperliquid public read reservation expired.", requestType);
48712
48820
  row.at = Date.now();
48713
48821
  budget.reservations.sort((a, b2) => a.at - b2.at);
48822
+ options.reservation.remaining.set(reservedKey, (options.reservation.remaining.get(reservedKey) ?? 0) - 1);
48714
48823
  saveBudget(`${PREFIX}${apiUrl}`, budget);
48715
48824
  });
48716
- options.reservation.remaining.set(reservedKey, remaining - 1);
48717
- } else await admit(apiUrl, requestType, options.signal);
48825
+ } else if (options.reservation) throw new HyperliquidPublicReadError("public_budget_exhausted", "Hyperliquid request is outside its admitted bundle.", requestType);
48826
+ else await admit(apiUrl, requestType, options.signal, void 0, void 0, options.deadlineMs);
48718
48827
  checkAbort(options.signal);
48719
- if (loadBudget(`${PREFIX}${apiUrl}`).cooldownUntil > Date.now()) throw Object.assign(new Error("Hyperliquid public read rate-limit cooldown."), { status: 429, requestType });
48828
+ if (options.reservation?.closed) throw new HyperliquidPublicReadError("public_budget_exhausted", "Hyperliquid public read bundle is closed.", requestType);
48829
+ const cooldownUntil = loadBudget(`${PREFIX}${apiUrl}`).cooldownUntil;
48830
+ if (cooldownUntil > Date.now()) throw cooldownError(requestType, cooldownUntil);
48720
48831
  const response = await fetch(`${apiUrl}/info`, {
48721
48832
  method: "POST",
48722
48833
  headers: { "Content-Type": "application/json" },
@@ -48724,22 +48835,31 @@ var init_hyperliquid_public_read = __esm({
48724
48835
  signal: options.signal
48725
48836
  });
48726
48837
  if (response.status === 429) await cooldown(apiUrl, response.headers.get("Retry-After"));
48727
- const payload = await response.json().catch(() => ({}));
48838
+ const payload = await response.json().catch((error48) => {
48839
+ if (error48 instanceof SyntaxError) return {};
48840
+ throw error48;
48841
+ });
48728
48842
  if (!response.ok) {
48729
48843
  const detail = sanitizeRuntimeDiagnosticValue(typeof payload?.response === "string" ? payload.response : typeof payload?.detail === "string" ? payload.detail : "");
48844
+ if (response.status === 429) throw new HyperliquidPublicReadError("public_rate_limited", "Hyperliquid public API returned HTTP 429.", requestType, 429);
48730
48845
  throw Object.assign(new Error(`Hyperliquid info request failed (${response.status}) request_type=${requestType}.${detail ? ` ${detail}` : ""}`), {
48731
48846
  status: response.status,
48732
48847
  requestType
48733
48848
  });
48734
48849
  }
48735
48850
  const result2 = { payload, fetchedAtMs: Date.now() };
48736
- if (ttlSeconds) {
48851
+ if (ttlMs) {
48737
48852
  cache.set(key, result2);
48738
48853
  while (cache.size > policy.cache_max_entries) cache.delete(cache.keys().next().value);
48739
48854
  }
48740
48855
  return result2;
48856
+ } catch (error48) {
48857
+ if (options.signal?.aborted || error48 instanceof HyperliquidPublicReadError) throw error48;
48858
+ if (error48 instanceof TypeError) throw new HyperliquidPublicReadError("public_network_error", "Hyperliquid public request network failure.", requestType);
48859
+ if (error48 instanceof Error && (error48.name === "TimeoutError" || error48.name === "AbortError")) throw new HyperliquidPublicReadError("public_timeout", "Hyperliquid public request timed out.", requestType);
48860
+ throw error48;
48741
48861
  } finally {
48742
- if (ttlSeconds) {
48862
+ if (ttlMs) {
48743
48863
  pending2.delete(key);
48744
48864
  settled?.();
48745
48865
  }
@@ -50736,273 +50856,283 @@ var init_hyperliquid_account_state_adapter = __esm({
50736
50856
  dexNames,
50737
50857
  staleIf429MaxAgeMs
50738
50858
  }) => {
50739
- const userFeesPromise = input.includeEffectiveTakerRate === true ? (async () => ({
50740
- ...await readHyperliquidPublicInfo(apiUrl, { type: "userFees", user: walletAddress }, { signal: input.signal }).catch((error48) => {
50741
- if (input.signal?.aborted) throw error48;
50742
- return { payload: null, fetchedAtMs: Date.now() };
50743
- }).then((result2) => ({ payload: result2.payload, capturedAt: new Date(result2.fetchedAtMs).toISOString() }))
50744
- }))() : Promise.resolve(null);
50745
- const exactAccountModePromise = input.includeExactAccountMode === true ? (async () => {
50746
- const abstractionRead = await readHyperliquidPublicInfo(apiUrl, { type: "userAbstraction", user: walletAddress }, { signal: input.signal, cacheAccountMode: true });
50747
- const userAbstraction = abstractionRead.payload;
50748
- let capturedAtMs = abstractionRead.fetchedAtMs;
50749
- const preliminaryMode = extractCanonicalHyperliquidAccountMode(userAbstraction);
50750
- if (!preliminaryMode) {
50751
- throw new Error("Exact Hyperliquid userAbstraction response is invalid.");
50752
- }
50753
- let userDexAbstraction;
50754
- if (preliminaryMode === "default" || preliminaryMode === "disabled") {
50755
- const dexRead = await readHyperliquidPublicInfo(apiUrl, { type: "userDexAbstraction", user: walletAddress }, { signal: input.signal, cacheAccountMode: true });
50756
- userDexAbstraction = dexRead.payload;
50757
- capturedAtMs = Math.min(capturedAtMs, dexRead.fetchedAtMs);
50758
- }
50759
- return {
50760
- accountMode: resolveExactHyperliquidAccountMode(
50761
- userAbstraction,
50762
- userDexAbstraction
50763
- ),
50764
- capturedAt: new Date(capturedAtMs).toISOString()
50765
- };
50766
- })() : Promise.resolve(null);
50767
- await Promise.all([userFeesPromise, exactAccountModePromise]);
50768
- const metadataByDex = /* @__PURE__ */ new Map();
50769
- if (input.includeEffectiveTakerRate === true) {
50770
- await Promise.all(["", ...dexNames].map(async (dex) => {
50771
- try {
50772
- metadataByDex.set(dex, await fetchHyperliquidInfoPayload(apiUrl, { type: "meta", ...dex ? { dex } : {} }, input.signal));
50773
- } catch (error48) {
50774
- if (input.signal?.aborted) throw error48;
50775
- metadataByDex.set(dex, null);
50776
- }
50777
- }));
50778
- }
50859
+ const metadataBodies = input.includeEffectiveTakerRate === true ? ["", ...dexNames].map((dex) => ({ type: "meta", ...dex ? { dex } : {} })) : [];
50779
50860
  const reservation = await reserveHyperliquidPublicReads(apiUrl, [
50780
50861
  { type: "clearinghouseState", user: walletAddress },
50781
50862
  ...dexNames.map((dex) => ({ type: "clearinghouseState", user: walletAddress, dex })),
50782
50863
  { type: "spotClearinghouseState", user: walletAddress },
50783
- ...input.includeActiveAssetData === false ? [] : activeAssetRequestTypes.map((type) => ({ type, user: walletAddress, coin: symbol2 }))
50784
- ], input.signal);
50785
- const perpsPromise = (async () => {
50786
- const defaultResponse = await fetchHyperliquidInfoPayload(
50787
- apiUrl,
50788
- { type: "clearinghouseState", user: walletAddress },
50789
- input.signal,
50790
- reservation
50791
- );
50864
+ ...input.includeActiveAssetData === false ? [] : activeAssetRequestTypes.map((type) => ({ type, user: walletAddress, coin: symbol2 })),
50865
+ ...input.includeEffectiveTakerRate === true ? [{ type: "userFees", user: walletAddress }, ...metadataBodies] : [],
50866
+ ...input.includeExactAccountMode === true ? [
50867
+ { type: "userAbstraction", user: walletAddress },
50868
+ { type: "userDexAbstraction", user: walletAddress }
50869
+ ] : []
50870
+ ], input.signal, { cacheAccountMode: true, cacheValidUntilMs: input.publicReadDeadlineMs });
50871
+ try {
50872
+ const userFeesPromise = input.includeEffectiveTakerRate === true ? (async () => ({
50873
+ ...await readHyperliquidPublicInfo(apiUrl, { type: "userFees", user: walletAddress }, { signal: input.signal, reservation }).catch((error48) => {
50874
+ if (input.signal?.aborted || error48 instanceof HyperliquidPublicReadError || isRateLimitError(error48)) throw error48;
50875
+ return { payload: null, fetchedAtMs: Date.now() };
50876
+ }).then((result2) => ({ payload: result2.payload, capturedAt: new Date(result2.fetchedAtMs).toISOString() }))
50877
+ }))() : Promise.resolve(null);
50878
+ const exactAccountModePromise = input.includeExactAccountMode === true ? (async () => {
50879
+ const abstractionRead = await readHyperliquidPublicInfo(apiUrl, { type: "userAbstraction", user: walletAddress }, { signal: input.signal, reservation, cacheAccountMode: true });
50880
+ const userAbstraction = abstractionRead.payload;
50881
+ let capturedAtMs = abstractionRead.fetchedAtMs;
50882
+ const preliminaryMode = extractCanonicalHyperliquidAccountMode(userAbstraction);
50883
+ if (!preliminaryMode) {
50884
+ throw new Error("Exact Hyperliquid userAbstraction response is invalid.");
50885
+ }
50886
+ let userDexAbstraction;
50887
+ if (preliminaryMode === "default" || preliminaryMode === "disabled") {
50888
+ const dexRead = await readHyperliquidPublicInfo(apiUrl, { type: "userDexAbstraction", user: walletAddress }, { signal: input.signal, reservation, cacheAccountMode: true });
50889
+ userDexAbstraction = dexRead.payload;
50890
+ capturedAtMs = Math.min(capturedAtMs, dexRead.fetchedAtMs);
50891
+ }
50892
+ return {
50893
+ accountMode: resolveExactHyperliquidAccountMode(
50894
+ userAbstraction,
50895
+ userDexAbstraction
50896
+ ),
50897
+ capturedAt: new Date(capturedAtMs).toISOString()
50898
+ };
50899
+ })() : Promise.resolve(null);
50900
+ await Promise.all([userFeesPromise, exactAccountModePromise]);
50901
+ const metadataByDex = /* @__PURE__ */ new Map();
50792
50902
  if (input.includeEffectiveTakerRate === true) {
50793
- requirePromptClearinghouseState(defaultResponse, "default");
50794
- }
50795
- const dexResponses = await Promise.all(
50796
- dexNames.map(async (dexName) => {
50797
- const response = await fetchHyperliquidInfoPayload(
50798
- apiUrl,
50799
- { type: "clearinghouseState", user: walletAddress, dex: dexName },
50800
- input.signal,
50801
- reservation
50802
- );
50803
- if (input.includeEffectiveTakerRate === true) {
50804
- requirePromptClearinghouseState(response, dexName);
50903
+ await Promise.all(["", ...dexNames].map(async (dex) => {
50904
+ try {
50905
+ metadataByDex.set(dex, await fetchHyperliquidInfoPayload(apiUrl, { type: "meta", ...dex ? { dex } : {} }, input.signal, reservation));
50906
+ } catch (error48) {
50907
+ if (input.signal?.aborted || error48 instanceof HyperliquidPublicReadError || isRateLimitError(error48)) throw error48;
50908
+ metadataByDex.set(dex, null);
50805
50909
  }
50806
- return {
50807
- dex: dexName,
50808
- payload: prefixHip3PositionCoins(response, dexName),
50809
- rawPayload: response
50810
- };
50811
- })
50812
- );
50813
- const selectedPayload = selectedDex ? dexResponses.find((entry) => entry.dex === selectedDex)?.payload : defaultResponse;
50814
- if (!selectedPayload) {
50815
- throw new Error(`Missing selected Hyperliquid clearinghouse state for DEX ${selectedDex}.`);
50910
+ }));
50816
50911
  }
50817
- return {
50818
- payload: aggregateClearinghouseResponses([
50819
- defaultResponse,
50820
- ...dexResponses.map((entry) => entry.payload)
50821
- ]),
50822
- selectedPayload,
50823
- dexPayloads: [
50824
- { dex: "", payload: defaultResponse },
50825
- ...dexResponses.map(({ dex, rawPayload }) => ({ dex, payload: rawPayload }))
50826
- ],
50827
- capturedAt: (/* @__PURE__ */ new Date()).toISOString()
50828
- };
50829
- })();
50830
- const spotPromise = (async () => {
50831
- let payload;
50832
- try {
50833
- payload = await fetchHyperliquidInfoPayload(
50912
+ const perpsPromise = (async () => {
50913
+ const defaultResponse = await fetchHyperliquidInfoPayload(
50834
50914
  apiUrl,
50835
- { type: "spotClearinghouseState", user: walletAddress },
50915
+ { type: "clearinghouseState", user: walletAddress },
50836
50916
  input.signal,
50837
50917
  reservation
50838
50918
  );
50839
- } catch (error48) {
50840
- recordInfoRateLimitCooldownFromError(apiUrl, error48, staleIf429MaxAgeMs);
50841
- if (input.forceRefresh || input.includeEffectiveTakerRate === true) {
50842
- throw error48;
50919
+ if (input.includeEffectiveTakerRate === true) {
50920
+ requirePromptClearinghouseState(defaultResponse, "default");
50921
+ }
50922
+ const dexResponses = await Promise.all(
50923
+ dexNames.map(async (dexName) => {
50924
+ const response = await fetchHyperliquidInfoPayload(
50925
+ apiUrl,
50926
+ { type: "clearinghouseState", user: walletAddress, dex: dexName },
50927
+ input.signal,
50928
+ reservation
50929
+ );
50930
+ if (input.includeEffectiveTakerRate === true) {
50931
+ requirePromptClearinghouseState(response, dexName);
50932
+ }
50933
+ return {
50934
+ dex: dexName,
50935
+ payload: prefixHip3PositionCoins(response, dexName),
50936
+ rawPayload: response
50937
+ };
50938
+ })
50939
+ );
50940
+ const selectedPayload = selectedDex ? dexResponses.find((entry) => entry.dex === selectedDex)?.payload : defaultResponse;
50941
+ if (!selectedPayload) {
50942
+ throw new Error(`Missing selected Hyperliquid clearinghouse state for DEX ${selectedDex}.`);
50843
50943
  }
50844
- payload = {};
50845
- }
50846
- return { payload, capturedAt: (/* @__PURE__ */ new Date()).toISOString() };
50847
- })();
50848
- const activeAssetPromise = input.includeActiveAssetData === false ? Promise.resolve(null) : (async () => {
50849
- let lastError = null;
50850
- for (const typeName of activeAssetRequestTypes) {
50944
+ return {
50945
+ payload: aggregateClearinghouseResponses([
50946
+ defaultResponse,
50947
+ ...dexResponses.map((entry) => entry.payload)
50948
+ ]),
50949
+ selectedPayload,
50950
+ dexPayloads: [
50951
+ { dex: "", payload: defaultResponse },
50952
+ ...dexResponses.map(({ dex, rawPayload }) => ({ dex, payload: rawPayload }))
50953
+ ],
50954
+ capturedAt: (/* @__PURE__ */ new Date()).toISOString()
50955
+ };
50956
+ })();
50957
+ const spotPromise = (async () => {
50958
+ let payload;
50851
50959
  try {
50852
- const payload = await fetchHyperliquidInfoPayload(
50960
+ payload = await fetchHyperliquidInfoPayload(
50853
50961
  apiUrl,
50854
- { type: typeName, user: walletAddress, coin: symbol2 },
50962
+ { type: "spotClearinghouseState", user: walletAddress },
50855
50963
  input.signal,
50856
50964
  reservation
50857
50965
  );
50858
- return { payload, type: typeName };
50859
50966
  } catch (error48) {
50860
- lastError = error48;
50861
50967
  recordInfoRateLimitCooldownFromError(apiUrl, error48, staleIf429MaxAgeMs);
50862
- if (isRateLimitError(error48)) throw error48;
50863
- if (typeName === "userActiveAssetData" && isUnsupportedUserActiveAssetError(error48)) {
50864
- rememberUnsupportedUserActiveAssetKey(activeAssetCacheKey);
50968
+ if (input.forceRefresh || input.includeEffectiveTakerRate === true) {
50969
+ throw error48;
50865
50970
  }
50971
+ payload = {};
50866
50972
  }
50867
- }
50868
- throw lastError instanceof Error ? lastError : new Error("Failed to fetch browser active asset data.");
50869
- })();
50870
- const [perpsResult, spotResult, activeAssetResult, userFeesResult, exactAccountMode] = await Promise.all([
50871
- perpsPromise,
50872
- spotPromise,
50873
- activeAssetPromise,
50874
- userFeesPromise,
50875
- exactAccountModePromise
50876
- ]);
50877
- const perpsResponse = perpsResult.payload;
50878
- const accountSummaryPerpsResponse = input.scopeAccountSummaryToSelectedDex === true ? perpsResult.selectedPayload : perpsResponse;
50879
- const spotResponse = spotResult.payload;
50880
- const userFeesResponse = userFeesResult?.payload ?? null;
50881
- if (input.includeEffectiveTakerRate === true) {
50882
- requirePromptSpotState(spotResponse);
50883
- }
50884
- let takerRate;
50885
- if (input.includeEffectiveTakerRate === true) {
50886
- const raw = userFeesResponse?.userCrossRate;
50887
- if ((typeof raw === "number" || typeof raw === "string" && raw.trim() !== "") && Number.isFinite(Number(raw)) && Number(raw) >= 0 && Number(raw) < 1) takerRate = Number(raw);
50888
- }
50889
- let effectiveTakerRates;
50890
- if (input.includeEffectiveTakerRate === true) {
50891
- const feeSymbols = [...new Set([
50892
- ...input.feeSymbols ?? [symbol2],
50893
- ...parseInfoPositions(perpsResponse).filter((position) => Number(position.size) !== 0).map((position) => position.symbol)
50894
- ].map(normalizeHyperliquidMarketSymbol).filter(Boolean))].sort();
50895
- const feeDexes = [...new Set(feeSymbols.map(getHyperliquidMarketDex))];
50896
- const metadata = await Promise.all(feeDexes.map(async (dex) => {
50897
- try {
50898
- const payload = metadataByDex.get(dex) ?? null;
50899
- return [dex, payload];
50900
- } catch (error48) {
50901
- if (input.signal?.aborted) throw error48;
50902
- return [dex, null];
50973
+ return { payload, capturedAt: (/* @__PURE__ */ new Date()).toISOString() };
50974
+ })();
50975
+ const activeAssetPromise = input.includeActiveAssetData === false ? Promise.resolve(null) : (async () => {
50976
+ let lastError = null;
50977
+ for (const typeName of activeAssetRequestTypes) {
50978
+ try {
50979
+ const payload = await fetchHyperliquidInfoPayload(
50980
+ apiUrl,
50981
+ { type: typeName, user: walletAddress, coin: symbol2 },
50982
+ input.signal,
50983
+ reservation
50984
+ );
50985
+ return { payload, type: typeName };
50986
+ } catch (error48) {
50987
+ lastError = error48;
50988
+ recordInfoRateLimitCooldownFromError(apiUrl, error48, staleIf429MaxAgeMs);
50989
+ if (isRateLimitError(error48)) throw error48;
50990
+ if (typeName === "userActiveAssetData" && isUnsupportedUserActiveAssetError(error48)) {
50991
+ rememberUnsupportedUserActiveAssetKey(activeAssetCacheKey);
50992
+ }
50993
+ }
50903
50994
  }
50904
- }));
50905
- effectiveTakerRates = effectiveHyperliquidTakerRates(feeSymbols, userFeesResponse ?? {}, Object.fromEntries(metadata));
50906
- }
50907
- const accountStateConfig = input.config.client_runtime_hyperliquid_account_state;
50908
- const summaryPerpsResponse = exactAccountMode ? { ...accountSummaryPerpsResponse, accountMode: exactAccountMode.accountMode } : accountSummaryPerpsResponse;
50909
- const accountSummaryOptions = {
50910
- spotDominatesMinTotalUsd: accountStateConfig?.spot_dominates_min_total_usd,
50911
- spotDominatesPerpsMultiplier: accountStateConfig?.spot_dominates_perps_multiplier,
50912
- mirroredAccountValueAbsoluteToleranceUsd: accountStateConfig?.mirrored_account_value_absolute_tolerance_usd,
50913
- mirroredAccountValueRelativeTolerance: accountStateConfig?.mirrored_account_value_relative_tolerance
50914
- };
50915
- const walletSummary = exactAccountMode && input.scopeAccountSummaryToSelectedDex !== true ? buildServerPromptRescueAccountSummary(
50916
- perpsResponse,
50917
- spotResponse,
50918
- exactAccountMode.accountMode,
50919
- accountSummaryOptions
50920
- ) : buildAccountSummaryFromInfoResponses(
50921
- perpsResponse,
50922
- spotResponse,
50923
- accountSummaryOptions
50924
- );
50925
- const normalizedSummary = input.scopeAccountSummaryToSelectedDex === true ? {
50926
- ...buildAccountSummaryFromInfoResponses(
50995
+ throw lastError instanceof Error ? lastError : new Error("Failed to fetch browser active asset data.");
50996
+ })();
50997
+ const [perpsResult, spotResult, activeAssetResult, userFeesResult, exactAccountMode] = await Promise.all([
50998
+ perpsPromise,
50999
+ spotPromise,
51000
+ activeAssetPromise,
51001
+ userFeesPromise,
51002
+ exactAccountModePromise
51003
+ ]);
51004
+ const perpsResponse = perpsResult.payload;
51005
+ const accountSummaryPerpsResponse = input.scopeAccountSummaryToSelectedDex === true ? perpsResult.selectedPayload : perpsResponse;
51006
+ const spotResponse = spotResult.payload;
51007
+ const userFeesResponse = userFeesResult?.payload ?? null;
51008
+ if (input.includeEffectiveTakerRate === true) {
51009
+ requirePromptSpotState(spotResponse);
51010
+ }
51011
+ let takerRate;
51012
+ if (input.includeEffectiveTakerRate === true) {
51013
+ const raw = userFeesResponse?.userCrossRate;
51014
+ if ((typeof raw === "number" || typeof raw === "string" && raw.trim() !== "") && Number.isFinite(Number(raw)) && Number(raw) >= 0 && Number(raw) < 1) takerRate = Number(raw);
51015
+ }
51016
+ let effectiveTakerRates;
51017
+ if (input.includeEffectiveTakerRate === true) {
51018
+ const feeSymbols = [...new Set([
51019
+ ...input.feeSymbols ?? [symbol2],
51020
+ ...parseInfoPositions(perpsResponse).filter((position) => Number(position.size) !== 0).map((position) => position.symbol)
51021
+ ].map(normalizeHyperliquidMarketSymbol).filter(Boolean))].sort();
51022
+ const feeDexes = [...new Set(feeSymbols.map(getHyperliquidMarketDex))];
51023
+ const metadata = await Promise.all(feeDexes.map(async (dex) => {
51024
+ try {
51025
+ const payload = metadataByDex.get(dex) ?? null;
51026
+ return [dex, payload];
51027
+ } catch (error48) {
51028
+ if (input.signal?.aborted) throw error48;
51029
+ return [dex, null];
51030
+ }
51031
+ }));
51032
+ effectiveTakerRates = effectiveHyperliquidTakerRates(feeSymbols, userFeesResponse ?? {}, Object.fromEntries(metadata));
51033
+ }
51034
+ const accountStateConfig = input.config.client_runtime_hyperliquid_account_state;
51035
+ const summaryPerpsResponse = exactAccountMode ? { ...accountSummaryPerpsResponse, accountMode: exactAccountMode.accountMode } : accountSummaryPerpsResponse;
51036
+ const accountSummaryOptions = {
51037
+ spotDominatesMinTotalUsd: accountStateConfig?.spot_dominates_min_total_usd,
51038
+ spotDominatesPerpsMultiplier: accountStateConfig?.spot_dominates_perps_multiplier,
51039
+ mirroredAccountValueAbsoluteToleranceUsd: accountStateConfig?.mirrored_account_value_absolute_tolerance_usd,
51040
+ mirroredAccountValueRelativeTolerance: accountStateConfig?.mirrored_account_value_relative_tolerance
51041
+ };
51042
+ const walletSummary = exactAccountMode && input.scopeAccountSummaryToSelectedDex !== true ? buildServerPromptRescueAccountSummary(
51043
+ perpsResponse,
51044
+ spotResponse,
51045
+ exactAccountMode.accountMode,
51046
+ accountSummaryOptions
51047
+ ) : buildAccountSummaryFromInfoResponses(
51048
+ perpsResponse,
51049
+ spotResponse,
51050
+ accountSummaryOptions
51051
+ );
51052
+ const normalizedSummary = input.scopeAccountSummaryToSelectedDex === true ? {
51053
+ ...buildAccountSummaryFromInfoResponses(
51054
+ summaryPerpsResponse,
51055
+ {},
51056
+ accountSummaryOptions
51057
+ ),
51058
+ balances: walletSummary.balances
51059
+ } : exactAccountMode ? buildServerPromptRescueAccountSummary(
51060
+ accountSummaryPerpsResponse,
51061
+ spotResponse,
51062
+ exactAccountMode.accountMode,
51063
+ accountSummaryOptions
51064
+ ) : buildAccountSummaryFromInfoResponses(
50927
51065
  summaryPerpsResponse,
50928
- {},
51066
+ spotResponse,
50929
51067
  accountSummaryOptions
50930
- ),
50931
- balances: walletSummary.balances
50932
- } : exactAccountMode ? buildServerPromptRescueAccountSummary(
50933
- accountSummaryPerpsResponse,
50934
- spotResponse,
50935
- exactAccountMode.accountMode,
50936
- accountSummaryOptions
50937
- ) : buildAccountSummaryFromInfoResponses(
50938
- summaryPerpsResponse,
50939
- spotResponse,
50940
- accountSummaryOptions
50941
- );
50942
- const accountSummary = {
50943
- ...normalizedSummary,
50944
- ...input.scopeAccountSummaryToSelectedDex === true ? {} : {
50945
- perp_dex_accounts: perpsResult.dexPayloads.filter(({ payload }) => hasCompletePerpDexAccountMetrics(payload)).map(({ dex, payload }) => {
50946
- const summary = buildServerPromptRescueAccountSummary({
50947
- ...payload,
50948
- crossMaintenanceMarginUsed: firstFiniteNumber([
50949
- payload.crossMaintenanceMarginUsed,
50950
- payload.marginSummary?.crossMaintenanceMarginUsed,
50951
- payload.marginSummary?.totalMaintenanceMargin
50952
- ])
50953
- }, {}, "disabled", accountSummaryOptions);
50954
- const accountValue = Number(payload.marginSummary.accountValue);
50955
- const calculatedAvailable = accountValue - summary.total_margin_used;
50956
- const availableMargin = summary.maintenance_margin > 0 ? Math.max(calculatedAvailable, Math.max(0, accountValue - 4 * summary.maintenance_margin), summary.withdrawable) : Math.max(calculatedAvailable, summary.withdrawable);
50957
- return {
50958
- dex,
50959
- account_value: accountValue,
50960
- total_margin_used: summary.total_margin_used,
50961
- available_margin: availableMargin,
50962
- withdrawable: summary.withdrawable,
50963
- maintenance_margin: summary.maintenance_margin,
50964
- cross_account_leverage: summary.cross_account_leverage,
50965
- total_unrealized_pnl: summary.total_unrealized_pnl ?? 0
50966
- };
50967
- })
50968
- },
50969
- ...exactAccountMode == null ? {} : { account_mode: exactAccountMode.accountMode, mode_source: "canonical" },
50970
- address: walletAddress,
50971
- dex: input.scopeAccountSummaryToSelectedDex === true ? selectedDex : "all",
50972
- market_type: "perp"
50973
- };
50974
- const activeAssetPayload = activeAssetResult?.payload ?? null;
50975
- const activeAssetType = activeAssetResult?.type ?? "promptAccountState";
50976
- const normalizedActiveAsset = normalizeActiveAssetData(activeAssetPayload, symbol2);
50977
- const markPrice = toPositiveFinite(normalizedActiveAsset.mark_price, toPositiveFinite(input.tickerPrice));
50978
- const fallbackLeverage = toPositiveFinite(input.leverage, 1);
50979
- const availableBase = Math.max(0, toFinite(accountSummary.available_margin, 0));
50980
- const availableToTrade = {
50981
- symbol: symbol2,
50982
- available_to_trade_buy: Math.max(0, toFinite(normalizedActiveAsset.available_to_trade_buy, availableBase)),
50983
- available_to_trade_sell: Math.max(0, toFinite(normalizedActiveAsset.available_to_trade_sell, availableBase)),
50984
- max_trade_size_buy: Math.max(0, toFinite(normalizedActiveAsset.max_trade_size_buy, availableBase * fallbackLeverage)),
50985
- max_trade_size_sell: Math.max(0, toFinite(normalizedActiveAsset.max_trade_size_sell, availableBase * fallbackLeverage)),
50986
- mark_price: markPrice,
50987
- source: `browser_exchange:${activeAssetType}`
50988
- };
50989
- return {
50990
- accountSummary,
50991
- availableToTrade,
50992
- positions: parseInfoPositions(perpsResponse),
50993
- ...takerRate == null ? {} : { takerRate },
50994
- ...effectiveTakerRates == null ? {} : { effectiveTakerRates },
50995
- ...exactAccountMode == null || userFeesResult == null ? {} : {
50996
- promptRescueEvidence: {
50997
- capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
50998
- perpsCapturedAt: perpsResult.capturedAt,
50999
- spotCapturedAt: spotResult.capturedAt,
51000
- feesCapturedAt: userFeesResult.capturedAt,
51001
- accountModeCapturedAt: exactAccountMode.capturedAt,
51002
- accountModeSource: "canonical"
51068
+ );
51069
+ const accountSummary = {
51070
+ ...normalizedSummary,
51071
+ ...input.scopeAccountSummaryToSelectedDex === true ? {} : {
51072
+ perp_dex_accounts: perpsResult.dexPayloads.filter(({ payload }) => hasCompletePerpDexAccountMetrics(payload)).map(({ dex, payload }) => {
51073
+ const summary = buildServerPromptRescueAccountSummary({
51074
+ ...payload,
51075
+ crossMaintenanceMarginUsed: firstFiniteNumber([
51076
+ payload.crossMaintenanceMarginUsed,
51077
+ payload.marginSummary?.crossMaintenanceMarginUsed,
51078
+ payload.marginSummary?.totalMaintenanceMargin
51079
+ ])
51080
+ }, {}, "disabled", accountSummaryOptions);
51081
+ const accountValue = Number(payload.marginSummary.accountValue);
51082
+ const calculatedAvailable = accountValue - summary.total_margin_used;
51083
+ const availableMargin = summary.maintenance_margin > 0 ? Math.max(calculatedAvailable, Math.max(0, accountValue - 4 * summary.maintenance_margin), summary.withdrawable) : Math.max(calculatedAvailable, summary.withdrawable);
51084
+ return {
51085
+ dex,
51086
+ account_value: accountValue,
51087
+ total_margin_used: summary.total_margin_used,
51088
+ available_margin: availableMargin,
51089
+ withdrawable: summary.withdrawable,
51090
+ maintenance_margin: summary.maintenance_margin,
51091
+ cross_account_leverage: summary.cross_account_leverage,
51092
+ total_unrealized_pnl: summary.total_unrealized_pnl ?? 0
51093
+ };
51094
+ })
51095
+ },
51096
+ ...exactAccountMode == null ? {} : { account_mode: exactAccountMode.accountMode, mode_source: "canonical" },
51097
+ address: walletAddress,
51098
+ dex: input.scopeAccountSummaryToSelectedDex === true ? selectedDex : "all",
51099
+ market_type: "perp"
51100
+ };
51101
+ const activeAssetPayload = activeAssetResult?.payload ?? null;
51102
+ const activeAssetType = activeAssetResult?.type ?? "promptAccountState";
51103
+ const normalizedActiveAsset = normalizeActiveAssetData(activeAssetPayload, symbol2);
51104
+ const markPrice = toPositiveFinite(normalizedActiveAsset.mark_price, toPositiveFinite(input.tickerPrice));
51105
+ const fallbackLeverage = toPositiveFinite(input.leverage, 1);
51106
+ const availableBase = Math.max(0, toFinite(accountSummary.available_margin, 0));
51107
+ const availableToTrade = {
51108
+ symbol: symbol2,
51109
+ available_to_trade_buy: Math.max(0, toFinite(normalizedActiveAsset.available_to_trade_buy, availableBase)),
51110
+ available_to_trade_sell: Math.max(0, toFinite(normalizedActiveAsset.available_to_trade_sell, availableBase)),
51111
+ max_trade_size_buy: Math.max(0, toFinite(normalizedActiveAsset.max_trade_size_buy, availableBase * fallbackLeverage)),
51112
+ max_trade_size_sell: Math.max(0, toFinite(normalizedActiveAsset.max_trade_size_sell, availableBase * fallbackLeverage)),
51113
+ mark_price: markPrice,
51114
+ source: `browser_exchange:${activeAssetType}`
51115
+ };
51116
+ return {
51117
+ accountSummary,
51118
+ availableToTrade,
51119
+ positions: parseInfoPositions(perpsResponse),
51120
+ ...takerRate == null ? {} : { takerRate },
51121
+ ...effectiveTakerRates == null ? {} : { effectiveTakerRates },
51122
+ ...exactAccountMode == null || userFeesResult == null ? {} : {
51123
+ promptRescueEvidence: {
51124
+ capturedAt: (/* @__PURE__ */ new Date()).toISOString(),
51125
+ perpsCapturedAt: perpsResult.capturedAt,
51126
+ spotCapturedAt: spotResult.capturedAt,
51127
+ feesCapturedAt: userFeesResult.capturedAt,
51128
+ accountModeCapturedAt: exactAccountMode.capturedAt,
51129
+ accountModeSource: "canonical"
51130
+ }
51003
51131
  }
51004
- }
51005
- };
51132
+ };
51133
+ } finally {
51134
+ await releaseHyperliquidPublicReadReservation(reservation);
51135
+ }
51006
51136
  };
51007
51137
  fetchBrowserUserFills = async (input) => {
51008
51138
  configureHyperliquidMarketSymbolCasing(input.config.client_runtime_hyperliquid_case_sensitive_symbols);
@@ -64531,9 +64661,9 @@ var init_fragments = __esm({
64531
64661
  }
64532
64662
  const result2 = [];
64533
64663
  while (this.#offset < top.match - 1) {
64534
- const link = this.peek().linkNext;
64535
- result2.push(this.#subTokenString(this.#offset + 1, link));
64536
- this.#offset = link;
64664
+ const link2 = this.peek().linkNext;
64665
+ result2.push(this.#subTokenString(this.#offset + 1, link2));
64666
+ this.#offset = link2;
64537
64667
  }
64538
64668
  this.#offset = top.match + 1;
64539
64669
  return result2;
@@ -69257,15 +69387,15 @@ var init_contract2 = __esm({
69257
69387
  });
69258
69388
 
69259
69389
  // node_modules/ethers/lib.esm/providers/ens-resolver.js
69260
- function getIpfsLink(link) {
69261
- if (link.match(/^ipfs:\/\/ipfs\//i)) {
69262
- link = link.substring(12);
69263
- } else if (link.match(/^ipfs:\/\//i)) {
69264
- link = link.substring(7);
69390
+ function getIpfsLink(link2) {
69391
+ if (link2.match(/^ipfs:\/\/ipfs\//i)) {
69392
+ link2 = link2.substring(12);
69393
+ } else if (link2.match(/^ipfs:\/\//i)) {
69394
+ link2 = link2.substring(7);
69265
69395
  } else {
69266
- assertArgument(false, "unsupported IPFS format", "link", link);
69396
+ assertArgument(false, "unsupported IPFS format", "link", link2);
69267
69397
  }
69268
- return `https://gateway.ipfs.io/ipfs/${link}`;
69398
+ return `https://gateway.ipfs.io/ipfs/${link2}`;
69269
69399
  }
69270
69400
  var MulticoinProviderPlugin, matcherIpfs, matchers, EnsResolver;
69271
69401
  var init_ens_resolver = __esm({
@@ -85510,9 +85640,11 @@ var init_hyperliquid_client = __esm({
85510
85640
  }
85511
85641
  }
85512
85642
  try {
85643
+ await admitHyperliquidExchangeRequest(apiUrl, input.payload.action, input.signal);
85513
85644
  assertFreshPreparedExecutionContext(input.preparedContext);
85514
85645
  } catch (preparedContextError) {
85515
85646
  await settleDurableMutation("rejected");
85647
+ if (isAbortLikeError(preparedContextError) || preparedContextError instanceof HyperliquidPublicReadError) throw preparedContextError;
85516
85648
  throw new RuntimeExecutionError(
85517
85649
  preparedContextError instanceof Error ? preparedContextError.message : "Prepared exchange context expired before dispatch.",
85518
85650
  "local_safety_block"
@@ -85545,6 +85677,7 @@ var init_hyperliquid_client = __esm({
85545
85677
  body: serializedPayload
85546
85678
  });
85547
85679
  responseStatus = response.status;
85680
+ await recordHyperliquidExchangeResponse(apiUrl, response);
85548
85681
  const payload = await response.json().catch(() => ({}));
85549
85682
  if (!response.ok) {
85550
85683
  await settleDurableMutation("transport_ambiguous");
@@ -92921,7 +93054,7 @@ var headless_local_worker_exports = {};
92921
93054
  __export(headless_local_worker_exports, {
92922
93055
  createHeadlessLocalWorker: () => createHeadlessLocalWorker
92923
93056
  });
92924
- import { randomUUID as randomUUID14 } from "node:crypto";
93057
+ import { randomUUID as randomUUID15 } from "node:crypto";
92925
93058
  function objectOrNull3(value) {
92926
93059
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
92927
93060
  }
@@ -93350,7 +93483,7 @@ function createHeadlessLocalWorker(options) {
93350
93483
  const statusMatch = errorText.match(/\b([45]\d{2})\b/);
93351
93484
  const statusCode = statusMatch ? Number(statusMatch[1]) : null;
93352
93485
  const failedInvocation = normalizeAiInvocationTelemetry({
93353
- client_invocation_id: randomUUID14(),
93486
+ client_invocation_id: randomUUID15(),
93354
93487
  use_case: "trader",
93355
93488
  role: "primary",
93356
93489
  attempt_index: 0,
@@ -93406,7 +93539,7 @@ function createHeadlessLocalWorker(options) {
93406
93539
  billable_cached_input_tokens: normalizedUsage.cached_input_tokens
93407
93540
  };
93408
93541
  const invocation = normalizeAiInvocationTelemetry({
93409
- client_invocation_id: randomUUID14(),
93542
+ client_invocation_id: randomUUID15(),
93410
93543
  use_case: "trader",
93411
93544
  role: "primary",
93412
93545
  attempt_index: 0,
@@ -93670,7 +93803,7 @@ var vtx_exports = {};
93670
93803
  __export(vtx_exports, {
93671
93804
  runVtxCli: () => runVtxCli
93672
93805
  });
93673
- import { randomUUID as randomUUID15 } from "node:crypto";
93806
+ import { randomUUID as randomUUID16 } from "node:crypto";
93674
93807
  import { spawn as spawn12 } from "node:child_process";
93675
93808
  function render2(value, json2) {
93676
93809
  if (json2) {
@@ -94084,8 +94217,8 @@ async function runVtxCli(argv2, env = process.env) {
94084
94217
  });
94085
94218
  return { exitCode: 0, stdout: render2(redactCliOutput(response2), json2), stderr: "" };
94086
94219
  }
94087
- const runtimeSessionId = randomUUID15();
94088
- const deviceId = config2.runtimeDeviceId ?? randomUUID15();
94220
+ const runtimeSessionId = randomUUID16();
94221
+ const deviceId = config2.runtimeDeviceId ?? randomUUID16();
94089
94222
  const response = await client.startRuntime(profileId, {
94090
94223
  session_id: runtimeSessionId,
94091
94224
  device_id: deviceId,