@vtxmacro/cli 2026.8.11 → 2026.8.12
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 +8 -3
- package/bin/vtx.js +183 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -77,6 +77,7 @@ vtx inference-host agent-connect \
|
|
|
77
77
|
--model-label "<display label>" \
|
|
78
78
|
--effort <reasoning-effort> \
|
|
79
79
|
--json
|
|
80
|
+
vtx inference-host agent-run
|
|
80
81
|
vtx inference-host agent-next --wait-seconds 50 --json
|
|
81
82
|
```
|
|
82
83
|
|
|
@@ -99,7 +100,9 @@ Use `not_dispatched` only when no harness inference began,
|
|
|
99
100
|
`outcome_unknown` when dispatch itself cannot be confirmed. Pipe exactly one
|
|
100
101
|
object to `vtx inference-host agent-fail --json`.
|
|
101
102
|
|
|
102
|
-
Keep
|
|
103
|
+
Keep `agent-run` open in a separate terminal and keep calling `agent-next`
|
|
104
|
+
while the host should remain available. The independent keeper preserves
|
|
105
|
+
truthful liveness while the harness reasons. This same loop
|
|
103
106
|
supports Main, Review, and Screener; Provider response and Decision candidate;
|
|
104
107
|
and normally running VTX Client Mode or Server Mode bots. Server Mode keeps the
|
|
105
108
|
normal VTX call fee. Client Mode has no VTX platform fee. Neither mode falls back
|
|
@@ -107,8 +110,10 @@ to another model when the agent host is unavailable.
|
|
|
107
110
|
|
|
108
111
|
## Remove
|
|
109
112
|
|
|
110
|
-
First
|
|
111
|
-
|
|
113
|
+
First stop the foreground run or agent-run process, revoke the VTX inference
|
|
114
|
+
grant, then uninstall the package. Cleanup refuses while a foreground host
|
|
115
|
+
process still owns the host. Automated Codex users should also remove the
|
|
116
|
+
dedicated Codex login:
|
|
112
117
|
|
|
113
118
|
```bash
|
|
114
119
|
vtx inference-host revoke
|
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.12",
|
|
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, 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, 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, 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;
|
|
14379
14379
|
var init_external_inference_contract = __esm({
|
|
14380
14380
|
"lib/external-inference-contract.ts"() {
|
|
14381
14381
|
"use strict";
|
|
@@ -15051,6 +15051,12 @@ var init_external_inference_contract = __esm({
|
|
|
15051
15051
|
host_id: identifierSchema,
|
|
15052
15052
|
requested_at: timestampSchema
|
|
15053
15053
|
});
|
|
15054
|
+
agentHeartbeatRequestSchema = external_exports.strictObject({
|
|
15055
|
+
operation_id: operationIdentifierSchema,
|
|
15056
|
+
host_id: identifierSchema,
|
|
15057
|
+
attempt_id: identifierSchema.nullable().optional(),
|
|
15058
|
+
requested_at: timestampSchema
|
|
15059
|
+
});
|
|
15054
15060
|
emptyAgentNextResultSchema = external_exports.strictObject({
|
|
15055
15061
|
claim_state: external_exports.literal("empty"),
|
|
15056
15062
|
retry_after_ms: nonNegativeSafeIntegerSchema
|
|
@@ -16979,7 +16985,7 @@ ${body}`;
|
|
|
16979
16985
|
});
|
|
16980
16986
|
|
|
16981
16987
|
// lib/inference-host/mcp-client.ts
|
|
16982
|
-
var EXTERNAL_INFERENCE_MCP_PROTOCOL_VERSION, EXTERNAL_INFERENCE_AUTOMATED_HOST_TOOLS, EXTERNAL_INFERENCE_OPERATIONAL_TOOLS, ExternalInferenceMcpError, DEFAULT_REQUEST_TIMEOUT_MS, identifierSchema2, safeCodeSchema2, hostMutationResultSchema, attemptStartResultSchema, agentConnectResultSchema, jobCompletionResultSchema, jobFailureResultSchema, toolContracts, discoveryResultSchema, toolListResultSchema, inlineStructuredContentSchema, protocolMeta, parseJsonDocument, parseSseDocuments, parseResponseDocuments, exactOperationalInventory, exactJson, invalidBoundResult, verifyToolResult, ExternalInferenceMcpClient;
|
|
16988
|
+
var EXTERNAL_INFERENCE_MCP_PROTOCOL_VERSION, EXTERNAL_INFERENCE_AUTOMATED_HOST_TOOLS, EXTERNAL_INFERENCE_OPERATIONAL_TOOLS, ExternalInferenceMcpError, DEFAULT_REQUEST_TIMEOUT_MS, identifierSchema2, safeCodeSchema2, hostMutationResultSchema, attemptStartResultSchema, agentConnectResultSchema, agentHeartbeatResultSchema, jobCompletionResultSchema, jobFailureResultSchema, toolContracts, discoveryResultSchema, toolListResultSchema, inlineStructuredContentSchema, protocolMeta, parseJsonDocument, parseSseDocuments, parseResponseDocuments, exactOperationalInventory, exactJson, invalidBoundResult, verifyToolResult, ExternalInferenceMcpClient;
|
|
16983
16989
|
var init_mcp_client = __esm({
|
|
16984
16990
|
"lib/inference-host/mcp-client.ts"() {
|
|
16985
16991
|
"use strict";
|
|
@@ -16999,6 +17005,7 @@ var init_mcp_client = __esm({
|
|
|
16999
17005
|
EXTERNAL_INFERENCE_OPERATIONAL_TOOLS = [
|
|
17000
17006
|
...EXTERNAL_INFERENCE_AUTOMATED_HOST_TOOLS,
|
|
17001
17007
|
"inference.agent.connect",
|
|
17008
|
+
"inference.agent.heartbeat",
|
|
17002
17009
|
"inference.agent.next",
|
|
17003
17010
|
"inference.agent.complete",
|
|
17004
17011
|
"inference.agent.fail"
|
|
@@ -17030,6 +17037,20 @@ var init_mcp_client = __esm({
|
|
|
17030
17037
|
reasoning_effort: safeCodeSchema2,
|
|
17031
17038
|
replayed: external_exports.boolean()
|
|
17032
17039
|
});
|
|
17040
|
+
agentHeartbeatResultSchema = external_exports.strictObject({
|
|
17041
|
+
host: hostStatusReadSchema,
|
|
17042
|
+
active_attempts: external_exports.number().int().min(0).max(1),
|
|
17043
|
+
available_slots: external_exports.number().int().min(0).max(1),
|
|
17044
|
+
replayed: external_exports.boolean()
|
|
17045
|
+
}).superRefine((value, context) => {
|
|
17046
|
+
if (value.active_attempts + value.available_slots !== 1) {
|
|
17047
|
+
context.addIssue({
|
|
17048
|
+
code: "custom",
|
|
17049
|
+
message: "Agent heartbeat capacity must describe exactly one slot.",
|
|
17050
|
+
path: ["available_slots"]
|
|
17051
|
+
});
|
|
17052
|
+
}
|
|
17053
|
+
});
|
|
17033
17054
|
jobCompletionResultSchema = external_exports.strictObject({
|
|
17034
17055
|
job_id: identifierSchema2,
|
|
17035
17056
|
attempt_id: identifierSchema2,
|
|
@@ -17099,6 +17120,10 @@ var init_mcp_client = __esm({
|
|
|
17099
17120
|
arguments: agentConnectRequestSchema,
|
|
17100
17121
|
result: agentConnectResultSchema
|
|
17101
17122
|
},
|
|
17123
|
+
"inference.agent.heartbeat": {
|
|
17124
|
+
arguments: agentHeartbeatRequestSchema,
|
|
17125
|
+
result: agentHeartbeatResultSchema
|
|
17126
|
+
},
|
|
17102
17127
|
"inference.agent.next": {
|
|
17103
17128
|
arguments: agentNextRequestSchema,
|
|
17104
17129
|
result: agentNextResultSchema
|
|
@@ -17225,6 +17250,12 @@ var init_mcp_client = __esm({
|
|
|
17225
17250
|
if (!host || host.host_id !== request.host_id || host.adapter !== request.adapter || result2.model_id !== request.model_id || result2.reasoning_effort !== request.reasoning_effort) invalidBoundResult(name);
|
|
17226
17251
|
return;
|
|
17227
17252
|
}
|
|
17253
|
+
if (name === "inference.agent.heartbeat") {
|
|
17254
|
+
const host = result2.host;
|
|
17255
|
+
const expectedActive = request.attempt_id == null ? 0 : 1;
|
|
17256
|
+
if (!host || host.host_id !== request.host_id || host.status !== "online" || result2.active_attempts !== expectedActive || result2.available_slots !== 1 - expectedActive) invalidBoundResult(name);
|
|
17257
|
+
return;
|
|
17258
|
+
}
|
|
17228
17259
|
if (name === "inference.agent.next") {
|
|
17229
17260
|
if (result2.claim_state === "claimed" && !result2.job_id) invalidBoundResult(name);
|
|
17230
17261
|
return;
|
|
@@ -17343,7 +17374,7 @@ var init_mcp_client = __esm({
|
|
|
17343
17374
|
}).passthrough().parse(rawResult);
|
|
17344
17375
|
if (callResult.isError === true) {
|
|
17345
17376
|
const errorText = (callResult.content ?? []).filter((block) => block.type === "text").map((block) => block.text ?? "").join("\n");
|
|
17346
|
-
const definitivelyNotApplied = (name === "inference.host.register" || name === "inference.host.advertise") && errorText.includes("Advertisement is already expired.") || name === "inference.agent.next" && (errorText.includes("Advertisement time is outside the allowed clock skew.") || errorText.includes("Advertisement is already expired.") || errorText.includes("Heartbeat time is outside the allowed clock skew."));
|
|
17377
|
+
const definitivelyNotApplied = (name === "inference.host.register" || name === "inference.host.advertise") && errorText.includes("Advertisement is already expired.") || (name === "inference.agent.next" || name === "inference.agent.heartbeat") && (errorText.includes("Advertisement time is outside the allowed clock skew.") || errorText.includes("Advertisement is already expired.") || errorText.includes("Heartbeat time is outside the allowed clock skew."));
|
|
17347
17378
|
throw new ExternalInferenceMcpError(
|
|
17348
17379
|
"tool_rejected",
|
|
17349
17380
|
`Insights MCP rejected ${name}.`,
|
|
@@ -28794,6 +28825,9 @@ async function runInferenceHostCli(argv2, env = process.env, dependencies = {})
|
|
|
28794
28825
|
async () => await agentConnect(config2, parsed, dependencies, warnings)
|
|
28795
28826
|
);
|
|
28796
28827
|
}
|
|
28828
|
+
if (parsed.command === "agent-run") {
|
|
28829
|
+
return await agentRun(config2, parsed, dependencies, warnings);
|
|
28830
|
+
}
|
|
28797
28831
|
if (parsed.command === "agent-next") {
|
|
28798
28832
|
return await withAgentCommandLock(
|
|
28799
28833
|
config2,
|
|
@@ -28828,7 +28862,7 @@ async function runInferenceHostCli(argv2, env = process.env, dependencies = {})
|
|
|
28828
28862
|
return await cleanupLogin(config2, parsed, dependencies, warnings, true);
|
|
28829
28863
|
}
|
|
28830
28864
|
throw new Error(
|
|
28831
|
-
"Usage: vtx inference-host <login|codex-login|run|agent-connect|agent-next|agent-complete|agent-fail|status|doctor|logout|codex-logout|revoke> [--json]"
|
|
28865
|
+
"Usage: vtx inference-host <login|codex-login|run|agent-connect|agent-run|agent-next|agent-complete|agent-fail|status|doctor|logout|codex-logout|revoke> [--json]"
|
|
28832
28866
|
);
|
|
28833
28867
|
} catch (error48) {
|
|
28834
28868
|
return {
|
|
@@ -28839,7 +28873,7 @@ async function runInferenceHostCli(argv2, env = process.env, dependencies = {})
|
|
|
28839
28873
|
};
|
|
28840
28874
|
}
|
|
28841
28875
|
}
|
|
28842
|
-
var INFERENCE_HOST_CLI_VERSION, runtimeReceiptPath, codexRecoveryPath, codexGuardianReceiptRoot, revocationCheckpointPath, assertRevocationCheckpoint, readRevocationCheckpoint, writeRevocationCheckpoint, clearRevocationCheckpoint, render, parsePositiveInteger, parseInferenceHostArgs, defaultOpenBrowser, defaultRegisterLifecycleSignalHandlers, lifecycleCancellation, configuredCredentialStore, accountKeyForState, assertCredentialMatchesState2, revocationCheckpointForCredential, assertRevocationCheckpointMatchesLocalIdentity, fileExistsPrivately, inspectCodexAuthentication, clearLocalRuntimeArtifacts, assertLocalRuntimeArtifactsMayBeDiscarded, defaultRunForeground, login, codexLogin, codexLogout, localStatus, doctor, cleanupLogin, runHost, defaultReadStdin, parseAgentStdin, agentOperationId, agentSession, agentConnect, agentNext, agentComplete, agentFail, withAgentCommandLock;
|
|
28876
|
+
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, parsePositiveInteger, parseInferenceHostArgs, defaultOpenBrowser, defaultRegisterLifecycleSignalHandlers, lifecycleCancellation, configuredCredentialStore, accountKeyForState, assertCredentialMatchesState2, revocationCheckpointForCredential, assertRevocationCheckpointMatchesLocalIdentity, fileExistsPrivately, inspectCodexAuthentication, clearLocalRuntimeArtifacts, assertLocalRuntimeArtifactsMayBeDiscarded, defaultRunForeground, login, codexLogin, codexLogout, localStatus, doctor, cleanupLogin, runHost, defaultReadStdin, parseAgentStdin, agentOperationId, agentSession, agentConnect, agentRun, agentNext, agentComplete, agentFail, withAgentCommandLock;
|
|
28843
28877
|
var init_cli = __esm({
|
|
28844
28878
|
"lib/inference-host/cli.ts"() {
|
|
28845
28879
|
"use strict";
|
|
@@ -28855,11 +28889,20 @@ var init_cli = __esm({
|
|
|
28855
28889
|
init_crypto();
|
|
28856
28890
|
init_oauth();
|
|
28857
28891
|
init_runner();
|
|
28892
|
+
init_mcp_client();
|
|
28858
28893
|
INFERENCE_HOST_CLI_VERSION = agent_cli_release_default.package_version;
|
|
28859
28894
|
runtimeReceiptPath = (config2) => `${config2.statePath}.runtime.json`;
|
|
28860
28895
|
codexRecoveryPath = (config2) => `${config2.statePath}.codex-recovery.json`;
|
|
28861
28896
|
codexGuardianReceiptRoot = (config2) => `${config2.statePath}.codex-processes`;
|
|
28862
28897
|
revocationCheckpointPath = (config2) => `${config2.statePath}.revoke.json`;
|
|
28898
|
+
foregroundHostLockPath = (config2) => `${config2.processLockPath}.foreground`;
|
|
28899
|
+
AGENT_HEARTBEAT_INTERVAL_MS = 3e3;
|
|
28900
|
+
AGENT_HEARTBEAT_MAX_RETRY_DELAY_MS = 9e3;
|
|
28901
|
+
retryableAgentHeartbeatError = (error48) => {
|
|
28902
|
+
if (!(error48 instanceof ExternalInferenceMcpError)) return false;
|
|
28903
|
+
if (error48.code === "network_error" || error48.code === "request_timeout") return true;
|
|
28904
|
+
return error48.code === "transport_rejected" && /HTTP (?:408|425|429|5\d\d)\b/u.test(error48.message);
|
|
28905
|
+
};
|
|
28863
28906
|
assertRevocationCheckpoint = (value) => {
|
|
28864
28907
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
28865
28908
|
throw new Error("Inference host revocation checkpoint is invalid.");
|
|
@@ -29489,7 +29532,18 @@ Waiting for approval...
|
|
|
29489
29532
|
};
|
|
29490
29533
|
cleanupLogin = async (config2, parsed, dependencies, warnings, revoke) => {
|
|
29491
29534
|
const lock2 = await acquireInferenceHostProcessLock(config2.processLockPath);
|
|
29535
|
+
let keeperLock = null;
|
|
29492
29536
|
try {
|
|
29537
|
+
try {
|
|
29538
|
+
keeperLock = await acquireInferenceHostProcessLock(foregroundHostLockPath(config2));
|
|
29539
|
+
} catch (error48) {
|
|
29540
|
+
if (error48 instanceof Error && error48.message.includes("Another inference host process already owns")) {
|
|
29541
|
+
throw new Error(
|
|
29542
|
+
"Stop vtx inference-host agent-run before logging out or revoking this host."
|
|
29543
|
+
);
|
|
29544
|
+
}
|
|
29545
|
+
throw error48;
|
|
29546
|
+
}
|
|
29493
29547
|
if (!revoke) {
|
|
29494
29548
|
await assertLocalRuntimeArtifactsMayBeDiscarded(config2);
|
|
29495
29549
|
}
|
|
@@ -29592,13 +29646,16 @@ Waiting for approval...
|
|
|
29592
29646
|
` : ""
|
|
29593
29647
|
};
|
|
29594
29648
|
} finally {
|
|
29649
|
+
await keeperLock?.release();
|
|
29595
29650
|
await lock2.release();
|
|
29596
29651
|
}
|
|
29597
29652
|
};
|
|
29598
29653
|
runHost = async (config2, parsed, env, dependencies, warnings) => {
|
|
29599
29654
|
const cancellation = lifecycleCancellation(dependencies);
|
|
29655
|
+
let foregroundLock = null;
|
|
29600
29656
|
let processLock = null;
|
|
29601
29657
|
try {
|
|
29658
|
+
foregroundLock = await acquireInferenceHostProcessLock(foregroundHostLockPath(config2));
|
|
29602
29659
|
processLock = await acquireInferenceHostProcessLock(config2.processLockPath);
|
|
29603
29660
|
cancellation.signal.throwIfAborted();
|
|
29604
29661
|
if (await readRevocationCheckpoint(config2)) {
|
|
@@ -29649,6 +29706,7 @@ Waiting for approval...
|
|
|
29649
29706
|
}
|
|
29650
29707
|
} finally {
|
|
29651
29708
|
await processLock?.release();
|
|
29709
|
+
await foregroundLock?.release();
|
|
29652
29710
|
cancellation.unregister();
|
|
29653
29711
|
}
|
|
29654
29712
|
};
|
|
@@ -29728,12 +29786,130 @@ Waiting for approval...
|
|
|
29728
29786
|
lanes: ["main", "review", "screener"],
|
|
29729
29787
|
response_modes: ["provider_response", "decision_candidate"],
|
|
29730
29788
|
execution_modes: ["client", "server"],
|
|
29731
|
-
next_command: "vtx inference-host agent-next --wait-seconds 50 --json"
|
|
29789
|
+
next_command: "vtx inference-host agent-next --wait-seconds 50 --json",
|
|
29790
|
+
keeper_command: "vtx inference-host agent-run"
|
|
29732
29791
|
}, parsed.json),
|
|
29733
29792
|
stderr: warnings.length > 0 ? `${warnings.join("\n")}
|
|
29734
29793
|
` : ""
|
|
29735
29794
|
};
|
|
29736
29795
|
};
|
|
29796
|
+
agentRun = async (config2, parsed, dependencies, warnings) => {
|
|
29797
|
+
const cancellation = lifecycleCancellation(dependencies);
|
|
29798
|
+
let keeperLock = null;
|
|
29799
|
+
let heartbeatCount = 0;
|
|
29800
|
+
try {
|
|
29801
|
+
keeperLock = await acquireInferenceHostProcessLock(foregroundHostLockPath(config2));
|
|
29802
|
+
const store = configuredCredentialStore(config2, dependencies, (message) => {
|
|
29803
|
+
warnings.push(message);
|
|
29804
|
+
});
|
|
29805
|
+
const session = await (dependencies.createAgentSession ?? createInferenceAgentMcpSession)({
|
|
29806
|
+
config: config2,
|
|
29807
|
+
credentialStore: store,
|
|
29808
|
+
clientVersion: INFERENCE_HOST_CLI_VERSION,
|
|
29809
|
+
signal: cancellation.signal
|
|
29810
|
+
});
|
|
29811
|
+
const emitStdout = dependencies.emitStdout ?? ((text) => {
|
|
29812
|
+
process.stdout.write(text);
|
|
29813
|
+
});
|
|
29814
|
+
const emitStderr = dependencies.emitStderr ?? ((text) => {
|
|
29815
|
+
process.stderr.write(text);
|
|
29816
|
+
});
|
|
29817
|
+
let consecutiveHeartbeatFailures = 0;
|
|
29818
|
+
let retryDelayMs = AGENT_HEARTBEAT_INTERVAL_MS;
|
|
29819
|
+
let pendingHeartbeatRequest = null;
|
|
29820
|
+
emitStdout(parsed.json ? `${JSON.stringify({ status: "running", host_id: session.localState.host_id })}
|
|
29821
|
+
` : "Agent-driven inference host keeper is running.\n");
|
|
29822
|
+
while (!cancellation.signal.aborted) {
|
|
29823
|
+
let commandLock = null;
|
|
29824
|
+
try {
|
|
29825
|
+
commandLock = await acquireInferenceHostProcessLock(config2.processLockPath);
|
|
29826
|
+
} catch (error48) {
|
|
29827
|
+
if (!(error48 instanceof Error) || !error48.message.includes("Another inference host process already owns")) {
|
|
29828
|
+
throw error48;
|
|
29829
|
+
}
|
|
29830
|
+
}
|
|
29831
|
+
if (commandLock) {
|
|
29832
|
+
let heartbeatSuppressed = false;
|
|
29833
|
+
try {
|
|
29834
|
+
const active = await readInferenceAgentAttemptState(config2.statePath);
|
|
29835
|
+
const pendingNext = await readInferenceAgentNextState(config2.statePath);
|
|
29836
|
+
heartbeatSuppressed = Boolean(pendingNext && !active);
|
|
29837
|
+
if (heartbeatSuppressed) pendingHeartbeatRequest = null;
|
|
29838
|
+
if (!heartbeatSuppressed) {
|
|
29839
|
+
if (active && active.host_id !== session.localState.host_id) {
|
|
29840
|
+
throw new Error("Active agent-driven attempt belongs to another inference host.");
|
|
29841
|
+
}
|
|
29842
|
+
const activeAttemptId = active?.attempt_id ?? null;
|
|
29843
|
+
if (pendingHeartbeatRequest?.attempt_id !== activeAttemptId) {
|
|
29844
|
+
pendingHeartbeatRequest = null;
|
|
29845
|
+
}
|
|
29846
|
+
const heartbeatRequest = pendingHeartbeatRequest ?? {
|
|
29847
|
+
operation_id: agentOperationId("agent-heartbeat"),
|
|
29848
|
+
host_id: session.localState.host_id,
|
|
29849
|
+
attempt_id: activeAttemptId,
|
|
29850
|
+
requested_at: (dependencies.now ?? (() => /* @__PURE__ */ new Date()))().toISOString()
|
|
29851
|
+
};
|
|
29852
|
+
try {
|
|
29853
|
+
await session.client.callTool(
|
|
29854
|
+
"inference.agent.heartbeat",
|
|
29855
|
+
heartbeatRequest,
|
|
29856
|
+
{ signal: cancellation.signal }
|
|
29857
|
+
);
|
|
29858
|
+
heartbeatCount += 1;
|
|
29859
|
+
pendingHeartbeatRequest = null;
|
|
29860
|
+
consecutiveHeartbeatFailures = 0;
|
|
29861
|
+
retryDelayMs = AGENT_HEARTBEAT_INTERVAL_MS;
|
|
29862
|
+
} catch (error48) {
|
|
29863
|
+
if (cancellation.signal.aborted) break;
|
|
29864
|
+
if (error48 instanceof ExternalInferenceMcpError && error48.definitivelyNotApplied) {
|
|
29865
|
+
pendingHeartbeatRequest = null;
|
|
29866
|
+
consecutiveHeartbeatFailures = 0;
|
|
29867
|
+
retryDelayMs = AGENT_HEARTBEAT_INTERVAL_MS;
|
|
29868
|
+
emitStderr(parsed.json ? `${JSON.stringify({
|
|
29869
|
+
status: "heartbeat_retry",
|
|
29870
|
+
retry_after_ms: retryDelayMs
|
|
29871
|
+
})}
|
|
29872
|
+
` : `Agent-driven inference heartbeat was not applied; retrying in ${retryDelayMs}ms.
|
|
29873
|
+
`);
|
|
29874
|
+
} else {
|
|
29875
|
+
if (!retryableAgentHeartbeatError(error48)) throw error48;
|
|
29876
|
+
pendingHeartbeatRequest = heartbeatRequest;
|
|
29877
|
+
consecutiveHeartbeatFailures += 1;
|
|
29878
|
+
retryDelayMs = Math.min(
|
|
29879
|
+
AGENT_HEARTBEAT_INTERVAL_MS * 2 ** Math.max(0, consecutiveHeartbeatFailures - 1),
|
|
29880
|
+
AGENT_HEARTBEAT_MAX_RETRY_DELAY_MS
|
|
29881
|
+
);
|
|
29882
|
+
const message = `Agent-driven inference heartbeat was temporarily unavailable; retrying in ${retryDelayMs}ms.
|
|
29883
|
+
`;
|
|
29884
|
+
emitStderr(parsed.json ? `${JSON.stringify({
|
|
29885
|
+
status: "heartbeat_retry",
|
|
29886
|
+
retry_after_ms: retryDelayMs
|
|
29887
|
+
})}
|
|
29888
|
+
` : message);
|
|
29889
|
+
}
|
|
29890
|
+
}
|
|
29891
|
+
}
|
|
29892
|
+
} finally {
|
|
29893
|
+
await commandLock.release();
|
|
29894
|
+
}
|
|
29895
|
+
if (parsed.once && (heartbeatCount > 0 || heartbeatSuppressed)) break;
|
|
29896
|
+
}
|
|
29897
|
+
if (parsed.once && !commandLock) break;
|
|
29898
|
+
await (dependencies.sleep ?? (async (milliseconds) => {
|
|
29899
|
+
await new Promise((resolve5) => setTimeout(resolve5, milliseconds));
|
|
29900
|
+
}))(retryDelayMs);
|
|
29901
|
+
}
|
|
29902
|
+
return {
|
|
29903
|
+
exitCode: 0,
|
|
29904
|
+
stdout: render({ status: "stopped", heartbeats: heartbeatCount }, parsed.json),
|
|
29905
|
+
stderr: warnings.length > 0 ? `${warnings.join("\n")}
|
|
29906
|
+
` : ""
|
|
29907
|
+
};
|
|
29908
|
+
} finally {
|
|
29909
|
+
await keeperLock?.release();
|
|
29910
|
+
cancellation.unregister();
|
|
29911
|
+
}
|
|
29912
|
+
};
|
|
29737
29913
|
agentNext = async (config2, parsed, dependencies, warnings) => {
|
|
29738
29914
|
const active = await readInferenceAgentAttemptState(config2.statePath);
|
|
29739
29915
|
const recoveredNext = await readInferenceAgentNextState(config2.statePath);
|