@vtxmacro/cli 2026.8.30 → 2026.8.32
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 +26 -0
- package/bin/vtx.js +758 -210
- package/package.json +1 -1
package/bin/vtx.js
CHANGED
|
@@ -38,7 +38,7 @@ var init_agent_cli_release = __esm({
|
|
|
38
38
|
"agent-cli-release.json"() {
|
|
39
39
|
agent_cli_release_default = {
|
|
40
40
|
package_name: "@vtxmacro/cli",
|
|
41
|
-
package_version: "2026.8.
|
|
41
|
+
package_version: "2026.8.32",
|
|
42
42
|
codex_package_name: "@openai/codex",
|
|
43
43
|
codex_version: "0.147.0",
|
|
44
44
|
platforms: {
|
|
@@ -14375,7 +14375,7 @@ var init_zod = __esm({
|
|
|
14375
14375
|
});
|
|
14376
14376
|
|
|
14377
14377
|
// lib/external-inference-contract.ts
|
|
14378
|
-
var EXTERNAL_INFERENCE_CONTRACT_VERSION, EXTERNAL_INFERENCE_CONTROLLER_SCHEMA_VERSION, EXTERNAL_INFERENCE_ADVERTISEMENT_SCHEMA_VERSION, EXTERNAL_INFERENCE_ENVELOPE_SCHEMA_VERSION, EXTERNAL_INFERENCE_JOB_INPUT_SCHEMA_VERSION, EXTERNAL_INFERENCE_USAGE_SCHEMA_VERSION, EXTERNAL_INFERENCE_INPUT_HASH_DOMAIN, MAX_EXTERNAL_INFERENCE_STATUS_HOSTS, MAX_GENERATION, MAX_SAFE_INTEGER, MAX_PROMPT_BYTES, MAX_IMMUTABLE_JOB_INPUT_BYTES, MAX_CANDIDATE_PLAINTEXT_BYTES, MAX_CIPHERTEXT_CHARS, SHA256_INITIAL_STATE, SHA256_ROUND_CONSTANTS, rotateRight, sha256BytesHex, sha256Utf8Hex, computeImmutableJobInputSha256, identifierSchema, operationIdentifierSchema, sha256HexSchema, generationSchema, zeroBasedGenerationSchema, nonNegativeSafeIntegerSchema, positiveSafeIntegerSchema, sqlIntegerTokenCountSchema, timestampSchema, safeCodeSchema, externalInferenceAdapterIdSchema, reasoningEffortSchema, modelNameSchema, displayNameSchema, authenticatedAccountEmailSchema, protocolVersionSchema, base64UrlAlphabet, isCanonicalBase64Url, base64Url32BytesSchema, base64UrlNonceSchema, base64UrlCiphertextSchema, claimHandleSchema, boundedJsonTextSchema, boundedPromptTextSchema, laneSchema, botModeSchema, executionModeSchema, responseModeSchema, dispatchOutcomeSchema, responseOutcomeSchema, nativeModelControllerSchema, externalAgentModelControllerSchema, externalAgentUnboundControllerSchema, liveModelControllerSchema, snapshotModelControllerSchema, modelIdentityMappingSchema, advertisedModelSchema, hostAdvertisementSchema, envelopeAadSchema, validateEnvelopeAad, commonEnvelopeShape, sealedKeyWrapEnvelopeSchema, sealedInputEnvelopeSchema, sealedCandidateEnvelopeSchema, sealedEnvelopeSchema, screenerCandidateRuntimeBindingSchema, screenerClientLeaseBindingSchema, screenerRuntimeBindingSchema, serverRuntimeBindingSchema, clientRuntimeBindingSchema, runtimeBindingSchema, immutableJobInputSchema, canonicalizeJsonValue, serializeImmutableJobInput, reportedTokenUsageSchema, unavailableTokenUsageSchema, tokenUsageSchema, agentConnectRequestSchema, agentNextRequestSchema, agentHeartbeatRequestSchema, emptyAgentNextResultSchema, claimedAgentNextResultSchema, agentNextResultSchema, agentCompleteRequestSchema, agentFailRequestSchema, requestedModelSelectionSchema, completedModelProvenanceSchema, attemptModelProvenanceSchema, hostHeartbeatRequestSchema, jobClaimRequestSchema, emptyJobClaimSchema, claimedJobSchema, jobClaimResultSchema, attemptStartRequestSchema, jobHeartbeatRequestSchema, continueHeartbeatDirectiveSchema, cancelHeartbeatDirectiveSchema, jobHeartbeatResultSchema, adapterOutcomeEvidenceSchema, completionBaseShape, validateCompletion, providerResponseCompletionSchema, decisionCandidateCompletionSchema, jobCompleteRequestSchema, jobFailRequestSchema, jobCancelRequestSchema, jobCancellationReceiptSchema, jobDeliveryRequestSchema, deliveryBaseShape, validateDeliveryCandidate, providerResponseDeliverySchema, decisionCandidateDeliverySchema, jobDeliveryResultSchema, jobConsumptionRequestSchema, jobConsumptionReceiptSchema, jobStateSchema, jobStatusReadSchema, hostStatusReadSchema, controllerBindingStatusReadSchema, queueStatusReadSchema, outcomeStatusReadSchema, externalInferenceStatusReadSchema, nativeResearchEvidenceSourceSchema, externalAgentResearchEvidenceSourceSchema, researchEvidenceSourceSchema, reportedResearchTokenUsageSchema, unavailableResearchTokenUsageSchema, researchTokenUsageSchema, externalInferenceProductLineageBaseShape, traderExternalInferenceProductLineageSchema, decisionChatExternalInferenceProductLineageSchema, screenerExternalInferenceProductLineageSchema, externalInferenceProductLineageSchema, normalProductLinkageSchema, evidenceMaterializationMarkerSchema, deliveredExternalAgentSourceIdentitySchema, deliveredRequestEvidenceSchema, researchEvidenceBaseShape, researchEvidenceBaseSchema, validateExactUtf8, validateResearchEvidence, providerResponseResearchEvidenceSchema, decisionCandidateResearchEvidenceSchema, researchEvidenceSchema;
|
|
14378
|
+
var EXTERNAL_INFERENCE_CONTRACT_VERSION, EXTERNAL_INFERENCE_CONTROLLER_SCHEMA_VERSION, EXTERNAL_INFERENCE_ADVERTISEMENT_SCHEMA_VERSION, EXTERNAL_INFERENCE_ENVELOPE_SCHEMA_VERSION, EXTERNAL_INFERENCE_JOB_INPUT_SCHEMA_VERSION, EXTERNAL_INFERENCE_USAGE_SCHEMA_VERSION, EXTERNAL_INFERENCE_INPUT_HASH_DOMAIN, MAX_EXTERNAL_INFERENCE_STATUS_HOSTS, MAX_GENERATION, MAX_SAFE_INTEGER, MAX_PROMPT_BYTES, MAX_IMMUTABLE_JOB_INPUT_BYTES, MAX_CANDIDATE_PLAINTEXT_BYTES, MAX_CIPHERTEXT_CHARS, SHA256_INITIAL_STATE, SHA256_ROUND_CONSTANTS, rotateRight, sha256BytesHex, sha256Utf8Hex, computeImmutableJobInputSha256, identifierSchema, operationIdentifierSchema, sha256HexSchema, generationSchema, zeroBasedGenerationSchema, nonNegativeSafeIntegerSchema, positiveSafeIntegerSchema, sqlIntegerTokenCountSchema, timestampSchema, safeCodeSchema, externalInferenceAdapterIdSchema, reasoningEffortSchema, modelNameSchema, displayNameSchema, authenticatedAccountEmailSchema, protocolVersionSchema, base64UrlAlphabet, isCanonicalBase64Url, base64Url32BytesSchema, base64UrlNonceSchema, base64UrlCiphertextSchema, claimHandleSchema, boundedJsonTextSchema, boundedPromptTextSchema, laneSchema, botModeSchema, executionModeSchema, responseModeSchema, dispatchOutcomeSchema, responseOutcomeSchema, nativeModelControllerSchema, externalAgentModelControllerSchema, externalAgentUnboundControllerSchema, liveModelControllerSchema, snapshotModelControllerSchema, modelIdentityMappingSchema, advertisedModelSchema, hostAdvertisementSchema, envelopeAadSchema, validateEnvelopeAad, commonEnvelopeShape, sealedKeyWrapEnvelopeSchema, sealedInputEnvelopeSchema, sealedCandidateEnvelopeSchema, sealedEnvelopeSchema, screenerCandidateRuntimeBindingSchema, screenerClientLeaseBindingSchema, screenerRuntimeBindingSchema, serverRuntimeBindingSchema, clientRuntimeBindingSchema, runtimeBindingSchema, immutableJobInputSchema, canonicalizeJsonValue, serializeImmutableJobInput, reportedTokenUsageSchema, unavailableTokenUsageSchema, tokenUsageSchema, agentConnectRequestSchema, agentNextRequestSchema, agentHeartbeatRequestSchema, emptyAgentNextResultSchema, claimedAgentNextResultSchema, agentNextResultSchema, agentCompleteRequestSchema, agentFailRequestSchema, requestedModelSelectionSchema, completedModelProvenanceSchema, attemptModelProvenanceSchema, providerWeeklyQuotaReadSchema, hostHeartbeatRequestSchema, jobClaimRequestSchema, emptyJobClaimSchema, claimedJobSchema, jobClaimResultSchema, attemptStartRequestSchema, jobHeartbeatRequestSchema, continueHeartbeatDirectiveSchema, cancelHeartbeatDirectiveSchema, jobHeartbeatResultSchema, adapterOutcomeEvidenceSchema, completionBaseShape, validateCompletion, providerResponseCompletionSchema, decisionCandidateCompletionSchema, jobCompleteRequestSchema, jobFailRequestSchema, jobCancelRequestSchema, jobCancellationReceiptSchema, jobDeliveryRequestSchema, deliveryBaseShape, validateDeliveryCandidate, providerResponseDeliverySchema, decisionCandidateDeliverySchema, jobDeliveryResultSchema, jobConsumptionRequestSchema, jobConsumptionReceiptSchema, jobStateSchema, jobStatusReadSchema, hostStatusReadSchema, controllerBindingStatusReadSchema, queueStatusReadSchema, outcomeStatusReadSchema, externalInferenceVolumeWindowReadSchema, externalInferenceFailureCountReadSchema, externalInferenceHostDiagnosticsReadSchema, externalInferenceProfileActivityReadSchema, externalInferenceStatusReadSchema, nativeResearchEvidenceSourceSchema, externalAgentResearchEvidenceSourceSchema, researchEvidenceSourceSchema, reportedResearchTokenUsageSchema, unavailableResearchTokenUsageSchema, researchTokenUsageSchema, externalInferenceProductLineageBaseShape, traderExternalInferenceProductLineageSchema, decisionChatExternalInferenceProductLineageSchema, screenerExternalInferenceProductLineageSchema, externalInferenceProductLineageSchema, normalProductLinkageSchema, evidenceMaterializationMarkerSchema, deliveredExternalAgentSourceIdentitySchema, deliveredRequestEvidenceSchema, researchEvidenceBaseShape, researchEvidenceBaseSchema, validateExactUtf8, validateResearchEvidence, providerResponseResearchEvidenceSchema, decisionCandidateResearchEvidenceSchema, researchEvidenceSchema;
|
|
14379
14379
|
var init_external_inference_contract = __esm({
|
|
14380
14380
|
"lib/external-inference-contract.ts"() {
|
|
14381
14381
|
"use strict";
|
|
@@ -15181,6 +15181,22 @@ var init_external_inference_contract = __esm({
|
|
|
15181
15181
|
});
|
|
15182
15182
|
}
|
|
15183
15183
|
});
|
|
15184
|
+
providerWeeklyQuotaReadSchema = external_exports.strictObject({
|
|
15185
|
+
source: external_exports.literal("codex_app_server"),
|
|
15186
|
+
used_percent: external_exports.number().finite().min(0).max(1e6),
|
|
15187
|
+
resets_at: timestampSchema,
|
|
15188
|
+
observed_at: timestampSchema
|
|
15189
|
+
}).superRefine((value, context) => {
|
|
15190
|
+
const observedAt = Date.parse(value.observed_at);
|
|
15191
|
+
const resetsAt = Date.parse(value.resets_at);
|
|
15192
|
+
if (resetsAt <= observedAt || resetsAt > observedAt + 8 * 24 * 60 * 60 * 1e3) {
|
|
15193
|
+
context.addIssue({
|
|
15194
|
+
code: "custom",
|
|
15195
|
+
message: "weekly quota reset must follow observation within eight days",
|
|
15196
|
+
path: ["resets_at"]
|
|
15197
|
+
});
|
|
15198
|
+
}
|
|
15199
|
+
});
|
|
15184
15200
|
hostHeartbeatRequestSchema = external_exports.strictObject({
|
|
15185
15201
|
schema_version: external_exports.literal("external_inference_host_heartbeat_v1"),
|
|
15186
15202
|
contract_version: external_exports.literal(EXTERNAL_INFERENCE_CONTRACT_VERSION),
|
|
@@ -15192,6 +15208,7 @@ var init_external_inference_contract = __esm({
|
|
|
15192
15208
|
status: external_exports.enum(["healthy", "degraded", "draining"]),
|
|
15193
15209
|
active_attempts: nonNegativeSafeIntegerSchema,
|
|
15194
15210
|
available_slots: nonNegativeSafeIntegerSchema,
|
|
15211
|
+
provider_weekly_quota: providerWeeklyQuotaReadSchema.nullable().optional(),
|
|
15195
15212
|
observed_at: timestampSchema
|
|
15196
15213
|
});
|
|
15197
15214
|
jobClaimRequestSchema = external_exports.strictObject({
|
|
@@ -15611,6 +15628,44 @@ var init_external_inference_contract = __esm({
|
|
|
15611
15628
|
cancelled: nonNegativeSafeIntegerSchema,
|
|
15612
15629
|
expired: nonNegativeSafeIntegerSchema
|
|
15613
15630
|
});
|
|
15631
|
+
externalInferenceVolumeWindowReadSchema = external_exports.strictObject({
|
|
15632
|
+
window_seconds: positiveSafeIntegerSchema,
|
|
15633
|
+
requests_started: nonNegativeSafeIntegerSchema,
|
|
15634
|
+
profiles_with_requests: nonNegativeSafeIntegerSchema,
|
|
15635
|
+
attempts_succeeded: nonNegativeSafeIntegerSchema,
|
|
15636
|
+
attempts_failed: nonNegativeSafeIntegerSchema,
|
|
15637
|
+
rate_limited: nonNegativeSafeIntegerSchema,
|
|
15638
|
+
quota_exhausted: nonNegativeSafeIntegerSchema,
|
|
15639
|
+
usage_reported: nonNegativeSafeIntegerSchema,
|
|
15640
|
+
usage_unavailable: nonNegativeSafeIntegerSchema,
|
|
15641
|
+
input_tokens: nonNegativeSafeIntegerSchema,
|
|
15642
|
+
output_tokens: nonNegativeSafeIntegerSchema,
|
|
15643
|
+
total_tokens: nonNegativeSafeIntegerSchema,
|
|
15644
|
+
reasoning_tokens: nonNegativeSafeIntegerSchema,
|
|
15645
|
+
cached_input_tokens: nonNegativeSafeIntegerSchema
|
|
15646
|
+
});
|
|
15647
|
+
externalInferenceFailureCountReadSchema = external_exports.strictObject({
|
|
15648
|
+
failure_category: safeCodeSchema.nullable(),
|
|
15649
|
+
failure_code: safeCodeSchema,
|
|
15650
|
+
count: positiveSafeIntegerSchema,
|
|
15651
|
+
last_observed_at: timestampSchema
|
|
15652
|
+
});
|
|
15653
|
+
externalInferenceHostDiagnosticsReadSchema = external_exports.strictObject({
|
|
15654
|
+
host_id: identifierSchema,
|
|
15655
|
+
active_attempts: nonNegativeSafeIntegerSchema,
|
|
15656
|
+
queue: queueStatusReadSchema,
|
|
15657
|
+
last_second: externalInferenceVolumeWindowReadSchema,
|
|
15658
|
+
last_minute: externalInferenceVolumeWindowReadSchema,
|
|
15659
|
+
last_hour: externalInferenceVolumeWindowReadSchema,
|
|
15660
|
+
last_day: externalInferenceVolumeWindowReadSchema,
|
|
15661
|
+
last_week: externalInferenceVolumeWindowReadSchema,
|
|
15662
|
+
recent_failures: external_exports.array(externalInferenceFailureCountReadSchema).max(32)
|
|
15663
|
+
});
|
|
15664
|
+
externalInferenceProfileActivityReadSchema = external_exports.strictObject({
|
|
15665
|
+
last_hour: externalInferenceVolumeWindowReadSchema,
|
|
15666
|
+
last_day: externalInferenceVolumeWindowReadSchema,
|
|
15667
|
+
last_week: externalInferenceVolumeWindowReadSchema
|
|
15668
|
+
});
|
|
15614
15669
|
externalInferenceStatusReadSchema = external_exports.strictObject({
|
|
15615
15670
|
schema_version: external_exports.literal("external_inference_status_v1"),
|
|
15616
15671
|
contract_version: external_exports.literal(EXTERNAL_INFERENCE_CONTRACT_VERSION),
|
|
@@ -15618,8 +15673,11 @@ var init_external_inference_contract = __esm({
|
|
|
15618
15673
|
catalog_generation: generationSchema,
|
|
15619
15674
|
hosts: external_exports.array(hostStatusReadSchema).max(MAX_EXTERNAL_INFERENCE_STATUS_HOSTS),
|
|
15620
15675
|
bindings: external_exports.array(controllerBindingStatusReadSchema).max(512),
|
|
15676
|
+
binding_count: nonNegativeSafeIntegerSchema.optional().default(0),
|
|
15677
|
+
bindings_truncated: external_exports.boolean().optional().default(false),
|
|
15621
15678
|
queue: queueStatusReadSchema,
|
|
15622
|
-
outcomes: outcomeStatusReadSchema
|
|
15679
|
+
outcomes: outcomeStatusReadSchema,
|
|
15680
|
+
host_diagnostics: external_exports.array(externalInferenceHostDiagnosticsReadSchema).max(MAX_EXTERNAL_INFERENCE_STATUS_HOSTS).optional().default([])
|
|
15623
15681
|
});
|
|
15624
15682
|
nativeResearchEvidenceSourceSchema = external_exports.strictObject({
|
|
15625
15683
|
source: external_exports.literal("native"),
|
|
@@ -16084,13 +16142,26 @@ import { spawn } from "node:child_process";
|
|
|
16084
16142
|
import { constants } from "node:fs";
|
|
16085
16143
|
import { lstat, mkdir, open, readFile, realpath, rename, rm } from "node:fs/promises";
|
|
16086
16144
|
import { homedir } from "node:os";
|
|
16087
|
-
import { dirname, join, relative, resolve } from "node:path";
|
|
16145
|
+
import { dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
16088
16146
|
function inferenceBaseDir(env) {
|
|
16089
16147
|
const configured = String(env.VTX_INFERENCE_HOST_HOME || "").trim();
|
|
16090
16148
|
return configured || join(homedir(), ".vtx", "inference-host");
|
|
16091
16149
|
}
|
|
16150
|
+
function normalizeInferenceHostInstanceName(raw) {
|
|
16151
|
+
const value = raw.trim().toLowerCase();
|
|
16152
|
+
if (!SAFE_INFERENCE_HOST_INSTANCE.test(value)) {
|
|
16153
|
+
throw new Error(
|
|
16154
|
+
"Inference host instance must be 1-48 lowercase letters, numbers, or hyphens, and cannot start or end with a hyphen."
|
|
16155
|
+
);
|
|
16156
|
+
}
|
|
16157
|
+
return value;
|
|
16158
|
+
}
|
|
16092
16159
|
function resolveInferenceHostConfig(env = process.env) {
|
|
16093
16160
|
const baseDir = inferenceBaseDir(env);
|
|
16161
|
+
const instanceName = normalizeInferenceHostInstanceName(
|
|
16162
|
+
String(env.VTX_INFERENCE_HOST_INSTANCE || DEFAULT_INFERENCE_HOST_INSTANCE)
|
|
16163
|
+
);
|
|
16164
|
+
const instanceDir = instanceName === DEFAULT_INFERENCE_HOST_INSTANCE ? baseDir : join(baseDir, "instances", instanceName);
|
|
16094
16165
|
const rawMode = String(env.VTX_INFERENCE_HOST_CREDENTIAL_STORE || "os").trim().toLowerCase();
|
|
16095
16166
|
if (rawMode !== "os" && rawMode !== "file") {
|
|
16096
16167
|
throw new Error("VTX_INFERENCE_HOST_CREDENTIAL_STORE must be os or file.");
|
|
@@ -16103,15 +16174,36 @@ function resolveInferenceHostConfig(env = process.env) {
|
|
|
16103
16174
|
"VTX_INFERENCE_HOST_CREDENTIAL_FILE requires explicit file credential-store mode."
|
|
16104
16175
|
);
|
|
16105
16176
|
}
|
|
16106
|
-
const credentialFilePath = rawMode === "file" ?
|
|
16177
|
+
const credentialFilePath = rawMode === "file" ? requireNamedInstancePath(
|
|
16178
|
+
instanceName,
|
|
16179
|
+
instanceDir,
|
|
16180
|
+
explicitCredentialPath,
|
|
16181
|
+
"VTX_INFERENCE_HOST_CREDENTIAL_FILE"
|
|
16182
|
+
) || join(instanceDir, "credentials.json") : null;
|
|
16183
|
+
const explicitStatePath = requireNamedInstancePath(
|
|
16184
|
+
instanceName,
|
|
16185
|
+
instanceDir,
|
|
16186
|
+
String(env.VTX_INFERENCE_HOST_STATE_PATH || "").trim(),
|
|
16187
|
+
"VTX_INFERENCE_HOST_STATE_PATH"
|
|
16188
|
+
);
|
|
16189
|
+
const explicitLockPath = requireNamedInstancePath(
|
|
16190
|
+
instanceName,
|
|
16191
|
+
instanceDir,
|
|
16192
|
+
String(env.VTX_INFERENCE_HOST_LOCK_PATH || "").trim(),
|
|
16193
|
+
"VTX_INFERENCE_HOST_LOCK_PATH"
|
|
16194
|
+
);
|
|
16107
16195
|
return {
|
|
16108
16196
|
apiUrl: String(env.VTX_API_URL || "https://api.vtxmacro.com").replace(/\/+$/, ""),
|
|
16197
|
+
baseDir,
|
|
16198
|
+
instanceName,
|
|
16109
16199
|
credentialStoreMode: rawMode,
|
|
16110
16200
|
credentialFilePath,
|
|
16111
16201
|
credentialStoreIdentity: credentialStoreIdentity(rawMode, credentialFilePath, env),
|
|
16112
|
-
codexHomePath: join(
|
|
16113
|
-
statePath:
|
|
16114
|
-
processLockPath:
|
|
16202
|
+
codexHomePath: join(instanceDir, "codex-home"),
|
|
16203
|
+
statePath: explicitStatePath || join(instanceDir, "state.json"),
|
|
16204
|
+
processLockPath: explicitLockPath || join(instanceDir, "host.lock"),
|
|
16205
|
+
supervisorStatePath: join(baseDir, "state.json"),
|
|
16206
|
+
supervisorProcessLockPath: join(baseDir, "host.lock")
|
|
16115
16207
|
};
|
|
16116
16208
|
}
|
|
16117
16209
|
function assertLocalState(value) {
|
|
@@ -16488,7 +16580,7 @@ async function acquireInferenceHostProcessLock(path, dependencies = {}) {
|
|
|
16488
16580
|
}
|
|
16489
16581
|
};
|
|
16490
16582
|
}
|
|
16491
|
-
var INFERENCE_CREDENTIAL_NAMESPACE, MAX_INFERENCE_PRIVATE_FILE_BYTES, WINDOWS_PRIVATE_ACL_SCRIPT, windowsPrivateAclInvocation, runWindowsPrivateAcl, windowsAclCache, windowsAclIdentity, aclCacheKey, secureWindowsPrivatePath, invalidateWindowsAclCache, rebindHardenedWindowsAclAfterRename, rebindHardenedWindowsDirectoryAfterOwnedMutation, isDefaultWindowsPrivatePath, secureExistingWindowsPath, linuxProcessIdentity, windowsProcessIdentity, darwinProcessIdentity, runSmallIdentityCommand, cachedSystemBootIdentity, readInferenceSystemBootIdentity, defaultProcessIdentity, defaultCurrentProcessIdentity, processLockObservationCache, inferenceProcessIdentitiesMatch, credentialStoreIdentity;
|
|
16583
|
+
var INFERENCE_CREDENTIAL_NAMESPACE, MAX_INFERENCE_PRIVATE_FILE_BYTES, WINDOWS_PRIVATE_ACL_SCRIPT, windowsPrivateAclInvocation, runWindowsPrivateAcl, windowsAclCache, windowsAclIdentity, aclCacheKey, secureWindowsPrivatePath, invalidateWindowsAclCache, rebindHardenedWindowsAclAfterRename, rebindHardenedWindowsDirectoryAfterOwnedMutation, isDefaultWindowsPrivatePath, secureExistingWindowsPath, linuxProcessIdentity, windowsProcessIdentity, darwinProcessIdentity, runSmallIdentityCommand, cachedSystemBootIdentity, readInferenceSystemBootIdentity, defaultProcessIdentity, defaultCurrentProcessIdentity, processLockObservationCache, inferenceProcessIdentitiesMatch, DEFAULT_INFERENCE_HOST_INSTANCE, SAFE_INFERENCE_HOST_INSTANCE, requireNamedInstancePath, credentialStoreIdentity;
|
|
16492
16584
|
var init_config = __esm({
|
|
16493
16585
|
"lib/inference-host/config.ts"() {
|
|
16494
16586
|
"use strict";
|
|
@@ -16845,6 +16937,16 @@ if(-not $userFull) { throw 'private ACL does not grant the current user full con
|
|
|
16845
16937
|
};
|
|
16846
16938
|
processLockObservationCache = /* @__PURE__ */ new Map();
|
|
16847
16939
|
inferenceProcessIdentitiesMatch = (stored, observed) => stored === observed;
|
|
16940
|
+
DEFAULT_INFERENCE_HOST_INSTANCE = "default";
|
|
16941
|
+
SAFE_INFERENCE_HOST_INSTANCE = /^[a-z0-9](?:[a-z0-9-]{0,46}[a-z0-9])?$/u;
|
|
16942
|
+
requireNamedInstancePath = (instanceName, instanceDir, rawPath, label) => {
|
|
16943
|
+
if (!rawPath || instanceName === DEFAULT_INFERENCE_HOST_INSTANCE) return rawPath;
|
|
16944
|
+
const relativePath = relative(resolve(instanceDir), resolve(rawPath));
|
|
16945
|
+
if (relativePath === ".." || relativePath.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) || isAbsolute(relativePath)) {
|
|
16946
|
+
throw new Error(`${label} for a named instance must stay inside its isolated instance directory.`);
|
|
16947
|
+
}
|
|
16948
|
+
return rawPath;
|
|
16949
|
+
};
|
|
16848
16950
|
credentialStoreIdentity = (mode, filePath, env) => {
|
|
16849
16951
|
if (mode === "file") {
|
|
16850
16952
|
if (!filePath) throw new Error("Inference credential fallback path is unavailable.");
|
|
@@ -19029,7 +19131,7 @@ var init_agent_state = __esm({
|
|
|
19029
19131
|
import { spawn as spawn3 } from "node:child_process";
|
|
19030
19132
|
import { chmod, lstat as lstat2, open as open2, readFile as readFile2, rename as rename2, rm as rm2, writeFile } from "node:fs/promises";
|
|
19031
19133
|
import { tmpdir } from "node:os";
|
|
19032
|
-
import { dirname as dirname2, isAbsolute, join as join2, resolve as resolve2, sep } from "node:path";
|
|
19134
|
+
import { dirname as dirname2, isAbsolute as isAbsolute2, join as join2, resolve as resolve2, sep } from "node:path";
|
|
19033
19135
|
import { createInterface } from "node:readline";
|
|
19034
19136
|
async function loginCodexSubscription(options) {
|
|
19035
19137
|
const session = await CodexAppServerSession.start(options);
|
|
@@ -19137,6 +19239,7 @@ var init_codex_app_server = __esm({
|
|
|
19137
19239
|
this.httpStatusCode = options.httpStatusCode ?? null;
|
|
19138
19240
|
this.retryAtMs = options.retryAtMs ?? null;
|
|
19139
19241
|
this.usage = options.usage ?? null;
|
|
19242
|
+
this.rateLimits = options.rateLimits ?? null;
|
|
19140
19243
|
}
|
|
19141
19244
|
};
|
|
19142
19245
|
objectOrNull = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
@@ -19726,7 +19829,10 @@ child.once('close', async () => {
|
|
|
19726
19829
|
title: "VTX External Inference Host",
|
|
19727
19830
|
version: "external_inference.v1"
|
|
19728
19831
|
},
|
|
19729
|
-
capabilities: {
|
|
19832
|
+
capabilities: {
|
|
19833
|
+
experimentalApi: true,
|
|
19834
|
+
optOutNotificationMethods: ["thread/started"]
|
|
19835
|
+
}
|
|
19730
19836
|
}, {
|
|
19731
19837
|
timeoutMs: Math.max(1, options.deadlineAtMs - Date.now()),
|
|
19732
19838
|
signal: options.signal
|
|
@@ -20297,7 +20403,7 @@ child.once('close', async () => {
|
|
|
20297
20403
|
const resolvedHome = resolve2(this.codexHome);
|
|
20298
20404
|
const resolvedThreadPath = resolve2(threadPath);
|
|
20299
20405
|
const resolvedSessionsRoot = join2(resolvedHome, "sessions");
|
|
20300
|
-
if (!threadId || !threadPath || !
|
|
20406
|
+
if (!threadId || !threadPath || !isAbsolute2(threadPath) || !resolvedThreadPath.startsWith(`${resolvedSessionsRoot}${sep}`) || !resolvedThreadPath.endsWith(".jsonl") || thread?.ephemeral !== false || thread?.modelProvider !== "openai" || !Array.isArray(thread?.turns) || thread.turns.length !== 0 || result2.model !== options.requestedModel || result2.modelProvider !== "openai" || result2.serviceTier !== "default" || result2.reasoningEffort !== options.requestedReasoningEffort || String(result2.cwd || "") !== options.workspacePath || !Array.isArray(result2.runtimeWorkspaceRoots) || result2.runtimeWorkspaceRoots.length !== 0 || !Array.isArray(result2.instructionSources) || result2.instructionSources.length !== 0 || result2.approvalPolicy !== "never" || result2.approvalsReviewer !== "user" || sandbox?.type !== "readOnly" || sandbox.networkAccess !== false || permission?.id !== CODEX_INFERENCE_PERMISSION_PROFILE || permission.extends !== null) {
|
|
20301
20407
|
throw new CodexAppServerError({
|
|
20302
20408
|
message: "Codex thread isolation or effective settings were invalid.",
|
|
20303
20409
|
category: "adapter",
|
|
@@ -20353,6 +20459,19 @@ child.once('close', async () => {
|
|
|
20353
20459
|
});
|
|
20354
20460
|
const startedAt = Date.now();
|
|
20355
20461
|
const unsubscribe = this.subscribe(({ method, params }) => {
|
|
20462
|
+
if (method === "thread/started") {
|
|
20463
|
+
const startedThread = objectOrNull(params.thread);
|
|
20464
|
+
if (!String(startedThread?.id || "")) {
|
|
20465
|
+
terminalReject(new CodexAppServerError({
|
|
20466
|
+
message: "Codex returned an invalid thread lifecycle notification.",
|
|
20467
|
+
category: "adapter",
|
|
20468
|
+
code: "invalid_thread_started_notification",
|
|
20469
|
+
retryable: false,
|
|
20470
|
+
dispatchOutcome: requestWritten ? turnId ? "confirmed_dispatched" : "outcome_unknown" : "not_dispatched"
|
|
20471
|
+
}));
|
|
20472
|
+
}
|
|
20473
|
+
return;
|
|
20474
|
+
}
|
|
20356
20475
|
const eventThreadId = String(params.threadId || "");
|
|
20357
20476
|
const scopedMethod = method.startsWith("thread/") || method.startsWith("turn/") || method.startsWith("item/") || method.startsWith("rawResponse") || method === "model/rerouted";
|
|
20358
20477
|
if (scopedMethod && !eventThreadId) {
|
|
@@ -20632,6 +20751,7 @@ child.once('close', async () => {
|
|
|
20632
20751
|
);
|
|
20633
20752
|
const observedUsage = threadUsage ?? rawResponseUsage;
|
|
20634
20753
|
let retryAtMs = null;
|
|
20754
|
+
let observedRateLimits = null;
|
|
20635
20755
|
if (failure.code === "quota_exceeded" || failure.httpStatusCode === 429) {
|
|
20636
20756
|
const observedAtMs = Date.now();
|
|
20637
20757
|
let accountLimitReached = failure.code === "quota_exceeded";
|
|
@@ -20641,9 +20761,12 @@ child.once('close', async () => {
|
|
|
20641
20761
|
observedAtMs + 5e3
|
|
20642
20762
|
);
|
|
20643
20763
|
if (metadataDeadlineAtMs <= observedAtMs) throw new Error("rate-limit deadline elapsed");
|
|
20644
|
-
|
|
20645
|
-
|
|
20646
|
-
|
|
20764
|
+
observedRateLimits = await this.readAccountRateLimits(
|
|
20765
|
+
metadataDeadlineAtMs,
|
|
20766
|
+
request.signal
|
|
20767
|
+
);
|
|
20768
|
+
accountLimitReached = accountLimitReached || codexAccountRateLimitReached(observedRateLimits);
|
|
20769
|
+
retryAtMs = codexRateLimitRetryAtMs(observedRateLimits);
|
|
20647
20770
|
} catch {
|
|
20648
20771
|
}
|
|
20649
20772
|
if (accountLimitReached) {
|
|
@@ -20673,7 +20796,8 @@ child.once('close', async () => {
|
|
|
20673
20796
|
dispatchOutcome: "confirmed_dispatched",
|
|
20674
20797
|
httpStatusCode: failure.httpStatusCode,
|
|
20675
20798
|
retryAtMs,
|
|
20676
|
-
usage: observedUsage
|
|
20799
|
+
usage: observedUsage,
|
|
20800
|
+
rateLimits: observedRateLimits
|
|
20677
20801
|
});
|
|
20678
20802
|
}
|
|
20679
20803
|
const items = Array.isArray(terminal.items) ? terminal.items.map(objectOrNull) : [];
|
|
@@ -20992,7 +21116,7 @@ import {
|
|
|
20992
21116
|
} from "node:fs/promises";
|
|
20993
21117
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
20994
21118
|
import { tmpdir as tmpdir2 } from "node:os";
|
|
20995
|
-
import { isAbsolute as
|
|
21119
|
+
import { isAbsolute as isAbsolute3, join as join4, relative as relative2, resolve as resolve3, sep as sep2 } from "node:path";
|
|
20996
21120
|
var MAX_PROMPT_BYTES2, CODEX_MODEL_NAME_PATTERN, CODEX_REASONING_EFFORT_PATTERN, tokenUsageReceiptSchema, turnResultReceiptSchema, terminalReceiptSchema, recoveryCheckpointSchema, recoveryFileSchema, FileCodexAttemptRecoveryStore, utf8Bytes, assertAttemptActive, tomlString, permissionConfig, ensureDedicatedCodexHome, createIsolatedCodexAttemptResources, createIsolatedCodexHostResources, validateAttemptInput, isStrictDescendant, assertRecoveryResourceScope, removeRecoveredThread, confirmGuardianTerminatedForRecovery, reconcileCodexAttemptRecovery, CodexSubscriptionAdapter;
|
|
20997
21121
|
var init_codex_adapter = __esm({
|
|
20998
21122
|
"lib/inference-host/codex-adapter.ts"() {
|
|
@@ -21323,7 +21447,7 @@ var init_codex_adapter = __esm({
|
|
|
21323
21447
|
const parentPath = resolve3(parent);
|
|
21324
21448
|
const candidatePath = resolve3(candidate);
|
|
21325
21449
|
const scoped = relative2(parentPath, candidatePath);
|
|
21326
|
-
return scoped.length > 0 && !scoped.startsWith(`..${sep2}`) && scoped !== ".." && !
|
|
21450
|
+
return scoped.length > 0 && !scoped.startsWith(`..${sep2}`) && scoped !== ".." && !isAbsolute3(scoped);
|
|
21327
21451
|
};
|
|
21328
21452
|
assertRecoveryResourceScope = (checkpoint) => {
|
|
21329
21453
|
const temporaryRoot = resolve3(tmpdir2());
|
|
@@ -21413,7 +21537,7 @@ var init_codex_adapter = __esm({
|
|
|
21413
21537
|
}
|
|
21414
21538
|
}
|
|
21415
21539
|
if (checkpoint.threadPath !== null) {
|
|
21416
|
-
if (!
|
|
21540
|
+
if (!isAbsolute3(checkpoint.threadPath) || !isStrictDescendant(
|
|
21417
21541
|
checkpoint.threadPath,
|
|
21418
21542
|
sessionsRoot
|
|
21419
21543
|
) || !checkpoint.threadPath.endsWith(".jsonl")) {
|
|
@@ -21505,6 +21629,23 @@ var init_codex_adapter = __esm({
|
|
|
21505
21629
|
this.adapterClosePromise = null;
|
|
21506
21630
|
this.dependencies = dependencies;
|
|
21507
21631
|
}
|
|
21632
|
+
async readAccountRateLimits(deadlineAtMs, signal) {
|
|
21633
|
+
const codexHome = this.dependencies.codexHome;
|
|
21634
|
+
if (!codexHome) {
|
|
21635
|
+
throw new CodexAppServerError({
|
|
21636
|
+
message: "Codex home is required to read account rate limits.",
|
|
21637
|
+
category: "adapter",
|
|
21638
|
+
code: "codex_home_required",
|
|
21639
|
+
retryable: false
|
|
21640
|
+
});
|
|
21641
|
+
}
|
|
21642
|
+
const durableSession = await this.acquireDurableSession(
|
|
21643
|
+
codexHome,
|
|
21644
|
+
deadlineAtMs,
|
|
21645
|
+
signal
|
|
21646
|
+
);
|
|
21647
|
+
return await durableSession.session.readAccountRateLimits(deadlineAtMs, signal);
|
|
21648
|
+
}
|
|
21508
21649
|
async startDurableSession(codexHome, deadlineAtMs) {
|
|
21509
21650
|
const binary = await (this.dependencies.resolveBinary ?? resolvePinnedCodexBinary)();
|
|
21510
21651
|
const guardianManaged = Boolean(
|
|
@@ -28680,7 +28821,7 @@ function createDefaultInferenceHostRunnerDependencies(options) {
|
|
|
28680
28821
|
envelopePublicKey: options.envelopePublicKey
|
|
28681
28822
|
};
|
|
28682
28823
|
}
|
|
28683
|
-
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_ATTEMPT_HEARTBEAT_MS, DEFAULT_DRAIN_TIMEOUT_MS, DEFAULT_REMOTE_RETRY_LIMIT,
|
|
28824
|
+
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, DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS, MIN_CLAIM_START_WINDOW_MS, UNBOUNDED_AVAILABLE_SLOTS, buildCodexInferenceAdvertisedModels, FileInferenceHostRuntimeReceiptStore, InferenceHostRecoveryRequiredError, InferenceHostRunnerError, defaultSleep, abortError, defaultRegisterSignalHandlers, safeInteger, exactObjectKeys, validIso, validateAttemptReceipt, validateRuntimeReceipt, sha256, stableOperationId, buildAttemptStartRequest, isoAt, providerWeeklyQuotaFromRateLimits, finitePositiveOption, validateRunnerOptions, assertLocalCredentialIdentity, retryableRemoteError, remoteRetryAfterMs, controlPlaneFatal, defaultValidateOutput, objectRecord, positiveUtf8ByteLimit, assertCompilableOutputSchema, parseOutputContract, safeFailureCode, exactJson2, runnerIdentityMismatch, assertAdvertisementResult, assertHostHeartbeatResult, assertClaimResult, assertStartResult, assertJobHeartbeatResult, assertTerminalResult, classifyFailure, ambiguousHeartbeatTransport, reportedTokenUsage, reportedUsage, InferenceHostRunner;
|
|
28684
28825
|
var init_runner = __esm({
|
|
28685
28826
|
"lib/inference-host/runner.ts"() {
|
|
28686
28827
|
"use strict";
|
|
@@ -28697,13 +28838,14 @@ var init_runner = __esm({
|
|
|
28697
28838
|
DEFAULT_ADVERTISEMENT_TTL_MS = 12e4;
|
|
28698
28839
|
DEFAULT_ADVERTISEMENT_REFRESH_LEAD_MS = 3e4;
|
|
28699
28840
|
DEFAULT_HOST_HEARTBEAT_MS = 3e3;
|
|
28841
|
+
DEFAULT_PROVIDER_RATE_LIMIT_REFRESH_MS = 6e4;
|
|
28700
28842
|
DEFAULT_ATTEMPT_HEARTBEAT_MS = 3e3;
|
|
28701
28843
|
DEFAULT_DRAIN_TIMEOUT_MS = 3e4;
|
|
28702
28844
|
DEFAULT_REMOTE_RETRY_LIMIT = 3;
|
|
28703
|
-
DEFAULT_MAX_CONCURRENCY = 1;
|
|
28704
28845
|
MIN_SLEEP_MS = 10;
|
|
28705
28846
|
DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS = 5 * 60 * 1e3;
|
|
28706
28847
|
MIN_CLAIM_START_WINDOW_MS = 5e3;
|
|
28848
|
+
UNBOUNDED_AVAILABLE_SLOTS = Number.MAX_SAFE_INTEGER;
|
|
28707
28849
|
buildCodexInferenceAdvertisedModels = (capabilities, adapterRuntimeVersion) => {
|
|
28708
28850
|
const visible = capabilities.filter((capability) => !capability.hidden);
|
|
28709
28851
|
if (visible.length === 0 || visible.length > 64) {
|
|
@@ -28957,6 +29099,19 @@ var init_runner = __esm({
|
|
|
28957
29099
|
started_at: startedAt
|
|
28958
29100
|
});
|
|
28959
29101
|
isoAt = (milliseconds) => new Date(milliseconds).toISOString();
|
|
29102
|
+
providerWeeklyQuotaFromRateLimits = (rateLimits, observedAtMs, currentTimeMs = observedAtMs) => {
|
|
29103
|
+
if (!rateLimits) return null;
|
|
29104
|
+
for (const window2 of [rateLimits.rateLimits.primary, rateLimits.rateLimits.secondary]) {
|
|
29105
|
+
if (window2?.windowDurationMins !== 7 * 24 * 60 || window2.resetsAt === null || window2.resetsAt * 1e3 <= currentTimeMs) continue;
|
|
29106
|
+
return {
|
|
29107
|
+
source: "codex_app_server",
|
|
29108
|
+
used_percent: window2.usedPercent,
|
|
29109
|
+
resets_at: isoAt(window2.resetsAt * 1e3),
|
|
29110
|
+
observed_at: isoAt(observedAtMs)
|
|
29111
|
+
};
|
|
29112
|
+
}
|
|
29113
|
+
return null;
|
|
29114
|
+
};
|
|
28960
29115
|
finitePositiveOption = (value, fallback, label) => {
|
|
28961
29116
|
const result2 = value ?? fallback;
|
|
28962
29117
|
if (!Number.isSafeInteger(result2) || result2 < 1) {
|
|
@@ -28992,11 +29147,7 @@ var init_runner = __esm({
|
|
|
28992
29147
|
options.codexModelCapabilities,
|
|
28993
29148
|
options.adapterRuntimeVersion
|
|
28994
29149
|
),
|
|
28995
|
-
maxConcurrency: finitePositiveOption(
|
|
28996
|
-
options.maxConcurrency,
|
|
28997
|
-
DEFAULT_MAX_CONCURRENCY,
|
|
28998
|
-
"Maximum concurrency"
|
|
28999
|
-
),
|
|
29150
|
+
maxConcurrency: options.maxConcurrency === null || options.maxConcurrency === void 0 ? null : finitePositiveOption(options.maxConcurrency, 1, "Maximum concurrency"),
|
|
29000
29151
|
advertisementTtlMs,
|
|
29001
29152
|
advertisementRefreshLeadMs,
|
|
29002
29153
|
hostHeartbeatMs: finitePositiveOption(
|
|
@@ -29004,6 +29155,11 @@ var init_runner = __esm({
|
|
|
29004
29155
|
DEFAULT_HOST_HEARTBEAT_MS,
|
|
29005
29156
|
"Host heartbeat interval"
|
|
29006
29157
|
),
|
|
29158
|
+
providerRateLimitRefreshMs: finitePositiveOption(
|
|
29159
|
+
options.providerRateLimitRefreshMs,
|
|
29160
|
+
DEFAULT_PROVIDER_RATE_LIMIT_REFRESH_MS,
|
|
29161
|
+
"Provider rate-limit refresh interval"
|
|
29162
|
+
),
|
|
29007
29163
|
attemptHeartbeatMs: finitePositiveOption(
|
|
29008
29164
|
options.attemptHeartbeatMs,
|
|
29009
29165
|
DEFAULT_ATTEMPT_HEARTBEAT_MS,
|
|
@@ -29334,6 +29490,20 @@ var init_runner = __esm({
|
|
|
29334
29490
|
"Inference host login is required before the runner can start."
|
|
29335
29491
|
);
|
|
29336
29492
|
}
|
|
29493
|
+
const emitDiagnostic = (event, fields = {}) => {
|
|
29494
|
+
try {
|
|
29495
|
+
this.options.emitDiagnosticEvent?.({
|
|
29496
|
+
schema_version: "vtx_inference_host_diagnostic_v1",
|
|
29497
|
+
at: isoAt(now()),
|
|
29498
|
+
event,
|
|
29499
|
+
instance_name: this.options.instanceName ?? "default",
|
|
29500
|
+
host_id: localState.host_id,
|
|
29501
|
+
display_name: this.options.displayName,
|
|
29502
|
+
...fields
|
|
29503
|
+
});
|
|
29504
|
+
} catch {
|
|
29505
|
+
}
|
|
29506
|
+
};
|
|
29337
29507
|
const accountKey = inferenceCredentialAccountKey({
|
|
29338
29508
|
issuer: localState.issuer,
|
|
29339
29509
|
clientId: localState.client_id,
|
|
@@ -29530,6 +29700,10 @@ var init_runner = __esm({
|
|
|
29530
29700
|
if (!wasRegistered && receipt.registered && (!receipt.advertisement_expires_at || Date.parse(receipt.advertisement_expires_at) - now() <= settings.advertisementRefreshLeadMs)) {
|
|
29531
29701
|
await publishAdvertisement("healthy", true);
|
|
29532
29702
|
}
|
|
29703
|
+
let providerRetryAtMs = this.options.codexRateLimits && codexAccountRateLimitReached(this.options.codexRateLimits) ? codexRateLimitRetryAtMs(this.options.codexRateLimits) ?? now() + DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS : null;
|
|
29704
|
+
let providerCooldownReason = providerRetryAtMs === null ? null : "provider_limit_snapshot";
|
|
29705
|
+
let providerRateLimits = this.options.codexRateLimits ?? null;
|
|
29706
|
+
let providerRateLimitsObservedAtMs = now();
|
|
29533
29707
|
const hostHeartbeat = async (status, requestOptions = {
|
|
29534
29708
|
signal: this.options.signal
|
|
29535
29709
|
}, retryRemote = true, allowOfflineProjection = false, definitiveReseedAttempt = 0) => {
|
|
@@ -29544,7 +29718,12 @@ var init_runner = __esm({
|
|
|
29544
29718
|
sequence,
|
|
29545
29719
|
status,
|
|
29546
29720
|
active_attempts: active.size,
|
|
29547
|
-
available_slots: Math.max(0, settings.maxConcurrency - active.size),
|
|
29721
|
+
available_slots: settings.maxConcurrency === null ? UNBOUNDED_AVAILABLE_SLOTS - active.size : Math.max(0, settings.maxConcurrency - active.size),
|
|
29722
|
+
provider_weekly_quota: providerWeeklyQuotaFromRateLimits(
|
|
29723
|
+
providerRateLimits,
|
|
29724
|
+
providerRateLimitsObservedAtMs,
|
|
29725
|
+
now()
|
|
29726
|
+
),
|
|
29548
29727
|
observed_at: isoAt(now())
|
|
29549
29728
|
};
|
|
29550
29729
|
receipt = {
|
|
@@ -29586,10 +29765,21 @@ var init_runner = __esm({
|
|
|
29586
29765
|
await hostHeartbeat("healthy");
|
|
29587
29766
|
let nextHostHeartbeatAt = now() + settings.hostHeartbeatMs;
|
|
29588
29767
|
let nextAdvertisementAttemptAt = 0;
|
|
29589
|
-
let
|
|
29768
|
+
let nextProviderRateLimitRefreshAt = now() + settings.providerRateLimitRefreshMs;
|
|
29590
29769
|
let nextClaimAt = Math.max(now(), providerRetryAtMs ?? 0);
|
|
29591
29770
|
let pendingClaimPromotions = 0;
|
|
29592
29771
|
let onceClaimed = false;
|
|
29772
|
+
emitDiagnostic("runtime_started", {
|
|
29773
|
+
max_concurrency: settings.maxConcurrency,
|
|
29774
|
+
active_attempts: active.size,
|
|
29775
|
+
provider_cooldown_reason: providerCooldownReason,
|
|
29776
|
+
provider_cooldown_until: providerRetryAtMs === null ? null : isoAt(providerRetryAtMs),
|
|
29777
|
+
provider_weekly_quota: providerWeeklyQuotaFromRateLimits(
|
|
29778
|
+
providerRateLimits,
|
|
29779
|
+
providerRateLimitsObservedAtMs,
|
|
29780
|
+
now()
|
|
29781
|
+
)
|
|
29782
|
+
});
|
|
29593
29783
|
const launchClaim = (claim, recovery, claimRequest) => {
|
|
29594
29784
|
if (!recovery) {
|
|
29595
29785
|
claimed += 1;
|
|
@@ -29633,10 +29823,37 @@ var init_runner = __esm({
|
|
|
29633
29823
|
attemptHeartbeatMs: settings.attemptHeartbeatMs,
|
|
29634
29824
|
sleep: sleep4,
|
|
29635
29825
|
now,
|
|
29636
|
-
onProviderCooldown: (retryAtMs) => {
|
|
29826
|
+
onProviderCooldown: ({ retryAtMs, reason, rateLimits }) => {
|
|
29637
29827
|
if (!Number.isSafeInteger(retryAtMs) || retryAtMs <= now()) return;
|
|
29828
|
+
const priorRetryAtMs = providerRetryAtMs;
|
|
29638
29829
|
providerRetryAtMs = Math.max(providerRetryAtMs ?? 0, retryAtMs);
|
|
29639
29830
|
nextClaimAt = Math.max(nextClaimAt, providerRetryAtMs);
|
|
29831
|
+
providerCooldownReason = reason;
|
|
29832
|
+
if (rateLimits) {
|
|
29833
|
+
providerRateLimits = rateLimits;
|
|
29834
|
+
providerRateLimitsObservedAtMs = now();
|
|
29835
|
+
}
|
|
29836
|
+
emitDiagnostic(
|
|
29837
|
+
priorRetryAtMs === null ? "provider_cooldown_started" : "provider_cooldown_extended",
|
|
29838
|
+
{
|
|
29839
|
+
reason,
|
|
29840
|
+
cooldown_until: isoAt(providerRetryAtMs),
|
|
29841
|
+
active_attempts: active.size,
|
|
29842
|
+
provider_weekly_quota: providerWeeklyQuotaFromRateLimits(
|
|
29843
|
+
providerRateLimits,
|
|
29844
|
+
providerRateLimitsObservedAtMs,
|
|
29845
|
+
now()
|
|
29846
|
+
)
|
|
29847
|
+
}
|
|
29848
|
+
);
|
|
29849
|
+
},
|
|
29850
|
+
onAttemptOutcome: (outcome) => {
|
|
29851
|
+
emitDiagnostic("attempt_finished", {
|
|
29852
|
+
...outcome,
|
|
29853
|
+
job_id: claim.job_id,
|
|
29854
|
+
attempt_id: attemptId,
|
|
29855
|
+
active_attempts: active.size
|
|
29856
|
+
});
|
|
29640
29857
|
},
|
|
29641
29858
|
resumeReceipt: recovery,
|
|
29642
29859
|
claimRequest,
|
|
@@ -29653,6 +29870,14 @@ var init_runner = __esm({
|
|
|
29653
29870
|
attemptControllers.delete(attemptId);
|
|
29654
29871
|
});
|
|
29655
29872
|
active.set(attemptId, promise2);
|
|
29873
|
+
emitDiagnostic("attempt_started", {
|
|
29874
|
+
job_id: claim.job_id,
|
|
29875
|
+
attempt_id: attemptId,
|
|
29876
|
+
attempt_index: claim.attempt_index,
|
|
29877
|
+
requested_model: claim.requested_model,
|
|
29878
|
+
requested_reasoning_effort: claim.requested_reasoning_effort,
|
|
29879
|
+
active_attempts: active.size
|
|
29880
|
+
});
|
|
29656
29881
|
return attemptId;
|
|
29657
29882
|
};
|
|
29658
29883
|
const removeRecoveredAttempt = async (attemptId) => {
|
|
@@ -29693,12 +29918,56 @@ var init_runner = __esm({
|
|
|
29693
29918
|
}
|
|
29694
29919
|
recoveryQueue.push(recovery);
|
|
29695
29920
|
}
|
|
29696
|
-
while (!drainRequested && recoveryQueue.length > 0 && active.size < settings.maxConcurrency) {
|
|
29921
|
+
while (!drainRequested && recoveryQueue.length > 0 && (settings.maxConcurrency === null || active.size < settings.maxConcurrency)) {
|
|
29697
29922
|
const recovery = recoveryQueue.shift();
|
|
29698
29923
|
launchClaim(recovery.claim, recovery);
|
|
29699
29924
|
}
|
|
29700
29925
|
while (!drainRequested) {
|
|
29701
29926
|
const currentTime = now();
|
|
29927
|
+
if (providerRetryAtMs !== null && currentTime >= providerRetryAtMs && providerCooldownReason !== null) {
|
|
29928
|
+
emitDiagnostic("provider_cooldown_cleared", {
|
|
29929
|
+
reason: providerCooldownReason,
|
|
29930
|
+
active_attempts: active.size,
|
|
29931
|
+
provider_weekly_quota: providerWeeklyQuotaFromRateLimits(
|
|
29932
|
+
providerRateLimits,
|
|
29933
|
+
providerRateLimitsObservedAtMs,
|
|
29934
|
+
currentTime
|
|
29935
|
+
)
|
|
29936
|
+
});
|
|
29937
|
+
providerRetryAtMs = null;
|
|
29938
|
+
providerCooldownReason = null;
|
|
29939
|
+
nextClaimAt = Math.min(nextClaimAt, currentTime);
|
|
29940
|
+
}
|
|
29941
|
+
if (this.dependencies.codexAdapter.readAccountRateLimits && currentTime >= nextProviderRateLimitRefreshAt) {
|
|
29942
|
+
try {
|
|
29943
|
+
providerRateLimits = await this.dependencies.codexAdapter.readAccountRateLimits(
|
|
29944
|
+
Date.now() + Math.min(2e3, settings.hostHeartbeatMs),
|
|
29945
|
+
this.options.signal
|
|
29946
|
+
);
|
|
29947
|
+
providerRateLimitsObservedAtMs = now();
|
|
29948
|
+
const refreshedRetryAt = codexAccountRateLimitReached(providerRateLimits) ? codexRateLimitRetryAtMs(providerRateLimits) ?? currentTime + DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS : null;
|
|
29949
|
+
if (refreshedRetryAt !== null && refreshedRetryAt > currentTime) {
|
|
29950
|
+
providerRetryAtMs = Math.max(providerRetryAtMs ?? 0, refreshedRetryAt);
|
|
29951
|
+
providerCooldownReason = "provider_limit_snapshot";
|
|
29952
|
+
nextClaimAt = Math.max(nextClaimAt, providerRetryAtMs);
|
|
29953
|
+
}
|
|
29954
|
+
emitDiagnostic("provider_rate_limits_refreshed", {
|
|
29955
|
+
provider_weekly_quota: providerWeeklyQuotaFromRateLimits(
|
|
29956
|
+
providerRateLimits,
|
|
29957
|
+
providerRateLimitsObservedAtMs,
|
|
29958
|
+
now()
|
|
29959
|
+
),
|
|
29960
|
+
active_attempts: active.size
|
|
29961
|
+
});
|
|
29962
|
+
} catch (error48) {
|
|
29963
|
+
emitDiagnostic("provider_rate_limits_refresh_failed", {
|
|
29964
|
+
failure_category: error48 instanceof CodexAppServerError ? error48.category : "adapter",
|
|
29965
|
+
failure_code: error48 instanceof CodexAppServerError ? error48.code : "provider_rate_limits_refresh_failed"
|
|
29966
|
+
});
|
|
29967
|
+
} finally {
|
|
29968
|
+
nextProviderRateLimitRefreshAt = now() + settings.providerRateLimitRefreshMs;
|
|
29969
|
+
}
|
|
29970
|
+
}
|
|
29702
29971
|
const expiresAt = receipt.advertisement_expires_at ? Date.parse(receipt.advertisement_expires_at) : 0;
|
|
29703
29972
|
if (currentTime >= nextAdvertisementAttemptAt && expiresAt - currentTime <= settings.advertisementRefreshLeadMs) {
|
|
29704
29973
|
try {
|
|
@@ -29741,11 +30010,11 @@ var init_runner = __esm({
|
|
|
29741
30010
|
nextHostHeartbeatAt = now() + settings.hostHeartbeatMs;
|
|
29742
30011
|
}
|
|
29743
30012
|
}
|
|
29744
|
-
while (recoveryQueue.length > 0 && active.size < settings.maxConcurrency) {
|
|
30013
|
+
while (recoveryQueue.length > 0 && (settings.maxConcurrency === null || active.size < settings.maxConcurrency)) {
|
|
29745
30014
|
const recovery = recoveryQueue.shift();
|
|
29746
30015
|
launchClaim(recovery.claim, recovery);
|
|
29747
30016
|
}
|
|
29748
|
-
while (!drainRequested && recoveryQueue.length === 0 && (!this.options.once || !onceClaimed) && active.size < settings.maxConcurrency && pendingClaimPromotions === 0 && now() >= nextClaimAt) {
|
|
30017
|
+
while (!drainRequested && recoveryQueue.length === 0 && (!this.options.once || !onceClaimed) && (settings.maxConcurrency === null || active.size < settings.maxConcurrency) && pendingClaimPromotions === 0 && now() >= nextClaimAt) {
|
|
29749
30018
|
if (!receipt.pending_claim_request) {
|
|
29750
30019
|
const claimSequence = receipt.claim_sequence + 1;
|
|
29751
30020
|
const pendingClaimRequest = {
|
|
@@ -29864,6 +30133,13 @@ var init_runner = __esm({
|
|
|
29864
30133
|
requestDrain("drain_timeout");
|
|
29865
30134
|
}
|
|
29866
30135
|
}
|
|
30136
|
+
emitDiagnostic("runtime_stopped", {
|
|
30137
|
+
claimed,
|
|
30138
|
+
completed,
|
|
30139
|
+
failed,
|
|
30140
|
+
drain_reason: drainReason,
|
|
30141
|
+
active_attempts: active.size
|
|
30142
|
+
});
|
|
29867
30143
|
return { claimed, completed, failed, drain_reason: drainReason };
|
|
29868
30144
|
} finally {
|
|
29869
30145
|
removeAbortListener();
|
|
@@ -30209,13 +30485,27 @@ var init_runner = __esm({
|
|
|
30209
30485
|
);
|
|
30210
30486
|
}
|
|
30211
30487
|
await removeAttempt();
|
|
30488
|
+
options.onAttemptOutcome?.({
|
|
30489
|
+
outcome: "completed",
|
|
30490
|
+
failure_category: null,
|
|
30491
|
+
failure_code: null,
|
|
30492
|
+
retryable: null,
|
|
30493
|
+
dispatch_outcome: completion.outcome.dispatch_outcome,
|
|
30494
|
+
response_outcome: completion.outcome.response_outcome,
|
|
30495
|
+
latency_ms: completion.latency_ms,
|
|
30496
|
+
usage: completion.usage
|
|
30497
|
+
});
|
|
30212
30498
|
return "completed";
|
|
30213
30499
|
} catch (error48) {
|
|
30214
30500
|
if (error48 instanceof InferenceHostRunnerError && error48.code === "terminal_outcome_unconfirmed") {
|
|
30215
30501
|
throw error48;
|
|
30216
30502
|
}
|
|
30217
30503
|
if (error48 instanceof CodexAppServerError && error48.retryAtMs !== null && ["quota_exceeded", "codex_rate_limited"].includes(error48.code)) {
|
|
30218
|
-
options.onProviderCooldown?.(
|
|
30504
|
+
options.onProviderCooldown?.({
|
|
30505
|
+
retryAtMs: error48.retryAtMs,
|
|
30506
|
+
reason: error48.code === "quota_exceeded" ? "quota_exceeded" : "codex_rate_limited",
|
|
30507
|
+
rateLimits: error48.rateLimits
|
|
30508
|
+
});
|
|
30219
30509
|
}
|
|
30220
30510
|
const classified = classifyFailure(heartbeatFailure ?? error48, adapterResult);
|
|
30221
30511
|
const heartbeatAmbiguous = ambiguousHeartbeatTransport(heartbeatFailure);
|
|
@@ -30295,6 +30585,16 @@ var init_runner = __esm({
|
|
|
30295
30585
|
);
|
|
30296
30586
|
}
|
|
30297
30587
|
await removeAttempt();
|
|
30588
|
+
options.onAttemptOutcome?.({
|
|
30589
|
+
outcome: "failed",
|
|
30590
|
+
failure_category: failureRequest.failure_category,
|
|
30591
|
+
failure_code: failureRequest.failure_code,
|
|
30592
|
+
retryable: failureRequest.retryable,
|
|
30593
|
+
dispatch_outcome: failureRequest.outcome.dispatch_outcome,
|
|
30594
|
+
response_outcome: failureRequest.outcome.response_outcome,
|
|
30595
|
+
latency_ms: adapterResult?.latencyMs ?? null,
|
|
30596
|
+
usage: failureRequest.usage
|
|
30597
|
+
});
|
|
30298
30598
|
return "failed";
|
|
30299
30599
|
} finally {
|
|
30300
30600
|
heartbeatStopped = true;
|
|
@@ -30335,7 +30635,7 @@ import { createWriteStream, readFileSync } from "node:fs";
|
|
|
30335
30635
|
import { access as access3, chmod as chmod3, mkdir as mkdir3, readFile as readFile5, rm as rm4, writeFile as writeFile2 } from "node:fs/promises";
|
|
30336
30636
|
import { homedir as homedir2 } from "node:os";
|
|
30337
30637
|
import { dirname as dirname4, join as join5, resolve as resolve4 } from "node:path";
|
|
30338
|
-
var SERVICE_NAME, SYSTEMD_UNIT, LAUNCHD_LABEL, SERVICE_COOPERATIVE_STOP_SECONDS, isWindowsSubsystemForLinux, inferenceHostServiceManifestPath, inferenceHostServiceDesiredPath, inferenceHostServiceLogPath, xmlEscape, plistEscape, systemdQuote, defaultRunCommand, managerName, assertManifest, assertDesiredState, readInferenceHostServiceManifest, readInferenceHostServiceDesired, readDesiredAcrossAtomicReplacement, writeDesired, runtimeEnvironment, serviceArguments, windowsOwnedCommandLine, vbScriptString, windowsServiceLauncher, windowsTaskXml, systemdUnit, launchAgentPlist, InferenceHostServiceManager, appendServiceLog, spawnServiceChild, runInferenceHostServiceSupervisor;
|
|
30638
|
+
var SERVICE_NAME, SYSTEMD_UNIT, LAUNCHD_LABEL, SERVICE_COOPERATIVE_STOP_SECONDS, inferenceHostServiceChildEnvironment, isWindowsSubsystemForLinux, inferenceHostServiceManifestPath, inferenceHostServiceDesiredPath, inferenceHostServiceLogPath, xmlEscape, plistEscape, systemdQuote, defaultRunCommand, managerName, assertRuntimeEnvironment, withoutConcurrencyLimit, assertServicePath, assertWorker, assertManifest, assertDesiredState, readInferenceHostServiceManifest, readInferenceHostServiceDesired, readDesiredAcrossAtomicReplacement, writeDesired, runtimeEnvironment, serviceArguments, windowsOwnedCommandLine, vbScriptString, windowsServiceLauncher, windowsTaskXml, systemdUnit, launchAgentPlist, InferenceHostServiceManager, appendServiceLog, spawnServiceChild, runInferenceHostServiceSupervisor;
|
|
30339
30639
|
var init_service = __esm({
|
|
30340
30640
|
"lib/inference-host/service.ts"() {
|
|
30341
30641
|
"use strict";
|
|
@@ -30344,6 +30644,15 @@ var init_service = __esm({
|
|
|
30344
30644
|
SYSTEMD_UNIT = "vtx-inference-host.service";
|
|
30345
30645
|
LAUNCHD_LABEL = "com.vtxmacro.inference-host";
|
|
30346
30646
|
SERVICE_COOPERATIVE_STOP_SECONDS = 75;
|
|
30647
|
+
inferenceHostServiceChildEnvironment = (runtimeEnvironment2, inheritedEnvironment = process.env) => {
|
|
30648
|
+
const environment = { ...inheritedEnvironment };
|
|
30649
|
+
for (const key of Object.keys(environment)) {
|
|
30650
|
+
if (key === "VTX_API_URL" || key.startsWith("VTX_INFERENCE_HOST_")) {
|
|
30651
|
+
delete environment[key];
|
|
30652
|
+
}
|
|
30653
|
+
}
|
|
30654
|
+
return { ...environment, ...runtimeEnvironment2 };
|
|
30655
|
+
};
|
|
30347
30656
|
isWindowsSubsystemForLinux = (env = process.env, kernelRelease) => Boolean(
|
|
30348
30657
|
String(env.WSL_INTEROP || "").trim() || String(env.WSL_DISTRO_NAME || "").trim() || /microsoft/iu.test(kernelRelease ?? (() => {
|
|
30349
30658
|
try {
|
|
@@ -30353,9 +30662,9 @@ var init_service = __esm({
|
|
|
30353
30662
|
}
|
|
30354
30663
|
})())
|
|
30355
30664
|
);
|
|
30356
|
-
inferenceHostServiceManifestPath = (config2) => `${config2.
|
|
30357
|
-
inferenceHostServiceDesiredPath = (config2) => `${config2.
|
|
30358
|
-
inferenceHostServiceLogPath = (config2) => `${config2.
|
|
30665
|
+
inferenceHostServiceManifestPath = (config2) => `${config2.supervisorStatePath}.service.json`;
|
|
30666
|
+
inferenceHostServiceDesiredPath = (config2) => `${config2.supervisorStatePath}.service-desired.json`;
|
|
30667
|
+
inferenceHostServiceLogPath = (config2) => `${config2.supervisorStatePath}.service.log`;
|
|
30359
30668
|
xmlEscape = (value) => value.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'");
|
|
30360
30669
|
plistEscape = xmlEscape;
|
|
30361
30670
|
systemdQuote = (value) => `"${value.replaceAll("\\", "\\\\").replaceAll('"', '\\"').replaceAll("%", "%%")}"`;
|
|
@@ -30385,29 +30694,118 @@ var init_service = __esm({
|
|
|
30385
30694
|
if (platform === "linux") return "systemd-user";
|
|
30386
30695
|
throw new Error(`Inference-host background service is unsupported on ${platform}.`);
|
|
30387
30696
|
};
|
|
30697
|
+
assertRuntimeEnvironment = (value) => {
|
|
30698
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
30699
|
+
throw new Error("Inference-host service runtime environment is invalid.");
|
|
30700
|
+
}
|
|
30701
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
30702
|
+
if (!key.startsWith("VTX_") || typeof entry !== "string") {
|
|
30703
|
+
throw new Error("Inference-host service runtime environment is invalid.");
|
|
30704
|
+
}
|
|
30705
|
+
}
|
|
30706
|
+
return value;
|
|
30707
|
+
};
|
|
30708
|
+
withoutConcurrencyLimit = (environment) => {
|
|
30709
|
+
const { VTX_INFERENCE_HOST_MAX_CONCURRENCY: _removed, ...rest } = environment;
|
|
30710
|
+
return rest;
|
|
30711
|
+
};
|
|
30712
|
+
assertServicePath = (value) => {
|
|
30713
|
+
if (typeof value !== "string" || !value || /[\r\n\0]/u.test(value)) {
|
|
30714
|
+
throw new Error("Inference-host service manifest paths contain control characters.");
|
|
30715
|
+
}
|
|
30716
|
+
return value;
|
|
30717
|
+
};
|
|
30718
|
+
assertWorker = (value) => {
|
|
30719
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
30720
|
+
throw new Error("Inference-host service worker is invalid.");
|
|
30721
|
+
}
|
|
30722
|
+
const record2 = value;
|
|
30723
|
+
if (typeof record2.instance_name !== "string" || !/^[a-z0-9](?:[a-z0-9-]{0,46}[a-z0-9])?$/u.test(record2.instance_name) || record2.adapter !== "codex" || typeof record2.display_name !== "string" || !record2.display_name || record2.max_concurrency !== null && (!Number.isSafeInteger(record2.max_concurrency) || Number(record2.max_concurrency) < 1) || record2.authenticated_account_email !== null && typeof record2.authenticated_account_email !== "string" || record2.authenticated_account_plan !== null && typeof record2.authenticated_account_plan !== "string") {
|
|
30724
|
+
throw new Error("Inference-host service worker is invalid.");
|
|
30725
|
+
}
|
|
30726
|
+
return {
|
|
30727
|
+
instance_name: record2.instance_name,
|
|
30728
|
+
adapter: "codex",
|
|
30729
|
+
display_name: record2.display_name,
|
|
30730
|
+
max_concurrency: record2.max_concurrency === null ? null : Number(record2.max_concurrency),
|
|
30731
|
+
authenticated_account_email: record2.authenticated_account_email,
|
|
30732
|
+
authenticated_account_plan: record2.authenticated_account_plan,
|
|
30733
|
+
runtime_environment: assertRuntimeEnvironment(record2.runtime_environment)
|
|
30734
|
+
};
|
|
30735
|
+
};
|
|
30388
30736
|
assertManifest = (value) => {
|
|
30389
30737
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
30390
30738
|
throw new Error("Inference-host service manifest is invalid.");
|
|
30391
30739
|
}
|
|
30392
30740
|
const record2 = value;
|
|
30393
|
-
if (record2.schema_version
|
|
30394
|
-
|
|
30741
|
+
if (record2.schema_version === "vtx_inference_service_v1") {
|
|
30742
|
+
const legacy = record2;
|
|
30743
|
+
if (legacy.adapter !== "codex" || typeof legacy.installed_at !== "string" || !Number.isFinite(Date.parse(legacy.installed_at)) || typeof legacy.executable !== "string" || !legacy.executable || typeof legacy.script !== "string" || !legacy.script || typeof legacy.display_name !== "string" || !legacy.display_name || typeof legacy.log_path !== "string" || !legacy.log_path) throw new Error("Inference-host service manifest is invalid.");
|
|
30744
|
+
const runtime_environment = withoutConcurrencyLimit(
|
|
30745
|
+
assertRuntimeEnvironment(legacy.runtime_environment)
|
|
30746
|
+
);
|
|
30747
|
+
const worker = assertWorker({
|
|
30748
|
+
instance_name: "default",
|
|
30749
|
+
adapter: "codex",
|
|
30750
|
+
display_name: legacy.display_name,
|
|
30751
|
+
max_concurrency: null,
|
|
30752
|
+
authenticated_account_email: null,
|
|
30753
|
+
authenticated_account_plan: null,
|
|
30754
|
+
runtime_environment
|
|
30755
|
+
});
|
|
30756
|
+
return {
|
|
30757
|
+
schema_version: "vtx_inference_service_v3",
|
|
30758
|
+
installed_at: legacy.installed_at,
|
|
30759
|
+
executable: assertServicePath(legacy.executable),
|
|
30760
|
+
script: assertServicePath(legacy.script),
|
|
30761
|
+
log_path: assertServicePath(legacy.log_path),
|
|
30762
|
+
workers: [worker]
|
|
30763
|
+
};
|
|
30395
30764
|
}
|
|
30396
|
-
|
|
30397
|
-
record2
|
|
30398
|
-
|
|
30399
|
-
|
|
30400
|
-
|
|
30401
|
-
|
|
30402
|
-
|
|
30765
|
+
if (record2.schema_version === "vtx_inference_service_v2") {
|
|
30766
|
+
const legacy = record2;
|
|
30767
|
+
if (typeof legacy.installed_at !== "string" || !Number.isFinite(Date.parse(legacy.installed_at)) || typeof legacy.executable !== "string" || !legacy.executable || typeof legacy.script !== "string" || !legacy.script || typeof legacy.log_path !== "string" || !legacy.log_path || !Array.isArray(legacy.workers) || legacy.workers.length < 1) {
|
|
30768
|
+
throw new Error("Inference-host service manifest is invalid.");
|
|
30769
|
+
}
|
|
30770
|
+
const workers2 = legacy.workers.map((worker) => {
|
|
30771
|
+
if (!worker || typeof worker !== "object" || Array.isArray(worker)) {
|
|
30772
|
+
throw new Error("Inference-host service worker is invalid.");
|
|
30773
|
+
}
|
|
30774
|
+
const legacyWorker = worker;
|
|
30775
|
+
if (!Number.isSafeInteger(legacyWorker.max_concurrency) || Number(legacyWorker.max_concurrency) < 1) {
|
|
30776
|
+
throw new Error("Inference-host service worker is invalid.");
|
|
30777
|
+
}
|
|
30778
|
+
return assertWorker({
|
|
30779
|
+
...legacyWorker,
|
|
30780
|
+
max_concurrency: null,
|
|
30781
|
+
runtime_environment: withoutConcurrencyLimit(
|
|
30782
|
+
assertRuntimeEnvironment(legacyWorker.runtime_environment)
|
|
30783
|
+
)
|
|
30784
|
+
});
|
|
30785
|
+
});
|
|
30786
|
+
if (new Set(workers2.map((worker) => worker.instance_name)).size !== workers2.length) {
|
|
30787
|
+
throw new Error("Inference-host service worker names must be unique.");
|
|
30403
30788
|
}
|
|
30789
|
+
return {
|
|
30790
|
+
schema_version: "vtx_inference_service_v3",
|
|
30791
|
+
installed_at: legacy.installed_at,
|
|
30792
|
+
executable: assertServicePath(legacy.executable),
|
|
30793
|
+
script: assertServicePath(legacy.script),
|
|
30794
|
+
log_path: assertServicePath(legacy.log_path),
|
|
30795
|
+
workers: workers2
|
|
30796
|
+
};
|
|
30404
30797
|
}
|
|
30405
|
-
|
|
30406
|
-
|
|
30407
|
-
throw new Error("Inference-host service runtime environment is invalid.");
|
|
30408
|
-
}
|
|
30798
|
+
if (record2.schema_version !== "vtx_inference_service_v3" || typeof record2.installed_at !== "string" || !Number.isFinite(Date.parse(record2.installed_at)) || typeof record2.executable !== "string" || !record2.executable || typeof record2.script !== "string" || !record2.script || typeof record2.log_path !== "string" || !record2.log_path || !Array.isArray(record2.workers) || record2.workers.length < 1) {
|
|
30799
|
+
throw new Error("Inference-host service manifest is invalid.");
|
|
30409
30800
|
}
|
|
30410
|
-
|
|
30801
|
+
assertServicePath(record2.executable);
|
|
30802
|
+
assertServicePath(record2.script);
|
|
30803
|
+
assertServicePath(record2.log_path);
|
|
30804
|
+
const workers = record2.workers.map(assertWorker);
|
|
30805
|
+
if (new Set(workers.map((worker) => worker.instance_name)).size !== workers.length) {
|
|
30806
|
+
throw new Error("Inference-host service worker names must be unique.");
|
|
30807
|
+
}
|
|
30808
|
+
return { ...record2, workers };
|
|
30411
30809
|
};
|
|
30412
30810
|
assertDesiredState = (value) => {
|
|
30413
30811
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
@@ -30459,14 +30857,18 @@ var init_service = __esm({
|
|
|
30459
30857
|
}, null, 2)}
|
|
30460
30858
|
`);
|
|
30461
30859
|
};
|
|
30462
|
-
runtimeEnvironment = (config2) => {
|
|
30860
|
+
runtimeEnvironment = (config2, maxConcurrency) => {
|
|
30463
30861
|
const result2 = {
|
|
30464
30862
|
VTX_API_URL: config2.apiUrl,
|
|
30465
|
-
VTX_INFERENCE_HOST_HOME:
|
|
30863
|
+
VTX_INFERENCE_HOST_HOME: config2.baseDir,
|
|
30864
|
+
VTX_INFERENCE_HOST_INSTANCE: config2.instanceName,
|
|
30466
30865
|
VTX_INFERENCE_HOST_CREDENTIAL_STORE: config2.credentialStoreMode,
|
|
30467
30866
|
VTX_INFERENCE_HOST_STATE_PATH: config2.statePath,
|
|
30468
30867
|
VTX_INFERENCE_HOST_LOCK_PATH: config2.processLockPath
|
|
30469
30868
|
};
|
|
30869
|
+
if (maxConcurrency !== null) {
|
|
30870
|
+
result2.VTX_INFERENCE_HOST_MAX_CONCURRENCY = String(maxConcurrency);
|
|
30871
|
+
}
|
|
30470
30872
|
if (config2.credentialFilePath) {
|
|
30471
30873
|
result2.VTX_INFERENCE_HOST_CREDENTIAL_FILE = config2.credentialFilePath;
|
|
30472
30874
|
}
|
|
@@ -30581,7 +30983,7 @@ WantedBy=default.target
|
|
|
30581
30983
|
return inferenceHostServiceLogPath(this.config);
|
|
30582
30984
|
}
|
|
30583
30985
|
controlLockPath() {
|
|
30584
|
-
return `${this.config.
|
|
30986
|
+
return `${this.config.supervisorProcessLockPath}.service-control`;
|
|
30585
30987
|
}
|
|
30586
30988
|
async withControlLock(operation) {
|
|
30587
30989
|
let lock2 = null;
|
|
@@ -30617,12 +31019,12 @@ WantedBy=default.target
|
|
|
30617
31019
|
];
|
|
30618
31020
|
}
|
|
30619
31021
|
definitionPath() {
|
|
30620
|
-
if (this.platform === "win32") return `${this.config.
|
|
31022
|
+
if (this.platform === "win32") return `${this.config.supervisorStatePath}.service-task.xml`;
|
|
30621
31023
|
if (this.platform === "darwin") return join5(this.home, "Library", "LaunchAgents", `${LAUNCHD_LABEL}.plist`);
|
|
30622
31024
|
return join5(this.home, ".config", "systemd", "user", SYSTEMD_UNIT);
|
|
30623
31025
|
}
|
|
30624
31026
|
windowsLauncherPath() {
|
|
30625
|
-
return `${this.config.
|
|
31027
|
+
return `${this.config.supervisorStatePath}.service-launcher.vbs`;
|
|
30626
31028
|
}
|
|
30627
31029
|
async managerCommand(action) {
|
|
30628
31030
|
const definition = this.definitionPath();
|
|
@@ -30665,37 +31067,19 @@ WantedBy=default.target
|
|
|
30665
31067
|
}
|
|
30666
31068
|
throw new Error("Background service did not reach an active state within 10 seconds.");
|
|
30667
31069
|
}
|
|
30668
|
-
async
|
|
30669
|
-
|
|
30670
|
-
|
|
30671
|
-
async installUnlocked(options) {
|
|
30672
|
-
if (await readInferenceHostServiceManifest(this.manifestPath())) {
|
|
30673
|
-
await this.uninstallUnlocked();
|
|
30674
|
-
}
|
|
30675
|
-
await access3(this.executable);
|
|
30676
|
-
await access3(this.script);
|
|
30677
|
-
const manifest = assertManifest({
|
|
30678
|
-
schema_version: "vtx_inference_service_v1",
|
|
30679
|
-
installed_at: this.now().toISOString(),
|
|
30680
|
-
adapter: options.adapter,
|
|
30681
|
-
executable: this.executable,
|
|
30682
|
-
script: this.script,
|
|
30683
|
-
display_name: options.displayName,
|
|
30684
|
-
log_path: this.logPath(),
|
|
30685
|
-
runtime_environment: runtimeEnvironment(this.config)
|
|
30686
|
-
});
|
|
30687
|
-
const args = serviceArguments(this.script, this.manifestPath());
|
|
30688
|
-
const definition = this.platform === "win32" ? windowsTaskXml(this.windowsLauncherPath(), this.windowsDirectory, this.username) : this.platform === "darwin" ? launchAgentPlist(this.executable, args, this.logPath()) : systemdUnit(this.executable, args);
|
|
31070
|
+
async registerManifestUnlocked(manifest, desiredRunning) {
|
|
31071
|
+
const args = serviceArguments(manifest.script, this.manifestPath());
|
|
31072
|
+
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);
|
|
30689
31073
|
let managerInstallAttempted = false;
|
|
30690
31074
|
try {
|
|
30691
31075
|
await writeAtomicInferencePrivateFile(this.manifestPath(), `${JSON.stringify(manifest, null, 2)}
|
|
30692
31076
|
`);
|
|
30693
|
-
await writeDesired(this.desiredPath(),
|
|
31077
|
+
await writeDesired(this.desiredPath(), desiredRunning, this.now());
|
|
30694
31078
|
await mkdir3(dirname4(this.definitionPath()), { recursive: true, mode: 448 });
|
|
30695
31079
|
if (this.platform === "win32") {
|
|
30696
31080
|
await writeAtomicInferencePrivateFile(
|
|
30697
31081
|
this.windowsLauncherPath(),
|
|
30698
|
-
windowsServiceLauncher(
|
|
31082
|
+
windowsServiceLauncher(manifest.executable, args)
|
|
30699
31083
|
);
|
|
30700
31084
|
await writeFile2(this.definitionPath(), `\uFEFF${definition}`, {
|
|
30701
31085
|
encoding: "utf16le",
|
|
@@ -30712,7 +31096,7 @@ WantedBy=default.target
|
|
|
30712
31096
|
managerInstallAttempted = true;
|
|
30713
31097
|
const installed = await this.managerCommand("install");
|
|
30714
31098
|
if (installed.exitCode !== 0) throw new Error(`Background service installation failed: ${installed.stderr.trim()}`);
|
|
30715
|
-
if (
|
|
31099
|
+
if (desiredRunning) {
|
|
30716
31100
|
const started = await this.managerCommand("start");
|
|
30717
31101
|
if (started.exitCode !== 0 && !/already running|in progress/iu.test(`${started.stdout}
|
|
30718
31102
|
${started.stderr}`)) {
|
|
@@ -30720,6 +31104,7 @@ ${started.stderr}`)) {
|
|
|
30720
31104
|
}
|
|
30721
31105
|
await this.waitForManagerActive();
|
|
30722
31106
|
}
|
|
31107
|
+
return await this.status();
|
|
30723
31108
|
} catch (error48) {
|
|
30724
31109
|
await writeDesired(this.desiredPath(), false, this.now()).catch(() => void 0);
|
|
30725
31110
|
if (managerInstallAttempted) {
|
|
@@ -30747,7 +31132,83 @@ ${cleanup.stderr}`)) {
|
|
|
30747
31132
|
}
|
|
30748
31133
|
throw error48;
|
|
30749
31134
|
}
|
|
30750
|
-
|
|
31135
|
+
}
|
|
31136
|
+
async replaceManifestUnlocked(next, desiredRunning) {
|
|
31137
|
+
const previous = await readInferenceHostServiceManifest(this.manifestPath());
|
|
31138
|
+
const previousDesired = previous ? await readInferenceHostServiceDesired(this.desiredPath()) : false;
|
|
31139
|
+
if (previous) await this.uninstallUnlocked();
|
|
31140
|
+
try {
|
|
31141
|
+
return await this.registerManifestUnlocked(next, desiredRunning);
|
|
31142
|
+
} catch (error48) {
|
|
31143
|
+
if (!previous) throw error48;
|
|
31144
|
+
try {
|
|
31145
|
+
await this.registerManifestUnlocked(previous, previousDesired);
|
|
31146
|
+
} catch (rollbackError) {
|
|
31147
|
+
throw new Error(
|
|
31148
|
+
"Inference-host service reconfiguration failed and the previous supervisor could not be restored.",
|
|
31149
|
+
{ cause: new AggregateError([error48, rollbackError]) }
|
|
31150
|
+
);
|
|
31151
|
+
}
|
|
31152
|
+
throw new Error(
|
|
31153
|
+
"Inference-host service reconfiguration failed; the previous supervisor was restored.",
|
|
31154
|
+
{ cause: error48 }
|
|
31155
|
+
);
|
|
31156
|
+
}
|
|
31157
|
+
}
|
|
31158
|
+
async install(options) {
|
|
31159
|
+
return await this.withControlLock(async () => await this.installUnlocked(options));
|
|
31160
|
+
}
|
|
31161
|
+
async installUnlocked(options) {
|
|
31162
|
+
const existing = await readInferenceHostServiceManifest(this.manifestPath());
|
|
31163
|
+
const normalizedEmail = options.authenticatedAccountEmail?.trim().toLowerCase() || null;
|
|
31164
|
+
const otherWorkers = existing?.workers.filter(
|
|
31165
|
+
(worker) => worker.instance_name !== this.config.instanceName
|
|
31166
|
+
) ?? [];
|
|
31167
|
+
if (otherWorkers.length > 0 && (!normalizedEmail || otherWorkers.some((worker) => !worker.authenticated_account_email))) {
|
|
31168
|
+
throw new Error(
|
|
31169
|
+
"Cannot prove that every installed instance uses a distinct ChatGPT subscription. Reinstall instances with live account identity before adding another."
|
|
31170
|
+
);
|
|
31171
|
+
}
|
|
31172
|
+
if (normalizedEmail && otherWorkers.some((worker) => worker.authenticated_account_email?.trim().toLowerCase() === normalizedEmail)) {
|
|
31173
|
+
throw new Error(
|
|
31174
|
+
"This ChatGPT subscription is already installed under another inference-host instance."
|
|
31175
|
+
);
|
|
31176
|
+
}
|
|
31177
|
+
if (this.config.credentialFilePath && otherWorkers.some((worker) => {
|
|
31178
|
+
const otherPath = worker.runtime_environment.VTX_INFERENCE_HOST_CREDENTIAL_FILE;
|
|
31179
|
+
return otherPath && resolve4(otherPath) === resolve4(this.config.credentialFilePath);
|
|
31180
|
+
})) {
|
|
31181
|
+
throw new Error(
|
|
31182
|
+
"Each inference-host instance must use a different private credential file."
|
|
31183
|
+
);
|
|
31184
|
+
}
|
|
31185
|
+
await access3(this.executable);
|
|
31186
|
+
await access3(this.script);
|
|
31187
|
+
const maxConcurrency = options.maxConcurrency ?? null;
|
|
31188
|
+
const workers = [
|
|
31189
|
+
...existing?.workers.filter((worker) => worker.instance_name !== this.config.instanceName) ?? [],
|
|
31190
|
+
{
|
|
31191
|
+
instance_name: this.config.instanceName,
|
|
31192
|
+
adapter: options.adapter,
|
|
31193
|
+
display_name: options.displayName,
|
|
31194
|
+
max_concurrency: maxConcurrency,
|
|
31195
|
+
authenticated_account_email: normalizedEmail,
|
|
31196
|
+
authenticated_account_plan: options.authenticatedAccountPlan ?? null,
|
|
31197
|
+
runtime_environment: runtimeEnvironment(this.config, maxConcurrency)
|
|
31198
|
+
}
|
|
31199
|
+
].sort((left, right) => left.instance_name.localeCompare(right.instance_name));
|
|
31200
|
+
const manifest = assertManifest({
|
|
31201
|
+
schema_version: "vtx_inference_service_v3",
|
|
31202
|
+
installed_at: this.now().toISOString(),
|
|
31203
|
+
executable: this.executable,
|
|
31204
|
+
script: this.script,
|
|
31205
|
+
log_path: this.logPath(),
|
|
31206
|
+
workers
|
|
31207
|
+
});
|
|
31208
|
+
return await this.replaceManifestUnlocked(
|
|
31209
|
+
manifest,
|
|
31210
|
+
options.startImmediately !== false
|
|
31211
|
+
);
|
|
30751
31212
|
}
|
|
30752
31213
|
async start() {
|
|
30753
31214
|
return await this.withControlLock(async () => await this.startUnlocked());
|
|
@@ -30774,11 +31235,12 @@ ${result2.stderr}`)) {
|
|
|
30774
31235
|
return await this.withControlLock(async () => await this.stopUnlocked());
|
|
30775
31236
|
}
|
|
30776
31237
|
async stopUnlocked() {
|
|
30777
|
-
|
|
31238
|
+
const manifest = await readInferenceHostServiceManifest(this.manifestPath());
|
|
31239
|
+
if (!manifest) {
|
|
30778
31240
|
throw new Error("Inference-host service is not installed.");
|
|
30779
31241
|
}
|
|
30780
31242
|
await writeDesired(this.desiredPath(), false, this.now());
|
|
30781
|
-
const serviceLockPath = `${this.config.
|
|
31243
|
+
const serviceLockPath = `${this.config.supervisorProcessLockPath}.service`;
|
|
30782
31244
|
let serviceReleased = false;
|
|
30783
31245
|
for (let attempt = 0; attempt < this.stopWaitAttempts; attempt += 1) {
|
|
30784
31246
|
try {
|
|
@@ -30796,7 +31258,7 @@ ${result2.stderr}`)) {
|
|
|
30796
31258
|
}
|
|
30797
31259
|
if (!serviceReleased) {
|
|
30798
31260
|
throw new Error(
|
|
30799
|
-
`Inference-host
|
|
31261
|
+
`Inference-host workers did not stop cooperatively within ${SERVICE_COOPERATIVE_STOP_SECONDS} seconds; refusing forced termination while cleanup may be pending.`
|
|
30800
31262
|
);
|
|
30801
31263
|
}
|
|
30802
31264
|
const result2 = await this.managerCommand("stop");
|
|
@@ -30822,22 +31284,56 @@ ${result2.stderr}`)) {
|
|
|
30822
31284
|
manager_active: managerActive,
|
|
30823
31285
|
manager: managerName(this.platform),
|
|
30824
31286
|
manager_state: result2.exitCode === 0 ? output3 || "installed" : "not-installed",
|
|
30825
|
-
adapter: manifest
|
|
30826
|
-
log_path: manifest?.log_path ?? this.logPath()
|
|
31287
|
+
adapter: manifest ? "codex" : null,
|
|
31288
|
+
log_path: manifest?.log_path ?? this.logPath(),
|
|
31289
|
+
workers: manifest?.workers.map((worker) => ({
|
|
31290
|
+
instance_name: worker.instance_name,
|
|
31291
|
+
display_name: worker.display_name,
|
|
31292
|
+
max_concurrency: worker.max_concurrency,
|
|
31293
|
+
authenticated_account_email: worker.authenticated_account_email,
|
|
31294
|
+
authenticated_account_plan: worker.authenticated_account_plan
|
|
31295
|
+
})) ?? []
|
|
30827
31296
|
};
|
|
30828
31297
|
}
|
|
30829
|
-
async logs(lines = 100) {
|
|
31298
|
+
async logs(lines = 100, instanceName) {
|
|
30830
31299
|
const manifest = await readInferenceHostServiceManifest(this.manifestPath());
|
|
30831
31300
|
const path = manifest?.log_path ?? this.logPath();
|
|
30832
31301
|
try {
|
|
30833
31302
|
const contents = await readFile5(path, "utf8");
|
|
30834
|
-
|
|
30835
|
-
|
|
31303
|
+
const logLines = contents.trimEnd().split(/\r?\n/u);
|
|
31304
|
+
const filtered = instanceName ? logLines.filter((line) => {
|
|
31305
|
+
try {
|
|
31306
|
+
const parsed = JSON.parse(line);
|
|
31307
|
+
return parsed.instance_name === instanceName || Array.isArray(parsed.instances) && parsed.instances.includes(instanceName);
|
|
31308
|
+
} catch {
|
|
31309
|
+
return false;
|
|
31310
|
+
}
|
|
31311
|
+
}) : logLines;
|
|
31312
|
+
return filtered.length > 0 ? `${filtered.slice(-lines).join("\n")}
|
|
31313
|
+
` : "";
|
|
30836
31314
|
} catch (error48) {
|
|
30837
31315
|
if (error48.code === "ENOENT") return "";
|
|
30838
31316
|
throw error48;
|
|
30839
31317
|
}
|
|
30840
31318
|
}
|
|
31319
|
+
async uninstallInstance(instanceName) {
|
|
31320
|
+
return await this.withControlLock(async () => {
|
|
31321
|
+
const manifest = await readInferenceHostServiceManifest(this.manifestPath());
|
|
31322
|
+
if (!manifest) throw new Error("Inference-host service is not installed.");
|
|
31323
|
+
if (!manifest.workers.some((worker) => worker.instance_name === instanceName)) {
|
|
31324
|
+
throw new Error(`Inference-host instance ${instanceName} is not installed.`);
|
|
31325
|
+
}
|
|
31326
|
+
const remaining = manifest.workers.filter(
|
|
31327
|
+
(worker) => worker.instance_name !== instanceName
|
|
31328
|
+
);
|
|
31329
|
+
if (remaining.length === 0) return await this.uninstallUnlocked();
|
|
31330
|
+
return await this.replaceManifestUnlocked({
|
|
31331
|
+
...manifest,
|
|
31332
|
+
installed_at: this.now().toISOString(),
|
|
31333
|
+
workers: remaining
|
|
31334
|
+
}, await readInferenceHostServiceDesired(this.desiredPath()));
|
|
31335
|
+
});
|
|
31336
|
+
}
|
|
30841
31337
|
async uninstall() {
|
|
30842
31338
|
return await this.withControlLock(async () => await this.uninstallUnlocked());
|
|
30843
31339
|
}
|
|
@@ -30867,7 +31363,8 @@ ${result2.stderr}`)) {
|
|
|
30867
31363
|
manager: managerName(this.platform),
|
|
30868
31364
|
manager_state: "not-installed",
|
|
30869
31365
|
adapter: null,
|
|
30870
|
-
log_path: manifest.log_path
|
|
31366
|
+
log_path: manifest.log_path,
|
|
31367
|
+
workers: []
|
|
30871
31368
|
};
|
|
30872
31369
|
}
|
|
30873
31370
|
};
|
|
@@ -30880,39 +31377,74 @@ ${result2.stderr}`)) {
|
|
|
30880
31377
|
`, resolvePromise);
|
|
30881
31378
|
});
|
|
30882
31379
|
};
|
|
30883
|
-
spawnServiceChild = async (manifest, signal) => {
|
|
31380
|
+
spawnServiceChild = async (manifest, worker, signal) => {
|
|
30884
31381
|
const args = [
|
|
30885
31382
|
manifest.script,
|
|
30886
31383
|
"inference-host",
|
|
30887
31384
|
"run",
|
|
30888
31385
|
"--json",
|
|
30889
31386
|
"--display-name",
|
|
30890
|
-
|
|
31387
|
+
worker.display_name
|
|
30891
31388
|
];
|
|
30892
31389
|
const startedAt = Date.now();
|
|
30893
31390
|
const log = createWriteStream(manifest.log_path, { flags: "a", mode: 384 });
|
|
30894
31391
|
return await new Promise((resolvePromise, reject) => {
|
|
30895
31392
|
let stdout = "";
|
|
31393
|
+
const pending = { stdout: "", stderr: "" };
|
|
31394
|
+
const writeTaggedOutput = (stream, text, flush = false) => {
|
|
31395
|
+
const lines = `${pending[stream]}${text}`.split(/\r?\n/u);
|
|
31396
|
+
const remainder = lines.pop() ?? "";
|
|
31397
|
+
pending[stream] = flush ? "" : remainder;
|
|
31398
|
+
if (flush && remainder) lines.push(remainder);
|
|
31399
|
+
if (flush && lines.at(-1) === "") lines.pop();
|
|
31400
|
+
for (const line of lines) {
|
|
31401
|
+
if (!line) continue;
|
|
31402
|
+
try {
|
|
31403
|
+
const parsed = JSON.parse(line);
|
|
31404
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
31405
|
+
log.write(`${JSON.stringify({
|
|
31406
|
+
...parsed,
|
|
31407
|
+
instance_name: worker.instance_name
|
|
31408
|
+
})}
|
|
31409
|
+
`);
|
|
31410
|
+
continue;
|
|
31411
|
+
}
|
|
31412
|
+
} catch {
|
|
31413
|
+
}
|
|
31414
|
+
log.write(`${JSON.stringify({
|
|
31415
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
31416
|
+
event: "worker_output",
|
|
31417
|
+
instance_name: worker.instance_name,
|
|
31418
|
+
stream,
|
|
31419
|
+
message: line.slice(0, 4096)
|
|
31420
|
+
})}
|
|
31421
|
+
`);
|
|
31422
|
+
}
|
|
31423
|
+
};
|
|
30896
31424
|
const child = spawn5(manifest.executable, args, {
|
|
30897
|
-
env:
|
|
31425
|
+
env: inferenceHostServiceChildEnvironment(worker.runtime_environment),
|
|
30898
31426
|
windowsHide: true,
|
|
30899
31427
|
stdio: ["ignore", "pipe", "pipe"]
|
|
30900
31428
|
});
|
|
30901
31429
|
child.stdout.on("data", (chunk) => {
|
|
30902
31430
|
const text = chunk.toString("utf8");
|
|
30903
|
-
|
|
31431
|
+
writeTaggedOutput("stdout", text);
|
|
30904
31432
|
stdout = `${stdout}${text}`.slice(-65536);
|
|
30905
31433
|
});
|
|
30906
|
-
child.stderr.on("data", (chunk) =>
|
|
31434
|
+
child.stderr.on("data", (chunk) => writeTaggedOutput("stderr", chunk.toString("utf8")));
|
|
30907
31435
|
const onAbort = () => child.kill("SIGTERM");
|
|
30908
31436
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
30909
31437
|
child.once("error", (error48) => {
|
|
30910
31438
|
signal.removeEventListener("abort", onAbort);
|
|
31439
|
+
writeTaggedOutput("stdout", "", true);
|
|
31440
|
+
writeTaggedOutput("stderr", "", true);
|
|
30911
31441
|
log.end();
|
|
30912
31442
|
reject(error48);
|
|
30913
31443
|
});
|
|
30914
31444
|
child.once("exit", (code) => {
|
|
30915
31445
|
signal.removeEventListener("abort", onAbort);
|
|
31446
|
+
writeTaggedOutput("stdout", "", true);
|
|
31447
|
+
writeTaggedOutput("stderr", "", true);
|
|
30916
31448
|
log.end();
|
|
30917
31449
|
let drainReason = null;
|
|
30918
31450
|
for (const line of stdout.trim().split("\n").reverse()) {
|
|
@@ -30938,64 +31470,72 @@ ${result2.stderr}`)) {
|
|
|
30938
31470
|
runInferenceHostServiceSupervisor = async (manifestPath, options = {}) => {
|
|
30939
31471
|
const manifest = await readInferenceHostServiceManifest(manifestPath);
|
|
30940
31472
|
if (!manifest) throw new Error("Inference-host service manifest is missing.");
|
|
30941
|
-
const desiredPath =
|
|
31473
|
+
const desiredPath = manifestPath.replace(/\.service\.json$/u, ".service-desired.json");
|
|
30942
31474
|
const signal = options.signal ?? new AbortController().signal;
|
|
30943
31475
|
const sleep4 = options.sleep ?? (async (milliseconds) => {
|
|
30944
31476
|
await new Promise((resolvePromise) => setTimeout(resolvePromise, milliseconds));
|
|
30945
31477
|
});
|
|
30946
31478
|
const launch = options.runWorker ?? options.spawnChild ?? spawnServiceChild;
|
|
30947
|
-
|
|
30948
|
-
|
|
30949
|
-
|
|
30950
|
-
|
|
30951
|
-
|
|
30952
|
-
|
|
30953
|
-
|
|
30954
|
-
let workerComplete = false;
|
|
30955
|
-
let monitorError = null;
|
|
30956
|
-
const desiredMonitor = (async () => {
|
|
30957
|
-
while (!workerComplete && !workerController.signal.aborted) {
|
|
30958
|
-
await sleep4(500);
|
|
30959
|
-
if (!await readDesiredAcrossAtomicReplacement(desiredPath)) {
|
|
30960
|
-
workerController.abort();
|
|
30961
|
-
break;
|
|
30962
|
-
}
|
|
30963
|
-
}
|
|
30964
|
-
})().catch((error48) => {
|
|
30965
|
-
monitorError = error48;
|
|
30966
|
-
workerController.abort();
|
|
30967
|
-
});
|
|
30968
|
-
let result2;
|
|
31479
|
+
await appendServiceLog(manifest.log_path, "service_supervisor_started", {
|
|
31480
|
+
adapter: "codex",
|
|
31481
|
+
instances: manifest.workers.map((worker) => worker.instance_name)
|
|
31482
|
+
});
|
|
31483
|
+
const superviseWorker = async (worker) => {
|
|
31484
|
+
let failures = 0;
|
|
31485
|
+
while (!signal.aborted && await readDesiredAcrossAtomicReplacement(desiredPath)) {
|
|
30969
31486
|
try {
|
|
30970
|
-
|
|
30971
|
-
|
|
30972
|
-
|
|
30973
|
-
|
|
30974
|
-
|
|
30975
|
-
|
|
30976
|
-
|
|
30977
|
-
|
|
30978
|
-
|
|
30979
|
-
|
|
30980
|
-
|
|
30981
|
-
|
|
30982
|
-
|
|
30983
|
-
|
|
30984
|
-
|
|
30985
|
-
|
|
30986
|
-
|
|
30987
|
-
|
|
30988
|
-
|
|
30989
|
-
|
|
30990
|
-
|
|
30991
|
-
|
|
30992
|
-
|
|
30993
|
-
|
|
30994
|
-
|
|
30995
|
-
|
|
30996
|
-
|
|
31487
|
+
const workerController = new AbortController();
|
|
31488
|
+
const forwardAbort = () => workerController.abort();
|
|
31489
|
+
signal.addEventListener("abort", forwardAbort, { once: true });
|
|
31490
|
+
let workerComplete = false;
|
|
31491
|
+
let monitorError = null;
|
|
31492
|
+
const desiredMonitor = (async () => {
|
|
31493
|
+
while (!workerComplete && !workerController.signal.aborted) {
|
|
31494
|
+
await sleep4(500);
|
|
31495
|
+
if (!await readDesiredAcrossAtomicReplacement(desiredPath)) {
|
|
31496
|
+
workerController.abort();
|
|
31497
|
+
break;
|
|
31498
|
+
}
|
|
31499
|
+
}
|
|
31500
|
+
})().catch((error48) => {
|
|
31501
|
+
monitorError = error48;
|
|
31502
|
+
workerController.abort();
|
|
31503
|
+
});
|
|
31504
|
+
let result2;
|
|
31505
|
+
try {
|
|
31506
|
+
result2 = await launch(manifest, worker, workerController.signal);
|
|
31507
|
+
} finally {
|
|
31508
|
+
workerComplete = true;
|
|
31509
|
+
workerController.abort();
|
|
31510
|
+
signal.removeEventListener("abort", forwardAbort);
|
|
31511
|
+
await desiredMonitor;
|
|
31512
|
+
}
|
|
31513
|
+
if (monitorError) throw monitorError;
|
|
31514
|
+
if (signal.aborted || !await readDesiredAcrossAtomicReplacement(desiredPath)) break;
|
|
31515
|
+
failures = result2.uptimeMs >= 6e4 ? 0 : failures + 1;
|
|
31516
|
+
const retryAfterMs = Math.min(1e3 * 2 ** Math.min(failures, 5), 3e4);
|
|
31517
|
+
await appendServiceLog(manifest.log_path, "worker_exited", {
|
|
31518
|
+
instance_name: worker.instance_name,
|
|
31519
|
+
exit_code: result2.exitCode,
|
|
31520
|
+
uptime_ms: result2.uptimeMs,
|
|
31521
|
+
drain_reason: result2.drainReason ?? null,
|
|
31522
|
+
retry_after_ms: retryAfterMs
|
|
31523
|
+
});
|
|
31524
|
+
await sleep4(retryAfterMs);
|
|
31525
|
+
} catch (error48) {
|
|
31526
|
+
if (signal.aborted) break;
|
|
31527
|
+
failures += 1;
|
|
31528
|
+
const retryAfterMs = Math.min(1e3 * 2 ** Math.min(failures, 5), 3e4);
|
|
31529
|
+
await appendServiceLog(manifest.log_path, "worker_launch_failed", {
|
|
31530
|
+
instance_name: worker.instance_name,
|
|
31531
|
+
error: error48 instanceof Error ? error48.message : "unknown",
|
|
31532
|
+
retry_after_ms: retryAfterMs
|
|
31533
|
+
});
|
|
31534
|
+
await sleep4(retryAfterMs);
|
|
31535
|
+
}
|
|
30997
31536
|
}
|
|
30998
|
-
}
|
|
31537
|
+
};
|
|
31538
|
+
await Promise.all(manifest.workers.map(superviseWorker));
|
|
30999
31539
|
await appendServiceLog(manifest.log_path, "service_supervisor_stopped");
|
|
31000
31540
|
};
|
|
31001
31541
|
}
|
|
@@ -31085,7 +31625,7 @@ async function runInferenceHostCli(argv2, env = process.env, dependencies = {})
|
|
|
31085
31625
|
};
|
|
31086
31626
|
}
|
|
31087
31627
|
}
|
|
31088
|
-
var INFERENCE_HOST_CLI_VERSION, runtimeReceiptPath, codexRecoveryPath, codexGuardianReceiptRoot, revocationCheckpointPath, foregroundHostLockPath, AGENT_HEARTBEAT_INTERVAL_MS, AGENT_HEARTBEAT_MAX_RETRY_DELAY_MS, retryableAgentHeartbeatError, assertRevocationCheckpoint, readRevocationCheckpoint, writeRevocationCheckpoint, clearRevocationCheckpoint, render, INFERENCE_HOST_HELP,
|
|
31628
|
+
var INFERENCE_HOST_CLI_VERSION, runtimeReceiptPath, codexRecoveryPath, codexGuardianReceiptRoot, revocationCheckpointPath, foregroundHostLockPath, AGENT_HEARTBEAT_INTERVAL_MS, AGENT_HEARTBEAT_MAX_RETRY_DELAY_MS, retryableAgentHeartbeatError, assertRevocationCheckpoint, readRevocationCheckpoint, writeRevocationCheckpoint, clearRevocationCheckpoint, render, INFERENCE_HOST_HELP, parseHostConcurrency, parseInferenceHostArgs, defaultOpenBrowser, defaultRegisterLifecycleSignalHandlers, lifecycleCancellation, configuredCredentialStore, accountKeyForState, assertCredentialMatchesState2, revocationCheckpointForCredential, assertRevocationCheckpointMatchesLocalIdentity, fileExistsPrivately, inspectCodexAuthentication, clearLocalRuntimeArtifacts, assertDurableServiceUninstalled, assertLocalRuntimeArtifactsMayBeDiscarded, defaultRunForeground, login, codexLogin, codexLogout, localStatus, doctor, cleanupLogin, runHost, defaultReadStdin, parseAgentStdin, agentOperationId, agentSession, agentConnect, agentRun, agentNext, agentComplete, agentFail, withAgentCommandLock, serviceCommand, hasExplicitCredentialStoreConfiguration, commandUsesInstalledServiceCredentials, resolveInferenceHostCommandConfig;
|
|
31089
31629
|
var init_cli = __esm({
|
|
31090
31630
|
"lib/inference-host/cli.ts"() {
|
|
31091
31631
|
"use strict";
|
|
@@ -31189,6 +31729,8 @@ Commands:
|
|
|
31189
31729
|
|
|
31190
31730
|
Common options:
|
|
31191
31731
|
--json Emit machine-readable JSON
|
|
31732
|
+
--instance NAME Target an isolated local subscription instance (default: default)
|
|
31733
|
+
--max-concurrency N Optional positive-integer Codex slot limit (default: unlimited)
|
|
31192
31734
|
--help, -h Show this help
|
|
31193
31735
|
|
|
31194
31736
|
If the OS credential store cannot retain the VTX grant, set
|
|
@@ -31196,23 +31738,29 @@ VTX_INFERENCE_HOST_CREDENTIAL_STORE=file before login to use the supported
|
|
|
31196
31738
|
private-file fallback. See https://vtxmacro.com/insights#subscription-inference.
|
|
31197
31739
|
|
|
31198
31740
|
Durable service:
|
|
31199
|
-
vtx inference-host
|
|
31741
|
+
vtx inference-host login --instance codex-1
|
|
31742
|
+
vtx inference-host codex-login --instance codex-1
|
|
31743
|
+
vtx inference-host service install --instance codex-1
|
|
31744
|
+
vtx inference-host login --instance codex-2
|
|
31745
|
+
vtx inference-host codex-login --instance codex-2
|
|
31746
|
+
vtx inference-host service install --instance codex-2
|
|
31747
|
+
vtx inference-host service uninstall --instance codex-2
|
|
31200
31748
|
vtx inference-host service <start|stop|status|logs|uninstall>
|
|
31201
31749
|
`;
|
|
31202
|
-
|
|
31750
|
+
parseHostConcurrency = (raw, label) => {
|
|
31203
31751
|
const value = Number(raw);
|
|
31204
|
-
if (value
|
|
31205
|
-
throw new Error(`${label} must be
|
|
31752
|
+
if (!Number.isSafeInteger(value) || value < 1) {
|
|
31753
|
+
throw new Error(`${label} must be a positive safe integer.`);
|
|
31206
31754
|
}
|
|
31207
31755
|
return value;
|
|
31208
31756
|
};
|
|
31209
31757
|
parseInferenceHostArgs = (argv2, env) => {
|
|
31210
31758
|
let json2 = String(env.VTX_OUTPUT_JSON || "").trim().toLowerCase() === "true";
|
|
31211
31759
|
let once = false;
|
|
31212
|
-
|
|
31213
|
-
|
|
31214
|
-
|
|
31215
|
-
);
|
|
31760
|
+
const configuredConcurrency = String(env.VTX_INFERENCE_HOST_MAX_CONCURRENCY || "").trim();
|
|
31761
|
+
let maxConcurrency = configuredConcurrency ? parseHostConcurrency(configuredConcurrency, "VTX_INFERENCE_HOST_MAX_CONCURRENCY") : null;
|
|
31762
|
+
let instanceName = String(env.VTX_INFERENCE_HOST_INSTANCE || "default").trim();
|
|
31763
|
+
let instanceExplicit = Boolean(String(env.VTX_INFERENCE_HOST_INSTANCE || "").trim());
|
|
31216
31764
|
let displayName = String(env.VTX_INFERENCE_HOST_DISPLAY_NAME || "").trim() || "Codex subscription host";
|
|
31217
31765
|
let displayNameExplicit = Boolean(String(env.VTX_INFERENCE_HOST_DISPLAY_NAME || "").trim());
|
|
31218
31766
|
let adapter = null;
|
|
@@ -31236,7 +31784,7 @@ Durable service:
|
|
|
31236
31784
|
if (argument === "--max-concurrency") {
|
|
31237
31785
|
const raw = argv2[index + 1];
|
|
31238
31786
|
if (!raw) throw new Error("--max-concurrency requires a value.");
|
|
31239
|
-
maxConcurrency =
|
|
31787
|
+
maxConcurrency = parseHostConcurrency(raw, "--max-concurrency");
|
|
31240
31788
|
index += 1;
|
|
31241
31789
|
continue;
|
|
31242
31790
|
}
|
|
@@ -31248,7 +31796,7 @@ Durable service:
|
|
|
31248
31796
|
index += 1;
|
|
31249
31797
|
continue;
|
|
31250
31798
|
}
|
|
31251
|
-
if (["--adapter", "--model", "--model-label", "--effort", "--wait-seconds", "--lines", "--service-manifest"].includes(argument)) {
|
|
31799
|
+
if (["--adapter", "--model", "--model-label", "--effort", "--wait-seconds", "--lines", "--service-manifest", "--instance"].includes(argument)) {
|
|
31252
31800
|
const raw = argv2[index + 1];
|
|
31253
31801
|
if (!raw?.trim()) throw new Error(`${argument} requires a value.`);
|
|
31254
31802
|
if (argument === "--adapter") adapter = raw.trim();
|
|
@@ -31268,6 +31816,10 @@ Durable service:
|
|
|
31268
31816
|
}
|
|
31269
31817
|
}
|
|
31270
31818
|
if (argument === "--service-manifest") serviceManifestPath = resolve5(raw.trim());
|
|
31819
|
+
if (argument === "--instance") {
|
|
31820
|
+
instanceName = raw.trim();
|
|
31821
|
+
instanceExplicit = true;
|
|
31822
|
+
}
|
|
31271
31823
|
index += 1;
|
|
31272
31824
|
continue;
|
|
31273
31825
|
}
|
|
@@ -31295,6 +31847,8 @@ Durable service:
|
|
|
31295
31847
|
json: json2,
|
|
31296
31848
|
once,
|
|
31297
31849
|
maxConcurrency,
|
|
31850
|
+
instanceName,
|
|
31851
|
+
instanceExplicit,
|
|
31298
31852
|
displayName,
|
|
31299
31853
|
adapter,
|
|
31300
31854
|
modelId,
|
|
@@ -31406,9 +31960,10 @@ Durable service:
|
|
|
31406
31960
|
await clearInferenceHostLocalState(config2.statePath);
|
|
31407
31961
|
};
|
|
31408
31962
|
assertDurableServiceUninstalled = async (config2) => {
|
|
31409
|
-
|
|
31963
|
+
const manifest = await readInferenceHostServiceManifest(`${config2.supervisorStatePath}.service.json`);
|
|
31964
|
+
if (manifest?.workers.some((worker) => worker.instance_name === config2.instanceName)) {
|
|
31410
31965
|
throw new Error(
|
|
31411
|
-
|
|
31966
|
+
`Uninstall the durable inference-host service before changing credentials for instance ${config2.instanceName}.`
|
|
31412
31967
|
);
|
|
31413
31968
|
}
|
|
31414
31969
|
};
|
|
@@ -31459,6 +32014,7 @@ Durable service:
|
|
|
31459
32014
|
...dependencies,
|
|
31460
32015
|
acquireProcessLock: async () => borrowedProcessLock
|
|
31461
32016
|
}, {
|
|
32017
|
+
instanceName: options.config.instanceName,
|
|
31462
32018
|
displayName: options.displayName,
|
|
31463
32019
|
authenticatedAccountEmail: options.authenticatedAccountEmail,
|
|
31464
32020
|
authenticatedAccountPlan: options.authenticatedAccountPlan,
|
|
@@ -31468,6 +32024,7 @@ Durable service:
|
|
|
31468
32024
|
adapterRuntimeVersion: INFERENCE_HOST_CLI_VERSION,
|
|
31469
32025
|
maxConcurrency: options.maxConcurrency,
|
|
31470
32026
|
once: options.once,
|
|
32027
|
+
emitDiagnosticEvent: options.emitDiagnosticEvent,
|
|
31471
32028
|
signal: options.signal
|
|
31472
32029
|
}).run();
|
|
31473
32030
|
};
|
|
@@ -31969,6 +32526,10 @@ Waiting for approval...
|
|
|
31969
32526
|
once: parsed.once,
|
|
31970
32527
|
env,
|
|
31971
32528
|
processLock,
|
|
32529
|
+
emitDiagnosticEvent: parsed.json ? (event) => (dependencies.emitStdout ?? ((text) => {
|
|
32530
|
+
process.stdout.write(text);
|
|
32531
|
+
}))(`${JSON.stringify(event)}
|
|
32532
|
+
`) : void 0,
|
|
31972
32533
|
signal: cancellation.signal
|
|
31973
32534
|
});
|
|
31974
32535
|
return {
|
|
@@ -32436,55 +32997,19 @@ Waiting for approval...
|
|
|
32436
32997
|
if (!parsed.serviceManifestPath) throw new Error("Internal service manifest path is required.");
|
|
32437
32998
|
const serviceManifest = await readInferenceHostServiceManifest(parsed.serviceManifestPath);
|
|
32438
32999
|
if (!serviceManifest) throw new Error("Inference-host service manifest is missing.");
|
|
32439
|
-
const
|
|
33000
|
+
const supervisorConfig = resolveInferenceHostConfig({
|
|
32440
33001
|
...env,
|
|
32441
|
-
...serviceManifest.runtime_environment
|
|
33002
|
+
...serviceManifest.workers[0].runtime_environment
|
|
32442
33003
|
});
|
|
32443
33004
|
const serviceLock = await acquireInferenceHostProcessLock(
|
|
32444
|
-
`${
|
|
33005
|
+
`${supervisorConfig.supervisorProcessLockPath}.service`
|
|
32445
33006
|
);
|
|
32446
33007
|
const cancellation = lifecycleCancellation(dependencies);
|
|
32447
33008
|
try {
|
|
32448
33009
|
await (dependencies.runServiceSupervisor ?? runInferenceHostServiceSupervisor)(
|
|
32449
33010
|
parsed.serviceManifestPath,
|
|
32450
33011
|
{
|
|
32451
|
-
signal: cancellation.signal
|
|
32452
|
-
runWorker: async (manifest, signal) => {
|
|
32453
|
-
const startedAt = Date.now();
|
|
32454
|
-
const serviceEnv = { ...env, ...manifest.runtime_environment };
|
|
32455
|
-
const serviceConfig2 = resolveInferenceHostConfig(serviceEnv);
|
|
32456
|
-
const unregister = (abort) => {
|
|
32457
|
-
const onAbort = () => abort("SIGTERM");
|
|
32458
|
-
signal.addEventListener("abort", onAbort, { once: true });
|
|
32459
|
-
return () => signal.removeEventListener("abort", onAbort);
|
|
32460
|
-
};
|
|
32461
|
-
const result2 = await runHost(serviceConfig2, {
|
|
32462
|
-
...parsed,
|
|
32463
|
-
command: "run",
|
|
32464
|
-
serviceAction: null,
|
|
32465
|
-
serviceManifestPath: null,
|
|
32466
|
-
displayName: manifest.display_name,
|
|
32467
|
-
once: false
|
|
32468
|
-
}, serviceEnv, {
|
|
32469
|
-
...dependencies,
|
|
32470
|
-
registerLifecycleSignalHandlers: unregister
|
|
32471
|
-
}, warnings);
|
|
32472
|
-
let drainReason = null;
|
|
32473
|
-
try {
|
|
32474
|
-
const summary = JSON.parse(result2.stdout);
|
|
32475
|
-
if (summary && typeof summary === "object" && !Array.isArray(summary) && typeof summary.drain_reason === "string" && /^[a-z0-9_]{1,96}$/u.test(
|
|
32476
|
-
summary.drain_reason
|
|
32477
|
-
)) {
|
|
32478
|
-
drainReason = summary.drain_reason;
|
|
32479
|
-
}
|
|
32480
|
-
} catch {
|
|
32481
|
-
}
|
|
32482
|
-
return {
|
|
32483
|
-
exitCode: result2.exitCode,
|
|
32484
|
-
uptimeMs: Date.now() - startedAt,
|
|
32485
|
-
drainReason
|
|
32486
|
-
};
|
|
32487
|
-
}
|
|
33012
|
+
signal: cancellation.signal
|
|
32488
33013
|
}
|
|
32489
33014
|
);
|
|
32490
33015
|
return { exitCode: 0, stdout: "", stderr: "" };
|
|
@@ -32518,12 +33043,18 @@ Waiting for approval...
|
|
|
32518
33043
|
throw new Error("Run vtx inference-host codex-login before installing the automated Codex service.");
|
|
32519
33044
|
}
|
|
32520
33045
|
const binary = await (dependencies.resolveBinary ?? resolvePinnedCodexBinary)(env);
|
|
32521
|
-
await (dependencies.preflightCodex ?? preflightCodexSubscription)({
|
|
33046
|
+
const preflight = await (dependencies.preflightCodex ?? preflightCodexSubscription)({
|
|
32522
33047
|
binary,
|
|
32523
33048
|
codexHome: config2.codexHomePath,
|
|
32524
33049
|
deadlineAtMs: Date.now() + 3e4
|
|
32525
33050
|
});
|
|
32526
|
-
const status = await manager.install({
|
|
33051
|
+
const status = await manager.install({
|
|
33052
|
+
adapter: "codex",
|
|
33053
|
+
displayName: parsed.displayName,
|
|
33054
|
+
maxConcurrency: parsed.maxConcurrency,
|
|
33055
|
+
authenticatedAccountEmail: preflight?.authenticated_account_email ?? null,
|
|
33056
|
+
authenticatedAccountPlan: preflight?.authenticated_account_plan ?? null
|
|
33057
|
+
});
|
|
32527
33058
|
return {
|
|
32528
33059
|
exitCode: 0,
|
|
32529
33060
|
stdout: render({ status: "service_installed", ...status }, parsed.json),
|
|
@@ -32535,7 +33066,14 @@ Waiting for approval...
|
|
|
32535
33066
|
throw new Error("Service adapter and model options are accepted only by service install.");
|
|
32536
33067
|
}
|
|
32537
33068
|
if (action === "logs") {
|
|
32538
|
-
return {
|
|
33069
|
+
return {
|
|
33070
|
+
exitCode: 0,
|
|
33071
|
+
stdout: await manager.logs(
|
|
33072
|
+
parsed.lines,
|
|
33073
|
+
parsed.instanceExplicit ? config2.instanceName : void 0
|
|
33074
|
+
),
|
|
33075
|
+
stderr: ""
|
|
33076
|
+
};
|
|
32539
33077
|
}
|
|
32540
33078
|
if (action === "start") {
|
|
32541
33079
|
return { exitCode: 0, stdout: render({ status: "service_started", ...await manager.start() }, parsed.json), stderr: "" };
|
|
@@ -32549,7 +33087,8 @@ Waiting for approval...
|
|
|
32549
33087
|
return { exitCode: lifecycleMatches ? 0 : 1, stdout: render(status, parsed.json), stderr: "" };
|
|
32550
33088
|
}
|
|
32551
33089
|
if (action === "uninstall") {
|
|
32552
|
-
|
|
33090
|
+
const status = parsed.instanceExplicit ? await manager.uninstallInstance(config2.instanceName) : await manager.uninstall();
|
|
33091
|
+
return { exitCode: 0, stdout: render({ status: "service_uninstalled", ...status }, parsed.json), stderr: "" };
|
|
32553
33092
|
}
|
|
32554
33093
|
throw new Error("Usage: vtx inference-host service <install|start|stop|status|logs|uninstall>.");
|
|
32555
33094
|
};
|
|
@@ -32558,16 +33097,20 @@ Waiting for approval...
|
|
|
32558
33097
|
);
|
|
32559
33098
|
commandUsesInstalledServiceCredentials = (parsed) => parsed.command === "status" || parsed.command === "doctor" || parsed.command === "service" && parsed.serviceAction === "install";
|
|
32560
33099
|
resolveInferenceHostCommandConfig = async (parsed, env) => {
|
|
32561
|
-
const
|
|
33100
|
+
const selectedEnv = {
|
|
33101
|
+
...env,
|
|
33102
|
+
VTX_INFERENCE_HOST_INSTANCE: parsed.instanceName
|
|
33103
|
+
};
|
|
33104
|
+
const baseConfig = resolveInferenceHostConfig(selectedEnv);
|
|
32562
33105
|
if (!commandUsesInstalledServiceCredentials(parsed) || hasExplicitCredentialStoreConfiguration(env)) {
|
|
32563
33106
|
return baseConfig;
|
|
32564
33107
|
}
|
|
32565
|
-
const manifestPath = `${baseConfig.
|
|
33108
|
+
const manifestPath = `${baseConfig.supervisorStatePath}.service.json`;
|
|
32566
33109
|
const manifest = await readInferenceHostServiceManifest(manifestPath);
|
|
32567
33110
|
if (!manifest) return baseConfig;
|
|
32568
33111
|
const installedConfig = resolveInferenceHostConfig({
|
|
32569
|
-
...
|
|
32570
|
-
...manifest.runtime_environment
|
|
33112
|
+
...selectedEnv,
|
|
33113
|
+
...manifest.workers.find((worker) => worker.instance_name === baseConfig.instanceName)?.runtime_environment
|
|
32571
33114
|
});
|
|
32572
33115
|
if (resolve5(installedConfig.statePath) !== resolve5(baseConfig.statePath)) {
|
|
32573
33116
|
throw new Error(
|
|
@@ -49994,7 +50537,11 @@ function buildHeadlessExchangeConfig(input) {
|
|
|
49994
50537
|
user_fills_ttl_seconds: readCacheNumberField("user_fills_ttl_seconds"),
|
|
49995
50538
|
stale_if_429_max_age_seconds: readCacheNumberField("stale_if_429_max_age_seconds")
|
|
49996
50539
|
},
|
|
49997
|
-
client_runtime_hyperliquid_case_sensitive_symbols: Array.isArray(input.client_runtime_hyperliquid_case_sensitive_symbols) ? input.client_runtime_hyperliquid_case_sensitive_symbols : null
|
|
50540
|
+
client_runtime_hyperliquid_case_sensitive_symbols: Array.isArray(input.client_runtime_hyperliquid_case_sensitive_symbols) ? input.client_runtime_hyperliquid_case_sensitive_symbols : null,
|
|
50541
|
+
client_runtime_hyperliquid_perp_dexs: input.client_runtime_hyperliquid_perp_dexs ? {
|
|
50542
|
+
enabled: input.client_runtime_hyperliquid_perp_dexs.enabled === true,
|
|
50543
|
+
allowed_dexes: Array.isArray(input.client_runtime_hyperliquid_perp_dexs.allowed_dexes) ? input.client_runtime_hyperliquid_perp_dexs.allowed_dexes.map((dex) => String(dex).trim()).filter(Boolean) : []
|
|
50544
|
+
} : void 0
|
|
49998
50545
|
};
|
|
49999
50546
|
}
|
|
50000
50547
|
async function fetchLocalHyperliquidSnapshot(input) {
|
|
@@ -50010,7 +50557,7 @@ async function fetchLocalHyperliquidSnapshot(input) {
|
|
|
50010
50557
|
symbol: input.symbol,
|
|
50011
50558
|
tickerPrice: 0,
|
|
50012
50559
|
leverage,
|
|
50013
|
-
aggregatePerpDexs:
|
|
50560
|
+
aggregatePerpDexs: true
|
|
50014
50561
|
});
|
|
50015
50562
|
const clientExchangeSnapshot = buildClientExchangeSnapshot({
|
|
50016
50563
|
walletAddress,
|
|
@@ -51041,7 +51588,8 @@ var INFERENCE_HOST_VALUE_OPTIONS = /* @__PURE__ */ new Set([
|
|
|
51041
51588
|
"--effort",
|
|
51042
51589
|
"--wait-seconds",
|
|
51043
51590
|
"--lines",
|
|
51044
|
-
"--service-manifest"
|
|
51591
|
+
"--service-manifest",
|
|
51592
|
+
"--instance"
|
|
51045
51593
|
]);
|
|
51046
51594
|
var isInferenceHostCliInvocation = (argv2) => {
|
|
51047
51595
|
for (let index = 0; index < argv2.length; index += 1) {
|