@vtxmacro/cli 2026.8.12 → 2026.8.13
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 +34 -0
- package/bin/vtx.js +488 -97
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -47,6 +47,15 @@ credential.
|
|
|
47
47
|
|
|
48
48
|
### Automated Codex host
|
|
49
49
|
|
|
50
|
+
Before the first Codex login, enable **Device code authorization for Codex** in
|
|
51
|
+
ChatGPT Security settings. Only enter a device code from a login you initiated,
|
|
52
|
+
and never share it. The automated host advertises `gpt-5.6-sol` with
|
|
53
|
+
`medium`, `high`, and `xhigh` reasoning effort. Before starting a Trader,
|
|
54
|
+
confirm that the VTX AI page shows the intended authenticated ChatGPT email and
|
|
55
|
+
plan. The host reads the live Codex account window: a reached limit pauses new
|
|
56
|
+
dispatch until its reported reset, while a transient throttle uses a short
|
|
57
|
+
bounded cooldown.
|
|
58
|
+
|
|
50
59
|
```bash
|
|
51
60
|
vtx inference-host login
|
|
52
61
|
vtx inference-host codex-login
|
|
@@ -63,6 +72,21 @@ OAuth grant. It also keeps its ChatGPT subscription login in a dedicated private
|
|
|
63
72
|
Codex home. Neither credential is copied from or widens the ordinary CLI or Codex
|
|
64
73
|
session. VTX logout/revoke and Codex logout are intentionally separate operations.
|
|
65
74
|
|
|
75
|
+
Use `vtx inference-host --help` for command discovery. The VTX login verifies
|
|
76
|
+
that the selected credential store can read back the exact saved grant. If an
|
|
77
|
+
OS credential store such as Windows Credential Manager cannot retain it, VTX
|
|
78
|
+
revokes the new remote grant and fails with an actionable error. Retry with the
|
|
79
|
+
supported private-file store by setting
|
|
80
|
+
`VTX_INFERENCE_HOST_CREDENTIAL_STORE=file` before running
|
|
81
|
+
`vtx inference-host login` again. In PowerShell use
|
|
82
|
+
`$env:VTX_INFERENCE_HOST_CREDENTIAL_STORE="file"`; in bash use
|
|
83
|
+
`export VTX_INFERENCE_HOST_CREDENTIAL_STORE=file`.
|
|
84
|
+
|
|
85
|
+
The browser callback shows a VTX authorization-complete page. If a browser
|
|
86
|
+
extension instead shows `ERR_BLOCKED_BY_CLIENT` but the CLI reports
|
|
87
|
+
`logged_in` and `doctor` reports `credential-present`, only the local
|
|
88
|
+
confirmation page was blocked; the grant succeeded.
|
|
89
|
+
|
|
66
90
|
### Any compatible agent harness
|
|
67
91
|
|
|
68
92
|
Codex, Claude Code, Cursor, GitHub Copilot, Antigravity, and other agents that can
|
|
@@ -108,6 +132,12 @@ and normally running VTX Client Mode or Server Mode bots. Server Mode keeps the
|
|
|
108
132
|
normal VTX call fee. Client Mode has no VTX platform fee. Neither mode falls back
|
|
109
133
|
to another model when the agent host is unavailable.
|
|
110
134
|
|
|
135
|
+
After any approved Trader start, use `vtx --profile <profile-id> bots status`
|
|
136
|
+
to confirm the normal Trader remains running. If it returns to Stopped, use
|
|
137
|
+
`vtx --profile <profile-id> runtime events` to read the latest error before one
|
|
138
|
+
controlled retry. A start receipt or a brief Live label is not proof of a
|
|
139
|
+
running bot.
|
|
140
|
+
|
|
111
141
|
## Remove
|
|
112
142
|
|
|
113
143
|
First stop the foreground run or agent-run process, revoke the VTX inference
|
|
@@ -121,3 +151,7 @@ vtx inference-host revoke
|
|
|
121
151
|
vtx inference-host codex-logout
|
|
122
152
|
npm uninstall -g @vtxmacro/cli
|
|
123
153
|
```
|
|
154
|
+
|
|
155
|
+
If an older failed login left no local credential to revoke, disconnect that
|
|
156
|
+
inactive inference grant from Connected Agent Apps on the VTX Insights page
|
|
157
|
+
before logging in again.
|
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.13",
|
|
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, 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, 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";
|
|
@@ -14580,6 +14580,7 @@ var init_external_inference_contract = __esm({
|
|
|
14580
14580
|
reasoningEffortSchema = external_exports.string().min(1).max(32).regex(/^[a-z][a-z0-9_-]{0,31}$/);
|
|
14581
14581
|
modelNameSchema = external_exports.string().min(1).max(256);
|
|
14582
14582
|
displayNameSchema = external_exports.string().min(1).max(128);
|
|
14583
|
+
authenticatedAccountEmailSchema = external_exports.string().max(320).email();
|
|
14583
14584
|
protocolVersionSchema = external_exports.string().min(1).max(64);
|
|
14584
14585
|
base64UrlAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
14585
14586
|
isCanonicalBase64Url = (value, exactBytes) => {
|
|
@@ -14713,6 +14714,8 @@ var init_external_inference_contract = __esm({
|
|
|
14713
14714
|
key_generation: generationSchema,
|
|
14714
14715
|
adapter: externalInferenceAdapterIdSchema,
|
|
14715
14716
|
display_name: displayNameSchema,
|
|
14717
|
+
authenticated_account_email: authenticatedAccountEmailSchema.nullable().optional(),
|
|
14718
|
+
authenticated_account_plan: safeCodeSchema.nullable().optional(),
|
|
14716
14719
|
protocol_version: protocolVersionSchema,
|
|
14717
14720
|
envelope_public_key: base64Url32BytesSchema,
|
|
14718
14721
|
health: external_exports.enum(["healthy", "degraded", "draining"]),
|
|
@@ -15576,6 +15579,8 @@ var init_external_inference_contract = __esm({
|
|
|
15576
15579
|
hostStatusReadSchema = external_exports.strictObject({
|
|
15577
15580
|
host_id: identifierSchema,
|
|
15578
15581
|
display_name: displayNameSchema,
|
|
15582
|
+
authenticated_account_email: authenticatedAccountEmailSchema.nullable().optional(),
|
|
15583
|
+
authenticated_account_plan: safeCodeSchema.nullable().optional(),
|
|
15579
15584
|
adapter: externalInferenceAdapterIdSchema,
|
|
15580
15585
|
status: external_exports.enum(["online", "degraded", "offline", "draining", "revoked"]),
|
|
15581
15586
|
host_generation: generationSchema,
|
|
@@ -16653,6 +16658,10 @@ var init_credential_store = __esm({
|
|
|
16653
16658
|
}
|
|
16654
16659
|
const result2 = await this.runner(command, { stdin: serialized, ...options });
|
|
16655
16660
|
if (result2.exitCode !== 0) throw new Error("OS credential write failed.");
|
|
16661
|
+
const retained = await this.read(accountKey, options);
|
|
16662
|
+
if (!retained || JSON.stringify(retained) !== JSON.stringify(validated)) {
|
|
16663
|
+
throw new Error("OS credential write could not be verified.");
|
|
16664
|
+
}
|
|
16656
16665
|
}
|
|
16657
16666
|
async remove(accountKey, options = {}) {
|
|
16658
16667
|
const command = this.commands.remove(INFERENCE_CREDENTIAL_NAMESPACE, accountKey);
|
|
@@ -16870,7 +16879,7 @@ public static class VtxInferenceCredential {
|
|
|
16870
16879
|
}`;
|
|
16871
16880
|
powershellCredentialCommand = (operation, namespace, accountKey) => {
|
|
16872
16881
|
const target = JSON.stringify(`${namespace}:${accountKey}`);
|
|
16873
|
-
const body = operation === "read" ? `try { [Console]::Out.Write([VtxInferenceCredential]::Read(${target})) } catch [System.ComponentModel.Win32Exception] { if ($_.Exception.NativeErrorCode -eq 1168) { exit 4 }; exit 1 }` : operation === "write" ? `[VtxInferenceCredential]::Write(${target}, [Console]::In.ReadToEnd())` : `try { [VtxInferenceCredential]::Delete(${target}) } catch [System.ComponentModel.Win32Exception] { if ($_.Exception.NativeErrorCode -eq 1168) { exit 4 }; exit 1 }`;
|
|
16882
|
+
const body = operation === "read" ? `try { [Console]::Out.Write([VtxInferenceCredential]::Read(${target})) } catch [System.ComponentModel.Win32Exception] { if ($_.Exception.NativeErrorCode -eq 1168) { exit 4 }; exit 1 }` : operation === "write" ? `try { [VtxInferenceCredential]::Write(${target}, [Console]::In.ReadToEnd()); exit 0 } catch { exit 1 }` : `try { [VtxInferenceCredential]::Delete(${target}) } catch [System.ComponentModel.Win32Exception] { if ($_.Exception.NativeErrorCode -eq 1168) { exit 4 }; exit 1 }`;
|
|
16874
16883
|
const script = `Add-Type -TypeDefinition @'
|
|
16875
16884
|
${windowsCredentialInterop}
|
|
16876
16885
|
'@
|
|
@@ -16985,7 +16994,7 @@ ${body}`;
|
|
|
16985
16994
|
});
|
|
16986
16995
|
|
|
16987
16996
|
// lib/inference-host/mcp-client.ts
|
|
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;
|
|
16997
|
+
var EXTERNAL_INFERENCE_MCP_PROTOCOL_VERSION, EXTERNAL_INFERENCE_AUTOMATED_HOST_TOOLS, EXTERNAL_INFERENCE_OPERATIONAL_TOOLS, ExternalInferenceMcpError, DEFAULT_REQUEST_TIMEOUT_MS, MAX_RETRY_AFTER_MS, parseRetryAfterMs, identifierSchema2, safeCodeSchema2, hostMutationResultSchema, attemptStartResultSchema, agentConnectResultSchema, agentHeartbeatResultSchema, jobCompletionResultSchema, jobFailureResultSchema, toolContracts, discoveryResultSchema, toolListResultSchema, inlineStructuredContentSchema, protocolMeta, parseJsonDocument, parseSseDocuments, parseResponseDocuments, exactOperationalInventory, exactJson, invalidBoundResult, verifyToolResult, ExternalInferenceMcpClient;
|
|
16989
16998
|
var init_mcp_client = __esm({
|
|
16990
16999
|
"lib/inference-host/mcp-client.ts"() {
|
|
16991
17000
|
"use strict";
|
|
@@ -17016,9 +17025,29 @@ var init_mcp_client = __esm({
|
|
|
17016
17025
|
this.name = "ExternalInferenceMcpError";
|
|
17017
17026
|
this.code = code;
|
|
17018
17027
|
this.definitivelyNotApplied = options.definitivelyNotApplied ?? false;
|
|
17028
|
+
this.httpStatusCode = options.httpStatusCode ?? null;
|
|
17029
|
+
this.retryAfterMs = options.retryAfterMs ?? null;
|
|
17030
|
+
this.retryable = options.retryable ?? [
|
|
17031
|
+
"network_error",
|
|
17032
|
+
"transport_rejected",
|
|
17033
|
+
"server_rejected",
|
|
17034
|
+
"rate_limited",
|
|
17035
|
+
"invalid_response",
|
|
17036
|
+
"request_timeout",
|
|
17037
|
+
"authentication_timeout"
|
|
17038
|
+
].includes(code);
|
|
17019
17039
|
}
|
|
17020
17040
|
};
|
|
17021
17041
|
DEFAULT_REQUEST_TIMEOUT_MS = 15e3;
|
|
17042
|
+
MAX_RETRY_AFTER_MS = 24 * 60 * 60 * 1e3;
|
|
17043
|
+
parseRetryAfterMs = (response, observedAtMs = Date.now()) => {
|
|
17044
|
+
const value = response.headers.get("retry-after")?.trim();
|
|
17045
|
+
if (!value) return null;
|
|
17046
|
+
const seconds = Number(value);
|
|
17047
|
+
const milliseconds = Number.isFinite(seconds) && seconds >= 0 ? Math.ceil(seconds * 1e3) : Math.max(0, Date.parse(value) - observedAtMs);
|
|
17048
|
+
if (!Number.isSafeInteger(milliseconds)) return null;
|
|
17049
|
+
return Math.min(milliseconds, MAX_RETRY_AFTER_MS);
|
|
17050
|
+
};
|
|
17022
17051
|
identifierSchema2 = external_exports.string().min(1).max(128);
|
|
17023
17052
|
safeCodeSchema2 = external_exports.string().min(1).max(96);
|
|
17024
17053
|
hostMutationResultSchema = external_exports.strictObject({
|
|
@@ -17238,11 +17267,11 @@ var init_mcp_client = __esm({
|
|
|
17238
17267
|
if (!host) return invalidBoundResult(name);
|
|
17239
17268
|
if (host.host_id !== request.host_id || host.host_generation !== request.host_generation || host.advertisement_generation !== request.advertisement_generation || host.key_generation !== request.key_generation || request.adapter !== void 0 && host.adapter !== request.adapter) invalidBoundResult(name);
|
|
17240
17269
|
if (name !== "inference.host.heartbeat") {
|
|
17241
|
-
if (host.display_name !== request.display_name || !exactJson(host.models, request.models) || host.status === "revoked") invalidBoundResult(name);
|
|
17270
|
+
if (host.display_name !== request.display_name || (host.authenticated_account_email ?? null) !== (request.authenticated_account_email ?? null) || (host.authenticated_account_plan ?? null) !== (request.authenticated_account_plan ?? null) || !exactJson(host.models, request.models) || host.status === "revoked") invalidBoundResult(name);
|
|
17242
17271
|
return;
|
|
17243
17272
|
}
|
|
17244
17273
|
const expectedStatus = request.status === "healthy" ? "online" : request.status;
|
|
17245
|
-
if (host.status !== expectedStatus) invalidBoundResult(name);
|
|
17274
|
+
if (host.status !== expectedStatus && !(request.status === "healthy" && host.status === "offline")) invalidBoundResult(name);
|
|
17246
17275
|
return;
|
|
17247
17276
|
}
|
|
17248
17277
|
if (name === "inference.agent.connect") {
|
|
@@ -17454,9 +17483,14 @@ var init_mcp_client = __esm({
|
|
|
17454
17483
|
);
|
|
17455
17484
|
}
|
|
17456
17485
|
if (!response.ok) {
|
|
17486
|
+
const httpStatusCode = response.status;
|
|
17487
|
+
const retryAfterMs = parseRetryAfterMs(response);
|
|
17488
|
+
await response.body?.cancel().catch(() => void 0);
|
|
17489
|
+
const retryable = httpStatusCode === 408 || httpStatusCode === 425 || httpStatusCode === 429 || httpStatusCode >= 500;
|
|
17457
17490
|
throw new ExternalInferenceMcpError(
|
|
17458
|
-
|
|
17459
|
-
`Insights MCP request failed with HTTP ${
|
|
17491
|
+
httpStatusCode === 401 ? "authentication_rejected" : httpStatusCode === 429 ? "rate_limited" : httpStatusCode >= 500 ? "server_rejected" : retryable ? "transport_rejected" : "http_rejected",
|
|
17492
|
+
`Insights MCP request failed with HTTP ${httpStatusCode}.`,
|
|
17493
|
+
{ httpStatusCode, retryAfterMs, retryable }
|
|
17460
17494
|
);
|
|
17461
17495
|
}
|
|
17462
17496
|
let documents;
|
|
@@ -18052,13 +18086,13 @@ async function beginInferenceOAuthLogin(options) {
|
|
|
18052
18086
|
);
|
|
18053
18087
|
}
|
|
18054
18088
|
const fetchImpl = options.fetchImpl || fetch;
|
|
18055
|
-
const callbackPath = `/
|
|
18089
|
+
const callbackPath = `/vtx-inference-authorized/${randomBytes2(16).toString("hex")}`;
|
|
18056
18090
|
let handler = null;
|
|
18057
18091
|
const server = createServer((request, response) => {
|
|
18058
18092
|
response.setHeader("Cache-Control", "no-store");
|
|
18059
18093
|
response.setHeader("Pragma", "no-cache");
|
|
18060
18094
|
response.setHeader("Referrer-Policy", "no-referrer");
|
|
18061
|
-
response.setHeader("Content-Type", "text/
|
|
18095
|
+
response.setHeader("Content-Type", "text/html; charset=utf-8");
|
|
18062
18096
|
const writeResponse = (status, body) => {
|
|
18063
18097
|
response.statusCode = status;
|
|
18064
18098
|
response.end(body);
|
|
@@ -18162,9 +18196,12 @@ async function beginInferenceOAuthLogin(options) {
|
|
|
18162
18196
|
cause: error48
|
|
18163
18197
|
});
|
|
18164
18198
|
}
|
|
18165
|
-
throw error48;
|
|
18199
|
+
throw new InferenceOAuthCredentialStoreError({ cause: error48 });
|
|
18166
18200
|
}
|
|
18167
|
-
writeResponse(
|
|
18201
|
+
writeResponse(
|
|
18202
|
+
200,
|
|
18203
|
+
'<!doctype html><html><head><meta charset="utf-8"><title>VTX authorization complete</title></head><body><main><h1>VTX authorization complete</h1><p>The VTX CLI received your approval. You can close this tab and return to the terminal.</p></main></body></html>'
|
|
18204
|
+
);
|
|
18168
18205
|
await closeServer(server);
|
|
18169
18206
|
resolve5({
|
|
18170
18207
|
accessToken: tokens.accessToken,
|
|
@@ -18173,9 +18210,12 @@ async function beginInferenceOAuthLogin(options) {
|
|
|
18173
18210
|
accountKey
|
|
18174
18211
|
});
|
|
18175
18212
|
} catch (error48) {
|
|
18176
|
-
writeResponse(
|
|
18213
|
+
writeResponse(
|
|
18214
|
+
400,
|
|
18215
|
+
'<!doctype html><html><head><meta charset="utf-8"><title>VTX authorization failed</title></head><body><main><h1>VTX authorization failed</h1><p>Return to the VTX CLI for the actionable error.</p></main></body></html>'
|
|
18216
|
+
);
|
|
18177
18217
|
await closeServer(server);
|
|
18178
|
-
reject(error48 instanceof InferenceOAuthRequestError ? error48 : new Error("Inference OAuth authorization failed."));
|
|
18218
|
+
reject(error48 instanceof InferenceOAuthRequestError || error48 instanceof InferenceOAuthCredentialStoreError ? error48 : new Error("Inference OAuth authorization failed."));
|
|
18179
18219
|
}
|
|
18180
18220
|
};
|
|
18181
18221
|
});
|
|
@@ -18225,7 +18265,7 @@ async function beginInferenceOAuthLogin(options) {
|
|
|
18225
18265
|
throw error48;
|
|
18226
18266
|
}
|
|
18227
18267
|
}
|
|
18228
|
-
var INFERENCE_SCOPE, CALLBACK_HOST, TOKEN_PREFIX, DEFAULT_OAUTH_REQUEST_TIMEOUT_MS, InferenceOAuthRequestError;
|
|
18268
|
+
var INFERENCE_SCOPE, CALLBACK_HOST, TOKEN_PREFIX, DEFAULT_OAUTH_REQUEST_TIMEOUT_MS, InferenceOAuthRequestError, InferenceOAuthCredentialStoreError;
|
|
18229
18269
|
var init_oauth = __esm({
|
|
18230
18270
|
"lib/inference-host/oauth.ts"() {
|
|
18231
18271
|
"use strict";
|
|
@@ -18241,6 +18281,15 @@ var init_oauth = __esm({
|
|
|
18241
18281
|
this.code = code;
|
|
18242
18282
|
}
|
|
18243
18283
|
};
|
|
18284
|
+
InferenceOAuthCredentialStoreError = class extends Error {
|
|
18285
|
+
constructor(options = {}) {
|
|
18286
|
+
super(
|
|
18287
|
+
"VTX authorization succeeded, but the credential store did not retain the grant. VTX revoked the new remote grant. Set VTX_INFERENCE_HOST_CREDENTIAL_STORE=file and run vtx inference-host login again to use the secure private-file fallback.",
|
|
18288
|
+
{ cause: options.cause }
|
|
18289
|
+
);
|
|
18290
|
+
this.name = "InferenceOAuthCredentialStoreError";
|
|
18291
|
+
}
|
|
18292
|
+
};
|
|
18244
18293
|
}
|
|
18245
18294
|
});
|
|
18246
18295
|
|
|
@@ -18488,7 +18537,25 @@ async function loginCodexSubscription(options) {
|
|
|
18488
18537
|
async function preflightCodexSubscription(options) {
|
|
18489
18538
|
const session = await CodexAppServerSession.start(options);
|
|
18490
18539
|
try {
|
|
18491
|
-
await session.
|
|
18540
|
+
const account = await session.readAccountSnapshot(
|
|
18541
|
+
options.deadlineAtMs,
|
|
18542
|
+
options.signal,
|
|
18543
|
+
true
|
|
18544
|
+
);
|
|
18545
|
+
if (!account.requiresOpenaiAuth || account.authenticatedChatGptAccount === null) {
|
|
18546
|
+
throw new CodexAppServerError({
|
|
18547
|
+
message: "Codex managed ChatGPT authentication is required.",
|
|
18548
|
+
category: "auth",
|
|
18549
|
+
code: "managed_chatgpt_auth_required",
|
|
18550
|
+
retryable: false
|
|
18551
|
+
});
|
|
18552
|
+
}
|
|
18553
|
+
const rateLimits = await session.readAccountRateLimits(options.deadlineAtMs, options.signal);
|
|
18554
|
+
return {
|
|
18555
|
+
authenticated_account_email: account.authenticatedChatGptAccount.email,
|
|
18556
|
+
authenticated_account_plan: account.authenticatedChatGptAccount.planType,
|
|
18557
|
+
rate_limits: rateLimits
|
|
18558
|
+
};
|
|
18492
18559
|
} finally {
|
|
18493
18560
|
await session.close();
|
|
18494
18561
|
}
|
|
@@ -18501,11 +18568,28 @@ async function logoutCodexSubscription(options) {
|
|
|
18501
18568
|
await session.close();
|
|
18502
18569
|
}
|
|
18503
18570
|
}
|
|
18504
|
-
var CODEX_INFERENCE_PERMISSION_PROFILE, CodexAppServerError, objectOrNull, finiteToken, tokenUsageFromBreakdown, usageFromNotification, forbiddenMethod, forbiddenTerminalItem, classifyCodexTurnFailure, scrubbedCodexEnvironment, killWindowsProcessTree, appServerArgs, GUARDIAN_SCRIPT, writeCodexGuardianSpawnIntent, parseGuardianReceipt, readCodexGuardianReceipt, waitForCodexGuardianState, defaultSpawn, CodexAppServerSession;
|
|
18571
|
+
var CODEX_INFERENCE_PERMISSION_PROFILE, CODEX_ACCOUNT_PLAN_TYPES, CodexAppServerError, objectOrNull, finiteToken, tokenUsageFromBreakdown, usageFromNotification, validPlanType, nonnegativeSafeIntegerOrNull, nonnegativeFiniteNumberOrNull, parseRateLimitWindow, RATE_LIMIT_REACHED_TYPES, DEFAULT_CODEX_QUOTA_COOLDOWN_MS, MAX_CODEX_QUOTA_COOLDOWN_MS, CODEX_TRANSIENT_RATE_LIMIT_COOLDOWN_MS, parseRateLimitSnapshot, codexRateLimitRetryAtMs, codexAccountRateLimitReached, forbiddenMethod, forbiddenTerminalItem, classifyCodexTurnFailure, scrubbedCodexEnvironment, killWindowsProcessTree, appServerArgs, GUARDIAN_SCRIPT, writeCodexGuardianSpawnIntent, parseGuardianReceipt, readCodexGuardianReceipt, waitForCodexGuardianState, defaultSpawn, CodexAppServerSession;
|
|
18505
18572
|
var init_codex_app_server = __esm({
|
|
18506
18573
|
"lib/inference-host/codex-app-server.ts"() {
|
|
18507
18574
|
"use strict";
|
|
18508
18575
|
CODEX_INFERENCE_PERMISSION_PROFILE = "vtx_inference_readonly";
|
|
18576
|
+
CODEX_ACCOUNT_PLAN_TYPES = [
|
|
18577
|
+
"free",
|
|
18578
|
+
"go",
|
|
18579
|
+
"plus",
|
|
18580
|
+
"pro",
|
|
18581
|
+
"prolite",
|
|
18582
|
+
"team",
|
|
18583
|
+
"self_serve_business_prolite",
|
|
18584
|
+
"self_serve_business_usage_based",
|
|
18585
|
+
"business",
|
|
18586
|
+
"ent26",
|
|
18587
|
+
"enterprise_cbp_automation",
|
|
18588
|
+
"enterprise_cbp_usage_based",
|
|
18589
|
+
"enterprise",
|
|
18590
|
+
"edu",
|
|
18591
|
+
"unknown"
|
|
18592
|
+
];
|
|
18509
18593
|
CodexAppServerError = class extends Error {
|
|
18510
18594
|
constructor(options) {
|
|
18511
18595
|
super(options.message, { cause: options.cause });
|
|
@@ -18514,6 +18598,9 @@ var init_codex_app_server = __esm({
|
|
|
18514
18598
|
this.code = options.code;
|
|
18515
18599
|
this.retryable = options.retryable;
|
|
18516
18600
|
this.dispatchOutcome = options.dispatchOutcome ?? "not_dispatched";
|
|
18601
|
+
this.httpStatusCode = options.httpStatusCode ?? null;
|
|
18602
|
+
this.retryAtMs = options.retryAtMs ?? null;
|
|
18603
|
+
this.usage = options.usage ?? null;
|
|
18517
18604
|
}
|
|
18518
18605
|
};
|
|
18519
18606
|
objectOrNull = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
@@ -18554,6 +18641,72 @@ var init_codex_app_server = __esm({
|
|
|
18554
18641
|
}
|
|
18555
18642
|
return null;
|
|
18556
18643
|
};
|
|
18644
|
+
validPlanType = (value) => typeof value === "string" && CODEX_ACCOUNT_PLAN_TYPES.includes(value);
|
|
18645
|
+
nonnegativeSafeIntegerOrNull = (value) => Number.isSafeInteger(value) && Number(value) >= 0 ? Number(value) : null;
|
|
18646
|
+
nonnegativeFiniteNumberOrNull = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : null;
|
|
18647
|
+
parseRateLimitWindow = (value) => {
|
|
18648
|
+
if (value === null) return null;
|
|
18649
|
+
const candidate = objectOrNull(value);
|
|
18650
|
+
if (!candidate) throw new Error("invalid rate-limit window");
|
|
18651
|
+
const usedPercent = nonnegativeFiniteNumberOrNull(candidate.usedPercent);
|
|
18652
|
+
const windowDurationMins = candidate.windowDurationMins == null ? null : nonnegativeSafeIntegerOrNull(candidate.windowDurationMins);
|
|
18653
|
+
const resetsAt = candidate.resetsAt == null ? null : nonnegativeSafeIntegerOrNull(candidate.resetsAt);
|
|
18654
|
+
if (usedPercent === null || windowDurationMins === null && candidate.windowDurationMins != null || resetsAt === null && candidate.resetsAt != null) {
|
|
18655
|
+
throw new Error("invalid rate-limit window");
|
|
18656
|
+
}
|
|
18657
|
+
return { usedPercent, windowDurationMins, resetsAt };
|
|
18658
|
+
};
|
|
18659
|
+
RATE_LIMIT_REACHED_TYPES = [
|
|
18660
|
+
"rate_limit_reached",
|
|
18661
|
+
"workspace_owner_credits_depleted",
|
|
18662
|
+
"workspace_member_credits_depleted",
|
|
18663
|
+
"workspace_owner_usage_limit_reached",
|
|
18664
|
+
"workspace_member_usage_limit_reached"
|
|
18665
|
+
];
|
|
18666
|
+
DEFAULT_CODEX_QUOTA_COOLDOWN_MS = 5 * 60 * 1e3;
|
|
18667
|
+
MAX_CODEX_QUOTA_COOLDOWN_MS = 8 * 24 * 60 * 60 * 1e3;
|
|
18668
|
+
CODEX_TRANSIENT_RATE_LIMIT_COOLDOWN_MS = 30 * 1e3;
|
|
18669
|
+
parseRateLimitSnapshot = (value) => {
|
|
18670
|
+
const candidate = objectOrNull(value);
|
|
18671
|
+
if (!candidate) throw new Error("invalid rate-limit snapshot");
|
|
18672
|
+
const limitId = candidate.limitId === null || candidate.limitId === void 0 ? null : typeof candidate.limitId === "string" && candidate.limitId.trim() ? candidate.limitId.trim() : void 0;
|
|
18673
|
+
const limitName = candidate.limitName === null || candidate.limitName === void 0 ? null : typeof candidate.limitName === "string" && candidate.limitName.trim() ? candidate.limitName.trim() : void 0;
|
|
18674
|
+
const planType = candidate.planType === null || candidate.planType === void 0 ? null : validPlanType(candidate.planType) ? candidate.planType : void 0;
|
|
18675
|
+
const reached = candidate.rateLimitReachedType === null || candidate.rateLimitReachedType === void 0 ? null : typeof candidate.rateLimitReachedType === "string" && RATE_LIMIT_REACHED_TYPES.includes(candidate.rateLimitReachedType) ? candidate.rateLimitReachedType : void 0;
|
|
18676
|
+
const spendControlReached = candidate.spendControlReached === null || candidate.spendControlReached === void 0 ? null : typeof candidate.spendControlReached === "boolean" ? candidate.spendControlReached : void 0;
|
|
18677
|
+
if (limitId === void 0 || limitName === void 0 || planType === void 0 || reached === void 0 || spendControlReached === void 0) throw new Error("invalid rate-limit snapshot");
|
|
18678
|
+
return {
|
|
18679
|
+
limitId,
|
|
18680
|
+
limitName,
|
|
18681
|
+
planType,
|
|
18682
|
+
primary: parseRateLimitWindow(candidate.primary ?? null),
|
|
18683
|
+
secondary: parseRateLimitWindow(candidate.secondary ?? null),
|
|
18684
|
+
rateLimitReachedType: reached,
|
|
18685
|
+
spendControlReached
|
|
18686
|
+
};
|
|
18687
|
+
};
|
|
18688
|
+
codexRateLimitRetryAtMs = (accountRateLimits) => {
|
|
18689
|
+
const snapshots = [accountRateLimits.rateLimits];
|
|
18690
|
+
const exhaustedResets = [];
|
|
18691
|
+
const reachedResets = [];
|
|
18692
|
+
for (const snapshot of snapshots) {
|
|
18693
|
+
const windows = [snapshot.primary, snapshot.secondary].filter(
|
|
18694
|
+
(window2) => window2 !== null
|
|
18695
|
+
);
|
|
18696
|
+
for (const window2 of windows) {
|
|
18697
|
+
if (window2.resetsAt === null) continue;
|
|
18698
|
+
const resetAtMs = window2.resetsAt * 1e3;
|
|
18699
|
+
if (!Number.isSafeInteger(resetAtMs)) continue;
|
|
18700
|
+
if (window2.usedPercent >= 100) exhaustedResets.push(resetAtMs);
|
|
18701
|
+
if (snapshot.rateLimitReachedType !== null || snapshot.spendControlReached === true) {
|
|
18702
|
+
reachedResets.push(resetAtMs);
|
|
18703
|
+
}
|
|
18704
|
+
}
|
|
18705
|
+
}
|
|
18706
|
+
const candidates = exhaustedResets.length > 0 ? exhaustedResets : reachedResets.length > 0 ? reachedResets : [];
|
|
18707
|
+
return candidates.length > 0 ? Math.max(...candidates) : null;
|
|
18708
|
+
};
|
|
18709
|
+
codexAccountRateLimitReached = (accountRateLimits) => [accountRateLimits.rateLimits].some((snapshot) => snapshot.rateLimitReachedType !== null || snapshot.spendControlReached === true || snapshot.primary?.usedPercent !== void 0 && snapshot.primary.usedPercent >= 100 || snapshot.secondary?.usedPercent !== void 0 && snapshot.secondary.usedPercent >= 100);
|
|
18557
18710
|
forbiddenMethod = (method) => method.startsWith("mcpServer/") || method.startsWith("serverRequest/") || method.startsWith("item/mcpToolCall") || method.startsWith("item/commandExecution") || method.startsWith("item/fileChange") || method.startsWith("item/dynamicToolCall") || method.startsWith("item/collabAgentToolCall");
|
|
18558
18711
|
forbiddenTerminalItem = (item) => ![
|
|
18559
18712
|
"userMessage",
|
|
@@ -18562,13 +18715,13 @@ var init_codex_app_server = __esm({
|
|
|
18562
18715
|
].includes(String(item.type || ""));
|
|
18563
18716
|
classifyCodexTurnFailure = (codexErrorInfo, terminalStatus) => {
|
|
18564
18717
|
if (terminalStatus === "interrupted") {
|
|
18565
|
-
return { code: "cancelled", category: "cancelled", retryable: false };
|
|
18718
|
+
return { code: "cancelled", category: "cancelled", retryable: false, httpStatusCode: null };
|
|
18566
18719
|
}
|
|
18567
18720
|
if (codexErrorInfo === "usageLimitExceeded") {
|
|
18568
|
-
return { code: "quota_exceeded", category: "model", retryable: false };
|
|
18721
|
+
return { code: "quota_exceeded", category: "model", retryable: false, httpStatusCode: null };
|
|
18569
18722
|
}
|
|
18570
18723
|
if (codexErrorInfo === "unauthorized") {
|
|
18571
|
-
return { code: "auth_expired", category: "auth", retryable: false };
|
|
18724
|
+
return { code: "auth_expired", category: "auth", retryable: false, httpStatusCode: null };
|
|
18572
18725
|
}
|
|
18573
18726
|
const stableStringCodes = {
|
|
18574
18727
|
badRequest: "codex_bad_request",
|
|
@@ -18585,22 +18738,40 @@ var init_codex_app_server = __esm({
|
|
|
18585
18738
|
return {
|
|
18586
18739
|
code,
|
|
18587
18740
|
category: "adapter",
|
|
18588
|
-
retryable: code === "codex_internal_error" || code === "codex_server_overloaded"
|
|
18741
|
+
retryable: code === "codex_internal_error" || code === "codex_server_overloaded",
|
|
18742
|
+
httpStatusCode: null
|
|
18589
18743
|
};
|
|
18590
18744
|
}
|
|
18591
18745
|
const structured = objectOrNull(codexErrorInfo);
|
|
18592
18746
|
if (structured) {
|
|
18593
|
-
|
|
18594
|
-
|
|
18595
|
-
|
|
18596
|
-
|
|
18597
|
-
|
|
18598
|
-
|
|
18599
|
-
|
|
18600
|
-
|
|
18747
|
+
const variants = [
|
|
18748
|
+
["httpConnectionFailed", "codex_http_connection_failed"],
|
|
18749
|
+
["responseStreamConnectionFailed", "codex_response_stream_connection_failed"],
|
|
18750
|
+
["responseStreamDisconnected", "codex_response_stream_disconnected"],
|
|
18751
|
+
["responseTooManyFailedAttempts", "codex_provider_retry_exhausted"]
|
|
18752
|
+
];
|
|
18753
|
+
for (const [variant, code] of variants) {
|
|
18754
|
+
if (!(variant in structured)) continue;
|
|
18755
|
+
const details = objectOrNull(structured[variant]);
|
|
18756
|
+
const rawStatus = details?.httpStatusCode;
|
|
18757
|
+
const httpStatusCode = Number.isSafeInteger(rawStatus) && Number(rawStatus) >= 100 && Number(rawStatus) <= 599 ? Number(rawStatus) : null;
|
|
18758
|
+
if (httpStatusCode === 429) {
|
|
18759
|
+
return {
|
|
18760
|
+
code: "codex_rate_limited",
|
|
18761
|
+
category: "adapter",
|
|
18762
|
+
retryable: true,
|
|
18763
|
+
httpStatusCode
|
|
18764
|
+
};
|
|
18765
|
+
}
|
|
18766
|
+
return {
|
|
18767
|
+
code,
|
|
18768
|
+
category: "adapter",
|
|
18769
|
+
retryable: httpStatusCode === null ? variant !== "responseTooManyFailedAttempts" : httpStatusCode === 408 || httpStatusCode === 425 || httpStatusCode >= 500,
|
|
18770
|
+
httpStatusCode
|
|
18771
|
+
};
|
|
18601
18772
|
}
|
|
18602
18773
|
}
|
|
18603
|
-
return { code: "turn_failed", category: "adapter", retryable: false };
|
|
18774
|
+
return { code: "turn_failed", category: "adapter", retryable: false, httpStatusCode: null };
|
|
18604
18775
|
};
|
|
18605
18776
|
scrubbedCodexEnvironment = (codexHome) => {
|
|
18606
18777
|
if (process.platform === "win32") {
|
|
@@ -19080,13 +19251,80 @@ child.once('close', async () => {
|
|
|
19080
19251
|
this.fatalListeners.add(listener);
|
|
19081
19252
|
return () => this.fatalListeners.delete(listener);
|
|
19082
19253
|
}
|
|
19083
|
-
async
|
|
19254
|
+
async readAccountSnapshot(deadlineAtMs, signal, refreshToken = false) {
|
|
19084
19255
|
const result2 = await this.request("account/read", { refreshToken }, {
|
|
19085
19256
|
timeoutMs: Math.max(1, deadlineAtMs - Date.now()),
|
|
19086
19257
|
signal
|
|
19087
19258
|
});
|
|
19088
19259
|
const account = objectOrNull(result2.account);
|
|
19089
|
-
|
|
19260
|
+
if (typeof result2.requiresOpenaiAuth !== "boolean") {
|
|
19261
|
+
throw new CodexAppServerError({
|
|
19262
|
+
message: "Codex returned invalid account metadata.",
|
|
19263
|
+
category: "auth",
|
|
19264
|
+
code: "invalid_account_metadata",
|
|
19265
|
+
retryable: false
|
|
19266
|
+
});
|
|
19267
|
+
}
|
|
19268
|
+
if (account?.type === "chatgpt") {
|
|
19269
|
+
const email3 = account.email === null ? null : typeof account.email === "string" && account.email.trim() ? account.email.trim() : void 0;
|
|
19270
|
+
if (email3 === void 0 || !validPlanType(account.planType)) {
|
|
19271
|
+
throw new CodexAppServerError({
|
|
19272
|
+
message: "Codex returned invalid managed ChatGPT account metadata.",
|
|
19273
|
+
category: "auth",
|
|
19274
|
+
code: "invalid_account_metadata",
|
|
19275
|
+
retryable: false
|
|
19276
|
+
});
|
|
19277
|
+
}
|
|
19278
|
+
return {
|
|
19279
|
+
requiresOpenaiAuth: result2.requiresOpenaiAuth,
|
|
19280
|
+
authenticatedChatGptAccount: { email: email3, planType: account.planType }
|
|
19281
|
+
};
|
|
19282
|
+
}
|
|
19283
|
+
if (account !== null && account?.type !== "apiKey" && account?.type !== "amazonBedrock") {
|
|
19284
|
+
throw new CodexAppServerError({
|
|
19285
|
+
message: "Codex returned an unsupported account type.",
|
|
19286
|
+
category: "auth",
|
|
19287
|
+
code: "invalid_account_metadata",
|
|
19288
|
+
retryable: false
|
|
19289
|
+
});
|
|
19290
|
+
}
|
|
19291
|
+
return {
|
|
19292
|
+
requiresOpenaiAuth: result2.requiresOpenaiAuth,
|
|
19293
|
+
authenticatedChatGptAccount: null
|
|
19294
|
+
};
|
|
19295
|
+
}
|
|
19296
|
+
async hasManagedChatGptAuth(deadlineAtMs, signal, refreshToken = false) {
|
|
19297
|
+
const snapshot = await this.readAccountSnapshot(deadlineAtMs, signal, refreshToken);
|
|
19298
|
+
return snapshot.authenticatedChatGptAccount !== null && snapshot.requiresOpenaiAuth;
|
|
19299
|
+
}
|
|
19300
|
+
async readAccountRateLimits(deadlineAtMs, signal) {
|
|
19301
|
+
const result2 = await this.request("account/rateLimits/read", void 0, {
|
|
19302
|
+
timeoutMs: Math.max(1, deadlineAtMs - Date.now()),
|
|
19303
|
+
signal
|
|
19304
|
+
});
|
|
19305
|
+
try {
|
|
19306
|
+
const rateLimits = parseRateLimitSnapshot(result2.rateLimits);
|
|
19307
|
+
const rawByLimitId = result2.rateLimitsByLimitId;
|
|
19308
|
+
let rateLimitsByLimitId = null;
|
|
19309
|
+
if (rawByLimitId !== null && rawByLimitId !== void 0) {
|
|
19310
|
+
const byLimitId = objectOrNull(rawByLimitId);
|
|
19311
|
+
if (!byLimitId) throw new Error("invalid rate-limit bucket map");
|
|
19312
|
+
rateLimitsByLimitId = {};
|
|
19313
|
+
for (const [limitId, snapshot] of Object.entries(byLimitId)) {
|
|
19314
|
+
if (!limitId.trim()) throw new Error("invalid rate-limit bucket identity");
|
|
19315
|
+
rateLimitsByLimitId[limitId] = parseRateLimitSnapshot(snapshot);
|
|
19316
|
+
}
|
|
19317
|
+
}
|
|
19318
|
+
return { rateLimits, rateLimitsByLimitId };
|
|
19319
|
+
} catch (error48) {
|
|
19320
|
+
throw new CodexAppServerError({
|
|
19321
|
+
message: "Codex returned invalid account rate-limit metadata.",
|
|
19322
|
+
category: "adapter",
|
|
19323
|
+
code: "invalid_rate_limit_metadata",
|
|
19324
|
+
retryable: false,
|
|
19325
|
+
cause: error48
|
|
19326
|
+
});
|
|
19327
|
+
}
|
|
19090
19328
|
}
|
|
19091
19329
|
async requireManagedChatGptAuth(deadlineAtMs, signal, refreshToken = false) {
|
|
19092
19330
|
if (!await this.hasManagedChatGptAuth(deadlineAtMs, signal, refreshToken)) {
|
|
@@ -19623,13 +19861,54 @@ child.once('close', async () => {
|
|
|
19623
19861
|
}
|
|
19624
19862
|
if (terminal.status !== "completed") {
|
|
19625
19863
|
const turnError = objectOrNull(terminal.error);
|
|
19626
|
-
|
|
19864
|
+
let failure = classifyCodexTurnFailure(
|
|
19865
|
+
turnError?.codexErrorInfo,
|
|
19866
|
+
String(terminal.status)
|
|
19867
|
+
);
|
|
19868
|
+
const observedUsage = threadUsage ?? rawResponseUsage;
|
|
19869
|
+
let retryAtMs = null;
|
|
19870
|
+
if (failure.code === "quota_exceeded" || failure.httpStatusCode === 429) {
|
|
19871
|
+
const observedAtMs = Date.now();
|
|
19872
|
+
let accountLimitReached = failure.code === "quota_exceeded";
|
|
19873
|
+
try {
|
|
19874
|
+
const metadataDeadlineAtMs = Math.min(
|
|
19875
|
+
request.deadlineAtMs,
|
|
19876
|
+
observedAtMs + 5e3
|
|
19877
|
+
);
|
|
19878
|
+
if (metadataDeadlineAtMs <= observedAtMs) throw new Error("rate-limit deadline elapsed");
|
|
19879
|
+
const rateLimits = await this.readAccountRateLimits(metadataDeadlineAtMs, request.signal);
|
|
19880
|
+
accountLimitReached = accountLimitReached || codexAccountRateLimitReached(rateLimits);
|
|
19881
|
+
retryAtMs = codexRateLimitRetryAtMs(rateLimits);
|
|
19882
|
+
} catch {
|
|
19883
|
+
}
|
|
19884
|
+
if (accountLimitReached) {
|
|
19885
|
+
failure = {
|
|
19886
|
+
...failure,
|
|
19887
|
+
code: "quota_exceeded",
|
|
19888
|
+
category: "model",
|
|
19889
|
+
retryable: false
|
|
19890
|
+
};
|
|
19891
|
+
if (retryAtMs === null || retryAtMs <= observedAtMs) {
|
|
19892
|
+
retryAtMs = observedAtMs + DEFAULT_CODEX_QUOTA_COOLDOWN_MS;
|
|
19893
|
+
} else {
|
|
19894
|
+
retryAtMs = Math.min(
|
|
19895
|
+
retryAtMs,
|
|
19896
|
+
observedAtMs + MAX_CODEX_QUOTA_COOLDOWN_MS
|
|
19897
|
+
);
|
|
19898
|
+
}
|
|
19899
|
+
} else {
|
|
19900
|
+
retryAtMs = observedAtMs + CODEX_TRANSIENT_RATE_LIMIT_COOLDOWN_MS;
|
|
19901
|
+
}
|
|
19902
|
+
}
|
|
19627
19903
|
throw new CodexAppServerError({
|
|
19628
19904
|
message: "Codex turn did not complete successfully.",
|
|
19629
19905
|
category: failure.category,
|
|
19630
19906
|
code: failure.code,
|
|
19631
19907
|
retryable: failure.retryable,
|
|
19632
|
-
dispatchOutcome: "confirmed_dispatched"
|
|
19908
|
+
dispatchOutcome: "confirmed_dispatched",
|
|
19909
|
+
httpStatusCode: failure.httpStatusCode,
|
|
19910
|
+
retryAtMs,
|
|
19911
|
+
usage: observedUsage
|
|
19633
19912
|
});
|
|
19634
19913
|
}
|
|
19635
19914
|
const items = Array.isArray(terminal.items) ? terminal.items.map(objectOrNull) : [];
|
|
@@ -19989,7 +20268,10 @@ var init_codex_adapter = __esm({
|
|
|
19989
20268
|
category: external_exports.enum(["auth", "model", "schema", "timeout", "cancelled", "transport", "adapter"]),
|
|
19990
20269
|
code: external_exports.string().min(1).max(96),
|
|
19991
20270
|
retryable: external_exports.boolean(),
|
|
19992
|
-
dispatchOutcome: external_exports.enum(["not_dispatched", "confirmed_dispatched", "outcome_unknown"])
|
|
20271
|
+
dispatchOutcome: external_exports.enum(["not_dispatched", "confirmed_dispatched", "outcome_unknown"]),
|
|
20272
|
+
httpStatusCode: external_exports.number().int().min(100).max(599).nullable().optional(),
|
|
20273
|
+
retryAtMs: external_exports.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).nullable().optional(),
|
|
20274
|
+
usage: tokenUsageReceiptSchema.nullable().optional()
|
|
19993
20275
|
})
|
|
19994
20276
|
})
|
|
19995
20277
|
]);
|
|
@@ -20510,7 +20792,10 @@ var init_codex_adapter = __esm({
|
|
|
20510
20792
|
category: recovered.category,
|
|
20511
20793
|
code: recovered.code,
|
|
20512
20794
|
retryable: recovered.retryable,
|
|
20513
|
-
dispatchOutcome: recovered.dispatchOutcome
|
|
20795
|
+
dispatchOutcome: recovered.dispatchOutcome,
|
|
20796
|
+
httpStatusCode: recovered.httpStatusCode,
|
|
20797
|
+
retryAtMs: recovered.retryAtMs,
|
|
20798
|
+
usage: recovered.usage
|
|
20514
20799
|
});
|
|
20515
20800
|
}
|
|
20516
20801
|
throw new CodexAppServerError({
|
|
@@ -20649,7 +20934,10 @@ var init_codex_adapter = __esm({
|
|
|
20649
20934
|
category: error48.category,
|
|
20650
20935
|
code: error48.code,
|
|
20651
20936
|
retryable: error48.retryable,
|
|
20652
|
-
dispatchOutcome
|
|
20937
|
+
dispatchOutcome,
|
|
20938
|
+
httpStatusCode: error48.httpStatusCode,
|
|
20939
|
+
retryAtMs: error48.retryAtMs,
|
|
20940
|
+
usage: error48.usage
|
|
20653
20941
|
}
|
|
20654
20942
|
}
|
|
20655
20943
|
};
|
|
@@ -20662,6 +20950,9 @@ var init_codex_adapter = __esm({
|
|
|
20662
20950
|
code: error48.code,
|
|
20663
20951
|
retryable: error48.retryable,
|
|
20664
20952
|
dispatchOutcome,
|
|
20953
|
+
httpStatusCode: error48.httpStatusCode,
|
|
20954
|
+
retryAtMs: error48.retryAtMs,
|
|
20955
|
+
usage: error48.usage,
|
|
20665
20956
|
cause: error48
|
|
20666
20957
|
});
|
|
20667
20958
|
}
|
|
@@ -27341,7 +27632,7 @@ function createDefaultInferenceHostRunnerDependencies(options) {
|
|
|
27341
27632
|
envelopePublicKey: options.envelopePublicKey
|
|
27342
27633
|
};
|
|
27343
27634
|
}
|
|
27344
|
-
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, DEFAULT_MAX_CONCURRENCY, MIN_SLEEP_MS, CODEX_INFERENCE_ADVERTISED_MODEL, FileInferenceHostRuntimeReceiptStore, InferenceHostRecoveryRequiredError, InferenceHostRunnerError, defaultSleep, abortError, defaultRegisterSignalHandlers, safeInteger, exactObjectKeys, validIso, validateAttemptReceipt, validateRuntimeReceipt, sha256, stableOperationId, buildAttemptStartRequest, isoAt, finitePositiveOption, validateRunnerOptions, assertLocalCredentialIdentity, retryableRemoteError, controlPlaneFatal, defaultValidateOutput, objectRecord, positiveUtf8ByteLimit, assertCompilableOutputSchema, parseOutputContract, safeFailureCode, exactJson2, runnerIdentityMismatch, assertAdvertisementResult, assertHostHeartbeatResult, assertClaimResult, assertStartResult, assertJobHeartbeatResult, assertTerminalResult, classifyFailure, ambiguousHeartbeatTransport, reportedUsage, InferenceHostRunner;
|
|
27635
|
+
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, DEFAULT_MAX_CONCURRENCY, MIN_SLEEP_MS, DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS, CODEX_INFERENCE_ADVERTISED_MODEL, FileInferenceHostRuntimeReceiptStore, InferenceHostRecoveryRequiredError, InferenceHostRunnerError, defaultSleep, abortError, defaultRegisterSignalHandlers, safeInteger, exactObjectKeys, validIso, validateAttemptReceipt, validateRuntimeReceipt, sha256, stableOperationId, buildAttemptStartRequest, isoAt, 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;
|
|
27345
27636
|
var init_runner = __esm({
|
|
27346
27637
|
"lib/inference-host/runner.ts"() {
|
|
27347
27638
|
"use strict";
|
|
@@ -27364,6 +27655,7 @@ var init_runner = __esm({
|
|
|
27364
27655
|
DEFAULT_REMOTE_RETRY_LIMIT = 3;
|
|
27365
27656
|
DEFAULT_MAX_CONCURRENCY = 1;
|
|
27366
27657
|
MIN_SLEEP_MS = 10;
|
|
27658
|
+
DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS = 5 * 60 * 1e3;
|
|
27367
27659
|
CODEX_INFERENCE_ADVERTISED_MODEL = Object.freeze({
|
|
27368
27660
|
model_id: INITIAL_CODEX_INFERENCE_MODEL,
|
|
27369
27661
|
label: "Codex GPT-5.6 Sol",
|
|
@@ -27653,19 +27945,14 @@ var init_runner = __esm({
|
|
|
27653
27945
|
};
|
|
27654
27946
|
retryableRemoteError = (error48) => {
|
|
27655
27947
|
if (error48 instanceof ExternalInferenceMcpError) {
|
|
27656
|
-
return
|
|
27657
|
-
"network_error",
|
|
27658
|
-
"transport_rejected",
|
|
27659
|
-
"invalid_response",
|
|
27660
|
-
"request_timeout",
|
|
27661
|
-
"authentication_timeout"
|
|
27662
|
-
].includes(error48.code);
|
|
27948
|
+
return error48.retryable;
|
|
27663
27949
|
}
|
|
27664
27950
|
if (error48 && typeof error48 === "object" && "retryable" in error48) {
|
|
27665
27951
|
return error48.retryable === true;
|
|
27666
27952
|
}
|
|
27667
27953
|
return false;
|
|
27668
27954
|
};
|
|
27955
|
+
remoteRetryAfterMs = (error48, fallbackMs) => error48 instanceof ExternalInferenceMcpError && error48.retryAfterMs !== null && Number.isSafeInteger(error48.retryAfterMs) && error48.retryAfterMs >= 0 ? Math.max(fallbackMs, error48.retryAfterMs) : fallbackMs;
|
|
27669
27956
|
controlPlaneFatal = (error48) => {
|
|
27670
27957
|
const code = error48 && typeof error48 === "object" && "code" in error48 ? String(error48.code) : "";
|
|
27671
27958
|
return [
|
|
@@ -27788,11 +28075,12 @@ var init_runner = __esm({
|
|
|
27788
28075
|
};
|
|
27789
28076
|
assertAdvertisementResult = (advertisement, result2) => {
|
|
27790
28077
|
const host = result2.host;
|
|
27791
|
-
if (host.host_id !== advertisement.host_id || host.host_generation !== advertisement.host_generation || host.advertisement_generation !== advertisement.advertisement_generation || host.key_generation !== advertisement.key_generation || host.display_name !== advertisement.display_name || host.adapter !== advertisement.adapter || host.status === "revoked" || !exactJson2(host.models, advertisement.models)) runnerIdentityMismatch("Host advertisement");
|
|
28078
|
+
if (host.host_id !== advertisement.host_id || host.host_generation !== advertisement.host_generation || host.advertisement_generation !== advertisement.advertisement_generation || host.key_generation !== advertisement.key_generation || host.display_name !== advertisement.display_name || (host.authenticated_account_email ?? null) !== (advertisement.authenticated_account_email ?? null) || (host.authenticated_account_plan ?? null) !== (advertisement.authenticated_account_plan ?? null) || host.adapter !== advertisement.adapter || host.status === "revoked" || !exactJson2(host.models, advertisement.models)) runnerIdentityMismatch("Host advertisement");
|
|
27792
28079
|
};
|
|
27793
|
-
assertHostHeartbeatResult = (request, result2) => {
|
|
28080
|
+
assertHostHeartbeatResult = (request, result2, allowOfflineProjection = false) => {
|
|
27794
28081
|
const expectedStatus = request.status === "healthy" ? "online" : request.status;
|
|
27795
|
-
|
|
28082
|
+
const expectedTemporaryOffline = allowOfflineProjection && request.status === "healthy" && result2.host.status === "offline";
|
|
28083
|
+
if (result2.host.host_id !== request.host_id || result2.host.host_generation !== request.host_generation || result2.host.advertisement_generation !== request.advertisement_generation || result2.host.key_generation !== request.key_generation || result2.host.adapter !== "codex" || result2.host.status !== expectedStatus && !expectedTemporaryOffline) runnerIdentityMismatch("Host heartbeat");
|
|
27796
28084
|
};
|
|
27797
28085
|
assertClaimResult = (request, result2) => {
|
|
27798
28086
|
if (result2.claim_request_id !== request.claim_request_id) {
|
|
@@ -27828,7 +28116,13 @@ var init_runner = __esm({
|
|
|
27828
28116
|
};
|
|
27829
28117
|
}
|
|
27830
28118
|
if (error48 instanceof ExternalInferenceMcpError) {
|
|
27831
|
-
const category2 = error48.code.startsWith("authentication") ? "auth" : [
|
|
28119
|
+
const category2 = error48.code.startsWith("authentication") ? "auth" : [
|
|
28120
|
+
"network_error",
|
|
28121
|
+
"transport_rejected",
|
|
28122
|
+
"server_rejected",
|
|
28123
|
+
"rate_limited",
|
|
28124
|
+
"request_timeout"
|
|
28125
|
+
].includes(error48.code) ? "network" : "transport";
|
|
27832
28126
|
return {
|
|
27833
28127
|
category: category2,
|
|
27834
28128
|
code: safeFailureCode(error48.code, "transport_failure"),
|
|
@@ -27854,24 +28148,27 @@ var init_runner = __esm({
|
|
|
27854
28148
|
return [
|
|
27855
28149
|
"network_error",
|
|
27856
28150
|
"transport_rejected",
|
|
28151
|
+
"server_rejected",
|
|
28152
|
+
"rate_limited",
|
|
27857
28153
|
"invalid_response",
|
|
27858
28154
|
"identity_mismatch",
|
|
27859
28155
|
"request_timeout",
|
|
27860
28156
|
"authentication_timeout"
|
|
27861
28157
|
].includes(code);
|
|
27862
28158
|
};
|
|
27863
|
-
|
|
28159
|
+
reportedTokenUsage = (usage) => ({
|
|
27864
28160
|
schema_version: EXTERNAL_INFERENCE_USAGE_SCHEMA_VERSION,
|
|
27865
28161
|
availability: "reported",
|
|
27866
28162
|
source: "codex_app_server",
|
|
27867
|
-
input_tokens:
|
|
27868
|
-
cached_input_tokens:
|
|
27869
|
-
output_tokens:
|
|
27870
|
-
reasoning_output_tokens:
|
|
27871
|
-
total_tokens:
|
|
27872
|
-
cache_write_input_tokens:
|
|
27873
|
-
cache_write_support:
|
|
27874
|
-
});
|
|
28163
|
+
input_tokens: usage.inputTokens,
|
|
28164
|
+
cached_input_tokens: usage.cachedInputTokens,
|
|
28165
|
+
output_tokens: usage.outputTokens,
|
|
28166
|
+
reasoning_output_tokens: usage.reasoningOutputTokens,
|
|
28167
|
+
total_tokens: usage.totalTokens,
|
|
28168
|
+
cache_write_input_tokens: usage.cacheWriteInputTokens,
|
|
28169
|
+
cache_write_support: usage.cacheWriteSupported ? "reported" : "unsupported"
|
|
28170
|
+
});
|
|
28171
|
+
reportedUsage = (result2) => reportedTokenUsage(result2.usage);
|
|
27875
28172
|
InferenceHostRunner = class {
|
|
27876
28173
|
constructor(dependencies, options) {
|
|
27877
28174
|
this.receiptWriteChain = Promise.resolve();
|
|
@@ -28034,24 +28331,24 @@ var init_runner = __esm({
|
|
|
28034
28331
|
} catch (error48) {
|
|
28035
28332
|
lastError = error48;
|
|
28036
28333
|
if (!retryableRemoteError(error48) || attempt === settings.remoteRetryLimit) throw error48;
|
|
28037
|
-
const
|
|
28038
|
-
|
|
28039
|
-
1e3
|
|
28040
|
-
boundary.deadlineAtMs === void 0 ? Number.POSITIVE_INFINITY : Math.max(0, boundary.deadlineAtMs - now())
|
|
28334
|
+
const requestedRetryDelay = remoteRetryAfterMs(
|
|
28335
|
+
error48,
|
|
28336
|
+
Math.min(250 * attempt, 1e3)
|
|
28041
28337
|
);
|
|
28042
|
-
|
|
28338
|
+
const remaining = boundary.deadlineAtMs === void 0 ? Number.POSITIVE_INFINITY : Math.max(0, boundary.deadlineAtMs - now());
|
|
28339
|
+
if (requestedRetryDelay < 1 || requestedRetryDelay >= remaining) {
|
|
28043
28340
|
throw new ExternalInferenceMcpError(
|
|
28044
28341
|
"request_timeout",
|
|
28045
28342
|
"Insights MCP retry deadline elapsed.",
|
|
28046
28343
|
{ cause: error48 }
|
|
28047
28344
|
);
|
|
28048
28345
|
}
|
|
28049
|
-
await sleep4(
|
|
28346
|
+
await sleep4(requestedRetryDelay, boundary.signal);
|
|
28050
28347
|
}
|
|
28051
28348
|
}
|
|
28052
28349
|
throw lastError;
|
|
28053
28350
|
};
|
|
28054
|
-
const publishAdvertisement = async (health, forceAdvance) => {
|
|
28351
|
+
const publishAdvertisement = async (health, forceAdvance, retryRemote = true) => {
|
|
28055
28352
|
let advertisement = receipt.pending_advertisement;
|
|
28056
28353
|
if (!advertisement) {
|
|
28057
28354
|
const generation = receipt.registered && forceAdvance ? receipt.advertisement_generation + 1 : receipt.advertisement_generation;
|
|
@@ -28072,6 +28369,8 @@ var init_runner = __esm({
|
|
|
28072
28369
|
key_generation: localState.key_generation,
|
|
28073
28370
|
adapter: "codex",
|
|
28074
28371
|
display_name: this.options.displayName.trim(),
|
|
28372
|
+
authenticated_account_email: this.options.authenticatedAccountEmail ?? null,
|
|
28373
|
+
authenticated_account_plan: this.options.authenticatedAccountPlan ?? null,
|
|
28075
28374
|
protocol_version: this.options.protocolVersion,
|
|
28076
28375
|
envelope_public_key: envelopePublicKey,
|
|
28077
28376
|
health,
|
|
@@ -28094,15 +28393,12 @@ var init_runner = __esm({
|
|
|
28094
28393
|
const tool = receipt.registered ? "inference.host.advertise" : "inference.host.register";
|
|
28095
28394
|
let result2;
|
|
28096
28395
|
try {
|
|
28097
|
-
|
|
28098
|
-
tool,
|
|
28099
|
-
advertisement,
|
|
28100
|
-
{ signal: this.options.signal }
|
|
28101
|
-
), { signal: this.options.signal }) : await retryExact(() => mcp.callTool(
|
|
28396
|
+
const advertiseOperation = () => mcp.callTool(
|
|
28102
28397
|
tool,
|
|
28103
28398
|
advertisement,
|
|
28104
28399
|
{ signal: this.options.signal }
|
|
28105
|
-
)
|
|
28400
|
+
);
|
|
28401
|
+
result2 = retryRemote ? await retryExact(advertiseOperation, { signal: this.options.signal }) : await advertiseOperation();
|
|
28106
28402
|
} catch (error48) {
|
|
28107
28403
|
const definitivelyNotApplied = error48 instanceof ExternalInferenceMcpError ? error48.definitivelyNotApplied : Boolean(error48 && typeof error48 === "object" && error48.definitivelyNotApplied === true);
|
|
28108
28404
|
const expectedGeneration = receipt.registered ? receipt.advertisement_generation + 1 : receipt.advertisement_generation;
|
|
@@ -28113,7 +28409,7 @@ var init_runner = __esm({
|
|
|
28113
28409
|
updated_at: isoAt(now())
|
|
28114
28410
|
};
|
|
28115
28411
|
await this.persistReceipt(receipt, now);
|
|
28116
|
-
return await publishAdvertisement(health, forceAdvance);
|
|
28412
|
+
return await publishAdvertisement(health, forceAdvance, retryRemote);
|
|
28117
28413
|
}
|
|
28118
28414
|
throw error48;
|
|
28119
28415
|
}
|
|
@@ -28135,7 +28431,7 @@ var init_runner = __esm({
|
|
|
28135
28431
|
}
|
|
28136
28432
|
const hostHeartbeat = async (status, requestOptions = {
|
|
28137
28433
|
signal: this.options.signal
|
|
28138
|
-
}) => {
|
|
28434
|
+
}, retryRemote = true, allowOfflineProjection = false) => {
|
|
28139
28435
|
const sequence = receipt.host_heartbeat_sequence + 1;
|
|
28140
28436
|
const request = {
|
|
28141
28437
|
schema_version: "external_inference_host_heartbeat_v1",
|
|
@@ -28161,9 +28457,9 @@ var init_runner = __esm({
|
|
|
28161
28457
|
request,
|
|
28162
28458
|
requestOptions
|
|
28163
28459
|
);
|
|
28164
|
-
const result2 = status === "draining" ? await heartbeatOperation() : await retryExact(heartbeatOperation, requestOptions);
|
|
28165
|
-
assertHostHeartbeatResult(request, result2);
|
|
28166
|
-
if (
|
|
28460
|
+
const result2 = status === "draining" || !retryRemote ? await heartbeatOperation() : await retryExact(heartbeatOperation, requestOptions);
|
|
28461
|
+
assertHostHeartbeatResult(request, result2, allowOfflineProjection);
|
|
28462
|
+
if (result2.host.status === "revoked" || result2.host.status === "offline" && !allowOfflineProjection) {
|
|
28167
28463
|
const error48 = new InferenceHostRunnerError(
|
|
28168
28464
|
result2.host.status === "revoked" ? "host_revoked" : "host_offline",
|
|
28169
28465
|
"The external inference host is no longer active."
|
|
@@ -28173,7 +28469,9 @@ var init_runner = __esm({
|
|
|
28173
28469
|
};
|
|
28174
28470
|
await hostHeartbeat("healthy");
|
|
28175
28471
|
let nextHostHeartbeatAt = now() + settings.hostHeartbeatMs;
|
|
28176
|
-
let
|
|
28472
|
+
let nextAdvertisementAttemptAt = 0;
|
|
28473
|
+
let providerRetryAtMs = this.options.codexRateLimits && codexAccountRateLimitReached(this.options.codexRateLimits) ? codexRateLimitRetryAtMs(this.options.codexRateLimits) ?? now() + DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS : null;
|
|
28474
|
+
let nextClaimAt = Math.max(now(), providerRetryAtMs ?? 0);
|
|
28177
28475
|
let onceClaimed = false;
|
|
28178
28476
|
const launchClaim = (claim, recovery) => {
|
|
28179
28477
|
if (!recovery) {
|
|
@@ -28211,6 +28509,11 @@ var init_runner = __esm({
|
|
|
28211
28509
|
attemptHeartbeatMs: settings.attemptHeartbeatMs,
|
|
28212
28510
|
sleep: sleep4,
|
|
28213
28511
|
now,
|
|
28512
|
+
onProviderCooldown: (retryAtMs) => {
|
|
28513
|
+
if (!Number.isSafeInteger(retryAtMs) || retryAtMs <= now()) return;
|
|
28514
|
+
providerRetryAtMs = Math.max(providerRetryAtMs ?? 0, retryAtMs);
|
|
28515
|
+
nextClaimAt = Math.max(nextClaimAt, providerRetryAtMs);
|
|
28516
|
+
},
|
|
28214
28517
|
resumeReceipt: recovery
|
|
28215
28518
|
}).then((outcome) => {
|
|
28216
28519
|
if (outcome === "completed") completed += 1;
|
|
@@ -28270,22 +28573,46 @@ var init_runner = __esm({
|
|
|
28270
28573
|
while (!drainRequested) {
|
|
28271
28574
|
const currentTime = now();
|
|
28272
28575
|
const expiresAt = receipt.advertisement_expires_at ? Date.parse(receipt.advertisement_expires_at) : 0;
|
|
28273
|
-
if (expiresAt - currentTime <= settings.advertisementRefreshLeadMs) {
|
|
28576
|
+
if (currentTime >= nextAdvertisementAttemptAt && expiresAt - currentTime <= settings.advertisementRefreshLeadMs) {
|
|
28274
28577
|
try {
|
|
28275
|
-
await publishAdvertisement("healthy", true);
|
|
28578
|
+
await publishAdvertisement("healthy", true, false);
|
|
28579
|
+
nextAdvertisementAttemptAt = 0;
|
|
28276
28580
|
} catch (error48) {
|
|
28277
|
-
|
|
28278
|
-
|
|
28581
|
+
if (controlPlaneFatal(error48)) {
|
|
28582
|
+
requestDrain("authority_lost");
|
|
28583
|
+
break;
|
|
28584
|
+
}
|
|
28585
|
+
if (!retryableRemoteError(error48)) {
|
|
28586
|
+
requestDrain("advertisement_failed");
|
|
28587
|
+
break;
|
|
28588
|
+
}
|
|
28589
|
+
nextAdvertisementAttemptAt = now() + remoteRetryAfterMs(error48, 1e3);
|
|
28590
|
+
nextClaimAt = Math.max(nextClaimAt, nextAdvertisementAttemptAt);
|
|
28279
28591
|
}
|
|
28280
28592
|
}
|
|
28281
28593
|
if (currentTime >= nextHostHeartbeatAt) {
|
|
28282
28594
|
try {
|
|
28283
|
-
|
|
28595
|
+
const refreshPendingAcrossExpiry = receipt.pending_advertisement !== null && expiresAt <= currentTime && nextAdvertisementAttemptAt > currentTime;
|
|
28596
|
+
await hostHeartbeat(
|
|
28597
|
+
"healthy",
|
|
28598
|
+
{ signal: this.options.signal },
|
|
28599
|
+
false,
|
|
28600
|
+
refreshPendingAcrossExpiry
|
|
28601
|
+
);
|
|
28284
28602
|
} catch (error48) {
|
|
28285
|
-
|
|
28286
|
-
|
|
28603
|
+
if (controlPlaneFatal(error48)) {
|
|
28604
|
+
requestDrain("authority_lost");
|
|
28605
|
+
break;
|
|
28606
|
+
}
|
|
28607
|
+
if (!retryableRemoteError(error48)) {
|
|
28608
|
+
requestDrain("host_heartbeat_failed");
|
|
28609
|
+
break;
|
|
28610
|
+
}
|
|
28611
|
+
nextHostHeartbeatAt = now() + remoteRetryAfterMs(error48, settings.hostHeartbeatMs);
|
|
28612
|
+
}
|
|
28613
|
+
if (!drainRequested && currentTime >= nextHostHeartbeatAt) {
|
|
28614
|
+
nextHostHeartbeatAt = now() + settings.hostHeartbeatMs;
|
|
28287
28615
|
}
|
|
28288
|
-
nextHostHeartbeatAt = now() + settings.hostHeartbeatMs;
|
|
28289
28616
|
}
|
|
28290
28617
|
while (recoveryQueue.length > 0 && active.size < settings.maxConcurrency) {
|
|
28291
28618
|
const recovery = recoveryQueue.shift();
|
|
@@ -28316,15 +28643,19 @@ var init_runner = __esm({
|
|
|
28316
28643
|
await this.persistReceipt(receipt, now);
|
|
28317
28644
|
let claim;
|
|
28318
28645
|
try {
|
|
28319
|
-
claim = await
|
|
28646
|
+
claim = await mcp.callTool(
|
|
28320
28647
|
"inference.job.claim",
|
|
28321
28648
|
request,
|
|
28322
28649
|
{ signal: this.options.signal }
|
|
28323
|
-
)
|
|
28650
|
+
);
|
|
28324
28651
|
assertClaimResult(request, claim);
|
|
28325
28652
|
} catch (error48) {
|
|
28326
|
-
if (!this.options.signal?.aborted) {
|
|
28327
|
-
requestDrain(
|
|
28653
|
+
if (!this.options.signal?.aborted && controlPlaneFatal(error48)) {
|
|
28654
|
+
requestDrain("authority_lost");
|
|
28655
|
+
} else if (!this.options.signal?.aborted && retryableRemoteError(error48)) {
|
|
28656
|
+
nextClaimAt = now() + remoteRetryAfterMs(error48, 1e3);
|
|
28657
|
+
} else if (!this.options.signal?.aborted) {
|
|
28658
|
+
requestDrain("claim_failed");
|
|
28328
28659
|
}
|
|
28329
28660
|
break;
|
|
28330
28661
|
}
|
|
@@ -28337,10 +28668,12 @@ var init_runner = __esm({
|
|
|
28337
28668
|
if (this.options.once) requestDrain("once_complete");
|
|
28338
28669
|
}
|
|
28339
28670
|
if (drainRequested) break;
|
|
28340
|
-
const
|
|
28341
|
-
|
|
28342
|
-
|
|
28343
|
-
|
|
28671
|
+
const advertisementDueAt = nextAdvertisementAttemptAt > now() ? nextAdvertisementAttemptAt : receipt.advertisement_expires_at ? Date.parse(receipt.advertisement_expires_at) - settings.advertisementRefreshLeadMs : now() + MIN_SLEEP_MS;
|
|
28672
|
+
const wakeAt = Math.min(
|
|
28673
|
+
nextClaimAt,
|
|
28674
|
+
nextHostHeartbeatAt,
|
|
28675
|
+
Math.max(now() + MIN_SLEEP_MS, advertisementDueAt)
|
|
28676
|
+
);
|
|
28344
28677
|
await Promise.race([
|
|
28345
28678
|
sleep4(Math.max(MIN_SLEEP_MS, wakeAt - now())),
|
|
28346
28679
|
drainSignal,
|
|
@@ -28684,6 +29017,9 @@ var init_runner = __esm({
|
|
|
28684
29017
|
if (error48 instanceof InferenceHostRunnerError && error48.code === "terminal_outcome_unconfirmed") {
|
|
28685
29018
|
throw error48;
|
|
28686
29019
|
}
|
|
29020
|
+
if (error48 instanceof CodexAppServerError && error48.retryAtMs !== null && ["quota_exceeded", "codex_rate_limited"].includes(error48.code)) {
|
|
29021
|
+
options.onProviderCooldown?.(error48.retryAtMs);
|
|
29022
|
+
}
|
|
28687
29023
|
const classified = classifyFailure(heartbeatFailure ?? error48, adapterResult);
|
|
28688
29024
|
const heartbeatAmbiguous = ambiguousHeartbeatTransport(heartbeatFailure);
|
|
28689
29025
|
const failure = heartbeatAmbiguous ? {
|
|
@@ -28734,7 +29070,7 @@ var init_runner = __esm({
|
|
|
28734
29070
|
adapter_request_id: canReportEffective ? adapterResult?.adapterRequestId ?? null : null,
|
|
28735
29071
|
adapter_response_id: canReportEffective ? adapterResult?.adapterResponseId ?? null : null
|
|
28736
29072
|
},
|
|
28737
|
-
usage: adapterResult ? reportedUsage(adapterResult) : null,
|
|
29073
|
+
usage: adapterResult ? reportedUsage(adapterResult) : error48 instanceof CodexAppServerError && error48.usage ? reportedTokenUsage(error48.usage) : null,
|
|
28738
29074
|
failure_category: failure.category,
|
|
28739
29075
|
failure_code: failure.code,
|
|
28740
29076
|
retryable: failure.retryable,
|
|
@@ -28808,6 +29144,9 @@ import { join as join5, resolve as resolve4 } from "node:path";
|
|
|
28808
29144
|
async function runInferenceHostCli(argv2, env = process.env, dependencies = {}) {
|
|
28809
29145
|
const warnings = [];
|
|
28810
29146
|
try {
|
|
29147
|
+
if (argv2.includes("--help") || argv2.includes("-h") || argv2[1] === "help") {
|
|
29148
|
+
return { exitCode: 0, stdout: INFERENCE_HOST_HELP, stderr: "" };
|
|
29149
|
+
}
|
|
28811
29150
|
const parsed = parseInferenceHostArgs(argv2, env);
|
|
28812
29151
|
const config2 = resolveInferenceHostConfig(env);
|
|
28813
29152
|
if (parsed.command === "login") {
|
|
@@ -28873,7 +29212,7 @@ async function runInferenceHostCli(argv2, env = process.env, dependencies = {})
|
|
|
28873
29212
|
};
|
|
28874
29213
|
}
|
|
28875
29214
|
}
|
|
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;
|
|
29215
|
+
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, 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;
|
|
28877
29216
|
var init_cli = __esm({
|
|
28878
29217
|
"lib/inference-host/cli.ts"() {
|
|
28879
29218
|
"use strict";
|
|
@@ -28955,6 +29294,31 @@ var init_cli = __esm({
|
|
|
28955
29294
|
render = (value, json2) => json2 ? `${JSON.stringify(value, null, 2)}
|
|
28956
29295
|
` : typeof value === "string" ? `${value}
|
|
28957
29296
|
` : `${JSON.stringify(value, null, 2)}
|
|
29297
|
+
`;
|
|
29298
|
+
INFERENCE_HOST_HELP = `Usage: vtx inference-host <command> [options]
|
|
29299
|
+
|
|
29300
|
+
Commands:
|
|
29301
|
+
login Authorize the isolated VTX insights:inference grant
|
|
29302
|
+
codex-login Sign the automated Codex host into a ChatGPT subscription
|
|
29303
|
+
run Run the automated Codex inference host in the foreground
|
|
29304
|
+
agent-connect Advertise a model from a compatible agent harness
|
|
29305
|
+
agent-run Keep an agent-driven host online in the foreground
|
|
29306
|
+
agent-next Claim the next exact VTX inference request
|
|
29307
|
+
agent-complete Submit one completed agent result from stdin
|
|
29308
|
+
agent-fail Submit one truthful agent failure from stdin
|
|
29309
|
+
status Inspect local host and credential state
|
|
29310
|
+
doctor Verify credentials, Codex, and private runtime state
|
|
29311
|
+
logout Remove local VTX host state without revoking the grant
|
|
29312
|
+
revoke Revoke the VTX grant and remove local host state
|
|
29313
|
+
codex-logout Remove the automated host's dedicated Codex login
|
|
29314
|
+
|
|
29315
|
+
Common options:
|
|
29316
|
+
--json Emit machine-readable JSON
|
|
29317
|
+
--help, -h Show this help
|
|
29318
|
+
|
|
29319
|
+
If the OS credential store cannot retain the VTX grant, set
|
|
29320
|
+
VTX_INFERENCE_HOST_CREDENTIAL_STORE=file before login to use the supported
|
|
29321
|
+
private-file fallback. See https://vtxmacro.com/insights#subscription-inference.
|
|
28958
29322
|
`;
|
|
28959
29323
|
parsePositiveInteger = (raw, label) => {
|
|
28960
29324
|
const value = Number(raw);
|
|
@@ -29194,6 +29558,9 @@ var init_cli = __esm({
|
|
|
29194
29558
|
acquireProcessLock: async () => borrowedProcessLock
|
|
29195
29559
|
}, {
|
|
29196
29560
|
displayName: options.displayName,
|
|
29561
|
+
authenticatedAccountEmail: options.authenticatedAccountEmail,
|
|
29562
|
+
authenticatedAccountPlan: options.authenticatedAccountPlan,
|
|
29563
|
+
codexRateLimits: options.codexRateLimits,
|
|
29197
29564
|
protocolVersion: EXTERNAL_INFERENCE_CONTRACT_VERSION,
|
|
29198
29565
|
adapterRuntimeVersion: INFERENCE_HOST_CLI_VERSION,
|
|
29199
29566
|
maxConcurrency: options.maxConcurrency,
|
|
@@ -29677,7 +30044,7 @@ Waiting for approval...
|
|
|
29677
30044
|
cancellation.signal.throwIfAborted();
|
|
29678
30045
|
const hostResources = await (dependencies.createHostResources ?? createIsolatedCodexHostResources)(config2.codexHomePath);
|
|
29679
30046
|
try {
|
|
29680
|
-
await (dependencies.preflightCodex ?? preflightCodexSubscription)({
|
|
30047
|
+
const preflight = await (dependencies.preflightCodex ?? preflightCodexSubscription)({
|
|
29681
30048
|
binary: verifiedBinary,
|
|
29682
30049
|
codexHome: config2.codexHomePath,
|
|
29683
30050
|
deadlineAtMs: Date.now() + 3e4,
|
|
@@ -29689,6 +30056,9 @@ Waiting for approval...
|
|
|
29689
30056
|
verifiedBinary,
|
|
29690
30057
|
hostResources,
|
|
29691
30058
|
displayName: parsed.displayName,
|
|
30059
|
+
authenticatedAccountEmail: preflight?.authenticated_account_email ?? null,
|
|
30060
|
+
authenticatedAccountPlan: preflight?.authenticated_account_plan ?? null,
|
|
30061
|
+
codexRateLimits: preflight?.rate_limits ?? null,
|
|
29692
30062
|
maxConcurrency: parsed.maxConcurrency,
|
|
29693
30063
|
once: parsed.once,
|
|
29694
30064
|
env,
|
|
@@ -48303,6 +48673,9 @@ Waiting for approval...
|
|
|
48303
48673
|
}
|
|
48304
48674
|
async function runVtxCli(argv2, env = process.env) {
|
|
48305
48675
|
try {
|
|
48676
|
+
if (argv2.length === 0 || argv2.includes("--help") || argv2.includes("-h") || argv2[0] === "help") {
|
|
48677
|
+
return { exitCode: 0, stdout: VTX_CLI_HELP, stderr: "" };
|
|
48678
|
+
}
|
|
48306
48679
|
const parsed = parseFlags(argv2);
|
|
48307
48680
|
const [group, command, ...args] = parsed.rest;
|
|
48308
48681
|
const config2 = resolveAgentCliConfig(env);
|
|
@@ -48550,7 +48923,7 @@ async function runVtxCli(argv2, env = process.env) {
|
|
|
48550
48923
|
` };
|
|
48551
48924
|
}
|
|
48552
48925
|
}
|
|
48553
|
-
var WRITABLE_SECRET_FIELDS, delay;
|
|
48926
|
+
var VTX_CLI_HELP, WRITABLE_SECRET_FIELDS, delay;
|
|
48554
48927
|
var init_vtx = __esm({
|
|
48555
48928
|
"lib/agent-cli/vtx.ts"() {
|
|
48556
48929
|
"use strict";
|
|
@@ -48559,6 +48932,24 @@ var init_vtx = __esm({
|
|
|
48559
48932
|
init_headless_runtime();
|
|
48560
48933
|
init_types();
|
|
48561
48934
|
init_hyperliquid_market_symbol();
|
|
48935
|
+
VTX_CLI_HELP = `Usage: vtx [--json] [--profile <id>] <command>
|
|
48936
|
+
|
|
48937
|
+
Common commands:
|
|
48938
|
+
auth login Authorize the normal VTX CLI
|
|
48939
|
+
auth whoami Show the current VTX CLI identity
|
|
48940
|
+
profiles list List accessible profiles
|
|
48941
|
+
bots status Read the selected profile's Trader state
|
|
48942
|
+
bots start Start the normal VTX Trader
|
|
48943
|
+
bots stop Stop the normal VTX Trader
|
|
48944
|
+
runtime events Read recent runtime events and errors
|
|
48945
|
+
inference-host --help Set up an automated or agent-driven inference host
|
|
48946
|
+
|
|
48947
|
+
Global options:
|
|
48948
|
+
--json Emit machine-readable JSON
|
|
48949
|
+
--profile <id> Select one VTX profile
|
|
48950
|
+
--version, -v Show the installed CLI version
|
|
48951
|
+
--help, -h Show this help
|
|
48952
|
+
`;
|
|
48562
48953
|
WRITABLE_SECRET_FIELDS = /* @__PURE__ */ new Set([
|
|
48563
48954
|
"hyperliquid_signing_key",
|
|
48564
48955
|
"local_ai_api_key",
|