@vtxmacro/cli 2026.8.55 → 2026.8.57
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/README.md +10 -5
- package/bin/vtx-service-bootstrap.js +1540 -0
- package/bin/vtx.js +248 -54
- package/package.json +1 -1
package/bin/vtx.js
CHANGED
|
@@ -47,7 +47,7 @@ var init_agent_cli_release = __esm({
|
|
|
47
47
|
"agent-cli-release.json"() {
|
|
48
48
|
agent_cli_release_default = {
|
|
49
49
|
package_name: "@vtxmacro/cli",
|
|
50
|
-
package_version: "2026.8.
|
|
50
|
+
package_version: "2026.8.57",
|
|
51
51
|
codex_package_name: "@openai/codex",
|
|
52
52
|
codex_version: "0.147.0",
|
|
53
53
|
copilot_sdk_package_name: "@github/copilot-sdk",
|
|
@@ -18756,7 +18756,8 @@ var init_mcp_client = __esm({
|
|
|
18756
18756
|
const errorText = (callResult.content ?? []).filter((block) => block.type === "text").map((block) => block.text ?? "").join("\n");
|
|
18757
18757
|
const definitivelyNotApplied = (name === "inference.host.register" || name === "inference.host.advertise") && (errorText.includes("Advertisement time is outside the allowed clock skew.") || errorText.includes("Advertisement is already expired.")) || (name === "inference.agent.next" || name === "inference.agent.heartbeat") && (errorText.includes("Advertisement time is outside the allowed clock skew.") || errorText.includes("Advertisement is already expired.") || errorText.includes("Heartbeat time is outside the allowed clock skew.")) || name === "inference.host.heartbeat" && errorText.includes("Heartbeat time is outside the allowed clock skew.") || name === "inference.job.claim" && (errorText.includes(
|
|
18758
18758
|
"External inference claim request was not applied before its generation became stale"
|
|
18759
|
-
) || errorText.includes("External inference host advertisement is expired or superseded"));
|
|
18759
|
+
) || errorText.includes("External inference host advertisement is expired or superseded")) || name === "inference.job.complete" && errorText.includes("External inference completion evidence window expired");
|
|
18760
|
+
const completionEvidenceExpired = name === "inference.job.complete" && errorText.includes("External inference completion evidence window expired");
|
|
18760
18761
|
const retryableInfrastructureRejection = EXTERNAL_INFERENCE_AUTOMATED_HOST_TOOLS.includes(name) && (errorText.includes("External inference polling is at its configured concurrency limit") || errorText.includes("The Insights action reached the response timeout") || errorText.includes("Insights capability failed without exposing private runtime details"));
|
|
18761
18762
|
const retryableClaimRejection = name === "inference.job.claim" && !definitivelyNotApplied && (retryableInfrastructureRejection || errorText.includes("External inference host is not live enough to claim work") || errorText.includes("External inference host request generation is stale") || errorText.includes("External inference claim runtime fence is stale"));
|
|
18762
18763
|
const retryableHeartbeatClockSkew = name === "inference.host.heartbeat" && definitivelyNotApplied;
|
|
@@ -18766,7 +18767,7 @@ var init_mcp_client = __esm({
|
|
|
18766
18767
|
"External inference claim replay is no longer dispatchable"
|
|
18767
18768
|
);
|
|
18768
18769
|
throw new ExternalInferenceMcpError(
|
|
18769
|
-
staleHostHeartbeatGeneration ? "generation_stale" : obsoleteClaimReplay ? "claim_replay_obsolete" : "tool_rejected",
|
|
18770
|
+
completionEvidenceExpired ? "completion_evidence_expired" : staleHostHeartbeatGeneration ? "generation_stale" : obsoleteClaimReplay ? "claim_replay_obsolete" : "tool_rejected",
|
|
18770
18771
|
`Insights MCP rejected ${name}.`,
|
|
18771
18772
|
{
|
|
18772
18773
|
definitivelyNotApplied: definitivelyNotApplied || staleHostHeartbeatGeneration,
|
|
@@ -32426,7 +32427,7 @@ function createDefaultInferenceHostRunnerDependencies(options) {
|
|
|
32426
32427
|
envelopePublicKey: options.envelopePublicKey
|
|
32427
32428
|
};
|
|
32428
32429
|
}
|
|
32429
|
-
var import_ajv, RUNTIME_RECEIPT_SCHEMA_VERSION, ATTEMPT_RECEIPT_SCHEMA_VERSION, DEFAULT_ADVERTISEMENT_TTL_MS, DEFAULT_ADVERTISEMENT_REFRESH_LEAD_MS, DEFAULT_HOST_HEARTBEAT_MS, DEFAULT_PROVIDER_RATE_LIMIT_REFRESH_MS, DEFAULT_ATTEMPT_HEARTBEAT_MS, DEFAULT_DRAIN_TIMEOUT_MS, DEFAULT_REMOTE_RETRY_LIMIT, MIN_SLEEP_MS, MIN_HOST_HEARTBEAT_GAP_DIAGNOSTIC_MS, HOST_HEARTBEAT_GAP_DIAGNOSTIC_FACTOR, DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS, DEFAULT_AGENT_RATE_LIMIT_COOLDOWN_MS, DEFAULT_AGENT_QUOTA_COOLDOWN_MS, DEFAULT_AGENT_TRANSIENT_COOLDOWN_MS, MIN_CLAIM_START_WINDOW_MS, MAX_ATTEMPT_START_RETRY_DELAY_MS, UNBOUNDED_AVAILABLE_SLOTS, buildInferenceAdvertisedModels, summarizeInferenceHostRuntimeRecovery, FileInferenceHostRuntimeReceiptStore, InferenceHostRecoveryRequiredError, InferenceHostRunnerError, defaultSleep, abortError, settlesWithin, defaultRegisterSignalHandlers, safeInteger, exactObjectKeys, validIso, validateAttemptReceipt, validateRuntimeReceipt, sha256, stableOperationId, buildAttemptStartRequest, isoAt, providerWeeklyQuotaFromRateLimits, finitePositiveOption, validateRunnerOptions, assertLocalCredentialIdentity, retryableRemoteError, remoteRetryAfterMs, controlPlaneFatal, defaultValidateOutput, objectRecord, positiveUtf8ByteLimit, assertCompilableOutputSchema, parseOutputContract, membershipFailureDisposition, safeFailureCode, attemptStartRetryFallbackMs, exactJson2, runnerIdentityMismatch, assertAdvertisementResult, assertHostHeartbeatResult, assertClaimResult, assertStartResult, assertJobHeartbeatResult, assertTerminalResult, classifyFailure, ambiguousHeartbeatTransport, reportedTokenUsage, reportedUsage, InferenceHostRunner, createInferenceAgentControlClient, INFERENCE_AGENT_SYSTEM_PROMPT, INFERENCE_AGENT_WAKE_SCHEMA, parseInferenceAgentWake, InferenceAgentRuntime;
|
|
32430
|
+
var import_ajv, RUNTIME_RECEIPT_SCHEMA_VERSION, ATTEMPT_RECEIPT_SCHEMA_VERSION, DEFAULT_ADVERTISEMENT_TTL_MS, DEFAULT_ADVERTISEMENT_REFRESH_LEAD_MS, DEFAULT_HOST_HEARTBEAT_MS, DEFAULT_PROVIDER_RATE_LIMIT_REFRESH_MS, DEFAULT_ATTEMPT_HEARTBEAT_MS, DEFAULT_DRAIN_TIMEOUT_MS, DEFAULT_REMOTE_RETRY_LIMIT, MIN_SLEEP_MS, MIN_HOST_HEARTBEAT_GAP_DIAGNOSTIC_MS, HOST_HEARTBEAT_GAP_DIAGNOSTIC_FACTOR, DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS, DEFAULT_AGENT_RATE_LIMIT_COOLDOWN_MS, DEFAULT_AGENT_QUOTA_COOLDOWN_MS, DEFAULT_AGENT_TRANSIENT_COOLDOWN_MS, MIN_CLAIM_START_WINDOW_MS, MAX_ATTEMPT_START_RETRY_DELAY_MS, UNBOUNDED_AVAILABLE_SLOTS, buildInferenceAdvertisedModels, summarizeInferenceHostRuntimeRecovery, FileInferenceHostRuntimeReceiptStore, InferenceHostRecoveryRequiredError, InferenceHostRunnerError, defaultSleep, abortError, settlesWithin, defaultRegisterSignalHandlers, safeInteger, exactObjectKeys, validIso, validateAttemptReceipt, validateRuntimeReceipt, sha256, stableOperationId, buildAttemptStartRequest, isoAt, providerWeeklyQuotaFromRateLimits, finitePositiveOption, validateRunnerOptions, assertLocalCredentialIdentity, retryableRemoteError, remoteRetryAfterMs, controlPlaneFatal, defaultValidateOutput, objectRecord, positiveUtf8ByteLimit, assertCompilableOutputSchema, parseOutputContract, membershipFailureDisposition, safeFailureCode, attemptStartRetryFallbackMs, exactJson2, runnerIdentityMismatch, assertAdvertisementResult, assertHostHeartbeatResult, assertClaimResult, assertStartResult, assertJobHeartbeatResult, assertTerminalResult, isDefinitiveCompletionEvidenceExpiry, classifyFailure, ambiguousHeartbeatTransport, reportedTokenUsage, reportedUsage, InferenceHostRunner, createInferenceAgentControlClient, INFERENCE_AGENT_SYSTEM_PROMPT, INFERENCE_AGENT_WAKE_SCHEMA, parseInferenceAgentWake, InferenceAgentRuntime;
|
|
32430
32431
|
var init_runner = __esm({
|
|
32431
32432
|
"lib/inference-host/runner.ts"() {
|
|
32432
32433
|
"use strict";
|
|
@@ -33050,6 +33051,7 @@ var init_runner = __esm({
|
|
|
33050
33051
|
if (failure.state !== request.attempt_status || failure.failure_category !== request.failure_category || failure.failure_code !== request.failure_code) runnerIdentityMismatch("Job failure receipt");
|
|
33051
33052
|
}
|
|
33052
33053
|
};
|
|
33054
|
+
isDefinitiveCompletionEvidenceExpiry = (error48, terminal) => terminal?.schema_version === "external_inference_job_complete_v1" && error48 instanceof ExternalInferenceMcpError && error48.code === "completion_evidence_expired" && error48.definitivelyNotApplied;
|
|
33053
33055
|
classifyFailure = (error48, result2) => {
|
|
33054
33056
|
if (error48 instanceof CodexAppServerError) {
|
|
33055
33057
|
const category2 = error48.code === "quota_exceeded" ? "quota" : error48.category;
|
|
@@ -33907,10 +33909,19 @@ var init_runner = __esm({
|
|
|
33907
33909
|
}
|
|
33908
33910
|
return attemptId;
|
|
33909
33911
|
};
|
|
33910
|
-
const removeRecoveredAttempt = async (
|
|
33912
|
+
const removeRecoveredAttempt = async (recovery) => {
|
|
33911
33913
|
await mutateReceipt((current) => {
|
|
33914
|
+
const persisted = current.attempts[recovery.attempt_id];
|
|
33915
|
+
const persistedTerminal = persisted?.terminal_request;
|
|
33916
|
+
const recoveryTerminal = recovery.terminal_request;
|
|
33917
|
+
const sameTerminalRequest = Boolean(
|
|
33918
|
+
persistedTerminal && recoveryTerminal && persistedTerminal.schema_version === recoveryTerminal.schema_version && (persistedTerminal.schema_version === "external_inference_job_complete_v1" && recoveryTerminal.schema_version === "external_inference_job_complete_v1" && persistedTerminal.completion_id === recoveryTerminal.completion_id || persistedTerminal.schema_version === "external_inference_job_fail_v1" && recoveryTerminal.schema_version === "external_inference_job_fail_v1" && persistedTerminal.failure_id === recoveryTerminal.failure_id)
|
|
33919
|
+
);
|
|
33920
|
+
if (persisted?.phase !== "terminal_pending" || persisted.job_id !== recovery.job_id || persisted.terminal_operation_id !== recovery.terminal_operation_id || !sameTerminalRequest) {
|
|
33921
|
+
return current;
|
|
33922
|
+
}
|
|
33912
33923
|
const attempts = { ...current.attempts };
|
|
33913
|
-
delete attempts[
|
|
33924
|
+
delete attempts[recovery.attempt_id];
|
|
33914
33925
|
return { ...current, attempts, updated_at: isoAt(now()) };
|
|
33915
33926
|
});
|
|
33916
33927
|
};
|
|
@@ -33936,8 +33947,22 @@ var init_runner = __esm({
|
|
|
33936
33947
|
failed += 1;
|
|
33937
33948
|
}
|
|
33938
33949
|
await this.dependencies.codexAdapter.acknowledgeAttempt?.(recovery.attempt_id);
|
|
33939
|
-
await removeRecoveredAttempt(recovery
|
|
33950
|
+
await removeRecoveredAttempt(recovery);
|
|
33940
33951
|
} catch (error48) {
|
|
33952
|
+
if (isDefinitiveCompletionEvidenceExpiry(error48, recovery.terminal_request)) {
|
|
33953
|
+
await this.dependencies.codexAdapter.acknowledgeAttempt?.(recovery.attempt_id);
|
|
33954
|
+
await removeRecoveredAttempt(recovery);
|
|
33955
|
+
failed += 1;
|
|
33956
|
+
emitDiagnostic("terminal_recovery_retired", {
|
|
33957
|
+
job_id: recovery.job_id,
|
|
33958
|
+
attempt_id: recovery.attempt_id,
|
|
33959
|
+
attempt_phase: recovery.phase,
|
|
33960
|
+
terminal_operation: "complete",
|
|
33961
|
+
error_code: error48.code,
|
|
33962
|
+
definitively_not_applied: true
|
|
33963
|
+
});
|
|
33964
|
+
continue;
|
|
33965
|
+
}
|
|
33941
33966
|
emitTerminalRecoveryFailure(recovery, error48);
|
|
33942
33967
|
requestDrain(controlPlaneFatal(error48) ? "authority_lost" : "attempt_terminal_unconfirmed");
|
|
33943
33968
|
break;
|
|
@@ -34568,6 +34593,22 @@ var init_runner = __esm({
|
|
|
34568
34593
|
assertTerminalResult(completion, completionResult);
|
|
34569
34594
|
await this.dependencies.codexAdapter.acknowledgeAttempt?.(attemptId);
|
|
34570
34595
|
} catch (error48) {
|
|
34596
|
+
if (isDefinitiveCompletionEvidenceExpiry(error48, completion)) {
|
|
34597
|
+
await this.dependencies.codexAdapter.acknowledgeAttempt?.(attemptId);
|
|
34598
|
+
await stopHeartbeat();
|
|
34599
|
+
await removeAttempt();
|
|
34600
|
+
options.onAttemptOutcome?.({
|
|
34601
|
+
outcome: "failed",
|
|
34602
|
+
failure_category: "deadline",
|
|
34603
|
+
failure_code: error48.code,
|
|
34604
|
+
retryable: false,
|
|
34605
|
+
dispatch_outcome: completion.outcome.dispatch_outcome,
|
|
34606
|
+
response_outcome: "none",
|
|
34607
|
+
latency_ms: completion.latency_ms,
|
|
34608
|
+
usage: completion.usage
|
|
34609
|
+
});
|
|
34610
|
+
return "failed";
|
|
34611
|
+
}
|
|
34571
34612
|
throw new InferenceHostRunnerError(
|
|
34572
34613
|
"terminal_outcome_unconfirmed",
|
|
34573
34614
|
"The exact completion receipt could not be confirmed; redispatch is fenced.",
|
|
@@ -35280,7 +35321,7 @@ import { createWriteStream, readFileSync } from "node:fs";
|
|
|
35280
35321
|
import { access as access3, chmod as chmod3, mkdir as mkdir3, readFile as readFile5, rm as rm6, writeFile as writeFile2 } from "node:fs/promises";
|
|
35281
35322
|
import { homedir as homedir2 } from "node:os";
|
|
35282
35323
|
import { dirname as dirname5, join as join7, resolve as resolve4 } from "node:path";
|
|
35283
|
-
var SERVICE_NAME, SYSTEMD_UNIT, LAUNCHD_LABEL, SERVICE_COOPERATIVE_STOP_SECONDS, INFERENCE_HOST_SERVICE_DRAIN_COMMAND, inferenceHostServiceChildEnvironment, isWindowsSubsystemForLinux, inferenceHostServiceManifestPath, inferenceHostServiceDesiredPath, inferenceHostServiceLogPath, inferenceHostServiceRuntimePath, xmlEscape, plistEscape, systemdQuote, defaultRunCommand, managerName, assertRuntimeEnvironment, withoutConcurrencyLimit, assertServicePath, manifestGeneration, assertWorker, assertManifest, assertServiceRuntimeState, assertDesiredState, readInferenceHostServiceManifest, readManifestAcrossAtomicReplacement, readInferenceHostServiceRuntime, readRuntimeAcrossAtomicReplacement, readInferenceHostServiceDesired, readDesiredAcrossAtomicReplacement, writeDesired, runtimeEnvironment,
|
|
35324
|
+
var SERVICE_NAME, SYSTEMD_UNIT, LAUNCHD_LABEL, SERVICE_COOPERATIVE_STOP_SECONDS, SERVICE_UPDATE_STARTUP_SECONDS, INFERENCE_HOST_SERVICE_DRAIN_COMMAND, inferenceHostServiceChildEnvironment, isWindowsSubsystemForLinux, inferenceHostServiceManifestPath, inferenceHostServiceDesiredPath, inferenceHostServiceLogPath, inferenceHostServiceRuntimePath, xmlEscape, plistEscape, systemdQuote, defaultRunCommand, 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;
|
|
35284
35325
|
var init_service = __esm({
|
|
35285
35326
|
"lib/inference-host/service.ts"() {
|
|
35286
35327
|
"use strict";
|
|
@@ -35290,6 +35331,7 @@ var init_service = __esm({
|
|
|
35290
35331
|
SYSTEMD_UNIT = "vtx-inference-host.service";
|
|
35291
35332
|
LAUNCHD_LABEL = "com.vtxmacro.inference-host";
|
|
35292
35333
|
SERVICE_COOPERATIVE_STOP_SECONDS = 75;
|
|
35334
|
+
SERVICE_UPDATE_STARTUP_SECONDS = 600;
|
|
35293
35335
|
INFERENCE_HOST_SERVICE_DRAIN_COMMAND = "vtx-inference-host-service-drain-v1";
|
|
35294
35336
|
inferenceHostServiceChildEnvironment = (runtimeEnvironment2, inheritedEnvironment = process.env) => {
|
|
35295
35337
|
const environment = { ...inheritedEnvironment };
|
|
@@ -35594,13 +35636,12 @@ var init_service = __esm({
|
|
|
35594
35636
|
}
|
|
35595
35637
|
return result2;
|
|
35596
35638
|
};
|
|
35597
|
-
|
|
35598
|
-
|
|
35599
|
-
"inference-host",
|
|
35600
|
-
"service",
|
|
35601
|
-
"run-internal",
|
|
35639
|
+
serviceBootstrapArguments = (bootstrapScript, manifestPath, lockPath) => [
|
|
35640
|
+
bootstrapScript,
|
|
35602
35641
|
"--service-manifest",
|
|
35603
|
-
manifestPath
|
|
35642
|
+
manifestPath,
|
|
35643
|
+
"--service-lock",
|
|
35644
|
+
lockPath
|
|
35604
35645
|
];
|
|
35605
35646
|
windowsOwnedCommandLine = (values) => {
|
|
35606
35647
|
if (values.some((value) => value.includes('"') || value.includes("\0"))) {
|
|
@@ -35679,6 +35720,9 @@ WantedBy=default.target
|
|
|
35679
35720
|
this.home = dependencies.homedir ?? homedir2();
|
|
35680
35721
|
this.executable = resolve4(dependencies.executable ?? process.execPath);
|
|
35681
35722
|
this.script = resolve4(dependencies.script ?? process.argv[1] ?? "");
|
|
35723
|
+
this.bootstrapScript = resolve4(
|
|
35724
|
+
dependencies.bootstrapScript ?? join7(dirname5(this.script), "vtx-service-bootstrap.js")
|
|
35725
|
+
);
|
|
35682
35726
|
this.username = dependencies.username ?? ([process.env.USERDOMAIN, process.env.USERNAME].filter(Boolean).join("\\") || process.env.USER || "");
|
|
35683
35727
|
this.windowsDirectory = (dependencies.windowsDirectory ?? process.env.SystemRoot ?? process.env.WINDIR ?? "C:\\Windows").replace(/[\\/]+$/u, "");
|
|
35684
35728
|
this.runCommand = dependencies.runCommand ?? defaultRunCommand;
|
|
@@ -35710,6 +35754,21 @@ WantedBy=default.target
|
|
|
35710
35754
|
runtimePath() {
|
|
35711
35755
|
return inferenceHostServiceRuntimePath(this.config);
|
|
35712
35756
|
}
|
|
35757
|
+
serviceBootstrapPath() {
|
|
35758
|
+
return `${this.config.supervisorStatePath}.service-bootstrap.js`;
|
|
35759
|
+
}
|
|
35760
|
+
serviceReleasePath() {
|
|
35761
|
+
return `${this.config.supervisorStatePath}.service-release.json`;
|
|
35762
|
+
}
|
|
35763
|
+
serviceReleaseRejectionPath() {
|
|
35764
|
+
return `${this.config.supervisorStatePath}.service-release-rejection.json`;
|
|
35765
|
+
}
|
|
35766
|
+
serviceReleasesPath() {
|
|
35767
|
+
return `${this.config.supervisorStatePath}.service-releases`;
|
|
35768
|
+
}
|
|
35769
|
+
serviceBootstrapLockPath() {
|
|
35770
|
+
return `${this.config.supervisorProcessLockPath}.service-bootstrap`;
|
|
35771
|
+
}
|
|
35713
35772
|
controlLockPath() {
|
|
35714
35773
|
return `${this.config.supervisorProcessLockPath}.service-control`;
|
|
35715
35774
|
}
|
|
@@ -35754,6 +35813,18 @@ WantedBy=default.target
|
|
|
35754
35813
|
windowsLauncherPath() {
|
|
35755
35814
|
return `${this.config.supervisorStatePath}.service-launcher.vbs`;
|
|
35756
35815
|
}
|
|
35816
|
+
async hasBootstrapDefinition() {
|
|
35817
|
+
try {
|
|
35818
|
+
await access3(this.serviceBootstrapPath());
|
|
35819
|
+
const definition = await readFile5(
|
|
35820
|
+
this.platform === "win32" ? this.windowsLauncherPath() : this.definitionPath(),
|
|
35821
|
+
"utf8"
|
|
35822
|
+
);
|
|
35823
|
+
return definition.includes(this.serviceBootstrapPath());
|
|
35824
|
+
} catch {
|
|
35825
|
+
return false;
|
|
35826
|
+
}
|
|
35827
|
+
}
|
|
35757
35828
|
async managerCommand(action) {
|
|
35758
35829
|
const definition = this.definitionPath();
|
|
35759
35830
|
if (this.platform === "win32") {
|
|
@@ -35875,13 +35946,23 @@ ${result2.stderr}`)) {
|
|
|
35875
35946
|
);
|
|
35876
35947
|
}
|
|
35877
35948
|
async registerManifestUnlocked(manifest, desiredRunning, targetInstanceName) {
|
|
35878
|
-
|
|
35949
|
+
await access3(this.bootstrapScript);
|
|
35950
|
+
const args = serviceBootstrapArguments(
|
|
35951
|
+
this.serviceBootstrapPath(),
|
|
35952
|
+
this.manifestPath(),
|
|
35953
|
+
this.serviceBootstrapLockPath()
|
|
35954
|
+
);
|
|
35879
35955
|
const definition = this.platform === "win32" ? windowsTaskXml(this.windowsLauncherPath(), this.windowsDirectory, this.username) : this.platform === "darwin" ? launchAgentPlist(manifest.executable, args, manifest.log_path) : systemdUnit(manifest.executable, args);
|
|
35880
35956
|
let managerInstallAttempted = false;
|
|
35881
35957
|
try {
|
|
35882
35958
|
await writeAtomicInferencePrivateFile(this.manifestPath(), `${JSON.stringify(manifest, null, 2)}
|
|
35883
35959
|
`);
|
|
35884
35960
|
await writeDesired(this.desiredPath(), desiredRunning, this.now());
|
|
35961
|
+
await writeAtomicInferencePrivateFile(
|
|
35962
|
+
this.serviceBootstrapPath(),
|
|
35963
|
+
await readFile5(this.bootstrapScript, "utf8")
|
|
35964
|
+
);
|
|
35965
|
+
await chmod3(this.serviceBootstrapPath(), 448);
|
|
35885
35966
|
await mkdir3(dirname5(this.definitionPath()), { recursive: true, mode: 448 });
|
|
35886
35967
|
if (this.platform === "win32") {
|
|
35887
35968
|
await writeAtomicInferencePrivateFile(
|
|
@@ -35911,7 +35992,11 @@ ${started.stderr}`)) {
|
|
|
35911
35992
|
}
|
|
35912
35993
|
await this.waitForManagerActive();
|
|
35913
35994
|
if (this.confirmInitialReadiness) {
|
|
35914
|
-
await this.waitForManifestApplied(
|
|
35995
|
+
await this.waitForManifestApplied(
|
|
35996
|
+
manifest,
|
|
35997
|
+
targetInstanceName,
|
|
35998
|
+
Math.max(this.reconcileWaitAttempts, SERVICE_UPDATE_STARTUP_SECONDS * 4)
|
|
35999
|
+
);
|
|
35915
36000
|
}
|
|
35916
36001
|
}
|
|
35917
36002
|
return await this.status();
|
|
@@ -35938,6 +36023,7 @@ ${cleanup.stderr}`)) {
|
|
|
35938
36023
|
await rm6(this.manifestPath(), { force: true }).catch(() => void 0);
|
|
35939
36024
|
await rm6(this.desiredPath(), { force: true }).catch(() => void 0);
|
|
35940
36025
|
await rm6(this.runtimePath(), { force: true }).catch(() => void 0);
|
|
36026
|
+
await rm6(this.serviceBootstrapPath(), { force: true }).catch(() => void 0);
|
|
35941
36027
|
if (this.platform === "linux") {
|
|
35942
36028
|
await this.runCommand("systemctl", ["--user", "daemon-reload"]).catch(() => void 0);
|
|
35943
36029
|
}
|
|
@@ -35947,10 +36033,11 @@ ${cleanup.stderr}`)) {
|
|
|
35947
36033
|
async replaceManifestUnlocked(next, desiredRunning, targetInstanceName) {
|
|
35948
36034
|
const previous = await readInferenceHostServiceManifest(this.manifestPath());
|
|
35949
36035
|
const previousDesired = previous ? await readInferenceHostServiceDesired(this.desiredPath()) : false;
|
|
35950
|
-
|
|
36036
|
+
const hasBootstrapDefinition = previous ? await this.hasBootstrapDefinition() : false;
|
|
36037
|
+
if (previous && sameServiceDefinition(previous, next) && sameWorkerSet(previous, next) && previousDesired === desiredRunning && hasBootstrapDefinition) {
|
|
35951
36038
|
return await this.status();
|
|
35952
36039
|
}
|
|
35953
|
-
if (previous && previousDesired && desiredRunning && sameServiceDefinition(previous, next)) {
|
|
36040
|
+
if (previous && previousDesired && desiredRunning && sameServiceDefinition(previous, next) && hasBootstrapDefinition) {
|
|
35954
36041
|
const current = await this.status();
|
|
35955
36042
|
const runtime = await readRuntimeAcrossAtomicReplacement(this.runtimePath()).catch(() => null);
|
|
35956
36043
|
if (current.manager_active && runtime?.manifest_generation === previous.generation) {
|
|
@@ -36070,6 +36157,7 @@ ${cleanup.stderr}`)) {
|
|
|
36070
36157
|
}
|
|
36071
36158
|
await access3(this.executable);
|
|
36072
36159
|
await access3(this.script);
|
|
36160
|
+
await access3(this.bootstrapScript);
|
|
36073
36161
|
const maxConcurrency = options.maxConcurrency ?? null;
|
|
36074
36162
|
const workers = [
|
|
36075
36163
|
...existing?.workers.filter((worker) => worker.instance_name !== this.config.instanceName) ?? [],
|
|
@@ -36195,25 +36283,34 @@ ${result2.stderr}`)) {
|
|
|
36195
36283
|
const restoreOnFailure = await readInferenceHostServiceDesired(this.desiredPath());
|
|
36196
36284
|
await writeDesired(this.desiredPath(), false, this.now());
|
|
36197
36285
|
try {
|
|
36198
|
-
const
|
|
36286
|
+
const serviceLockPaths = [
|
|
36287
|
+
`${this.config.supervisorProcessLockPath}.service`,
|
|
36288
|
+
this.serviceBootstrapLockPath()
|
|
36289
|
+
];
|
|
36199
36290
|
let serviceReleased = false;
|
|
36200
36291
|
for (let attempt = 0; attempt < this.stopWaitAttempts; attempt += 1) {
|
|
36201
|
-
|
|
36202
|
-
|
|
36203
|
-
|
|
36292
|
+
let allReleased = true;
|
|
36293
|
+
for (const serviceLockPath of serviceLockPaths) {
|
|
36294
|
+
try {
|
|
36295
|
+
const probe = await this.acquireProcessLock(serviceLockPath);
|
|
36296
|
+
await probe.release();
|
|
36297
|
+
} catch (error48) {
|
|
36298
|
+
if (error48 instanceof Error && error48.message.includes("Another inference host process already owns")) {
|
|
36299
|
+
allReleased = false;
|
|
36300
|
+
break;
|
|
36301
|
+
}
|
|
36302
|
+
throw error48;
|
|
36303
|
+
}
|
|
36304
|
+
}
|
|
36305
|
+
if (allReleased) {
|
|
36204
36306
|
serviceReleased = true;
|
|
36205
36307
|
break;
|
|
36206
|
-
} catch (error48) {
|
|
36207
|
-
if (error48 instanceof Error && error48.message.includes("Another inference host process already owns")) {
|
|
36208
|
-
await this.sleep(250);
|
|
36209
|
-
continue;
|
|
36210
|
-
}
|
|
36211
|
-
throw error48;
|
|
36212
36308
|
}
|
|
36309
|
+
await this.sleep(250);
|
|
36213
36310
|
}
|
|
36214
36311
|
if (!serviceReleased) {
|
|
36215
36312
|
throw new Error(
|
|
36216
|
-
`Inference-host workers did not stop cooperatively within ${SERVICE_COOPERATIVE_STOP_SECONDS} seconds; refusing forced termination while cleanup may be pending.`
|
|
36313
|
+
`Inference-host updater or workers did not stop cooperatively within ${SERVICE_COOPERATIVE_STOP_SECONDS} seconds; refusing forced termination while cleanup may be pending.`
|
|
36217
36314
|
);
|
|
36218
36315
|
}
|
|
36219
36316
|
const result2 = await this.managerCommand("stop");
|
|
@@ -36329,6 +36426,10 @@ ${result2.stderr}`)) {
|
|
|
36329
36426
|
await rm6(this.manifestPath(), { force: true });
|
|
36330
36427
|
await rm6(this.desiredPath(), { force: true });
|
|
36331
36428
|
await rm6(this.runtimePath(), { force: true });
|
|
36429
|
+
await rm6(this.serviceBootstrapPath(), { force: true });
|
|
36430
|
+
await rm6(this.serviceReleasePath(), { force: true });
|
|
36431
|
+
await rm6(this.serviceReleaseRejectionPath(), { force: true });
|
|
36432
|
+
await rm6(this.serviceReleasesPath(), { recursive: true, force: true });
|
|
36332
36433
|
return {
|
|
36333
36434
|
installed: false,
|
|
36334
36435
|
desired_running: false,
|
|
@@ -36461,8 +36562,11 @@ ${result2.stderr}`)) {
|
|
|
36461
36562
|
});
|
|
36462
36563
|
};
|
|
36463
36564
|
runInferenceHostServiceSupervisor = async (manifestPath, options = {}) => {
|
|
36464
|
-
const
|
|
36465
|
-
if (!
|
|
36565
|
+
const storedInitialManifest = await readInferenceHostServiceManifest(manifestPath);
|
|
36566
|
+
if (!storedInitialManifest) throw new Error("Inference-host service manifest is missing.");
|
|
36567
|
+
const serviceScript = options.serviceScript ? resolve4(options.serviceScript) : null;
|
|
36568
|
+
const withServiceScript = (manifest) => serviceScript ? { ...manifest, script: serviceScript } : manifest;
|
|
36569
|
+
const initialManifest = withServiceScript(storedInitialManifest);
|
|
36466
36570
|
const desiredPath = manifestPath.replace(/\.service\.json$/u, ".service-desired.json");
|
|
36467
36571
|
const runtimePath = manifestPath.replace(/\.service\.json$/u, ".service-runtime.json");
|
|
36468
36572
|
const signal = options.signal ?? new AbortController().signal;
|
|
@@ -36659,15 +36763,17 @@ ${result2.stderr}`)) {
|
|
|
36659
36763
|
try {
|
|
36660
36764
|
while (!signal.aborted) {
|
|
36661
36765
|
while (!signal.aborted && await readDesiredAcrossAtomicReplacement(desiredPath)) {
|
|
36662
|
-
const
|
|
36663
|
-
if (!
|
|
36766
|
+
const storedNext = await readManifestAcrossAtomicReplacement(manifestPath);
|
|
36767
|
+
if (!storedNext) throw new Error("Inference-host service manifest is missing.");
|
|
36768
|
+
const next = withServiceScript(storedNext);
|
|
36664
36769
|
if (next.generation !== appliedManifest.generation && next.generation !== rejectedManifestGeneration) await reconcile(next);
|
|
36665
36770
|
await sleep4(250);
|
|
36666
36771
|
}
|
|
36667
36772
|
await drainWorkers();
|
|
36668
36773
|
if (signal.aborted || !await readDesiredAcrossAtomicReplacement(desiredPath)) break;
|
|
36669
|
-
const
|
|
36670
|
-
if (!
|
|
36774
|
+
const storedRestored = await readManifestAcrossAtomicReplacement(manifestPath);
|
|
36775
|
+
if (!storedRestored) throw new Error("Inference-host service manifest is missing.");
|
|
36776
|
+
const restored = withServiceScript(storedRestored);
|
|
36671
36777
|
await reconcile(restored);
|
|
36672
36778
|
await appendServiceLog(restored.log_path, "service_desired_state_restored", {
|
|
36673
36779
|
manifest_generation: restored.generation,
|
|
@@ -39406,7 +39512,8 @@ Waiting for approval...
|
|
|
39406
39512
|
await (dependencies.runServiceSupervisor ?? runInferenceHostServiceSupervisor)(
|
|
39407
39513
|
parsed.serviceManifestPath,
|
|
39408
39514
|
{
|
|
39409
|
-
signal: cancellation.signal
|
|
39515
|
+
signal: cancellation.signal,
|
|
39516
|
+
serviceScript: resolve5(process.argv[1] ?? "")
|
|
39410
39517
|
}
|
|
39411
39518
|
);
|
|
39412
39519
|
return { exitCode: 0, stdout: "", stderr: "" };
|
|
@@ -41762,12 +41869,13 @@ var init_hyperliquid_account_state_adapter = __esm({
|
|
|
41762
41869
|
buildUserFillsStorageKey = (cacheKey) => {
|
|
41763
41870
|
return `${USER_FILLS_CACHE_STORAGE_PREFIX}${cacheKey}`;
|
|
41764
41871
|
};
|
|
41765
|
-
buildAccountStateCacheKey = (apiUrl, walletAddress, symbol2, aggregatePerpDexs, dexNames, includeEffectiveTakerRate, includeExactAccountMode, includeActiveAssetData) => {
|
|
41872
|
+
buildAccountStateCacheKey = (apiUrl, walletAddress, symbol2, aggregatePerpDexs, scopeAccountSummaryToSelectedDex, dexNames, includeEffectiveTakerRate, includeExactAccountMode, includeActiveAssetData) => {
|
|
41766
41873
|
return [
|
|
41767
41874
|
apiUrl.replace(/\/$/, "").toLowerCase(),
|
|
41768
41875
|
walletAddress.trim().toLowerCase(),
|
|
41769
41876
|
normalizeHyperliquidMarketSymbol(symbol2),
|
|
41770
41877
|
aggregatePerpDexs ? "aggregate" : "selected",
|
|
41878
|
+
scopeAccountSummaryToSelectedDex ? "selected-summary" : "aggregate-summary",
|
|
41771
41879
|
includeEffectiveTakerRate ? "with-effective-taker-rate" : "without-effective-taker-rate",
|
|
41772
41880
|
includeExactAccountMode ? "with-exact-account-mode" : "without-exact-account-mode",
|
|
41773
41881
|
includeActiveAssetData ? "with-active-asset" : "without-active-asset",
|
|
@@ -42439,15 +42547,20 @@ var init_hyperliquid_account_state_adapter = __esm({
|
|
|
42439
42547
|
const activeAssetCacheKey = buildActiveAssetCacheKey(apiUrl, walletAddress, symbol2);
|
|
42440
42548
|
const activeAssetRequestTypes = getBrowserActiveAssetTypeCandidates(apiUrl, walletAddress, symbol2);
|
|
42441
42549
|
const aggregatePerpDexs = input.aggregatePerpDexs !== false;
|
|
42550
|
+
const scopeAccountSummaryToSelectedDex = input.scopeAccountSummaryToSelectedDex === true;
|
|
42442
42551
|
const includeEffectiveTakerRate = input.includeEffectiveTakerRate === true;
|
|
42443
42552
|
const includeExactAccountMode = input.includeExactAccountMode === true;
|
|
42444
42553
|
const includeActiveAssetData = input.includeActiveAssetData !== false;
|
|
42445
42554
|
const dexNames = listPerpDexsForAccountState(input.config, dex, aggregatePerpDexs);
|
|
42555
|
+
if (scopeAccountSummaryToSelectedDex && dex && !dexNames.includes(dex)) {
|
|
42556
|
+
dexNames.push(dex);
|
|
42557
|
+
}
|
|
42446
42558
|
const cacheKey = buildAccountStateCacheKey(
|
|
42447
42559
|
apiUrl,
|
|
42448
42560
|
walletAddress,
|
|
42449
42561
|
symbol2,
|
|
42450
42562
|
aggregatePerpDexs,
|
|
42563
|
+
scopeAccountSummaryToSelectedDex,
|
|
42451
42564
|
dexNames,
|
|
42452
42565
|
includeEffectiveTakerRate,
|
|
42453
42566
|
includeExactAccountMode,
|
|
@@ -42475,6 +42588,7 @@ var init_hyperliquid_account_state_adapter = __esm({
|
|
|
42475
42588
|
apiUrl,
|
|
42476
42589
|
walletAddress,
|
|
42477
42590
|
symbol: symbol2,
|
|
42591
|
+
selectedDex: dex,
|
|
42478
42592
|
activeAssetCacheKey,
|
|
42479
42593
|
activeAssetRequestTypes,
|
|
42480
42594
|
dexNames,
|
|
@@ -42514,6 +42628,7 @@ var init_hyperliquid_account_state_adapter = __esm({
|
|
|
42514
42628
|
apiUrl,
|
|
42515
42629
|
walletAddress,
|
|
42516
42630
|
symbol: symbol2,
|
|
42631
|
+
selectedDex,
|
|
42517
42632
|
activeAssetCacheKey,
|
|
42518
42633
|
activeAssetRequestTypes,
|
|
42519
42634
|
dexNames,
|
|
@@ -42538,11 +42653,22 @@ var init_hyperliquid_account_state_adapter = __esm({
|
|
|
42538
42653
|
if (input.includeEffectiveTakerRate === true) {
|
|
42539
42654
|
requirePromptClearinghouseState(response, dexName);
|
|
42540
42655
|
}
|
|
42541
|
-
return
|
|
42656
|
+
return {
|
|
42657
|
+
dex: dexName,
|
|
42658
|
+
payload: prefixHip3PositionCoins(response, dexName)
|
|
42659
|
+
};
|
|
42542
42660
|
})
|
|
42543
42661
|
);
|
|
42662
|
+
const selectedPayload = selectedDex ? dexResponses.find((entry) => entry.dex === selectedDex)?.payload : defaultResponse;
|
|
42663
|
+
if (!selectedPayload) {
|
|
42664
|
+
throw new Error(`Missing selected Hyperliquid clearinghouse state for DEX ${selectedDex}.`);
|
|
42665
|
+
}
|
|
42544
42666
|
return {
|
|
42545
|
-
payload: aggregateClearinghouseResponses([
|
|
42667
|
+
payload: aggregateClearinghouseResponses([
|
|
42668
|
+
defaultResponse,
|
|
42669
|
+
...dexResponses.map((entry) => entry.payload)
|
|
42670
|
+
]),
|
|
42671
|
+
selectedPayload,
|
|
42546
42672
|
capturedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
42547
42673
|
};
|
|
42548
42674
|
})();
|
|
@@ -42625,6 +42751,7 @@ var init_hyperliquid_account_state_adapter = __esm({
|
|
|
42625
42751
|
exactAccountModePromise
|
|
42626
42752
|
]);
|
|
42627
42753
|
const perpsResponse = perpsResult.payload;
|
|
42754
|
+
const accountSummaryPerpsResponse = input.scopeAccountSummaryToSelectedDex === true ? perpsResult.selectedPayload : perpsResponse;
|
|
42628
42755
|
const spotResponse = spotResult.payload;
|
|
42629
42756
|
const userFeesResponse = userFeesResult?.payload ?? null;
|
|
42630
42757
|
if (input.includeEffectiveTakerRate === true) {
|
|
@@ -42646,18 +42773,35 @@ var init_hyperliquid_account_state_adapter = __esm({
|
|
|
42646
42773
|
takerRate = parsedUserCrossRate;
|
|
42647
42774
|
}
|
|
42648
42775
|
const accountStateConfig = input.config.client_runtime_hyperliquid_account_state;
|
|
42649
|
-
const summaryPerpsResponse = exactAccountMode ? { ...
|
|
42776
|
+
const summaryPerpsResponse = exactAccountMode ? { ...accountSummaryPerpsResponse, accountMode: exactAccountMode.accountMode } : accountSummaryPerpsResponse;
|
|
42650
42777
|
const accountSummaryOptions = {
|
|
42651
42778
|
spotDominatesMinTotalUsd: accountStateConfig?.spot_dominates_min_total_usd,
|
|
42652
42779
|
spotDominatesPerpsMultiplier: accountStateConfig?.spot_dominates_perps_multiplier,
|
|
42653
42780
|
mirroredAccountValueAbsoluteToleranceUsd: accountStateConfig?.mirrored_account_value_absolute_tolerance_usd,
|
|
42654
42781
|
mirroredAccountValueRelativeTolerance: accountStateConfig?.mirrored_account_value_relative_tolerance
|
|
42655
42782
|
};
|
|
42656
|
-
const
|
|
42783
|
+
const walletSummary = exactAccountMode && input.scopeAccountSummaryToSelectedDex !== true ? buildServerPromptRescueAccountSummary(
|
|
42657
42784
|
perpsResponse,
|
|
42658
42785
|
spotResponse,
|
|
42659
42786
|
exactAccountMode.accountMode,
|
|
42660
42787
|
accountSummaryOptions
|
|
42788
|
+
) : buildAccountSummaryFromInfoResponses(
|
|
42789
|
+
perpsResponse,
|
|
42790
|
+
spotResponse,
|
|
42791
|
+
accountSummaryOptions
|
|
42792
|
+
);
|
|
42793
|
+
const normalizedSummary = input.scopeAccountSummaryToSelectedDex === true ? {
|
|
42794
|
+
...buildAccountSummaryFromInfoResponses(
|
|
42795
|
+
summaryPerpsResponse,
|
|
42796
|
+
{},
|
|
42797
|
+
accountSummaryOptions
|
|
42798
|
+
),
|
|
42799
|
+
balances: walletSummary.balances
|
|
42800
|
+
} : exactAccountMode ? buildServerPromptRescueAccountSummary(
|
|
42801
|
+
accountSummaryPerpsResponse,
|
|
42802
|
+
spotResponse,
|
|
42803
|
+
exactAccountMode.accountMode,
|
|
42804
|
+
accountSummaryOptions
|
|
42661
42805
|
) : buildAccountSummaryFromInfoResponses(
|
|
42662
42806
|
summaryPerpsResponse,
|
|
42663
42807
|
spotResponse,
|
|
@@ -42667,7 +42811,7 @@ var init_hyperliquid_account_state_adapter = __esm({
|
|
|
42667
42811
|
...normalizedSummary,
|
|
42668
42812
|
...exactAccountMode == null ? {} : { account_mode: exactAccountMode.accountMode, mode_source: "canonical" },
|
|
42669
42813
|
address: walletAddress,
|
|
42670
|
-
dex: "all",
|
|
42814
|
+
dex: input.scopeAccountSummaryToSelectedDex === true ? selectedDex : "all",
|
|
42671
42815
|
market_type: "perp"
|
|
42672
42816
|
};
|
|
42673
42817
|
const activeAssetPayload = activeAssetResult?.payload ?? null;
|
|
@@ -43504,9 +43648,12 @@ async function postClientRuntime(path, profileId, body, options) {
|
|
|
43504
43648
|
const numericProfileId = toNumericProfileId(profileId);
|
|
43505
43649
|
const keepalive = options?.keepalive === true;
|
|
43506
43650
|
const signal = options?.signal;
|
|
43651
|
+
const parsedRequestTimeoutMs = Number(options?.requestTimeoutMs);
|
|
43652
|
+
const requestTimeoutMs = Number.isFinite(parsedRequestTimeoutMs) && parsedRequestTimeoutMs > 0 ? Math.round(parsedRequestTimeoutMs) : null;
|
|
43507
43653
|
const maxAttempts = keepalive ? 1 : 3;
|
|
43508
43654
|
const requestContext = parseClientRuntimeRequestContext(body);
|
|
43509
|
-
const
|
|
43655
|
+
const explicitIdempotencyKey = String(options?.idempotencyKey ?? "").trim();
|
|
43656
|
+
const idempotencyKey = shouldAttachRuntimeIdempotencyKey(path) ? explicitIdempotencyKey || createIdempotencyKey(`runtime-${path.replace(/\//g, "-")}`) : null;
|
|
43510
43657
|
const requestHeaders = getProfileHeaders({
|
|
43511
43658
|
"Content-Type": "application/json"
|
|
43512
43659
|
}, numericProfileId);
|
|
@@ -43523,6 +43670,24 @@ async function postClientRuntime(path, profileId, body, options) {
|
|
|
43523
43670
|
let missingRuntimeLeaseRecoveryAttempted = false;
|
|
43524
43671
|
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
43525
43672
|
let response = null;
|
|
43673
|
+
let requestTimedOut = false;
|
|
43674
|
+
let timeoutId = null;
|
|
43675
|
+
let relayCallerAbort = null;
|
|
43676
|
+
let requestSignal = signal;
|
|
43677
|
+
if (requestTimeoutMs !== null) {
|
|
43678
|
+
const timeoutController = new AbortController();
|
|
43679
|
+
relayCallerAbort = () => timeoutController.abort(signal?.reason);
|
|
43680
|
+
if (signal?.aborted) {
|
|
43681
|
+
relayCallerAbort();
|
|
43682
|
+
} else {
|
|
43683
|
+
signal?.addEventListener("abort", relayCallerAbort, { once: true });
|
|
43684
|
+
}
|
|
43685
|
+
timeoutId = globalThis.setTimeout(() => {
|
|
43686
|
+
requestTimedOut = true;
|
|
43687
|
+
timeoutController.abort(new DOMException("Runtime request timeout reached.", "TimeoutError"));
|
|
43688
|
+
}, requestTimeoutMs);
|
|
43689
|
+
requestSignal = timeoutController.signal;
|
|
43690
|
+
}
|
|
43526
43691
|
const trace = startRuntimeNetworkDebugTrace({
|
|
43527
43692
|
kind: "runtime",
|
|
43528
43693
|
label: "client_runtime_api",
|
|
@@ -43535,7 +43700,7 @@ async function postClientRuntime(path, profileId, body, options) {
|
|
|
43535
43700
|
method: "POST",
|
|
43536
43701
|
credentials: "include",
|
|
43537
43702
|
keepalive,
|
|
43538
|
-
signal,
|
|
43703
|
+
signal: requestSignal,
|
|
43539
43704
|
headers: { ...requestHeaders },
|
|
43540
43705
|
body
|
|
43541
43706
|
});
|
|
@@ -43543,7 +43708,11 @@ async function postClientRuntime(path, profileId, body, options) {
|
|
|
43543
43708
|
const error48 = await createRuntimeRequestError(response, "Client runtime request failed");
|
|
43544
43709
|
if (!resolvedRuntimeLeaseToken && !missingRuntimeLeaseRecoveryAttempted && shouldRecoverMissingRuntimeLease(path, requestContext, keepalive) && isMissingRuntimeLeaseError(response.status, error48.message)) {
|
|
43545
43710
|
missingRuntimeLeaseRecoveryAttempted = true;
|
|
43546
|
-
const recoveredRuntimeLeaseToken = await recoverMissingRuntimeLease(
|
|
43711
|
+
const recoveredRuntimeLeaseToken = await recoverMissingRuntimeLease(
|
|
43712
|
+
numericProfileId,
|
|
43713
|
+
requestContext,
|
|
43714
|
+
requestSignal
|
|
43715
|
+
);
|
|
43547
43716
|
if (recoveredRuntimeLeaseToken) {
|
|
43548
43717
|
resolvedRuntimeLeaseToken = recoveredRuntimeLeaseToken;
|
|
43549
43718
|
attachRuntimeLeaseHeader(requestHeaders, resolvedRuntimeLeaseToken);
|
|
@@ -43561,7 +43730,7 @@ async function postClientRuntime(path, profileId, body, options) {
|
|
|
43561
43730
|
hadRuntimeLeaseToken: Boolean(resolvedRuntimeLeaseToken),
|
|
43562
43731
|
leaseCleared: shouldClearLease
|
|
43563
43732
|
});
|
|
43564
|
-
if (!keepalive && attempt < maxAttempts && !shouldClearLease && shouldRetryClientRuntimeHttpStatus(path, response.status)) {
|
|
43733
|
+
if (!keepalive && attempt < maxAttempts && !shouldClearLease && (shouldRetryClientRuntimeHttpStatus(path, response.status) || isRuntimeIdempotencyInProgressError(response.status, error48.message) || Boolean(idempotencyKey) && isRetryableRuntimeConflictError(response.status, error48))) {
|
|
43565
43734
|
await sleep2(resolveClientRuntimeRetryDelayMs(attempt, response.headers.get("Retry-After")));
|
|
43566
43735
|
continue;
|
|
43567
43736
|
}
|
|
@@ -43576,10 +43745,11 @@ async function postClientRuntime(path, profileId, body, options) {
|
|
|
43576
43745
|
trace.completeSuccess(response.status);
|
|
43577
43746
|
return payload;
|
|
43578
43747
|
} catch (error48) {
|
|
43579
|
-
|
|
43580
|
-
|
|
43581
|
-
|
|
43582
|
-
|
|
43748
|
+
const requestError = requestTimedOut && !signal?.aborted ? new TypeError("Runtime request timeout reached.") : error48;
|
|
43749
|
+
lastNetworkError = requestError;
|
|
43750
|
+
trace.completeError(requestError, response?.status ?? null);
|
|
43751
|
+
if (signal?.aborted || !requestTimedOut && !isTransientNetworkFetchError(requestError) || attempt >= maxAttempts) {
|
|
43752
|
+
throw annotateRuntimeRequestError(requestError, {
|
|
43583
43753
|
path,
|
|
43584
43754
|
method: "POST",
|
|
43585
43755
|
attempt,
|
|
@@ -43591,6 +43761,13 @@ async function postClientRuntime(path, profileId, body, options) {
|
|
|
43591
43761
|
}
|
|
43592
43762
|
await sleep2(resolveClientRuntimeRetryDelayMs(attempt, null));
|
|
43593
43763
|
continue;
|
|
43764
|
+
} finally {
|
|
43765
|
+
if (timeoutId !== null) {
|
|
43766
|
+
globalThis.clearTimeout(timeoutId);
|
|
43767
|
+
}
|
|
43768
|
+
if (signal && relayCallerAbort) {
|
|
43769
|
+
signal.removeEventListener("abort", relayCallerAbort);
|
|
43770
|
+
}
|
|
43594
43771
|
}
|
|
43595
43772
|
}
|
|
43596
43773
|
if (lastNetworkError instanceof Error) {
|
|
@@ -43793,7 +43970,7 @@ async function reconcileActiveClientRuntimeExchangeMutation(profileId, requestOp
|
|
|
43793
43970
|
}
|
|
43794
43971
|
return rememberCompletedDeferredClientRuntimeStop(profileId, result2);
|
|
43795
43972
|
}
|
|
43796
|
-
var getApiUrl, API_URL, sleep2, isTransientNetworkFetchError, createIdempotencyKey, getErrorMessage, getErrorPayloadOrEmpty, getErrorPayloadOrFallbackDetail, getErrorMessageFromResponse, _activeProfileId, PROFILE_STORAGE_KEY, preferencesWriteQueue, CLIENT_SUPPORTED_PROMPT_CONTRACT_VERSION, completedDeferredClientRuntimeStops, rememberCompletedDeferredClientRuntimeStop, toNumericProfileId, shouldAttachRuntimeIdempotencyKey, attachRuntimeLeaseHeader, resolveRuntimeLeaseToken, persistRuntimeLeaseFromPayload, persistRuntimeLeaseStatusMetadata, shouldClearPersistedRuntimeLeaseOnError, isMissingRuntimeLeaseError, createRuntimeRequestError, parseClientRuntimeRequestContext, recordRuntimeAuthFailureBreadcrumb, classifyRuntimeRequestError, annotateRuntimeRequestError, parseRuntimeRetryAfterMs, shouldRecoverMissingRuntimeLease, recoverMissingRuntimeLease, isRetryableClientRuntimeStatus, shouldRetryClientRuntimeHttpStatus, resolveClientRuntimeRetryDelayMs, CLIENT_EXCHANGE_AUTHORITY_DEVICE_KEY, CLIENT_EXCHANGE_AUTHORITY_SESSION_KEY, getOrCreateClientExchangeAuthorityIdentity, resolveClientExchangeMutationAuthority, clientExchangeMutationAuthorityBody, isPendingClientExchangeMutationError, clientExchangeMutationReconciliationTimers, MAX_CLIENT_EXCHANGE_RECONCILIATION_DELAY_MS, CLIENT_EXCHANGE_RECONCILIATION_CLOCK_SKEW_MS, ClientExchangeMutationRebuildRequiredError, isTerminalClientExchangeMutation, clientExchangeMutationReconciliationKey, clearScheduledClientExchangeMutationReconciliation, snapshotClientExchangeMutationReconciliationAuthority, postClientExchangeMutationReconciliation, scheduleClientExchangeMutationReconciliation;
|
|
43973
|
+
var getApiUrl, API_URL, sleep2, isTransientNetworkFetchError, createIdempotencyKey, getErrorMessage, getErrorPayloadOrEmpty, getErrorPayloadOrFallbackDetail, getErrorMessageFromResponse, _activeProfileId, PROFILE_STORAGE_KEY, preferencesWriteQueue, CLIENT_SUPPORTED_PROMPT_CONTRACT_VERSION, completedDeferredClientRuntimeStops, rememberCompletedDeferredClientRuntimeStop, toNumericProfileId, shouldAttachRuntimeIdempotencyKey, attachRuntimeLeaseHeader, resolveRuntimeLeaseToken, persistRuntimeLeaseFromPayload, persistRuntimeLeaseStatusMetadata, shouldClearPersistedRuntimeLeaseOnError, isMissingRuntimeLeaseError, createRuntimeRequestError, parseClientRuntimeRequestContext, recordRuntimeAuthFailureBreadcrumb, classifyRuntimeRequestError, annotateRuntimeRequestError, parseRuntimeRetryAfterMs, shouldRecoverMissingRuntimeLease, recoverMissingRuntimeLease, isRetryableClientRuntimeStatus, shouldRetryClientRuntimeHttpStatus, isRuntimeIdempotencyInProgressError, isRetryableRuntimeConflictError, resolveClientRuntimeRetryDelayMs, CLIENT_EXCHANGE_AUTHORITY_DEVICE_KEY, CLIENT_EXCHANGE_AUTHORITY_SESSION_KEY, getOrCreateClientExchangeAuthorityIdentity, resolveClientExchangeMutationAuthority, clientExchangeMutationAuthorityBody, isPendingClientExchangeMutationError, clientExchangeMutationReconciliationTimers, MAX_CLIENT_EXCHANGE_RECONCILIATION_DELAY_MS, CLIENT_EXCHANGE_RECONCILIATION_CLOCK_SKEW_MS, ClientExchangeMutationRebuildRequiredError, isTerminalClientExchangeMutation, clientExchangeMutationReconciliationKey, clearScheduledClientExchangeMutationReconciliation, snapshotClientExchangeMutationReconciliationAuthority, postClientExchangeMutationReconciliation, scheduleClientExchangeMutationReconciliation;
|
|
43797
43974
|
var init_api2 = __esm({
|
|
43798
43975
|
"lib/api.ts"() {
|
|
43799
43976
|
"use strict";
|
|
@@ -43992,7 +44169,9 @@ var init_api2 = __esm({
|
|
|
43992
44169
|
};
|
|
43993
44170
|
isMissingRuntimeLeaseError = (statusCode, message) => statusCode === 401 && String(message ?? "").trim().toLowerCase().includes("runtime lease required");
|
|
43994
44171
|
createRuntimeRequestError = async (response, defaultMessage) => {
|
|
43995
|
-
const
|
|
44172
|
+
const payload = await getErrorPayloadOrEmpty(response);
|
|
44173
|
+
const nestedDetail = payload.detail && typeof payload.detail === "object" && !Array.isArray(payload.detail) ? payload.detail : null;
|
|
44174
|
+
const rawMessage = getErrorMessage(payload, defaultMessage);
|
|
43996
44175
|
const walletCohortMessage = response.status === 409 ? {
|
|
43997
44176
|
client_wallet_unavailable: "The active profile wallet is unavailable. Save a wallet for this profile, then try again.",
|
|
43998
44177
|
client_wallet_mismatch: "The active profile wallet does not match this Client Mode session. Reload the profile, then try again.",
|
|
@@ -44001,6 +44180,15 @@ var init_api2 = __esm({
|
|
|
44001
44180
|
const message = walletCohortMessage ?? rawMessage;
|
|
44002
44181
|
const error48 = new Error(message);
|
|
44003
44182
|
error48.status = response.status;
|
|
44183
|
+
error48.detail = payload.detail;
|
|
44184
|
+
const code = typeof payload.code === "string" ? payload.code.trim() : typeof nestedDetail?.code === "string" ? nestedDetail.code.trim() : "";
|
|
44185
|
+
if (code) {
|
|
44186
|
+
error48.code = code;
|
|
44187
|
+
}
|
|
44188
|
+
const retryable = payload.retryable ?? nestedDetail?.retryable;
|
|
44189
|
+
if (typeof retryable === "boolean") {
|
|
44190
|
+
error48.retryable = retryable;
|
|
44191
|
+
}
|
|
44004
44192
|
return error48;
|
|
44005
44193
|
};
|
|
44006
44194
|
parseClientRuntimeRequestContext = (body) => {
|
|
@@ -44101,7 +44289,7 @@ var init_api2 = __esm({
|
|
|
44101
44289
|
}
|
|
44102
44290
|
return path === "/runtime/heartbeat" || path === "/runtime/analyze" || path === "/runtime/prompt-contract/metadata" || path === "/runtime/prompt-contract/derived-context" || path === "/runtime/prompt" || path === "/runtime/decision" || path === "/runtime/error" || path === "/runtime/trade-sync";
|
|
44103
44291
|
};
|
|
44104
|
-
recoverMissingRuntimeLease = async (profileId, requestContext) => {
|
|
44292
|
+
recoverMissingRuntimeLease = async (profileId, requestContext, signal) => {
|
|
44105
44293
|
if (!requestContext.sessionId || !requestContext.deviceId) {
|
|
44106
44294
|
return null;
|
|
44107
44295
|
}
|
|
@@ -44115,6 +44303,7 @@ var init_api2 = __esm({
|
|
|
44115
44303
|
method: "POST",
|
|
44116
44304
|
credentials: "include",
|
|
44117
44305
|
cache: "no-store",
|
|
44306
|
+
signal,
|
|
44118
44307
|
headers,
|
|
44119
44308
|
body: JSON.stringify({
|
|
44120
44309
|
session_id: requestContext.sessionId,
|
|
@@ -44129,7 +44318,10 @@ var init_api2 = __esm({
|
|
|
44129
44318
|
return null;
|
|
44130
44319
|
}
|
|
44131
44320
|
payload = await response.json();
|
|
44132
|
-
} catch {
|
|
44321
|
+
} catch (error48) {
|
|
44322
|
+
if (signal?.aborted) {
|
|
44323
|
+
throw signal.reason ?? error48;
|
|
44324
|
+
}
|
|
44133
44325
|
return null;
|
|
44134
44326
|
}
|
|
44135
44327
|
persistRuntimeLeaseFromPayload(payload);
|
|
@@ -44150,6 +44342,8 @@ var init_api2 = __esm({
|
|
|
44150
44342
|
}
|
|
44151
44343
|
return true;
|
|
44152
44344
|
};
|
|
44345
|
+
isRuntimeIdempotencyInProgressError = (status, message) => status === 409 && (message.toLowerCase().includes("duplicate request already in progress") || message.toLowerCase().includes("duplicate request in-flight"));
|
|
44346
|
+
isRetryableRuntimeConflictError = (status, error48) => status === 409 && error48.retryable === true && (error48.code === "profile_runtime_contract_busy" || error48.code === "runtime_trade_sync_finalizing");
|
|
44153
44347
|
resolveClientRuntimeRetryDelayMs = (attempt, retryAfterHeader) => {
|
|
44154
44348
|
const retryAfterMs = parseRuntimeRetryAfterMs(retryAfterHeader);
|
|
44155
44349
|
if (retryAfterMs != null) {
|