@vtxmacro/cli 2026.9.68 → 2026.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/vtx-mcp.js +21 -2
- package/bin/vtx-service-bootstrap.js +293 -126
- package/bin/vtx-service-launcher.js +289 -122
- package/bin/vtx.js +582 -240
- package/package.json +1 -1
package/bin/vtx.js
CHANGED
|
@@ -77,7 +77,7 @@ 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.
|
|
80
|
+
package_version: "2026.10.1",
|
|
81
81
|
codex_package_name: "@openai/codex",
|
|
82
82
|
codex_version: "0.155.0",
|
|
83
83
|
copilot_sdk_package_name: "@github/copilot-sdk",
|
|
@@ -17607,9 +17607,9 @@ var init_mcp_transport_config = __esm({
|
|
|
17607
17607
|
import { randomBytes } from "node:crypto";
|
|
17608
17608
|
import { spawn } from "node:child_process";
|
|
17609
17609
|
import { constants } from "node:fs";
|
|
17610
|
-
import { lstat, mkdir, open, readFile, realpath, rename, rm } from "node:fs/promises";
|
|
17610
|
+
import { lstat, mkdir, open, readdir, readFile, realpath, rename, rm } from "node:fs/promises";
|
|
17611
17611
|
import { homedir } from "node:os";
|
|
17612
|
-
import { dirname, isAbsolute as isAbsolute2, join, relative, resolve, win32 as windowsPath } from "node:path";
|
|
17612
|
+
import { basename, dirname, isAbsolute as isAbsolute2, join, relative, resolve, win32 as windowsPath } from "node:path";
|
|
17613
17613
|
function inferenceBaseDir(env) {
|
|
17614
17614
|
const configured = String(env.VTX_INFERENCE_HOST_HOME || "").trim();
|
|
17615
17615
|
return configured || join(homedir(), ".vtx", "inference-host");
|
|
@@ -18012,146 +18012,65 @@ async function acquireInferenceHostProcessLock(path, dependencies = {}) {
|
|
|
18012
18012
|
const directory2 = dirname(path);
|
|
18013
18013
|
await ensureInferencePrivateDirectory(directory2);
|
|
18014
18014
|
const ownerToken = randomBytes(24).toString("base64url");
|
|
18015
|
-
const
|
|
18016
|
-
|
|
18017
|
-
|
|
18018
|
-
|
|
18019
|
-
process.kill(pid, 0);
|
|
18020
|
-
return true;
|
|
18021
|
-
} catch (error48) {
|
|
18022
|
-
if (error48.code === "ESRCH") return false;
|
|
18023
|
-
throw error48;
|
|
18024
|
-
}
|
|
18025
|
-
});
|
|
18026
|
-
let handle;
|
|
18027
|
-
for (let acquisition = 0; acquisition < 2; acquisition += 1) {
|
|
18028
|
-
try {
|
|
18029
|
-
handle = await open(
|
|
18030
|
-
path,
|
|
18031
|
-
constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY | constants.O_NOFOLLOW,
|
|
18032
|
-
384
|
|
18033
|
-
);
|
|
18034
|
-
break;
|
|
18035
|
-
} catch (error48) {
|
|
18036
|
-
if (error48.code !== "EEXIST") throw error48;
|
|
18037
|
-
if (acquisition > 0) {
|
|
18038
|
-
throw new InferenceHostProcessLockBusyError();
|
|
18039
|
-
}
|
|
18040
|
-
let before;
|
|
18015
|
+
const probes = {
|
|
18016
|
+
currentBootIdentity: dependencies.currentBootIdentity ?? (() => readInferenceSystemBootIdentity()),
|
|
18017
|
+
observeIdentity: dependencies.processIdentity ?? defaultProcessIdentity,
|
|
18018
|
+
isProcessAlive: dependencies.processAlive ?? ((pid) => {
|
|
18041
18019
|
try {
|
|
18042
|
-
|
|
18043
|
-
} catch (error49) {
|
|
18044
|
-
if (error49.code === "ENOENT") continue;
|
|
18045
|
-
throw error49;
|
|
18046
|
-
}
|
|
18047
|
-
if (before.isSymbolicLink() || !before.isFile() || process.platform !== "win32" && (before.mode & 63) !== 0 || typeof process.getuid === "function" && before.uid !== process.getuid()) {
|
|
18048
|
-
throw new Error("Inference host process lock is unsafe.");
|
|
18049
|
-
}
|
|
18050
|
-
const reclaimPublicationResidue = async () => {
|
|
18051
|
-
let current2;
|
|
18052
|
-
try {
|
|
18053
|
-
current2 = await lstat(path);
|
|
18054
|
-
} catch (error49) {
|
|
18055
|
-
if (error49.code === "ENOENT") return false;
|
|
18056
|
-
throw error49;
|
|
18057
|
-
}
|
|
18058
|
-
if (current2.isSymbolicLink() || !current2.isFile() || current2.dev !== before.dev || current2.ino !== before.ino || process.platform !== "win32" && (current2.mode & 63) !== 0 || typeof process.getuid === "function" && current2.uid !== process.getuid()) {
|
|
18059
|
-
throw new Error("Inference host process lock publication residue changed or is unsafe.");
|
|
18060
|
-
}
|
|
18061
|
-
try {
|
|
18062
|
-
await rm(path);
|
|
18063
|
-
} catch (error49) {
|
|
18064
|
-
if (error49.code === "ENOENT") return false;
|
|
18065
|
-
throw error49;
|
|
18066
|
-
}
|
|
18067
|
-
processLockObservationCache.delete(resolve(path));
|
|
18068
|
-
await syncInferenceDirectory(directory2);
|
|
18020
|
+
process.kill(pid, 0);
|
|
18069
18021
|
return true;
|
|
18070
|
-
}
|
|
18071
|
-
|
|
18072
|
-
|
|
18073
|
-
} catch (error49) {
|
|
18074
|
-
if (error49.code === "ENOENT") continue;
|
|
18075
|
-
throw error49;
|
|
18022
|
+
} catch (error48) {
|
|
18023
|
+
if (error48.code === "ESRCH") return false;
|
|
18024
|
+
throw error48;
|
|
18076
18025
|
}
|
|
18077
|
-
|
|
18026
|
+
})
|
|
18027
|
+
};
|
|
18028
|
+
const [ownerIdentity, bootIdentity] = await Promise.all([
|
|
18029
|
+
(dependencies.currentProcessIdentity ?? defaultCurrentProcessIdentity)(),
|
|
18030
|
+
probes.currentBootIdentity()
|
|
18031
|
+
]);
|
|
18032
|
+
const ownerRecord = (token) => `${JSON.stringify({
|
|
18033
|
+
schema_version: 2,
|
|
18034
|
+
pid: process.pid,
|
|
18035
|
+
owner_token: token,
|
|
18036
|
+
process_identity: ownerIdentity,
|
|
18037
|
+
boot_identity: bootIdentity
|
|
18038
|
+
})}
|
|
18039
|
+
`;
|
|
18040
|
+
let handle = await openExclusiveProcessLockFile(path);
|
|
18041
|
+
if (!handle) {
|
|
18042
|
+
const inspection = await inspectProcessLockFile(path, PROCESS_LOCK_LABEL, probes);
|
|
18043
|
+
if (inspection.state === "busy") throw new InferenceHostProcessLockBusyError();
|
|
18044
|
+
if (inspection.state === "stale") {
|
|
18045
|
+
await inspection.handle.close();
|
|
18046
|
+
const guard = await acquireProcessLockReclaimGuard(path, ownerRecord, probes);
|
|
18078
18047
|
try {
|
|
18079
|
-
|
|
18080
|
-
|
|
18081
|
-
if (
|
|
18082
|
-
|
|
18083
|
-
throw new InferenceHostProcessLockBusyError();
|
|
18084
|
-
}
|
|
18085
|
-
await reclaimPublicationResidue();
|
|
18086
|
-
continue;
|
|
18087
|
-
}
|
|
18088
|
-
if (staleOwner.schema_version !== 2 || !Number.isSafeInteger(staleOwner.pid) || Number(staleOwner.pid) < 1 || typeof staleOwner.owner_token !== "string" || !staleOwner.owner_token || typeof staleOwner.process_identity !== "string" || !staleOwner.process_identity || typeof staleOwner.boot_identity !== "string" || !staleOwner.boot_identity) {
|
|
18089
|
-
if (Date.now() - before.mtimeMs < 1e4) {
|
|
18090
|
-
throw new InferenceHostProcessLockBusyError();
|
|
18048
|
+
const guarded = await inspectProcessLockFile(path, PROCESS_LOCK_LABEL, probes);
|
|
18049
|
+
if (guarded.state === "busy") throw new InferenceHostProcessLockBusyError();
|
|
18050
|
+
if (guarded.state === "stale") {
|
|
18051
|
+
await removeVerifiedStaleProcessLockFile(path, guarded, guard.assertHeld);
|
|
18091
18052
|
}
|
|
18092
|
-
await
|
|
18093
|
-
|
|
18094
|
-
|
|
18095
|
-
const stalePid = Number(staleOwner.pid);
|
|
18096
|
-
const bootIdentity2 = await currentBootIdentity();
|
|
18097
|
-
if (bootIdentity2 === staleOwner.boot_identity && isProcessAlive(stalePid)) {
|
|
18098
|
-
const cached2 = processLockObservationCache.get(resolve(path));
|
|
18099
|
-
const observedIdentity = cached2 && cached2.dev === before.dev && cached2.ino === before.ino && cached2.pid === stalePid && cached2.storedIdentity === staleOwner.process_identity && Date.now() - cached2.observedAtMs < 5e3 ? cached2.observedIdentity : await observeIdentity(stalePid);
|
|
18100
|
-
if (!observedIdentity) {
|
|
18101
|
-
throw new Error("Inference host could not verify the existing lock owner identity.");
|
|
18102
|
-
}
|
|
18103
|
-
processLockObservationCache.set(resolve(path), {
|
|
18104
|
-
dev: before.dev,
|
|
18105
|
-
ino: before.ino,
|
|
18106
|
-
pid: stalePid,
|
|
18107
|
-
storedIdentity: staleOwner.process_identity,
|
|
18108
|
-
observedIdentity,
|
|
18109
|
-
observedAtMs: Date.now()
|
|
18110
|
-
});
|
|
18111
|
-
if (inferenceProcessIdentitiesMatch(staleOwner.process_identity, observedIdentity)) {
|
|
18112
|
-
throw new InferenceHostProcessLockBusyError();
|
|
18113
|
-
}
|
|
18114
|
-
}
|
|
18115
|
-
let current;
|
|
18116
|
-
try {
|
|
18117
|
-
current = await lstat(path);
|
|
18118
|
-
} catch (error49) {
|
|
18119
|
-
if (error49.code === "ENOENT") continue;
|
|
18120
|
-
throw error49;
|
|
18121
|
-
}
|
|
18122
|
-
if (current.dev !== before.dev || current.ino !== before.ino) {
|
|
18123
|
-
throw new Error("Inference host process lock ownership changed.");
|
|
18053
|
+
handle = await openExclusiveProcessLockFile(path);
|
|
18054
|
+
} finally {
|
|
18055
|
+
await guard.release();
|
|
18124
18056
|
}
|
|
18125
|
-
|
|
18126
|
-
|
|
18127
|
-
await syncInferenceDirectory(directory2);
|
|
18057
|
+
} else {
|
|
18058
|
+
handle = await openExclusiveProcessLockFile(path);
|
|
18128
18059
|
}
|
|
18060
|
+
if (!handle) throw new InferenceHostProcessLockBusyError();
|
|
18129
18061
|
}
|
|
18130
|
-
if (!handle) throw new Error("Inference host process lock could not be acquired.");
|
|
18131
|
-
let ownerIdentity;
|
|
18132
|
-
let bootIdentity;
|
|
18133
18062
|
try {
|
|
18134
|
-
|
|
18135
|
-
|
|
18136
|
-
currentBootIdentity()
|
|
18137
|
-
]);
|
|
18063
|
+
await handle.writeFile(ownerRecord(ownerToken), "utf8");
|
|
18064
|
+
await handle.sync();
|
|
18138
18065
|
} catch (error48) {
|
|
18066
|
+
const created = await handle.stat().catch(() => null);
|
|
18139
18067
|
await handle.close().catch(() => void 0);
|
|
18140
|
-
await
|
|
18068
|
+
const current = await lstat(path).catch(() => null);
|
|
18069
|
+
if (created && current && current.dev === created.dev && current.ino === created.ino) {
|
|
18070
|
+
await rm(path, { force: true }).catch(() => void 0);
|
|
18071
|
+
}
|
|
18141
18072
|
throw error48;
|
|
18142
18073
|
}
|
|
18143
|
-
await handle.writeFile(
|
|
18144
|
-
`${JSON.stringify({
|
|
18145
|
-
schema_version: 2,
|
|
18146
|
-
pid: process.pid,
|
|
18147
|
-
owner_token: ownerToken,
|
|
18148
|
-
process_identity: ownerIdentity,
|
|
18149
|
-
boot_identity: bootIdentity
|
|
18150
|
-
})}
|
|
18151
|
-
`,
|
|
18152
|
-
"utf8"
|
|
18153
|
-
);
|
|
18154
|
-
await handle.sync();
|
|
18155
18074
|
await handle.close();
|
|
18156
18075
|
await secureWindowsPrivatePath(path, "file", "harden");
|
|
18157
18076
|
await syncInferenceDirectory(directory2);
|
|
@@ -18176,7 +18095,7 @@ async function acquireInferenceHostProcessLock(path, dependencies = {}) {
|
|
|
18176
18095
|
}
|
|
18177
18096
|
};
|
|
18178
18097
|
}
|
|
18179
|
-
var loadInferenceReceiptDurabilityTimeoutMs, loadInferenceAgentDataRequestTimeoutMs, loadInferenceAgentCommandLockPolicy, InferenceHostProcessLockBusyError, 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, readInferenceHostProcessLockStatus, processLockObservationCache, inferenceProcessIdentitiesMatch, DEFAULT_INFERENCE_HOST_INSTANCE, SAFE_INFERENCE_HOST_INSTANCE, requireNamedInstancePath, credentialStoreIdentity, inferenceHostCredentialContextPath, inferenceHostCredentialContextTransitionPath, credentialContextForConfig, WINDOWS_PRIVATE_FILE_REPLACE_ERROR_CODES;
|
|
18098
|
+
var loadInferenceReceiptDurabilityTimeoutMs, loadInferenceAgentDataRequestTimeoutMs, loadInferenceAgentCommandLockPolicy, InferenceHostProcessLockBusyError, 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, cachedCurrentProcessIdentity, defaultCurrentProcessIdentity, readInferenceHostProcessLockStatus, processLockObservationCache, inferenceProcessIdentitiesMatch, DEFAULT_INFERENCE_HOST_INSTANCE, SAFE_INFERENCE_HOST_INSTANCE, requireNamedInstancePath, credentialStoreIdentity, inferenceHostCredentialContextPath, inferenceHostCredentialContextTransitionPath, credentialContextForConfig, WINDOWS_PRIVATE_FILE_REPLACE_ERROR_CODES, PROCESS_LOCK_PUBLICATION_GRACE_MS, PROCESS_LOCK_MAX_RECORD_BYTES, PROCESS_LOCK_GUARD_ELECTION_LEASE_MS, PROCESS_LOCK_GUARD_ELECTION_STALE_MS, PROCESS_LOCK_GUARD_ELECTION_ATTEMPTS, PROCESS_LOCK_GUARD_ELECTION_BACKOFF_MS, PROCESS_LOCK_LABEL, PROCESS_LOCK_GUARD_LABEL, sameProcessLockFile, openExclusiveProcessLockFile, inspectProcessLockFile, removeVerifiedStaleProcessLockFile, removeStaleProcessLockReclaimGuard, acquireProcessLockReclaimGuard;
|
|
18180
18099
|
var init_config = __esm({
|
|
18181
18100
|
"lib/inference-host/config.ts"() {
|
|
18182
18101
|
"use strict";
|
|
@@ -18770,10 +18689,22 @@ while(($line=[Console]::In.ReadLine()) -ne $null) {
|
|
|
18770
18689
|
if (process.platform === "darwin") return await darwinProcessIdentity(pid);
|
|
18771
18690
|
return null;
|
|
18772
18691
|
};
|
|
18692
|
+
cachedCurrentProcessIdentity = null;
|
|
18773
18693
|
defaultCurrentProcessIdentity = async () => {
|
|
18774
|
-
|
|
18775
|
-
|
|
18776
|
-
|
|
18694
|
+
if (!cachedCurrentProcessIdentity) {
|
|
18695
|
+
cachedCurrentProcessIdentity = (async () => {
|
|
18696
|
+
const identity2 = await defaultProcessIdentity(process.pid);
|
|
18697
|
+
if (!identity2) throw new Error("Inference host could not establish its process-start identity.");
|
|
18698
|
+
return identity2;
|
|
18699
|
+
})();
|
|
18700
|
+
}
|
|
18701
|
+
const pending3 = cachedCurrentProcessIdentity;
|
|
18702
|
+
try {
|
|
18703
|
+
return await pending3;
|
|
18704
|
+
} catch (error48) {
|
|
18705
|
+
if (cachedCurrentProcessIdentity === pending3) cachedCurrentProcessIdentity = null;
|
|
18706
|
+
throw error48;
|
|
18707
|
+
}
|
|
18777
18708
|
};
|
|
18778
18709
|
readInferenceHostProcessLockStatus = async (path) => {
|
|
18779
18710
|
const raw = await readInferencePrivateFile(path, "Inference host process lock");
|
|
@@ -18836,6 +18767,242 @@ while(($line=[Console]::In.ReadLine()) -ne $null) {
|
|
|
18836
18767
|
"ENOTEMPTY",
|
|
18837
18768
|
"EPERM"
|
|
18838
18769
|
]);
|
|
18770
|
+
PROCESS_LOCK_PUBLICATION_GRACE_MS = 1e4;
|
|
18771
|
+
PROCESS_LOCK_MAX_RECORD_BYTES = 64 * 1024;
|
|
18772
|
+
PROCESS_LOCK_GUARD_ELECTION_LEASE_MS = 5e3;
|
|
18773
|
+
PROCESS_LOCK_GUARD_ELECTION_STALE_MS = 3e4;
|
|
18774
|
+
PROCESS_LOCK_GUARD_ELECTION_ATTEMPTS = 8;
|
|
18775
|
+
PROCESS_LOCK_GUARD_ELECTION_BACKOFF_MS = 10;
|
|
18776
|
+
PROCESS_LOCK_LABEL = "Inference host process lock";
|
|
18777
|
+
PROCESS_LOCK_GUARD_LABEL = "Inference host process lock reclamation guard";
|
|
18778
|
+
sameProcessLockFile = (left, right) => left.dev === right.dev && left.ino === right.ino && left.size === right.size && left.mtimeMs === right.mtimeMs && left.ctimeMs === right.ctimeMs;
|
|
18779
|
+
openExclusiveProcessLockFile = async (path) => {
|
|
18780
|
+
try {
|
|
18781
|
+
return await open(
|
|
18782
|
+
path,
|
|
18783
|
+
constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY | constants.O_NOFOLLOW,
|
|
18784
|
+
384
|
|
18785
|
+
);
|
|
18786
|
+
} catch (error48) {
|
|
18787
|
+
if (error48.code === "EEXIST") return null;
|
|
18788
|
+
throw error48;
|
|
18789
|
+
}
|
|
18790
|
+
};
|
|
18791
|
+
inspectProcessLockFile = async (path, label, probes) => {
|
|
18792
|
+
let before;
|
|
18793
|
+
try {
|
|
18794
|
+
before = await lstat(path);
|
|
18795
|
+
} catch (error48) {
|
|
18796
|
+
if (error48.code === "ENOENT") return { state: "missing" };
|
|
18797
|
+
throw error48;
|
|
18798
|
+
}
|
|
18799
|
+
if (before.isSymbolicLink() || !before.isFile() || process.platform !== "win32" && (before.mode & 63) !== 0 || typeof process.getuid === "function" && before.uid !== process.getuid()) {
|
|
18800
|
+
throw new Error(`${label} is unsafe.`);
|
|
18801
|
+
}
|
|
18802
|
+
let handle;
|
|
18803
|
+
try {
|
|
18804
|
+
await secureExistingWindowsPath(path, "file");
|
|
18805
|
+
handle = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
18806
|
+
} catch (error48) {
|
|
18807
|
+
if (error48.code === "ENOENT") return { state: "missing" };
|
|
18808
|
+
throw error48;
|
|
18809
|
+
}
|
|
18810
|
+
let stale = false;
|
|
18811
|
+
try {
|
|
18812
|
+
const opened = await handle.stat();
|
|
18813
|
+
if (!opened.isFile() || opened.dev !== before.dev || opened.ino !== before.ino) {
|
|
18814
|
+
return { state: "busy" };
|
|
18815
|
+
}
|
|
18816
|
+
const raw = opened.size > PROCESS_LOCK_MAX_RECORD_BYTES ? "" : await handle.readFile("utf8");
|
|
18817
|
+
const stat = await handle.stat();
|
|
18818
|
+
if (!sameProcessLockFile(opened, stat)) return { state: "busy" };
|
|
18819
|
+
let record5 = null;
|
|
18820
|
+
try {
|
|
18821
|
+
const parsed = JSON.parse(raw);
|
|
18822
|
+
if (parsed && typeof parsed === "object") record5 = parsed;
|
|
18823
|
+
} catch {
|
|
18824
|
+
record5 = null;
|
|
18825
|
+
}
|
|
18826
|
+
if (!record5 || record5.schema_version !== 2 || !Number.isSafeInteger(record5.pid) || Number(record5.pid) < 1 || typeof record5.owner_token !== "string" || !record5.owner_token || typeof record5.process_identity !== "string" || !record5.process_identity || typeof record5.boot_identity !== "string" || !record5.boot_identity) {
|
|
18827
|
+
if (Date.now() - stat.mtimeMs < PROCESS_LOCK_PUBLICATION_GRACE_MS) return { state: "busy" };
|
|
18828
|
+
stale = true;
|
|
18829
|
+
return { state: "stale", handle, stat };
|
|
18830
|
+
}
|
|
18831
|
+
const ownerPid = Number(record5.pid);
|
|
18832
|
+
const storedIdentity = record5.process_identity;
|
|
18833
|
+
const cacheKey = resolve(path);
|
|
18834
|
+
if (await probes.currentBootIdentity() === record5.boot_identity && probes.isProcessAlive(ownerPid)) {
|
|
18835
|
+
const cached2 = processLockObservationCache.get(cacheKey);
|
|
18836
|
+
const observedIdentity = cached2 && cached2.dev === stat.dev && cached2.ino === stat.ino && cached2.pid === ownerPid && cached2.storedIdentity === storedIdentity && Date.now() - cached2.observedAtMs < 5e3 ? cached2.observedIdentity : await probes.observeIdentity(ownerPid);
|
|
18837
|
+
if (!observedIdentity) {
|
|
18838
|
+
throw new Error("Inference host could not verify the existing lock owner identity.");
|
|
18839
|
+
}
|
|
18840
|
+
processLockObservationCache.set(cacheKey, {
|
|
18841
|
+
dev: stat.dev,
|
|
18842
|
+
ino: stat.ino,
|
|
18843
|
+
pid: ownerPid,
|
|
18844
|
+
storedIdentity,
|
|
18845
|
+
observedIdentity,
|
|
18846
|
+
observedAtMs: Date.now()
|
|
18847
|
+
});
|
|
18848
|
+
if (inferenceProcessIdentitiesMatch(storedIdentity, observedIdentity)) {
|
|
18849
|
+
return { state: "busy" };
|
|
18850
|
+
}
|
|
18851
|
+
}
|
|
18852
|
+
stale = true;
|
|
18853
|
+
return { state: "stale", handle, stat };
|
|
18854
|
+
} finally {
|
|
18855
|
+
if (!stale) await handle.close().catch(() => void 0);
|
|
18856
|
+
}
|
|
18857
|
+
};
|
|
18858
|
+
removeVerifiedStaleProcessLockFile = async (path, inspection, assertExclusive) => {
|
|
18859
|
+
try {
|
|
18860
|
+
await assertExclusive();
|
|
18861
|
+
let current;
|
|
18862
|
+
try {
|
|
18863
|
+
current = await lstat(path);
|
|
18864
|
+
} catch (error48) {
|
|
18865
|
+
if (error48.code === "ENOENT") return;
|
|
18866
|
+
throw error48;
|
|
18867
|
+
}
|
|
18868
|
+
const opened = await inspection.handle.stat();
|
|
18869
|
+
if (current.isSymbolicLink() || !sameProcessLockFile(current, opened) || !sameProcessLockFile(opened, inspection.stat)) {
|
|
18870
|
+
throw new InferenceHostProcessLockBusyError();
|
|
18871
|
+
}
|
|
18872
|
+
if (process.platform === "win32") await inspection.handle.close();
|
|
18873
|
+
try {
|
|
18874
|
+
await rm(path);
|
|
18875
|
+
} catch (error48) {
|
|
18876
|
+
if (error48.code !== "ENOENT") throw error48;
|
|
18877
|
+
}
|
|
18878
|
+
} finally {
|
|
18879
|
+
await inspection.handle.close().catch(() => void 0);
|
|
18880
|
+
}
|
|
18881
|
+
processLockObservationCache.delete(resolve(path));
|
|
18882
|
+
invalidateWindowsAclCache(path);
|
|
18883
|
+
await syncInferenceDirectory(dirname(path));
|
|
18884
|
+
};
|
|
18885
|
+
removeStaleProcessLockReclaimGuard = async (lockPath, guardPath, inspection) => {
|
|
18886
|
+
const directory2 = dirname(lockPath);
|
|
18887
|
+
const prefix = `${basename(lockPath)}.reclaim-ballot.`;
|
|
18888
|
+
try {
|
|
18889
|
+
for (let attempt = 0; attempt < PROCESS_LOCK_GUARD_ELECTION_ATTEMPTS; attempt += 1) {
|
|
18890
|
+
if (attempt > 0) {
|
|
18891
|
+
await new Promise((resolvePromise) => setTimeout(
|
|
18892
|
+
resolvePromise,
|
|
18893
|
+
Math.floor(Math.random() * PROCESS_LOCK_GUARD_ELECTION_BACKOFF_MS * 2 ** Math.min(attempt, 4))
|
|
18894
|
+
));
|
|
18895
|
+
let current;
|
|
18896
|
+
try {
|
|
18897
|
+
current = await lstat(guardPath);
|
|
18898
|
+
} catch (error48) {
|
|
18899
|
+
if (error48.code === "ENOENT") return;
|
|
18900
|
+
throw error48;
|
|
18901
|
+
}
|
|
18902
|
+
if (!sameProcessLockFile(current, inspection.stat)) return;
|
|
18903
|
+
}
|
|
18904
|
+
const ballotName = `${prefix}${randomBytes(16).toString("hex")}`;
|
|
18905
|
+
const ballotPath = join(directory2, ballotName);
|
|
18906
|
+
const ballot = await openExclusiveProcessLockFile(ballotPath);
|
|
18907
|
+
if (!ballot) continue;
|
|
18908
|
+
await ballot.close();
|
|
18909
|
+
const electedAt = performance.now();
|
|
18910
|
+
try {
|
|
18911
|
+
let contested = false;
|
|
18912
|
+
for (const name of await readdir(directory2)) {
|
|
18913
|
+
if (!name.startsWith(prefix) || name === ballotName) continue;
|
|
18914
|
+
const otherPath = join(directory2, name);
|
|
18915
|
+
let other;
|
|
18916
|
+
try {
|
|
18917
|
+
other = await lstat(otherPath);
|
|
18918
|
+
} catch (error48) {
|
|
18919
|
+
if (error48.code === "ENOENT") continue;
|
|
18920
|
+
throw error48;
|
|
18921
|
+
}
|
|
18922
|
+
if (!other.isDirectory() && Date.now() - other.mtimeMs > PROCESS_LOCK_GUARD_ELECTION_STALE_MS) {
|
|
18923
|
+
await rm(otherPath, { force: true });
|
|
18924
|
+
continue;
|
|
18925
|
+
}
|
|
18926
|
+
contested = true;
|
|
18927
|
+
}
|
|
18928
|
+
if (contested) continue;
|
|
18929
|
+
await removeVerifiedStaleProcessLockFile(guardPath, inspection, async () => {
|
|
18930
|
+
if (performance.now() - electedAt > PROCESS_LOCK_GUARD_ELECTION_LEASE_MS) {
|
|
18931
|
+
throw new InferenceHostProcessLockBusyError();
|
|
18932
|
+
}
|
|
18933
|
+
});
|
|
18934
|
+
return;
|
|
18935
|
+
} finally {
|
|
18936
|
+
await rm(ballotPath, { force: true }).catch(() => void 0);
|
|
18937
|
+
}
|
|
18938
|
+
}
|
|
18939
|
+
throw new InferenceHostProcessLockBusyError();
|
|
18940
|
+
} finally {
|
|
18941
|
+
await inspection.handle.close().catch(() => void 0);
|
|
18942
|
+
}
|
|
18943
|
+
};
|
|
18944
|
+
acquireProcessLockReclaimGuard = async (lockPath, ownerRecord, probes) => {
|
|
18945
|
+
const guardPath = `${lockPath}.reclaim`;
|
|
18946
|
+
const guardToken = randomBytes(24).toString("base64url");
|
|
18947
|
+
for (let attempt = 0; attempt < 2; attempt += 1) {
|
|
18948
|
+
const handle = await openExclusiveProcessLockFile(guardPath);
|
|
18949
|
+
if (handle) {
|
|
18950
|
+
try {
|
|
18951
|
+
await handle.writeFile(ownerRecord(guardToken), "utf8");
|
|
18952
|
+
} catch (error48) {
|
|
18953
|
+
await handle.close().catch(() => void 0);
|
|
18954
|
+
await rm(guardPath, { force: true }).catch(() => void 0);
|
|
18955
|
+
throw error48;
|
|
18956
|
+
}
|
|
18957
|
+
await handle.close();
|
|
18958
|
+
await secureWindowsPrivatePath(guardPath, "file", "harden");
|
|
18959
|
+
const isHeld = async () => {
|
|
18960
|
+
let reader;
|
|
18961
|
+
try {
|
|
18962
|
+
reader = await open(guardPath, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
18963
|
+
} catch (error48) {
|
|
18964
|
+
if (error48.code === "ENOENT") return false;
|
|
18965
|
+
throw error48;
|
|
18966
|
+
}
|
|
18967
|
+
try {
|
|
18968
|
+
const [opened, current] = await Promise.all([reader.stat(), lstat(guardPath)]);
|
|
18969
|
+
if (current.isSymbolicLink() || current.dev !== opened.dev || current.ino !== opened.ino) {
|
|
18970
|
+
return false;
|
|
18971
|
+
}
|
|
18972
|
+
const parsed = JSON.parse(await reader.readFile("utf8"));
|
|
18973
|
+
return parsed.owner_token === guardToken;
|
|
18974
|
+
} catch {
|
|
18975
|
+
return false;
|
|
18976
|
+
} finally {
|
|
18977
|
+
await reader.close().catch(() => void 0);
|
|
18978
|
+
}
|
|
18979
|
+
};
|
|
18980
|
+
return {
|
|
18981
|
+
assertHeld: async () => {
|
|
18982
|
+
if (!await isHeld()) throw new InferenceHostProcessLockBusyError();
|
|
18983
|
+
},
|
|
18984
|
+
// Best effort: a guard left behind carries this live process identity
|
|
18985
|
+
// and becomes reclaimable once this process exits.
|
|
18986
|
+
release: async () => {
|
|
18987
|
+
try {
|
|
18988
|
+
if (!await isHeld()) return;
|
|
18989
|
+
await rm(guardPath);
|
|
18990
|
+
processLockObservationCache.delete(resolve(guardPath));
|
|
18991
|
+
invalidateWindowsAclCache(guardPath);
|
|
18992
|
+
} catch {
|
|
18993
|
+
}
|
|
18994
|
+
}
|
|
18995
|
+
};
|
|
18996
|
+
}
|
|
18997
|
+
if (attempt > 0) break;
|
|
18998
|
+
const inspection = await inspectProcessLockFile(guardPath, PROCESS_LOCK_GUARD_LABEL, probes);
|
|
18999
|
+
if (inspection.state === "busy") break;
|
|
19000
|
+
if (inspection.state === "stale") {
|
|
19001
|
+
await removeStaleProcessLockReclaimGuard(lockPath, guardPath, inspection);
|
|
19002
|
+
}
|
|
19003
|
+
}
|
|
19004
|
+
throw new InferenceHostProcessLockBusyError();
|
|
19005
|
+
};
|
|
18839
19006
|
}
|
|
18840
19007
|
});
|
|
18841
19008
|
|
|
@@ -21111,6 +21278,7 @@ var init_mcp_client = __esm({
|
|
|
21111
21278
|
agentDecisionTimingSchema = external_exports.strictObject({
|
|
21112
21279
|
analysis_started_at: timestampSchema2,
|
|
21113
21280
|
model_latency_ms: external_exports.number().int().nonnegative().nullable(),
|
|
21281
|
+
analysis_duration_ms: external_exports.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).nullable().optional(),
|
|
21114
21282
|
model_latency_source: external_exports.literal("harness_invocation").nullable()
|
|
21115
21283
|
}).refine((timing) => timing.model_latency_ms === null === (timing.model_latency_source === null), {
|
|
21116
21284
|
message: "Model latency and its measurement source must be supplied together."
|
|
@@ -21123,7 +21291,7 @@ var init_mcp_client = __esm({
|
|
|
21123
21291
|
observed_at: timestampSchema2,
|
|
21124
21292
|
timing: agentDecisionTimingSchema.optional(),
|
|
21125
21293
|
provenance: jsonObjectSchema.nullable().optional()
|
|
21126
|
-
}).refine((request) => !request.timing || Date.parse(request.timing.analysis_started_at) <= Date.parse(request.observed_at), {
|
|
21294
|
+
}).refine((request) => !request.timing || Date.parse(request.timing.analysis_started_at) <= Date.parse(request.observed_at) && (request.timing.analysis_duration_ms == null || request.timing.analysis_duration_ms <= Date.parse(request.observed_at) - Date.parse(request.timing.analysis_started_at)), {
|
|
21127
21295
|
message: "Analysis start must precede decision observation."
|
|
21128
21296
|
});
|
|
21129
21297
|
agentDecisionSubmitResultSchema = external_exports.strictObject({
|
|
@@ -21477,6 +21645,7 @@ var init_mcp_client = __esm({
|
|
|
21477
21645
|
#initialized = false;
|
|
21478
21646
|
#providerQuotaRecoverySupported = false;
|
|
21479
21647
|
#providerCreditsSupported = false;
|
|
21648
|
+
#agentAnalysisDurationSupported = false;
|
|
21480
21649
|
#runtimeRecoveryDiagnosticsSupported = false;
|
|
21481
21650
|
#providerHttpStatusTools = /* @__PURE__ */ new Set();
|
|
21482
21651
|
#grokToolValidationTools = /* @__PURE__ */ new Set();
|
|
@@ -21523,6 +21692,18 @@ var init_mcp_client = __esm({
|
|
|
21523
21692
|
supportsRuntimeRecoveryDiagnostics() {
|
|
21524
21693
|
return this.#runtimeRecoveryDiagnosticsSupported;
|
|
21525
21694
|
}
|
|
21695
|
+
supportsAgentAnalysisDuration() {
|
|
21696
|
+
return this.#agentAnalysisDurationSupported;
|
|
21697
|
+
}
|
|
21698
|
+
async refreshAgentAnalysisDurationSupport(options = {}) {
|
|
21699
|
+
if (this.supportsAgentAnalysisDuration()) return true;
|
|
21700
|
+
try {
|
|
21701
|
+
await this.initialize(options);
|
|
21702
|
+
} catch {
|
|
21703
|
+
return false;
|
|
21704
|
+
}
|
|
21705
|
+
return this.supportsAgentAnalysisDuration();
|
|
21706
|
+
}
|
|
21526
21707
|
supportsProviderCredits() {
|
|
21527
21708
|
return this.#providerCreditsSupported;
|
|
21528
21709
|
}
|
|
@@ -21603,6 +21784,20 @@ var init_mcp_client = __esm({
|
|
|
21603
21784
|
return Array.isArray(node.anyOf) && node.anyOf.some((branch) => advertisesCredits(branch, depth + 1));
|
|
21604
21785
|
};
|
|
21605
21786
|
this.#providerCreditsSupported = advertisesCredits(hostHeartbeatSchema?.properties?.provider_weekly_quota);
|
|
21787
|
+
const decisionSchema = listed.tools.find(
|
|
21788
|
+
(tool) => tool.name === "inference.agent.decision.submit"
|
|
21789
|
+
)?.inputSchema;
|
|
21790
|
+
const advertisesAnalysisDuration = (value, depth = 0) => {
|
|
21791
|
+
if (depth > 4 || !value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
21792
|
+
const node = value;
|
|
21793
|
+
if (node.properties && typeof node.properties === "object" && Object.hasOwn(node.properties, "analysis_duration_ms")) return true;
|
|
21794
|
+
if (typeof node.$ref === "string" && /^#\/\$defs\/[^/]+$/u.test(node.$ref)) {
|
|
21795
|
+
const definition = node.$ref.slice("#/$defs/".length).replace(/~1/gu, "/").replace(/~0/gu, "~");
|
|
21796
|
+
return advertisesAnalysisDuration(decisionSchema?.$defs?.[definition], depth + 1);
|
|
21797
|
+
}
|
|
21798
|
+
return Array.isArray(node.anyOf) && node.anyOf.some((branch) => advertisesAnalysisDuration(branch, depth + 1));
|
|
21799
|
+
};
|
|
21800
|
+
this.#agentAnalysisDurationSupported = advertisesAnalysisDuration(decisionSchema?.properties?.timing);
|
|
21606
21801
|
this.#grokToolValidationTools.clear();
|
|
21607
21802
|
if (advertisesFields("inference.job.fail", ["grok_tool_validation"])) {
|
|
21608
21803
|
this.#grokToolValidationTools.add("inference.job.fail");
|
|
@@ -30901,7 +31096,7 @@ async function clearInferenceAgentNextState(statePath) {
|
|
|
30901
31096
|
"Agent-driven inference next recovery state"
|
|
30902
31097
|
);
|
|
30903
31098
|
}
|
|
30904
|
-
var inferenceAgentAttemptStatePath, inferenceAgentNextStatePath, assertDecisionTiming, inferenceAgentRuntimeStatePath, inferenceAgentFailureFencePath, isIsoTimestamp, assertPlainObject, hasExactKeys, assertInferenceAgentFailureFence, assertInferenceAgentRuntimeState, readCodexAgentRuntimeState, clearCodexAgentRuntimeState, foregroundAgentControlStatePath, assertRuntimeAssignment, assertForegroundAgentControlState, assertNextState, assertAttemptState;
|
|
31099
|
+
var inferenceAgentAttemptStatePath, inferenceAgentNextStatePath, measureAgentReviewTiming, assertDecisionTiming, inferenceAgentRuntimeStatePath, inferenceAgentFailureFencePath, isIsoTimestamp, assertPlainObject, hasExactKeys, assertInferenceAgentFailureFence, assertInferenceAgentRuntimeState, readCodexAgentRuntimeState, clearCodexAgentRuntimeState, foregroundAgentControlStatePath, assertRuntimeAssignment, assertForegroundAgentControlState, assertNextState, assertAttemptState;
|
|
30905
31100
|
var init_agent_state = __esm({
|
|
30906
31101
|
"lib/inference-host/agent-state.ts"() {
|
|
30907
31102
|
"use strict";
|
|
@@ -30912,9 +31107,20 @@ var init_agent_state = __esm({
|
|
|
30912
31107
|
init_external_inference_contract();
|
|
30913
31108
|
inferenceAgentAttemptStatePath = (statePath) => `${statePath}.agent-attempt.json`;
|
|
30914
31109
|
inferenceAgentNextStatePath = (statePath) => `${statePath}.agent-next.json`;
|
|
31110
|
+
measureAgentReviewTiming = (analysisStartedAt, observedAt, measureDuration = true) => ({
|
|
31111
|
+
analysis_started_at: analysisStartedAt,
|
|
31112
|
+
model_latency_ms: null,
|
|
31113
|
+
model_latency_source: null,
|
|
31114
|
+
...measureDuration ? { analysis_duration_ms: Date.parse(observedAt) - Date.parse(analysisStartedAt) } : {}
|
|
31115
|
+
});
|
|
30915
31116
|
assertDecisionTiming = (value, observedAt, message) => {
|
|
30916
31117
|
const timing = assertPlainObject(value, message);
|
|
30917
|
-
if (!hasExactKeys(timing, [
|
|
31118
|
+
if (!hasExactKeys(timing, [
|
|
31119
|
+
"analysis_started_at",
|
|
31120
|
+
"model_latency_ms",
|
|
31121
|
+
"model_latency_source",
|
|
31122
|
+
..."analysis_duration_ms" in timing ? ["analysis_duration_ms"] : []
|
|
31123
|
+
]) || !isIsoTimestamp(timing.analysis_started_at) || Date.parse(timing.analysis_started_at) > Date.parse(String(observedAt)) || timing.analysis_duration_ms != null && (!Number.isSafeInteger(timing.analysis_duration_ms) || Number(timing.analysis_duration_ms) < 0 || Number(timing.analysis_duration_ms) > Date.parse(String(observedAt)) - Date.parse(timing.analysis_started_at)) || (timing.model_latency_ms === null ? timing.model_latency_source !== null : !Number.isSafeInteger(timing.model_latency_ms) || Number(timing.model_latency_ms) < 0 || timing.model_latency_source !== "harness_invocation")) throw new Error(message);
|
|
30918
31124
|
};
|
|
30919
31125
|
inferenceAgentRuntimeStatePath = (statePath) => `${statePath}.codex-agent-runtime.json`;
|
|
30920
31126
|
inferenceAgentFailureFencePath = (statePath) => `${statePath}.agent-failure-fence.json`;
|
|
@@ -34609,6 +34815,7 @@ var init_runner = __esm({
|
|
|
34609
34815
|
}
|
|
34610
34816
|
};
|
|
34611
34817
|
createInferenceAgentControlClient = (mcp) => ({
|
|
34818
|
+
supportsAgentAnalysisDuration: async (options = {}) => mcp.supportsAgentAnalysisDuration?.() === true || await mcp.refreshAgentAnalysisDurationSupport?.(options) === true,
|
|
34612
34819
|
supportsProviderHttpStatusDiagnostics: async (options = {}) => mcp.supportsProviderHttpStatusDiagnostics?.("inference.agent.assignment.heartbeat") === true || await mcp.refreshProviderHttpStatusSupport?.("inference.agent.assignment.heartbeat", options) === true,
|
|
34613
34820
|
supportsGrokResponseIdentityDiagnostics: async (options = {}) => mcp.supportsGrokResponseIdentityDiagnostics?.("inference.agent.assignment.heartbeat") === true || await mcp.refreshGrokResponseIdentitySupport?.("inference.agent.assignment.heartbeat", options) === true,
|
|
34614
34821
|
supportsGrokToolValidationDiagnostics: async (options = {}) => mcp.supportsGrokToolValidationDiagnostics?.("inference.agent.assignment.heartbeat") === true || await mcp.refreshGrokToolValidationSupport?.("inference.agent.assignment.heartbeat", options) === true,
|
|
@@ -35028,15 +35235,19 @@ var init_runner = __esm({
|
|
|
35028
35235
|
if (state.pending_decision) {
|
|
35029
35236
|
return { success: false, value: { error: "decision_outcome_unresolved" } };
|
|
35030
35237
|
}
|
|
35238
|
+
const measureDuration = state.pending_turn.decision_operation_ids.length === 0 && await this.options.controlClient.supportsAgentAnalysisDuration?.({ signal: turnAbort.signal }) === true;
|
|
35239
|
+
const observedAt = nowIso();
|
|
35031
35240
|
const pending3 = {
|
|
35032
35241
|
operation_id: randomUUID(),
|
|
35033
35242
|
candidate,
|
|
35034
|
-
observed_at:
|
|
35035
|
-
|
|
35036
|
-
|
|
35037
|
-
|
|
35038
|
-
|
|
35039
|
-
|
|
35243
|
+
observed_at: observedAt,
|
|
35244
|
+
// A later decision in the same turn has no independent review
|
|
35245
|
+
// boundary. Do not report the whole turn again as its duration.
|
|
35246
|
+
timing: measureAgentReviewTiming(
|
|
35247
|
+
state.pending_turn.started_at,
|
|
35248
|
+
observedAt,
|
|
35249
|
+
measureDuration
|
|
35250
|
+
),
|
|
35040
35251
|
provenance: {
|
|
35041
35252
|
source: "external_agent",
|
|
35042
35253
|
agent_run_id: liveThread.threadId,
|
|
@@ -35920,7 +36131,7 @@ import {
|
|
|
35920
36131
|
lstat as lstat3,
|
|
35921
36132
|
mkdir as mkdir2,
|
|
35922
36133
|
mkdtemp,
|
|
35923
|
-
readdir,
|
|
36134
|
+
readdir as readdir2,
|
|
35924
36135
|
readFile as readFile4,
|
|
35925
36136
|
realpath as realpath3,
|
|
35926
36137
|
rm as rm3
|
|
@@ -36358,7 +36569,7 @@ var init_codex_adapter = __esm({
|
|
|
36358
36569
|
if (!directoryState.isDirectory() || directoryState.isSymbolicLink() || typeof process.getuid === "function" && directoryState.uid !== process.getuid()) {
|
|
36359
36570
|
throw new Error("Codex recovery home contains an unsafe directory.");
|
|
36360
36571
|
}
|
|
36361
|
-
const entries = await
|
|
36572
|
+
const entries = await readdir2(current.path, { withFileTypes: true });
|
|
36362
36573
|
for (const entry of entries) {
|
|
36363
36574
|
entriesSeen += 1;
|
|
36364
36575
|
if (entriesSeen > 2e4) {
|
|
@@ -38453,7 +38664,7 @@ var init_deepseek_transport_proxy = __esm({
|
|
|
38453
38664
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
38454
38665
|
import { mkdtemp as mkdtemp3, realpath as realpath4, rm as rm5 } from "node:fs/promises";
|
|
38455
38666
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
38456
|
-
import { basename, dirname as dirname4, join as join6 } from "node:path";
|
|
38667
|
+
import { basename as basename2, dirname as dirname4, join as join6 } from "node:path";
|
|
38457
38668
|
import { Context } from "@deepseek-ai/cordis";
|
|
38458
38669
|
import * as AgentSpine from "@deepseek-ai/dsh-agent-spine-demo";
|
|
38459
38670
|
import {
|
|
@@ -39111,7 +39322,7 @@ ${JSON.stringify(input.outputSchema)}`,
|
|
|
39111
39322
|
}
|
|
39112
39323
|
const resolved = await realpath4(thread.threadPath);
|
|
39113
39324
|
const temporaryRoot = await realpath4(tmpdir4());
|
|
39114
|
-
if (dirname4(resolved) !== temporaryRoot || !
|
|
39325
|
+
if (dirname4(resolved) !== temporaryRoot || !basename2(resolved).startsWith("vtx-deepseek-harness-")) throw new Error("deepseek_harness_thread_path_not_owned");
|
|
39115
39326
|
await rm5(resolved, { recursive: true, force: true });
|
|
39116
39327
|
}
|
|
39117
39328
|
async close() {
|
|
@@ -39317,8 +39528,8 @@ var init_pi_transport = __esm({
|
|
|
39317
39528
|
|
|
39318
39529
|
// lib/inference-host/pi-adapter.ts
|
|
39319
39530
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
39320
|
-
import { lstat as lstat4, realpath as realpath5, rm as rm6, readdir as
|
|
39321
|
-
import { basename as
|
|
39531
|
+
import { lstat as lstat4, realpath as realpath5, rm as rm6, readdir as readdir3 } from "node:fs/promises";
|
|
39532
|
+
import { basename as basename3, dirname as dirname5, join as join7, resolve as resolve4 } from "node:path";
|
|
39322
39533
|
import {
|
|
39323
39534
|
createAgentSession,
|
|
39324
39535
|
DefaultResourceLoader,
|
|
@@ -39481,7 +39692,7 @@ var init_pi_adapter = __esm({
|
|
|
39481
39692
|
async ownedThread(thread) {
|
|
39482
39693
|
const root = await realpath5(this.dependencies.stateRoot);
|
|
39483
39694
|
const supplied = resolve4(thread.threadPath);
|
|
39484
|
-
if (dirname5(supplied) !== root ||
|
|
39695
|
+
if (dirname5(supplied) !== root || basename3(supplied) !== `agent-${thread.threadId}` || !/^[a-f0-9-]{36}$/u.test(thread.threadId)) throw fail("pi_thread_not_owned");
|
|
39485
39696
|
const info = await lstat4(supplied);
|
|
39486
39697
|
if (info.isSymbolicLink() || !info.isDirectory()) throw fail("pi_thread_not_owned");
|
|
39487
39698
|
if (await realpath5(supplied) !== supplied) throw fail("pi_thread_not_owned");
|
|
@@ -39564,7 +39775,7 @@ var init_pi_adapter = __esm({
|
|
|
39564
39775
|
const selection = manager.buildSessionContext().model;
|
|
39565
39776
|
if (!selection || selection.provider !== model.provider || selection.modelId !== model.id) throw fail("pi_thread_binding_changed", "model");
|
|
39566
39777
|
} else if (agent) {
|
|
39567
|
-
const initial = SessionManager.inMemory(cwd, { id:
|
|
39778
|
+
const initial = SessionManager.inMemory(cwd, { id: basename3(cwd).slice("agent-".length) });
|
|
39568
39779
|
await writeAtomicInferencePrivateFile(sessionFile, `${JSON.stringify(initial.getHeader())}
|
|
39569
39780
|
`);
|
|
39570
39781
|
manager = SessionManager.open(sessionFile, cwd, cwd);
|
|
@@ -39635,7 +39846,7 @@ var init_pi_adapter = __esm({
|
|
|
39635
39846
|
if (created.modelFallbackMessage || session.model?.id !== model.id || session.model.provider !== model.provider || session.thinkingLevel !== thinkingLevel) throw fail("pi_effective_selection_mismatch", "model");
|
|
39636
39847
|
if (session.getActiveToolNames().sort().join(",") !== (agent ? [...CODEX_AGENT_DYNAMIC_TOOLS].sort().join(",") : "")) throw fail("pi_tool_isolation_failed");
|
|
39637
39848
|
if (agent) {
|
|
39638
|
-
const threadId =
|
|
39849
|
+
const threadId = basename3(cwd).slice("agent-".length);
|
|
39639
39850
|
thread = { threadId, threadPath: cwd, effectiveModel: input.requestedModel, effectiveReasoningEffort: input.requestedReasoningEffort };
|
|
39640
39851
|
await agent.onThreadReady?.(thread);
|
|
39641
39852
|
published = true;
|
|
@@ -39830,11 +40041,11 @@ var init_pi_adapter = __esm({
|
|
|
39830
40041
|
if (metadata.isSymbolicLink() || !metadata.isDirectory()) throw fail("pi_state_not_owned");
|
|
39831
40042
|
await ensureInferencePrivateDirectory(stateRoot);
|
|
39832
40043
|
const root = await realpath5(stateRoot);
|
|
39833
|
-
const entries = await
|
|
40044
|
+
const entries = await readdir3(root, { withFileTypes: true });
|
|
39834
40045
|
for (const entry of entries) {
|
|
39835
40046
|
if (entry.isSymbolicLink() || !entry.isDirectory() || entry.name !== "provider" && !/^agent-[a-f0-9-]{36}$/u.test(entry.name)) throw fail("pi_state_not_owned");
|
|
39836
40047
|
const path = join7(root, entry.name);
|
|
39837
|
-
for (const child of await
|
|
40048
|
+
for (const child of await readdir3(path, { withFileTypes: true })) {
|
|
39838
40049
|
if (child.isSymbolicLink() || !child.isFile() || entry.name === "provider" || child.name !== "session.jsonl") throw fail("pi_state_not_owned");
|
|
39839
40050
|
const contents = await readInferencePrivateFile(join7(path, child.name), "Pi session");
|
|
39840
40051
|
const header = contents === null ? null : object2(JSON.parse(contents.split("\n", 1)[0]));
|
|
@@ -40815,8 +41026,8 @@ var init_grok_runtime = __esm({
|
|
|
40815
41026
|
|
|
40816
41027
|
// lib/inference-host/grok-state.ts
|
|
40817
41028
|
import { constants as constants2 } from "node:fs";
|
|
40818
|
-
import { lstat as lstat7, mkdtemp as mkdtemp4, open as open3, readdir as
|
|
40819
|
-
import { basename as
|
|
41029
|
+
import { lstat as lstat7, mkdtemp as mkdtemp4, open as open3, readdir as readdir4, realpath as realpath6, rm as rm9, rmdir, unlink, writeFile as writeFile3 } from "node:fs/promises";
|
|
41030
|
+
import { basename as basename4, dirname as dirname8, join as join10, resolve as resolve6 } from "node:path";
|
|
40820
41031
|
var markerName, ownedName, invalid, missing, sessionIdValid, directory, nativeDirectory, roots, owner, nativeFile, encodedCwd, nativeSession, removeEmptyNativeGroup, createGrokOwnedWorkspace, bindGrokOwnedSession, validateGrokOwnedThread, releaseGrokOwnedWorkspace, cleanupGrokOwnedState;
|
|
40821
41032
|
var init_grok_state = __esm({
|
|
40822
41033
|
"lib/inference-host/grok-state.ts"() {
|
|
@@ -40853,7 +41064,7 @@ var init_grok_state = __esm({
|
|
|
40853
41064
|
};
|
|
40854
41065
|
owner = async (options, workspace) => {
|
|
40855
41066
|
const scope = await roots(options);
|
|
40856
|
-
if (workspace !== resolve6(workspace) || dirname8(workspace) !== scope.workspaceRoot || !ownedName.test(
|
|
41067
|
+
if (workspace !== resolve6(workspace) || dirname8(workspace) !== scope.workspaceRoot || !ownedName.test(basename4(workspace))) throw invalid();
|
|
40857
41068
|
await directory(scope.workspaceRoot);
|
|
40858
41069
|
await directory(workspace);
|
|
40859
41070
|
const raw = await readInferencePrivateFile(join10(workspace, markerName), "Grok workspace owner");
|
|
@@ -40896,7 +41107,7 @@ var init_grok_state = __esm({
|
|
|
40896
41107
|
if (encoded.length <= 255) groups = [join10(sessions, encoded)];
|
|
40897
41108
|
else {
|
|
40898
41109
|
groups = [];
|
|
40899
|
-
for (const entry of await
|
|
41110
|
+
for (const entry of await readdir4(sessions, { withFileTypes: true })) {
|
|
40900
41111
|
if (!entry.isDirectory() || entry.isSymbolicLink()) continue;
|
|
40901
41112
|
const group = join10(sessions, entry.name);
|
|
40902
41113
|
if (await realpath6(group) !== resolve6(group)) throw invalid();
|
|
@@ -40943,7 +41154,7 @@ var init_grok_state = __esm({
|
|
|
40943
41154
|
if (missing(error48)) return;
|
|
40944
41155
|
throw error48;
|
|
40945
41156
|
}
|
|
40946
|
-
const entries = await
|
|
41157
|
+
const entries = await readdir4(group);
|
|
40947
41158
|
let cwdMarker = null;
|
|
40948
41159
|
if (entries.length === 1 && entries[0] === ".cwd") {
|
|
40949
41160
|
cwdMarker = await nativeFile(join10(group, ".cwd"), 32768);
|
|
@@ -41003,7 +41214,7 @@ var init_grok_state = __esm({
|
|
|
41003
41214
|
};
|
|
41004
41215
|
releaseGrokOwnedWorkspace = async (options, workspace, expectedSessionId) => {
|
|
41005
41216
|
const scope = await roots(options);
|
|
41006
|
-
if (workspace !== resolve6(workspace) || dirname8(workspace) !== scope.workspaceRoot || !ownedName.test(
|
|
41217
|
+
if (workspace !== resolve6(workspace) || dirname8(workspace) !== scope.workspaceRoot || !ownedName.test(basename4(workspace))) throw invalid();
|
|
41007
41218
|
await directory(scope.workspaceRoot);
|
|
41008
41219
|
try {
|
|
41009
41220
|
await lstat7(workspace);
|
|
@@ -41037,7 +41248,7 @@ var init_grok_state = __esm({
|
|
|
41037
41248
|
if (missing(error48)) return;
|
|
41038
41249
|
throw error48;
|
|
41039
41250
|
}
|
|
41040
|
-
for (const entry of await
|
|
41251
|
+
for (const entry of await readdir4(scope.workspaceRoot, { withFileTypes: true })) {
|
|
41041
41252
|
if (!ownedName.test(entry.name)) continue;
|
|
41042
41253
|
const workspace = join10(scope.workspaceRoot, entry.name);
|
|
41043
41254
|
try {
|
|
@@ -41606,8 +41817,8 @@ var init_grok_auth = __esm({
|
|
|
41606
41817
|
import { spawn as spawn9 } from "node:child_process";
|
|
41607
41818
|
import { randomUUID as randomUUID9, timingSafeEqual as timingSafeEqual2 } from "node:crypto";
|
|
41608
41819
|
import { createServer as createServer5 } from "node:http";
|
|
41609
|
-
import { access as access3, lstat as lstat8, readdir as
|
|
41610
|
-
import { basename as
|
|
41820
|
+
import { access as access3, lstat as lstat8, readdir as readdir5, realpath as realpath7, rm as rm10 } from "node:fs/promises";
|
|
41821
|
+
import { basename as basename5, dirname as dirname9, join as join12, resolve as resolve7 } from "node:path";
|
|
41611
41822
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
41612
41823
|
var import_ajv3, failure, object4, validModel, receiptUsage, assertOwnedRuntime, cleanupExoOwnedState, ExoForegroundAdapter;
|
|
41613
41824
|
var init_exo_adapter = __esm({
|
|
@@ -41663,7 +41874,7 @@ var init_exo_adapter = __esm({
|
|
|
41663
41874
|
}
|
|
41664
41875
|
await ensureInferencePrivateDirectory(stateRoot);
|
|
41665
41876
|
const root = await realpath7(stateRoot);
|
|
41666
|
-
for (const entry of await
|
|
41877
|
+
for (const entry of await readdir5(root, { withFileTypes: true })) {
|
|
41667
41878
|
const match = /^(?:agent|attempt)-([a-f0-9-]{36})$/u.exec(entry.name);
|
|
41668
41879
|
if (!match || !entry.isDirectory() || entry.isSymbolicLink()) throw failure("exo_state_not_owned");
|
|
41669
41880
|
await assertOwnedRuntime(join12(root, entry.name), match[1]);
|
|
@@ -41777,7 +41988,7 @@ var init_exo_adapter = __esm({
|
|
|
41777
41988
|
async ownedRoot(thread) {
|
|
41778
41989
|
const parent = await realpath7(this.options.stateRoot);
|
|
41779
41990
|
const root = resolve7(thread.threadPath);
|
|
41780
|
-
if (!/^[a-f0-9-]{36}$/u.test(thread.threadId) || dirname9(root) !== parent ||
|
|
41991
|
+
if (!/^[a-f0-9-]{36}$/u.test(thread.threadId) || dirname9(root) !== parent || basename5(root) !== `agent-${thread.threadId}`) throw failure("exo_thread_not_owned");
|
|
41781
41992
|
await assertOwnedRuntime(root, thread.threadId);
|
|
41782
41993
|
return root;
|
|
41783
41994
|
}
|
|
@@ -46806,11 +47017,11 @@ Waiting for approval...
|
|
|
46806
47017
|
operation_id: agentOperationId("agent-decision-submit"),
|
|
46807
47018
|
candidate: input.candidate,
|
|
46808
47019
|
observed_at: observedAt,
|
|
46809
|
-
...state.review ? { timing:
|
|
46810
|
-
|
|
46811
|
-
|
|
46812
|
-
|
|
46813
|
-
|
|
47020
|
+
...state.review ? { timing: measureAgentReviewTiming(
|
|
47021
|
+
state.review.analysis_started_at,
|
|
47022
|
+
observedAt,
|
|
47023
|
+
session.client.supportsAgentAnalysisDuration?.() === true
|
|
47024
|
+
) } : {},
|
|
46814
47025
|
provenance: input.provenance
|
|
46815
47026
|
},
|
|
46816
47027
|
first_transmit_at: null,
|
|
@@ -48121,7 +48332,8 @@ async function parseError(response, fallback) {
|
|
|
48121
48332
|
detail = null;
|
|
48122
48333
|
}
|
|
48123
48334
|
const rawDetail = detail && typeof detail === "object" && "detail" in detail ? detail.detail : detail;
|
|
48124
|
-
const
|
|
48335
|
+
const detailMessage = rawDetail && typeof rawDetail === "object" && typeof rawDetail.message === "string" ? String(rawDetail.message).trim() : "";
|
|
48336
|
+
const message = typeof rawDetail === "string" ? rawDetail : detailMessage || fallback;
|
|
48125
48337
|
const code = rawDetail && typeof rawDetail === "object" && "code" in rawDetail ? String(rawDetail.code || "") : void 0;
|
|
48126
48338
|
return new AgentClientError({
|
|
48127
48339
|
status: response.status,
|
|
@@ -52490,6 +52702,28 @@ var init_client_host_commands = __esm({
|
|
|
52490
52702
|
}
|
|
52491
52703
|
});
|
|
52492
52704
|
|
|
52705
|
+
// lib/api/insights-access-center.ts
|
|
52706
|
+
var init_insights_access_center = __esm({
|
|
52707
|
+
"lib/api/insights-access-center.ts"() {
|
|
52708
|
+
"use strict";
|
|
52709
|
+
init_define_VTX_EXO_POLICY();
|
|
52710
|
+
init_define_VTX_GROK_POLICY();
|
|
52711
|
+
init_define_VTX_PI_MODEL_POLICY();
|
|
52712
|
+
init_shared();
|
|
52713
|
+
}
|
|
52714
|
+
});
|
|
52715
|
+
|
|
52716
|
+
// lib/api/updates.ts
|
|
52717
|
+
var init_updates = __esm({
|
|
52718
|
+
"lib/api/updates.ts"() {
|
|
52719
|
+
"use strict";
|
|
52720
|
+
init_define_VTX_EXO_POLICY();
|
|
52721
|
+
init_define_VTX_GROK_POLICY();
|
|
52722
|
+
init_define_VTX_PI_MODEL_POLICY();
|
|
52723
|
+
init_shared();
|
|
52724
|
+
}
|
|
52725
|
+
});
|
|
52726
|
+
|
|
52493
52727
|
// lib/runtime/server-runtime-lease.ts
|
|
52494
52728
|
var CLIENT_RUNTIME_SERVER_LEASE_STORAGE_KEY, canUseStorage, normalizeProfileId, normalizeLeaseGeneration, parseLeaseRecord, readPersistedLeaseMap, writePersistedLeaseMap, isLeaseExpired, getPersistedClientRuntimeServerLease, persistExistingClientRuntimeServerLease, persistClientRuntimeServerLease, clearPersistedClientRuntimeServerLease;
|
|
52495
52729
|
var init_server_runtime_lease = __esm({
|
|
@@ -53199,6 +53433,8 @@ var init_api2 = __esm({
|
|
|
53199
53433
|
init_market_data();
|
|
53200
53434
|
init_screener();
|
|
53201
53435
|
init_client_host_commands();
|
|
53436
|
+
init_insights_access_center();
|
|
53437
|
+
init_updates();
|
|
53202
53438
|
init_server_runtime_lease();
|
|
53203
53439
|
preferencesWriteQueue = Promise.resolve();
|
|
53204
53440
|
CLIENT_SUPPORTED_PROMPT_CONTRACT_VERSION = String(
|
|
@@ -71102,8 +71338,8 @@ var init_network = __esm({
|
|
|
71102
71338
|
* Gets a list of all plugins that match %%name%%, with otr without
|
|
71103
71339
|
* a fragment.
|
|
71104
71340
|
*/
|
|
71105
|
-
getPlugins(
|
|
71106
|
-
return this.plugins.filter((p) => p.name.split("#")[0] ===
|
|
71341
|
+
getPlugins(basename6) {
|
|
71342
|
+
return this.plugins.filter((p) => p.name.split("#")[0] === basename6);
|
|
71107
71343
|
}
|
|
71108
71344
|
/**
|
|
71109
71345
|
* Create a copy of this Network.
|
|
@@ -86693,7 +86929,7 @@ var init_openai_compatible_capabilities = __esm({
|
|
|
86693
86929
|
});
|
|
86694
86930
|
|
|
86695
86931
|
// lib/local-ai.ts
|
|
86696
|
-
var LOCAL_CONTEXT_CACHE_TTL_MS, LOCAL_AI_SERVER_TYPE_ALIASES, normalizeLocalAiServerType;
|
|
86932
|
+
var LOCAL_CONTEXT_CACHE_TTL_MS, LOCAL_AI_SERVER_TYPE_ALIASES, normalizeLocalAiServerType, endpointOrigin, sameEndpointOriginKey;
|
|
86697
86933
|
var init_local_ai = __esm({
|
|
86698
86934
|
"lib/local-ai.ts"() {
|
|
86699
86935
|
"use strict";
|
|
@@ -86717,6 +86953,17 @@ var init_local_ai = __esm({
|
|
|
86717
86953
|
}
|
|
86718
86954
|
return Object.prototype.hasOwnProperty.call(LOCAL_AI_SERVER_TYPE_ALIASES, normalized) ? "openai-compatible" : null;
|
|
86719
86955
|
};
|
|
86956
|
+
endpointOrigin = (value) => {
|
|
86957
|
+
try {
|
|
86958
|
+
return value ? new URL(value).origin : null;
|
|
86959
|
+
} catch {
|
|
86960
|
+
return null;
|
|
86961
|
+
}
|
|
86962
|
+
};
|
|
86963
|
+
sameEndpointOriginKey = (saved, targetBaseUrl) => {
|
|
86964
|
+
const savedOrigin = endpointOrigin(saved?.baseUrl);
|
|
86965
|
+
return savedOrigin !== null && savedOrigin === endpointOrigin(targetBaseUrl) ? saved?.apiKey || void 0 : void 0;
|
|
86966
|
+
};
|
|
86720
86967
|
}
|
|
86721
86968
|
});
|
|
86722
86969
|
|
|
@@ -87086,7 +87333,10 @@ var init_vault = __esm({
|
|
|
87086
87333
|
serverType: localNormalized?.localAi?.serverType ?? remoteNormalized?.localAi?.serverType
|
|
87087
87334
|
}) : normalizeLocalAiSecrets({
|
|
87088
87335
|
baseUrl: remoteNormalized?.localAi?.baseUrl,
|
|
87089
|
-
apiKey: remoteNormalized?.localAi?.apiKey ??
|
|
87336
|
+
apiKey: remoteNormalized?.localAi?.apiKey ?? sameEndpointOriginKey(
|
|
87337
|
+
localNormalized?.localAi,
|
|
87338
|
+
remoteNormalized?.localAi?.baseUrl
|
|
87339
|
+
),
|
|
87090
87340
|
serverType: remoteNormalized?.localAi?.serverType ?? localNormalized?.localAi?.serverType
|
|
87091
87341
|
});
|
|
87092
87342
|
const mergedOpenAiCompatible = storage2.byok === "device" ? normalizeOpenAiCompatibleSecrets({
|
|
@@ -87094,7 +87344,10 @@ var init_vault = __esm({
|
|
|
87094
87344
|
apiKey: localNormalized?.openaiCompatible?.apiKey
|
|
87095
87345
|
}) : normalizeOpenAiCompatibleSecrets({
|
|
87096
87346
|
baseUrl: remoteNormalized?.openaiCompatible?.baseUrl,
|
|
87097
|
-
apiKey: remoteNormalized?.openaiCompatible?.apiKey ??
|
|
87347
|
+
apiKey: remoteNormalized?.openaiCompatible?.apiKey ?? sameEndpointOriginKey(
|
|
87348
|
+
localNormalized?.openaiCompatible,
|
|
87349
|
+
remoteNormalized?.openaiCompatible?.baseUrl
|
|
87350
|
+
)
|
|
87098
87351
|
});
|
|
87099
87352
|
return validateDeviceSecrets({
|
|
87100
87353
|
hyperliquidSigningKey: storage2.hyperliquid === "device" ? localNormalized?.hyperliquidSigningKey : remoteNormalized?.hyperliquidSigningKey,
|
|
@@ -87113,8 +87366,15 @@ var init_vault = __esm({
|
|
|
87113
87366
|
return null;
|
|
87114
87367
|
}
|
|
87115
87368
|
const storage2 = normalizeDeviceSecretStorage(normalized.storage);
|
|
87116
|
-
const localAi = storage2.byok === "device" ? normalizeLocalAiSecrets(normalized.localAi) : normalizeLocalAiSecrets({
|
|
87117
|
-
|
|
87369
|
+
const localAi = storage2.byok === "device" ? normalizeLocalAiSecrets(normalized.localAi) : normalizeLocalAiSecrets({
|
|
87370
|
+
apiKey: normalized.localAi?.apiKey,
|
|
87371
|
+
baseUrl: normalized.localAi?.apiKey ? normalized.localAi?.baseUrl : void 0,
|
|
87372
|
+
serverType: normalized.localAi?.serverType
|
|
87373
|
+
});
|
|
87374
|
+
const openaiCompatible = storage2.byok === "device" ? normalizeOpenAiCompatibleSecrets(normalized.openaiCompatible) : normalizeOpenAiCompatibleSecrets({
|
|
87375
|
+
apiKey: normalized.openaiCompatible?.apiKey,
|
|
87376
|
+
baseUrl: normalized.openaiCompatible?.apiKey ? normalized.openaiCompatible?.baseUrl : void 0
|
|
87377
|
+
});
|
|
87118
87378
|
return validateDeviceSecrets({
|
|
87119
87379
|
hyperliquidSigningKey: storage2.hyperliquid === "device" ? normalized.hyperliquidSigningKey : void 0,
|
|
87120
87380
|
providerKeys: storage2.byok === "device" ? { ...normalized.providerKeys } : {},
|
|
@@ -88065,7 +88325,7 @@ var init_execution_guard_contract = __esm({
|
|
|
88065
88325
|
});
|
|
88066
88326
|
|
|
88067
88327
|
// lib/runtime/runtime-execution.ts
|
|
88068
|
-
var executionReadPriority, fetchClientRuntimeOpenOrders, createRuntimeId, _extractOrderId, _toExecutionMetadata, _extractClientMutationId, trailingStopMemory, protectiveGroupMemory, protectiveGroupReadFailures, windowHandoffCleanupAttempts, clientRuntimeProtectionStorage, resolveClientRuntimeProtectionStorage, setClientRuntimeProtectionStorage, trailingStopStorageKey, readTrackedTrailingStops, writeTrackedTrailingStops, rememberTrailingStop, protectiveGroupStorageKey, readClientProtectiveGroups, writeClientProtectiveGroups, hasClientProtectiveGroupReadFailure, readFreshClientProtectiveGroups, stableProtectionSnapshot, exactClientProtectiveGroupSnapshot, exactClientProtectiveGroupSetSnapshot, replaceExactClientProtectiveGroup, replaceExactClientProtectiveGroupSet, isClientRuntimeLeaseOwnershipError, hasClientRuntimeProtectionState, clearClientRuntimeVetoedProtectiveIntent, rethrowWindowHandoffAfterProtectiveReplacementVeto, canPersistClientProtectiveGroups, removeTrackedTrailingStop, replaceTrackedTrailingStop, replaceProtectiveLeg, replacementJournalEntryOrderId, buildProtectiveReplacementJournalGroup, isProtectiveReplacementJournalGroup, reserveProtectiveLegReplacement, ensureProtectiveReplacementJournalCompanion, buildVetoedProtectiveReplacementCleanup, assertExactProtectiveReplacementDispatchAuthority, transitionProtectiveReplacementAcknowledgement, transitionTerminalProtectiveReplacement, pendingProtectiveReplacementReport, toPositiveNumber, resolveRiskPct, buildTriggerPrice, isConfiguredProtectionRequested, protectiveAction, isExactClientPositionTpslPair, hasAmbiguousClientPositionTpslAuthority, protectiveStableShapeMatches, protectiveLiveShapeMatches, protectiveTerminalShapeMatches, cancelClientProtectiveLeg, buildPendingProtectivePlan, attachClientProtectivePlan, resolveJournaledAttachmentContinuity, recoverJournaledClientProtectiveAttachments, recoverPendingClientProtectiveGroups, recoverPendingProtectiveReplacements, reconcileClientProtectiveGroups, cancelAllClientProtectiveGroups, tightenClientTrailingStops, throwIfAborted2, sleep3, roundAssetSize, resolvePositionSize, resolveCurrentPositionSize, buildPositionSnapshot, signedRemainingExposureAfterConfirmedReduction, verifyNoLiveClientProtectiveTriggers, clientExecutionMutations, withClientExecutionMutation, executeClientRuntimeDecision, maintainClientRuntimeTrailingStops, executeClientRuntimeDecisionUnlocked;
|
|
88328
|
+
var clientProtectiveMutationAuthority, executionReadPriority, fetchClientRuntimeOpenOrders, createRuntimeId, _extractOrderId, _toExecutionMetadata, _extractClientMutationId, trailingStopMemory, protectiveGroupMemory, protectiveGroupReadFailures, windowHandoffCleanupAttempts, clientRuntimeProtectionStorage, resolveClientRuntimeProtectionStorage, setClientRuntimeProtectionStorage, trailingStopStorageKey, readTrackedTrailingStops, writeTrackedTrailingStops, rememberTrailingStop, protectiveGroupStorageKey, readClientProtectiveGroups, writeClientProtectiveGroups, hasClientProtectiveGroupReadFailure, readFreshClientProtectiveGroups, stableProtectionSnapshot, exactClientProtectiveGroupSnapshot, exactClientProtectiveGroupSetSnapshot, replaceExactClientProtectiveGroup, replaceExactClientProtectiveGroupSet, isClientRuntimeLeaseOwnershipError, hasClientRuntimeProtectionState, clearClientRuntimeVetoedProtectiveIntent, rethrowWindowHandoffAfterProtectiveReplacementVeto, canPersistClientProtectiveGroups, removeTrackedTrailingStop, replaceTrackedTrailingStop, replaceProtectiveLeg, replacementJournalEntryOrderId, buildProtectiveReplacementJournalGroup, isProtectiveReplacementJournalGroup, reserveProtectiveLegReplacement, ensureProtectiveReplacementJournalCompanion, buildVetoedProtectiveReplacementCleanup, assertExactProtectiveReplacementDispatchAuthority, transitionProtectiveReplacementAcknowledgement, transitionTerminalProtectiveReplacement, pendingProtectiveReplacementReport, toPositiveNumber, resolveRiskPct, buildTriggerPrice, isConfiguredProtectionRequested, protectiveAction, isExactClientPositionTpslPair, hasAmbiguousClientPositionTpslAuthority, protectiveStableShapeMatches, protectiveLiveShapeMatches, protectiveTerminalShapeMatches, cancelClientProtectiveLeg, buildPendingProtectivePlan, persistPendingClientProtectiveGroup, attachClientProtectivePlan, resolveJournaledAttachmentContinuity, recoverJournaledClientProtectiveAttachments, recoverPendingClientProtectiveGroups, recoverPendingProtectiveReplacements, reconcileClientProtectiveGroups, cancelAllClientProtectiveGroups, tightenClientTrailingStops, throwIfAborted2, sleep3, roundAssetSize, resolvePositionSize, resolveCurrentPositionSize, buildPositionSnapshot, signedRemainingExposureAfterConfirmedReduction, verifyNoLiveClientProtectiveTriggers, clientExecutionMutations, withClientExecutionMutation, executeClientRuntimeDecision, maintainClientRuntimeTrailingStops, executeClientRuntimeDecisionUnlocked;
|
|
88069
88329
|
var init_runtime_execution = __esm({
|
|
88070
88330
|
"lib/runtime/runtime-execution.ts"() {
|
|
88071
88331
|
"use strict";
|
|
@@ -88081,6 +88341,12 @@ var init_runtime_execution = __esm({
|
|
|
88081
88341
|
init_runtime_redaction();
|
|
88082
88342
|
init_error_surface_contract();
|
|
88083
88343
|
init_runtime_handoff();
|
|
88344
|
+
clientProtectiveMutationAuthority = (request) => request.mutationAuthority === "manual_session" ? {} : {
|
|
88345
|
+
runtimeSessionId: request.sessionId || "__missing_runtime_session__",
|
|
88346
|
+
runtimeLeaseToken: request.runtimeLeaseToken,
|
|
88347
|
+
runtimeDeviceId: request.runtimeDeviceId,
|
|
88348
|
+
schedulerInstanceId: request.schedulerInstanceId
|
|
88349
|
+
};
|
|
88084
88350
|
executionReadPriority = (input) => {
|
|
88085
88351
|
const context = input.executionContext;
|
|
88086
88352
|
const classified = classifyExecutionIntent(
|
|
@@ -89094,10 +89360,7 @@ var init_runtime_execution = __esm({
|
|
|
89094
89360
|
await executeClientCancelOrder({
|
|
89095
89361
|
publicRequestPriority: "trading_reduce",
|
|
89096
89362
|
profileId: request.profileId,
|
|
89097
|
-
|
|
89098
|
-
runtimeLeaseToken: request.runtimeLeaseToken,
|
|
89099
|
-
runtimeDeviceId: request.runtimeDeviceId,
|
|
89100
|
-
schedulerInstanceId: request.schedulerInstanceId,
|
|
89363
|
+
...clientProtectiveMutationAuthority(request),
|
|
89101
89364
|
walletAddress: request.executionContext.walletAddress,
|
|
89102
89365
|
config: request.config ?? null,
|
|
89103
89366
|
signal: request.signal,
|
|
@@ -89130,24 +89393,58 @@ var init_runtime_execution = __esm({
|
|
|
89130
89393
|
};
|
|
89131
89394
|
}
|
|
89132
89395
|
};
|
|
89133
|
-
buildPendingProtectivePlan = (
|
|
89396
|
+
buildPendingProtectivePlan = (settings, input) => ({
|
|
89134
89397
|
...input,
|
|
89135
89398
|
stopLoss: {
|
|
89136
|
-
enabled:
|
|
89137
|
-
mode:
|
|
89399
|
+
enabled: settings.stopLossEnabled !== false,
|
|
89400
|
+
mode: settings.stopLossMode === "usdc" ? "usdc" : "percent",
|
|
89138
89401
|
value: toPositiveNumber(
|
|
89139
|
-
|
|
89402
|
+
settings.stopLossMode === "usdc" ? settings.stopLossUsdc : settings.stopLossPct
|
|
89140
89403
|
),
|
|
89141
|
-
isTrailing:
|
|
89404
|
+
isTrailing: settings.stopLossType === "trailing"
|
|
89142
89405
|
},
|
|
89143
89406
|
takeProfit: {
|
|
89144
|
-
enabled:
|
|
89145
|
-
mode:
|
|
89407
|
+
enabled: settings.takeProfitEnabled !== false,
|
|
89408
|
+
mode: settings.takeProfitMode === "usdc" ? "usdc" : "percent",
|
|
89146
89409
|
value: toPositiveNumber(
|
|
89147
|
-
|
|
89410
|
+
settings.takeProfitMode === "usdc" ? settings.takeProfitUsdc : settings.takeProfitPct
|
|
89148
89411
|
)
|
|
89149
89412
|
}
|
|
89150
89413
|
});
|
|
89414
|
+
persistPendingClientProtectiveGroup = (input) => {
|
|
89415
|
+
const { profileId, symbol: symbol2 } = input;
|
|
89416
|
+
const group = {
|
|
89417
|
+
version: 2,
|
|
89418
|
+
profileId,
|
|
89419
|
+
symbol: symbol2.trim().toUpperCase(),
|
|
89420
|
+
walletAddress: String(input.walletAddress || "").trim().toLowerCase(),
|
|
89421
|
+
entryOrderId: input.entryClientOrderId,
|
|
89422
|
+
isLong: input.entrySide === "buy",
|
|
89423
|
+
legs: [],
|
|
89424
|
+
pendingEntry: buildPendingProtectivePlan(input.settings, {
|
|
89425
|
+
entryMutationId: input.entryMutationId,
|
|
89426
|
+
entryClientOrderId: input.entryClientOrderId,
|
|
89427
|
+
entrySide: input.entrySide,
|
|
89428
|
+
requestedSize: input.requestedSize
|
|
89429
|
+
})
|
|
89430
|
+
};
|
|
89431
|
+
const cleanup = {
|
|
89432
|
+
kind: "vetoed_protective_intent",
|
|
89433
|
+
profileId,
|
|
89434
|
+
symbol: symbol2,
|
|
89435
|
+
entryOrderId: group.entryOrderId,
|
|
89436
|
+
pendingGroupSnapshot: exactClientProtectiveGroupSnapshot(group)
|
|
89437
|
+
};
|
|
89438
|
+
const existingGroups = readFreshClientProtectiveGroups(profileId, symbol2);
|
|
89439
|
+
const nextGroups = [...existingGroups, group];
|
|
89440
|
+
const persistenceFailed = hasClientProtectiveGroupReadFailure(profileId, symbol2) || !replaceExactClientProtectiveGroupSet(
|
|
89441
|
+
profileId,
|
|
89442
|
+
symbol2,
|
|
89443
|
+
existingGroups,
|
|
89444
|
+
nextGroups
|
|
89445
|
+
);
|
|
89446
|
+
return { group, cleanup, persistedGroupSet: persistenceFailed ? null : nextGroups };
|
|
89447
|
+
};
|
|
89151
89448
|
attachClientProtectivePlan = async (request, group, fill) => {
|
|
89152
89449
|
const reports = [];
|
|
89153
89450
|
const plan = group.pendingEntry;
|
|
@@ -89211,8 +89508,7 @@ var init_runtime_execution = __esm({
|
|
|
89211
89508
|
"trading_reduce"
|
|
89212
89509
|
);
|
|
89213
89510
|
const livePositionSize = Number(snapshot.size);
|
|
89214
|
-
|
|
89215
|
-
if (!directionMatches) {
|
|
89511
|
+
if (!Number.isFinite(livePositionSize)) {
|
|
89216
89512
|
reports.push({
|
|
89217
89513
|
order_id: fill.orderId,
|
|
89218
89514
|
symbol: symbol2,
|
|
@@ -89222,6 +89518,26 @@ var init_runtime_execution = __esm({
|
|
|
89222
89518
|
});
|
|
89223
89519
|
return reports;
|
|
89224
89520
|
}
|
|
89521
|
+
const directionMatches = isLong ? livePositionSize > 0 : livePositionSize < 0;
|
|
89522
|
+
if (!directionMatches) {
|
|
89523
|
+
const flat = livePositionSize === 0;
|
|
89524
|
+
const retired = replaceExactClientProtectiveGroupSet(
|
|
89525
|
+
profileId,
|
|
89526
|
+
symbol2,
|
|
89527
|
+
observedGroups,
|
|
89528
|
+
existingGroups
|
|
89529
|
+
);
|
|
89530
|
+
reports.push({
|
|
89531
|
+
order_id: fill.orderId,
|
|
89532
|
+
symbol: symbol2,
|
|
89533
|
+
action: "PROTECTIVE_RECONCILIATION",
|
|
89534
|
+
status: "failed",
|
|
89535
|
+
execution_metadata: {
|
|
89536
|
+
reason_code: !retired ? "protective_lifecycle_persistence_failed" : flat ? "protective_position_flat" : "protective_position_drift"
|
|
89537
|
+
}
|
|
89538
|
+
});
|
|
89539
|
+
return reports;
|
|
89540
|
+
}
|
|
89225
89541
|
const liveExposure = Math.abs(livePositionSize);
|
|
89226
89542
|
const allocatedCandidates = planned.flatMap((candidate) => {
|
|
89227
89543
|
const allocated = existingGroups.flatMap((existing) => existing.legs).filter((leg) => leg.kind === candidate.kind).reduce((total, leg) => total + leg.size, 0);
|
|
@@ -89229,7 +89545,22 @@ var init_runtime_execution = __esm({
|
|
|
89229
89545
|
Math.min(fill.filledSize, Math.max(0, liveExposure - allocated)),
|
|
89230
89546
|
request.executionContext.sizeDecimals
|
|
89231
89547
|
);
|
|
89232
|
-
if (!Number.isFinite(size) || size <= 0)
|
|
89548
|
+
if (!Number.isFinite(size) || size <= 0) {
|
|
89549
|
+
reports.push({
|
|
89550
|
+
order_id: null,
|
|
89551
|
+
symbol: symbol2,
|
|
89552
|
+
action: candidate.kind === "sl" ? "AUTO_SL" : "AUTO_TP",
|
|
89553
|
+
status: "blocked",
|
|
89554
|
+
execution_metadata: {
|
|
89555
|
+
reason_code: "protective_exposure_already_covered",
|
|
89556
|
+
entry_order_id: fill.orderId,
|
|
89557
|
+
entry_filled_size: fill.filledSize,
|
|
89558
|
+
entry_average_price: fill.averagePrice,
|
|
89559
|
+
live_position_size: livePositionSize
|
|
89560
|
+
}
|
|
89561
|
+
});
|
|
89562
|
+
return [];
|
|
89563
|
+
}
|
|
89233
89564
|
const triggerPrice = buildTriggerPrice(
|
|
89234
89565
|
fill.averagePrice,
|
|
89235
89566
|
resolveRiskPct(
|
|
@@ -89271,7 +89602,7 @@ var init_runtime_execution = __esm({
|
|
|
89271
89602
|
(candidate) => candidate.triggerPrice <= 0
|
|
89272
89603
|
);
|
|
89273
89604
|
if (invalidCandidates.length > 0) {
|
|
89274
|
-
for (const candidate of
|
|
89605
|
+
for (const candidate of allocatedCandidates) {
|
|
89275
89606
|
reports.push({
|
|
89276
89607
|
order_id: fill.orderId,
|
|
89277
89608
|
symbol: symbol2,
|
|
@@ -89279,6 +89610,7 @@ var init_runtime_execution = __esm({
|
|
|
89279
89610
|
status: "failed",
|
|
89280
89611
|
execution_metadata: {
|
|
89281
89612
|
reason_code: "protective_trigger_invalid",
|
|
89613
|
+
...candidate.triggerPrice > 0 ? { invalid_sibling: true } : {},
|
|
89282
89614
|
entry_filled_size: fill.filledSize,
|
|
89283
89615
|
entry_average_price: fill.averagePrice
|
|
89284
89616
|
}
|
|
@@ -89496,10 +89828,7 @@ var init_runtime_execution = __esm({
|
|
|
89496
89828
|
if (positionTpsl) {
|
|
89497
89829
|
response = await executeClientOrderBatch({
|
|
89498
89830
|
profileId: request.profileId,
|
|
89499
|
-
|
|
89500
|
-
runtimeLeaseToken: request.runtimeLeaseToken,
|
|
89501
|
-
runtimeDeviceId: request.runtimeDeviceId,
|
|
89502
|
-
schedulerInstanceId: request.schedulerInstanceId,
|
|
89831
|
+
...clientProtectiveMutationAuthority(request),
|
|
89503
89832
|
walletAddress: request.executionContext.walletAddress,
|
|
89504
89833
|
config: request.config ?? null,
|
|
89505
89834
|
signal: request.signal,
|
|
@@ -89529,10 +89858,7 @@ var init_runtime_execution = __esm({
|
|
|
89529
89858
|
const candidate = candidates[0];
|
|
89530
89859
|
response = await executeClientTriggerOrder({
|
|
89531
89860
|
profileId: request.profileId,
|
|
89532
|
-
|
|
89533
|
-
runtimeLeaseToken: request.runtimeLeaseToken,
|
|
89534
|
-
runtimeDeviceId: request.runtimeDeviceId,
|
|
89535
|
-
schedulerInstanceId: request.schedulerInstanceId,
|
|
89861
|
+
...clientProtectiveMutationAuthority(request),
|
|
89536
89862
|
walletAddress: request.executionContext.walletAddress,
|
|
89537
89863
|
config: request.config ?? null,
|
|
89538
89864
|
signal: request.signal,
|
|
@@ -89605,14 +89931,15 @@ var init_runtime_execution = __esm({
|
|
|
89605
89931
|
return acknowledgement == null ? null : [acknowledgement];
|
|
89606
89932
|
})();
|
|
89607
89933
|
if (acknowledgements == null) {
|
|
89608
|
-
|
|
89934
|
+
reports.push(...candidates.map((candidate) => ({
|
|
89609
89935
|
order_id: null,
|
|
89610
89936
|
client_mutation_id: candidate.mutationId,
|
|
89611
89937
|
symbol: symbol2,
|
|
89612
89938
|
action: candidate.kind === "sl" ? "AUTO_SL" : "AUTO_TP",
|
|
89613
89939
|
status: "blocked",
|
|
89614
89940
|
execution_metadata: { reason_code: "protective_trigger_ack_unresolved" }
|
|
89615
|
-
}));
|
|
89941
|
+
})));
|
|
89942
|
+
return reports;
|
|
89616
89943
|
}
|
|
89617
89944
|
const acknowledgedLegs = acknowledgements.map((acknowledgement, index) => ({
|
|
89618
89945
|
...provisionalLegs[index],
|
|
@@ -92570,41 +92897,19 @@ var init_runtime_execution = __esm({
|
|
|
92570
92897
|
if (shouldAttachSlTp) {
|
|
92571
92898
|
entryMutationId = createRuntimeId().toLowerCase();
|
|
92572
92899
|
entryClientOrderId = `0x${entryMutationId.replaceAll("-", "")}`;
|
|
92573
|
-
const
|
|
92574
|
-
|
|
92575
|
-
version: 2,
|
|
92576
|
-
profileId: profileId2,
|
|
92577
|
-
symbol: input.executionContext.symbol.trim().toUpperCase(),
|
|
92578
|
-
walletAddress: String(input.executionContext.walletAddress || "").trim().toLowerCase(),
|
|
92579
|
-
entryOrderId: entryClientOrderId,
|
|
92580
|
-
isLong: classified.side === "buy",
|
|
92581
|
-
legs: [],
|
|
92582
|
-
pendingEntry: buildPendingProtectivePlan(input, {
|
|
92583
|
-
entryMutationId,
|
|
92584
|
-
entryClientOrderId,
|
|
92585
|
-
entrySide: classified.side,
|
|
92586
|
-
requestedSize: sizeAsset
|
|
92587
|
-
})
|
|
92588
|
-
};
|
|
92589
|
-
pendingProtectiveCleanup = {
|
|
92590
|
-
kind: "vetoed_protective_intent",
|
|
92591
|
-
profileId: profileId2,
|
|
92900
|
+
const pendingProtection = persistPendingClientProtectiveGroup({
|
|
92901
|
+
profileId: String(input.profileId).trim(),
|
|
92592
92902
|
symbol: input.executionContext.symbol,
|
|
92593
|
-
|
|
92594
|
-
|
|
92595
|
-
|
|
92596
|
-
|
|
92597
|
-
|
|
92598
|
-
|
|
92599
|
-
);
|
|
92600
|
-
|
|
92601
|
-
|
|
92602
|
-
|
|
92603
|
-
input.executionContext.symbol,
|
|
92604
|
-
existingGroups,
|
|
92605
|
-
nextGroups
|
|
92606
|
-
);
|
|
92607
|
-
if (persistenceFailed) {
|
|
92903
|
+
walletAddress: input.executionContext.walletAddress,
|
|
92904
|
+
settings: input.executionContext,
|
|
92905
|
+
entryMutationId,
|
|
92906
|
+
entryClientOrderId,
|
|
92907
|
+
entrySide: classified.side,
|
|
92908
|
+
requestedSize: sizeAsset
|
|
92909
|
+
});
|
|
92910
|
+
pendingProtectiveGroup = pendingProtection.group;
|
|
92911
|
+
pendingProtectiveCleanup = pendingProtection.cleanup;
|
|
92912
|
+
if (pendingProtection.persistedGroupSet == null) {
|
|
92608
92913
|
const cleanupComplete = clearClientRuntimeVetoedProtectiveIntent(
|
|
92609
92914
|
pendingProtectiveCleanup
|
|
92610
92915
|
);
|
|
@@ -92635,7 +92940,7 @@ var init_runtime_execution = __esm({
|
|
|
92635
92940
|
executionSnapshotCapturedAt
|
|
92636
92941
|
};
|
|
92637
92942
|
}
|
|
92638
|
-
persistedProtectiveGroupSet =
|
|
92943
|
+
persistedProtectiveGroupSet = pendingProtection.persistedGroupSet;
|
|
92639
92944
|
}
|
|
92640
92945
|
let marketOrderResponse;
|
|
92641
92946
|
let entryDispatchBoundaryPassed = false;
|
|
@@ -95013,8 +95318,34 @@ function parseMarketOrderPayload(args) {
|
|
|
95013
95318
|
if (estimatedPriceTimestampMs) {
|
|
95014
95319
|
payload.estimated_price_timestamp_ms = parsePositiveInt(estimatedPriceTimestampMs, "--estimated-price-timestamp-ms");
|
|
95015
95320
|
}
|
|
95321
|
+
if (args.includes("--reduce-only")) {
|
|
95322
|
+
payload.reduce_only = true;
|
|
95323
|
+
}
|
|
95324
|
+
const protection = parseMarketOrderProtection(args);
|
|
95325
|
+
if (protection) {
|
|
95326
|
+
payload.protection = protection;
|
|
95327
|
+
}
|
|
95016
95328
|
return payload;
|
|
95017
95329
|
}
|
|
95330
|
+
function parseMarketOrderProtection(args) {
|
|
95331
|
+
const leg = (name) => {
|
|
95332
|
+
const percent = optionalValue(args, `--${name}-percent`);
|
|
95333
|
+
const usdc = optionalValue(args, `--${name}-usdc`);
|
|
95334
|
+
if (percent && usdc) {
|
|
95335
|
+
throw new Error(`Use either --${name}-percent or --${name}-usdc, not both`);
|
|
95336
|
+
}
|
|
95337
|
+
if (percent) return { mode: "percent", value: parsePositiveNumber(percent, `--${name}-percent`) };
|
|
95338
|
+
if (usdc) return { mode: "usdc", value: parsePositiveNumber(usdc, `--${name}-usdc`) };
|
|
95339
|
+
return null;
|
|
95340
|
+
};
|
|
95341
|
+
const takeProfit = leg("take-profit");
|
|
95342
|
+
const stopLoss = leg("stop-loss");
|
|
95343
|
+
if (!takeProfit && !stopLoss) return null;
|
|
95344
|
+
return {
|
|
95345
|
+
...takeProfit ? { take_profit: takeProfit } : {},
|
|
95346
|
+
...stopLoss ? { stop_loss: { ...stopLoss, stop_type: "fixed" } } : {}
|
|
95347
|
+
};
|
|
95348
|
+
}
|
|
95018
95349
|
function parseLimitOrderPayload(args) {
|
|
95019
95350
|
return {
|
|
95020
95351
|
symbol: normalizeHyperliquidMarketSymbol(requireValue(args, "--symbol")),
|
|
@@ -95373,6 +95704,17 @@ Common commands:
|
|
|
95373
95704
|
runtime events Read recent runtime events and errors
|
|
95374
95705
|
inference-host --help Set up an automated or agent-driven inference host
|
|
95375
95706
|
|
|
95707
|
+
Trading commands (Server Mode profiles):
|
|
95708
|
+
trade market-order --symbol <s> --side buy|sell --size <n>
|
|
95709
|
+
[--slippage <fraction>] [--estimated-price <n>] [--reduce-only]
|
|
95710
|
+
[--take-profit-percent <n> | --take-profit-usdc <n>]
|
|
95711
|
+
[--stop-loss-percent <n> | --stop-loss-usdc <n>]
|
|
95712
|
+
Fixed TP/SL as reduce-only market triggers from the
|
|
95713
|
+
average fill, within the AI page's Auto SL/TP limits;
|
|
95714
|
+
not allowed with --reduce-only; no trailing stops
|
|
95715
|
+
trade limit-order --symbol <s> --side buy|sell --size <n> --limit-price <n> [--reduce-only]
|
|
95716
|
+
trade cancel-order --symbol <s> --oid <n>
|
|
95717
|
+
|
|
95376
95718
|
Global options:
|
|
95377
95719
|
--json Emit machine-readable JSON
|
|
95378
95720
|
--profile <id> Select one VTX profile
|