@vtxmacro/cli 2026.8.31 → 2026.8.33
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 +21 -4
- package/bin/vtx.js +501 -66
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -58,6 +58,10 @@ exposed. Before starting a Trader, confirm that the VTX AI page shows the
|
|
|
58
58
|
intended authenticated ChatGPT email and plan. The host reads the live Codex
|
|
59
59
|
account window: a reached limit pauses new dispatch until its reported reset,
|
|
60
60
|
while a transient throttle uses a short bounded cooldown.
|
|
61
|
+
The selected AI model row shows the open VTX profile's rolling 1-hour, 24-hour,
|
|
62
|
+
and 7-day request and reported-token activity for that subscription path.
|
|
63
|
+
Account-wide quota percentages remain in safe host diagnostics instead of the
|
|
64
|
+
profile-scoped selector.
|
|
61
65
|
|
|
62
66
|
```bash
|
|
63
67
|
vtx inference-host login
|
|
@@ -82,10 +86,20 @@ distinct. Use `service uninstall --instance <name>` to remove one worker;
|
|
|
82
86
|
unqualified `service uninstall` removes the whole supervisor. The legacy
|
|
83
87
|
unqualified host commands continue to target `default`.
|
|
84
88
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
+
For one VTX account and adapter, the selected host is tried first and other
|
|
90
|
+
compatible memberships follow in setup order. Quota/credits exhaustion,
|
|
91
|
+
unusable authentication, and exhausted recoverable provider failures can
|
|
92
|
+
advance the same logical call. VTX never changes provider, model, effort, or
|
|
93
|
+
response mode, and never cascades a bad request, policy rejection, or uncertain
|
|
94
|
+
dispatch outcome.
|
|
95
|
+
|
|
96
|
+
Automated hosts do not impose a subscription-specific profile-count or
|
|
97
|
+
concurrency limit by default. Set an explicit positive integer with
|
|
98
|
+
`--max-concurrency` when you want a local limit. Every active turn shares the live subscription
|
|
99
|
+
rate-limit gate and cooldown; unlimited local admission does not guarantee
|
|
100
|
+
capacity beyond the authenticated account's current entitlement. Updating from
|
|
101
|
+
an older bounded host removes its previous numeric limit; run
|
|
102
|
+
`service install --max-concurrency <positive-integer>` only to add one back.
|
|
89
103
|
|
|
90
104
|
This durable host uses a separate least-privilege `insights:inference`
|
|
91
105
|
OAuth grant. It also keeps its ChatGPT subscription login in a dedicated private
|
|
@@ -94,6 +108,9 @@ session. The per-user OS service starts immediately, starts again at login, and
|
|
|
94
108
|
reconnects after sleep, network loss, or a worker exit. Stopping a VTX bot leaves
|
|
95
109
|
the provider online and idle. Use `vtx inference-host run` only for foreground
|
|
96
110
|
diagnostics. VTX logout/revoke and Codex logout are intentionally separate operations.
|
|
111
|
+
JSON foreground and service logs include safe concurrency, latency, token,
|
|
112
|
+
failure-code, and cooldown events without prompts, responses, or credentials.
|
|
113
|
+
Use `service logs --instance <name>` to isolate one subscription.
|
|
97
114
|
|
|
98
115
|
Use `vtx inference-host --help` for command discovery. The VTX login verifies
|
|
99
116
|
that the selected credential store can read back the exact saved grant. If an
|
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.33",
|
|
42
42
|
codex_package_name: "@openai/codex",
|
|
43
43
|
codex_version: "0.147.0",
|
|
44
44
|
platforms: {
|
|
@@ -14375,7 +14375,7 @@ var init_zod = __esm({
|
|
|
14375
14375
|
});
|
|
14376
14376
|
|
|
14377
14377
|
// lib/external-inference-contract.ts
|
|
14378
|
-
var EXTERNAL_INFERENCE_CONTRACT_VERSION, EXTERNAL_INFERENCE_CONTROLLER_SCHEMA_VERSION, EXTERNAL_INFERENCE_ADVERTISEMENT_SCHEMA_VERSION, EXTERNAL_INFERENCE_ENVELOPE_SCHEMA_VERSION, EXTERNAL_INFERENCE_JOB_INPUT_SCHEMA_VERSION, EXTERNAL_INFERENCE_USAGE_SCHEMA_VERSION, EXTERNAL_INFERENCE_INPUT_HASH_DOMAIN, MAX_EXTERNAL_INFERENCE_STATUS_HOSTS, MAX_GENERATION, MAX_SAFE_INTEGER, MAX_PROMPT_BYTES, MAX_IMMUTABLE_JOB_INPUT_BYTES, MAX_CANDIDATE_PLAINTEXT_BYTES, MAX_CIPHERTEXT_CHARS, SHA256_INITIAL_STATE, SHA256_ROUND_CONSTANTS, rotateRight, sha256BytesHex, sha256Utf8Hex, computeImmutableJobInputSha256, identifierSchema, operationIdentifierSchema, sha256HexSchema, generationSchema, zeroBasedGenerationSchema, nonNegativeSafeIntegerSchema, positiveSafeIntegerSchema, sqlIntegerTokenCountSchema, timestampSchema, safeCodeSchema, externalInferenceAdapterIdSchema, reasoningEffortSchema, modelNameSchema, displayNameSchema, authenticatedAccountEmailSchema, protocolVersionSchema, base64UrlAlphabet, isCanonicalBase64Url, base64Url32BytesSchema, base64UrlNonceSchema, base64UrlCiphertextSchema, claimHandleSchema, boundedJsonTextSchema, boundedPromptTextSchema, laneSchema, botModeSchema, executionModeSchema, responseModeSchema, dispatchOutcomeSchema, responseOutcomeSchema, nativeModelControllerSchema, externalAgentModelControllerSchema, externalAgentUnboundControllerSchema, liveModelControllerSchema, snapshotModelControllerSchema, modelIdentityMappingSchema, advertisedModelSchema, hostAdvertisementSchema, envelopeAadSchema, validateEnvelopeAad, commonEnvelopeShape, sealedKeyWrapEnvelopeSchema, sealedInputEnvelopeSchema, sealedCandidateEnvelopeSchema, sealedEnvelopeSchema, screenerCandidateRuntimeBindingSchema, screenerClientLeaseBindingSchema, screenerRuntimeBindingSchema, serverRuntimeBindingSchema, clientRuntimeBindingSchema, runtimeBindingSchema, immutableJobInputSchema, canonicalizeJsonValue, serializeImmutableJobInput, reportedTokenUsageSchema, unavailableTokenUsageSchema, tokenUsageSchema, agentConnectRequestSchema, agentNextRequestSchema, agentHeartbeatRequestSchema, emptyAgentNextResultSchema, claimedAgentNextResultSchema, agentNextResultSchema, agentCompleteRequestSchema, agentFailRequestSchema, requestedModelSelectionSchema, completedModelProvenanceSchema, attemptModelProvenanceSchema, hostHeartbeatRequestSchema, jobClaimRequestSchema, emptyJobClaimSchema, claimedJobSchema, jobClaimResultSchema, attemptStartRequestSchema, jobHeartbeatRequestSchema, continueHeartbeatDirectiveSchema, cancelHeartbeatDirectiveSchema, jobHeartbeatResultSchema, adapterOutcomeEvidenceSchema, completionBaseShape, validateCompletion, providerResponseCompletionSchema, decisionCandidateCompletionSchema, jobCompleteRequestSchema, jobFailRequestSchema, jobCancelRequestSchema, jobCancellationReceiptSchema, jobDeliveryRequestSchema, deliveryBaseShape, validateDeliveryCandidate, providerResponseDeliverySchema, decisionCandidateDeliverySchema, jobDeliveryResultSchema, jobConsumptionRequestSchema, jobConsumptionReceiptSchema, jobStateSchema, jobStatusReadSchema, hostStatusReadSchema, controllerBindingStatusReadSchema, queueStatusReadSchema, outcomeStatusReadSchema, externalInferenceStatusReadSchema, nativeResearchEvidenceSourceSchema, externalAgentResearchEvidenceSourceSchema, researchEvidenceSourceSchema, reportedResearchTokenUsageSchema, unavailableResearchTokenUsageSchema, researchTokenUsageSchema, externalInferenceProductLineageBaseShape, traderExternalInferenceProductLineageSchema, decisionChatExternalInferenceProductLineageSchema, screenerExternalInferenceProductLineageSchema, externalInferenceProductLineageSchema, normalProductLinkageSchema, evidenceMaterializationMarkerSchema, deliveredExternalAgentSourceIdentitySchema, deliveredRequestEvidenceSchema, researchEvidenceBaseShape, researchEvidenceBaseSchema, validateExactUtf8, validateResearchEvidence, providerResponseResearchEvidenceSchema, decisionCandidateResearchEvidenceSchema, researchEvidenceSchema;
|
|
14378
|
+
var EXTERNAL_INFERENCE_CONTRACT_VERSION, EXTERNAL_INFERENCE_CONTROLLER_SCHEMA_VERSION, EXTERNAL_INFERENCE_ADVERTISEMENT_SCHEMA_VERSION, EXTERNAL_INFERENCE_ENVELOPE_SCHEMA_VERSION, EXTERNAL_INFERENCE_JOB_INPUT_SCHEMA_VERSION, LEGACY_EXTERNAL_INFERENCE_JOB_INPUT_SCHEMA_VERSION, EXTERNAL_INFERENCE_USAGE_SCHEMA_VERSION, EXTERNAL_INFERENCE_INPUT_HASH_DOMAIN, MAX_EXTERNAL_INFERENCE_STATUS_HOSTS, MAX_GENERATION, MAX_SAFE_INTEGER, MAX_PROMPT_BYTES, MAX_IMMUTABLE_JOB_INPUT_BYTES, MAX_CANDIDATE_PLAINTEXT_BYTES, MAX_CIPHERTEXT_CHARS, SHA256_INITIAL_STATE, SHA256_ROUND_CONSTANTS, rotateRight, sha256BytesHex, sha256Utf8Hex, computeImmutableJobInputSha256, identifierSchema, operationIdentifierSchema, sha256HexSchema, generationSchema, zeroBasedGenerationSchema, nonNegativeSafeIntegerSchema, positiveSafeIntegerSchema, sqlIntegerTokenCountSchema, timestampSchema, safeCodeSchema, externalInferenceAdapterIdSchema, reasoningEffortSchema, modelNameSchema, displayNameSchema, authenticatedAccountEmailSchema, protocolVersionSchema, base64UrlAlphabet, isCanonicalBase64Url, base64Url32BytesSchema, base64UrlNonceSchema, base64UrlCiphertextSchema, claimHandleSchema, boundedJsonTextSchema, boundedPromptTextSchema, laneSchema, botModeSchema, executionModeSchema, responseModeSchema, dispatchOutcomeSchema, responseOutcomeSchema, nativeModelControllerSchema, externalAgentModelControllerSchema, externalAgentUnboundControllerSchema, liveModelControllerSchema, snapshotModelControllerSchema, modelIdentityMappingSchema, advertisedModelSchema, hostAdvertisementSchema, envelopeAadSchema, validateEnvelopeAad, commonEnvelopeShape, sealedKeyWrapEnvelopeSchema, sealedInputEnvelopeSchema, sealedCandidateEnvelopeSchema, sealedEnvelopeSchema, screenerCandidateRuntimeBindingSchema, screenerClientLeaseBindingSchema, screenerRuntimeBindingSchema, serverRuntimeBindingSchema, clientRuntimeBindingSchema, runtimeBindingSchema, immutableJobInputSchema, canonicalizeJsonValue, serializeImmutableJobInput, reportedTokenUsageSchema, unavailableTokenUsageSchema, tokenUsageSchema, agentConnectRequestSchema, agentNextRequestSchema, agentHeartbeatRequestSchema, emptyAgentNextResultSchema, claimedAgentNextResultSchema, agentNextResultSchema, agentCompleteRequestSchema, agentFailRequestSchema, requestedModelSelectionSchema, completedModelProvenanceSchema, attemptModelProvenanceSchema, providerWeeklyQuotaReadSchema, hostHeartbeatRequestSchema, jobClaimRequestSchema, emptyJobClaimSchema, claimedJobSchema, jobClaimResultSchema, attemptStartRequestSchema, jobHeartbeatRequestSchema, continueHeartbeatDirectiveSchema, cancelHeartbeatDirectiveSchema, jobHeartbeatResultSchema, adapterOutcomeEvidenceSchema, completionBaseShape, validateCompletion, providerResponseCompletionSchema, decisionCandidateCompletionSchema, jobCompleteRequestSchema, jobFailRequestSchema, jobCancelRequestSchema, jobCancellationReceiptSchema, jobDeliveryRequestSchema, deliveryBaseShape, validateDeliveryCandidate, providerResponseDeliverySchema, decisionCandidateDeliverySchema, jobDeliveryResultSchema, jobConsumptionRequestSchema, jobConsumptionReceiptSchema, jobStateSchema, jobStatusReadSchema, hostStatusReadSchema, controllerBindingStatusReadSchema, queueStatusReadSchema, outcomeStatusReadSchema, externalInferenceVolumeWindowReadSchema, externalInferenceFailureCountReadSchema, externalInferenceHostDiagnosticsReadSchema, externalInferenceProfileActivityReadSchema, externalInferenceStatusReadSchema, nativeResearchEvidenceSourceSchema, externalAgentResearchEvidenceSourceSchema, researchEvidenceSourceSchema, reportedResearchTokenUsageSchema, unavailableResearchTokenUsageSchema, researchTokenUsageSchema, externalInferenceProductLineageBaseShape, traderExternalInferenceProductLineageSchema, decisionChatExternalInferenceProductLineageSchema, screenerExternalInferenceProductLineageSchema, externalInferenceProductLineageSchema, normalProductLinkageSchema, evidenceMaterializationMarkerSchema, deliveredExternalAgentSourceIdentitySchema, deliveredRequestEvidenceSchema, researchEvidenceBaseShape, researchEvidenceBaseSchema, validateExactUtf8, validateResearchEvidence, providerResponseResearchEvidenceSchema, decisionCandidateResearchEvidenceSchema, researchEvidenceSchema;
|
|
14379
14379
|
var init_external_inference_contract = __esm({
|
|
14380
14380
|
"lib/external-inference-contract.ts"() {
|
|
14381
14381
|
"use strict";
|
|
@@ -14384,7 +14384,8 @@ var init_external_inference_contract = __esm({
|
|
|
14384
14384
|
EXTERNAL_INFERENCE_CONTROLLER_SCHEMA_VERSION = "external_inference_controller_v1";
|
|
14385
14385
|
EXTERNAL_INFERENCE_ADVERTISEMENT_SCHEMA_VERSION = "external_inference_advertisement_v1";
|
|
14386
14386
|
EXTERNAL_INFERENCE_ENVELOPE_SCHEMA_VERSION = "external_inference_envelope_v1";
|
|
14387
|
-
EXTERNAL_INFERENCE_JOB_INPUT_SCHEMA_VERSION = "
|
|
14387
|
+
EXTERNAL_INFERENCE_JOB_INPUT_SCHEMA_VERSION = "external_inference_job_input_v2";
|
|
14388
|
+
LEGACY_EXTERNAL_INFERENCE_JOB_INPUT_SCHEMA_VERSION = "external_inference_job_input_v1";
|
|
14388
14389
|
EXTERNAL_INFERENCE_USAGE_SCHEMA_VERSION = "external_inference_usage_v1";
|
|
14389
14390
|
EXTERNAL_INFERENCE_INPUT_HASH_DOMAIN = "vtx.external-inference.input-sha256.v1\0";
|
|
14390
14391
|
MAX_EXTERNAL_INFERENCE_STATUS_HOSTS = 640;
|
|
@@ -14538,6 +14539,7 @@ var init_external_inference_contract = __esm({
|
|
|
14538
14539
|
["analysis_run_id", values.analysis_run_id],
|
|
14539
14540
|
["cycle_id", values.cycle_id],
|
|
14540
14541
|
["request_id", values.request_id],
|
|
14542
|
+
...values.use_case !== void 0 && values.role !== void 0 ? [["use_case", values.use_case], ["role", values.role]] : [],
|
|
14541
14543
|
["system_prompt", values.system_prompt],
|
|
14542
14544
|
["user_prompt", values.user_prompt],
|
|
14543
14545
|
["context_json", values.context_json],
|
|
@@ -14865,16 +14867,34 @@ var init_external_inference_contract = __esm({
|
|
|
14865
14867
|
});
|
|
14866
14868
|
runtimeBindingSchema = external_exports.discriminatedUnion("binding_kind", [
|
|
14867
14869
|
serverRuntimeBindingSchema,
|
|
14868
|
-
clientRuntimeBindingSchema
|
|
14870
|
+
clientRuntimeBindingSchema,
|
|
14871
|
+
external_exports.strictObject({
|
|
14872
|
+
binding_kind: external_exports.literal("historical_chat"),
|
|
14873
|
+
bot_mode: external_exports.literal("assistant"),
|
|
14874
|
+
confirmed_active: external_exports.literal(false),
|
|
14875
|
+
bot_run_id: identifierSchema,
|
|
14876
|
+
analysis_run_id: identifierSchema,
|
|
14877
|
+
cycle_id: identifierSchema,
|
|
14878
|
+
runtime_contract_generation: generationSchema,
|
|
14879
|
+
trade_decision_id: positiveSafeIntegerSchema,
|
|
14880
|
+
decision_chat_generation: nonNegativeSafeIntegerSchema,
|
|
14881
|
+
source_invocation_public_id: identifierSchema,
|
|
14882
|
+
source_attempt_public_id: identifierSchema
|
|
14883
|
+
})
|
|
14869
14884
|
]);
|
|
14870
14885
|
immutableJobInputSchema = external_exports.strictObject({
|
|
14871
|
-
schema_version: external_exports.
|
|
14886
|
+
schema_version: external_exports.union([
|
|
14887
|
+
external_exports.literal(LEGACY_EXTERNAL_INFERENCE_JOB_INPUT_SCHEMA_VERSION),
|
|
14888
|
+
external_exports.literal(EXTERNAL_INFERENCE_JOB_INPUT_SCHEMA_VERSION)
|
|
14889
|
+
]),
|
|
14872
14890
|
contract_version: external_exports.literal(EXTERNAL_INFERENCE_CONTRACT_VERSION),
|
|
14873
14891
|
job_id: identifierSchema,
|
|
14874
14892
|
owner_id: positiveSafeIntegerSchema,
|
|
14875
14893
|
profile_id: positiveSafeIntegerSchema,
|
|
14876
14894
|
stable_bot_id: identifierSchema,
|
|
14877
14895
|
request_id: identifierSchema,
|
|
14896
|
+
use_case: external_exports.enum(["trader", "decision_chat", "screener"]).optional(),
|
|
14897
|
+
role: external_exports.enum(["primary", "review", "chat", "candidate"]).optional(),
|
|
14878
14898
|
lane: laneSchema,
|
|
14879
14899
|
execution_mode: executionModeSchema,
|
|
14880
14900
|
host_id: identifierSchema,
|
|
@@ -14911,7 +14931,14 @@ var init_external_inference_contract = __esm({
|
|
|
14911
14931
|
deadline_at: timestampSchema,
|
|
14912
14932
|
evidence_expires_at: timestampSchema
|
|
14913
14933
|
}).superRefine((value, context) => {
|
|
14914
|
-
if (value.
|
|
14934
|
+
if (value.schema_version === EXTERNAL_INFERENCE_JOB_INPUT_SCHEMA_VERSION) {
|
|
14935
|
+
if (value.use_case === void 0 || value.role === void 0) {
|
|
14936
|
+
context.addIssue({ code: "custom", message: "v2 job input requires immutable use_case and role" });
|
|
14937
|
+
}
|
|
14938
|
+
} else if (value.use_case !== void 0 || value.role !== void 0) {
|
|
14939
|
+
context.addIssue({ code: "custom", message: "v1 job input cannot contain v2 product identity" });
|
|
14940
|
+
}
|
|
14941
|
+
if (value.runtime_binding.binding_kind !== value.execution_mode && !(value.runtime_binding.binding_kind === "historical_chat" && value.execution_mode === "server" && value.use_case === "decision_chat")) {
|
|
14915
14942
|
context.addIssue({ code: "custom", message: "runtime binding must match execution_mode", path: ["runtime_binding", "binding_kind"] });
|
|
14916
14943
|
}
|
|
14917
14944
|
if (value.lane === "screener" && value.runtime_binding.bot_mode !== "trader") {
|
|
@@ -14953,6 +14980,8 @@ var init_external_inference_contract = __esm({
|
|
|
14953
14980
|
analysis_run_id: value.runtime_binding.analysis_run_id,
|
|
14954
14981
|
cycle_id: value.runtime_binding.cycle_id,
|
|
14955
14982
|
request_id: value.request_id,
|
|
14983
|
+
use_case: value.schema_version === EXTERNAL_INFERENCE_JOB_INPUT_SCHEMA_VERSION ? value.use_case : void 0,
|
|
14984
|
+
role: value.schema_version === EXTERNAL_INFERENCE_JOB_INPUT_SCHEMA_VERSION ? value.role : void 0,
|
|
14956
14985
|
system_prompt: value.system_prompt,
|
|
14957
14986
|
user_prompt: value.user_prompt,
|
|
14958
14987
|
context_json: value.context_json,
|
|
@@ -15181,6 +15210,22 @@ var init_external_inference_contract = __esm({
|
|
|
15181
15210
|
});
|
|
15182
15211
|
}
|
|
15183
15212
|
});
|
|
15213
|
+
providerWeeklyQuotaReadSchema = external_exports.strictObject({
|
|
15214
|
+
source: external_exports.literal("codex_app_server"),
|
|
15215
|
+
used_percent: external_exports.number().finite().min(0).max(1e6),
|
|
15216
|
+
resets_at: timestampSchema,
|
|
15217
|
+
observed_at: timestampSchema
|
|
15218
|
+
}).superRefine((value, context) => {
|
|
15219
|
+
const observedAt = Date.parse(value.observed_at);
|
|
15220
|
+
const resetsAt = Date.parse(value.resets_at);
|
|
15221
|
+
if (resetsAt <= observedAt || resetsAt > observedAt + 8 * 24 * 60 * 60 * 1e3) {
|
|
15222
|
+
context.addIssue({
|
|
15223
|
+
code: "custom",
|
|
15224
|
+
message: "weekly quota reset must follow observation within eight days",
|
|
15225
|
+
path: ["resets_at"]
|
|
15226
|
+
});
|
|
15227
|
+
}
|
|
15228
|
+
});
|
|
15184
15229
|
hostHeartbeatRequestSchema = external_exports.strictObject({
|
|
15185
15230
|
schema_version: external_exports.literal("external_inference_host_heartbeat_v1"),
|
|
15186
15231
|
contract_version: external_exports.literal(EXTERNAL_INFERENCE_CONTRACT_VERSION),
|
|
@@ -15192,6 +15237,7 @@ var init_external_inference_contract = __esm({
|
|
|
15192
15237
|
status: external_exports.enum(["healthy", "degraded", "draining"]),
|
|
15193
15238
|
active_attempts: nonNegativeSafeIntegerSchema,
|
|
15194
15239
|
available_slots: nonNegativeSafeIntegerSchema,
|
|
15240
|
+
provider_weekly_quota: providerWeeklyQuotaReadSchema.nullable().optional(),
|
|
15195
15241
|
observed_at: timestampSchema
|
|
15196
15242
|
});
|
|
15197
15243
|
jobClaimRequestSchema = external_exports.strictObject({
|
|
@@ -15397,6 +15443,13 @@ var init_external_inference_contract = __esm({
|
|
|
15397
15443
|
failure_category: safeCodeSchema,
|
|
15398
15444
|
failure_code: safeCodeSchema,
|
|
15399
15445
|
retryable: external_exports.boolean(),
|
|
15446
|
+
membership_disposition: external_exports.enum([
|
|
15447
|
+
"retry_same_host",
|
|
15448
|
+
"cascade_cooldown",
|
|
15449
|
+
"cascade_disable",
|
|
15450
|
+
"fail_request",
|
|
15451
|
+
"quarantine_ambiguous"
|
|
15452
|
+
]).optional(),
|
|
15400
15453
|
failed_at: timestampSchema
|
|
15401
15454
|
}).superRefine((value, context) => {
|
|
15402
15455
|
if (value.outcome.response_outcome !== "none") {
|
|
@@ -15406,6 +15459,9 @@ var init_external_inference_contract = __esm({
|
|
|
15406
15459
|
if (value.attempt_status !== expectedStatus) {
|
|
15407
15460
|
context.addIssue({ code: "custom", message: "attempt_status must match dispatch outcome", path: ["attempt_status"] });
|
|
15408
15461
|
}
|
|
15462
|
+
if (value.outcome.dispatch_outcome === "outcome_unknown" && value.membership_disposition !== void 0 && value.membership_disposition !== "quarantine_ambiguous") {
|
|
15463
|
+
context.addIssue({ code: "custom", message: "outcome-unknown failures must be quarantined", path: ["membership_disposition"] });
|
|
15464
|
+
}
|
|
15409
15465
|
if (value.outcome.dispatch_outcome === "not_dispatched") {
|
|
15410
15466
|
if (value.model.effective_model !== null || value.model.effective_reasoning_effort !== null) {
|
|
15411
15467
|
context.addIssue({ code: "custom", message: "not-dispatched failures cannot report effective model provenance", path: ["model"] });
|
|
@@ -15611,6 +15667,44 @@ var init_external_inference_contract = __esm({
|
|
|
15611
15667
|
cancelled: nonNegativeSafeIntegerSchema,
|
|
15612
15668
|
expired: nonNegativeSafeIntegerSchema
|
|
15613
15669
|
});
|
|
15670
|
+
externalInferenceVolumeWindowReadSchema = external_exports.strictObject({
|
|
15671
|
+
window_seconds: positiveSafeIntegerSchema,
|
|
15672
|
+
requests_started: nonNegativeSafeIntegerSchema,
|
|
15673
|
+
profiles_with_requests: nonNegativeSafeIntegerSchema,
|
|
15674
|
+
attempts_succeeded: nonNegativeSafeIntegerSchema,
|
|
15675
|
+
attempts_failed: nonNegativeSafeIntegerSchema,
|
|
15676
|
+
rate_limited: nonNegativeSafeIntegerSchema,
|
|
15677
|
+
quota_exhausted: nonNegativeSafeIntegerSchema,
|
|
15678
|
+
usage_reported: nonNegativeSafeIntegerSchema,
|
|
15679
|
+
usage_unavailable: nonNegativeSafeIntegerSchema,
|
|
15680
|
+
input_tokens: nonNegativeSafeIntegerSchema,
|
|
15681
|
+
output_tokens: nonNegativeSafeIntegerSchema,
|
|
15682
|
+
total_tokens: nonNegativeSafeIntegerSchema,
|
|
15683
|
+
reasoning_tokens: nonNegativeSafeIntegerSchema,
|
|
15684
|
+
cached_input_tokens: nonNegativeSafeIntegerSchema
|
|
15685
|
+
});
|
|
15686
|
+
externalInferenceFailureCountReadSchema = external_exports.strictObject({
|
|
15687
|
+
failure_category: safeCodeSchema.nullable(),
|
|
15688
|
+
failure_code: safeCodeSchema,
|
|
15689
|
+
count: positiveSafeIntegerSchema,
|
|
15690
|
+
last_observed_at: timestampSchema
|
|
15691
|
+
});
|
|
15692
|
+
externalInferenceHostDiagnosticsReadSchema = external_exports.strictObject({
|
|
15693
|
+
host_id: identifierSchema,
|
|
15694
|
+
active_attempts: nonNegativeSafeIntegerSchema,
|
|
15695
|
+
queue: queueStatusReadSchema,
|
|
15696
|
+
last_second: externalInferenceVolumeWindowReadSchema,
|
|
15697
|
+
last_minute: externalInferenceVolumeWindowReadSchema,
|
|
15698
|
+
last_hour: externalInferenceVolumeWindowReadSchema,
|
|
15699
|
+
last_day: externalInferenceVolumeWindowReadSchema,
|
|
15700
|
+
last_week: externalInferenceVolumeWindowReadSchema,
|
|
15701
|
+
recent_failures: external_exports.array(externalInferenceFailureCountReadSchema).max(32)
|
|
15702
|
+
});
|
|
15703
|
+
externalInferenceProfileActivityReadSchema = external_exports.strictObject({
|
|
15704
|
+
last_hour: externalInferenceVolumeWindowReadSchema,
|
|
15705
|
+
last_day: externalInferenceVolumeWindowReadSchema,
|
|
15706
|
+
last_week: externalInferenceVolumeWindowReadSchema
|
|
15707
|
+
});
|
|
15614
15708
|
externalInferenceStatusReadSchema = external_exports.strictObject({
|
|
15615
15709
|
schema_version: external_exports.literal("external_inference_status_v1"),
|
|
15616
15710
|
contract_version: external_exports.literal(EXTERNAL_INFERENCE_CONTRACT_VERSION),
|
|
@@ -15618,8 +15712,11 @@ var init_external_inference_contract = __esm({
|
|
|
15618
15712
|
catalog_generation: generationSchema,
|
|
15619
15713
|
hosts: external_exports.array(hostStatusReadSchema).max(MAX_EXTERNAL_INFERENCE_STATUS_HOSTS),
|
|
15620
15714
|
bindings: external_exports.array(controllerBindingStatusReadSchema).max(512),
|
|
15715
|
+
binding_count: nonNegativeSafeIntegerSchema.optional().default(0),
|
|
15716
|
+
bindings_truncated: external_exports.boolean().optional().default(false),
|
|
15621
15717
|
queue: queueStatusReadSchema,
|
|
15622
|
-
outcomes: outcomeStatusReadSchema
|
|
15718
|
+
outcomes: outcomeStatusReadSchema,
|
|
15719
|
+
host_diagnostics: external_exports.array(externalInferenceHostDiagnosticsReadSchema).max(MAX_EXTERNAL_INFERENCE_STATUS_HOSTS).optional().default([])
|
|
15623
15720
|
});
|
|
15624
15721
|
nativeResearchEvidenceSourceSchema = external_exports.strictObject({
|
|
15625
15722
|
source: external_exports.literal("native"),
|
|
@@ -16522,14 +16619,12 @@ async function acquireInferenceHostProcessLock(path, dependencies = {}) {
|
|
|
16522
16619
|
}
|
|
16523
16620
|
};
|
|
16524
16621
|
}
|
|
16525
|
-
var INFERENCE_CREDENTIAL_NAMESPACE, MAX_INFERENCE_PRIVATE_FILE_BYTES,
|
|
16622
|
+
var INFERENCE_CREDENTIAL_NAMESPACE, MAX_INFERENCE_PRIVATE_FILE_BYTES, WINDOWS_PRIVATE_ACL_SCRIPT, windowsPrivateAclInvocation, runWindowsPrivateAcl, windowsAclCache, windowsAclIdentity, aclCacheKey, secureWindowsPrivatePath, invalidateWindowsAclCache, rebindHardenedWindowsAclAfterRename, rebindHardenedWindowsDirectoryAfterOwnedMutation, isDefaultWindowsPrivatePath, secureExistingWindowsPath, linuxProcessIdentity, windowsProcessIdentity, darwinProcessIdentity, runSmallIdentityCommand, cachedSystemBootIdentity, readInferenceSystemBootIdentity, defaultProcessIdentity, defaultCurrentProcessIdentity, processLockObservationCache, inferenceProcessIdentitiesMatch, DEFAULT_INFERENCE_HOST_INSTANCE, SAFE_INFERENCE_HOST_INSTANCE, requireNamedInstancePath, credentialStoreIdentity;
|
|
16526
16623
|
var init_config = __esm({
|
|
16527
16624
|
"lib/inference-host/config.ts"() {
|
|
16528
16625
|
"use strict";
|
|
16529
16626
|
INFERENCE_CREDENTIAL_NAMESPACE = "vtxmacro-insights-inference";
|
|
16530
16627
|
MAX_INFERENCE_PRIVATE_FILE_BYTES = 16 * 1024 * 1024;
|
|
16531
|
-
DEFAULT_CODEX_HOST_CONCURRENCY = 3;
|
|
16532
|
-
MAX_CODEX_HOST_CONCURRENCY = 8;
|
|
16533
16628
|
WINDOWS_PRIVATE_ACL_SCRIPT = `$ErrorActionPreference='Stop'
|
|
16534
16629
|
$path=[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($env:VTX_PRIVATE_PATH_B64))
|
|
16535
16630
|
$kind=$env:VTX_PRIVATE_PATH_KIND
|
|
@@ -19183,6 +19278,7 @@ var init_codex_app_server = __esm({
|
|
|
19183
19278
|
this.httpStatusCode = options.httpStatusCode ?? null;
|
|
19184
19279
|
this.retryAtMs = options.retryAtMs ?? null;
|
|
19185
19280
|
this.usage = options.usage ?? null;
|
|
19281
|
+
this.rateLimits = options.rateLimits ?? null;
|
|
19186
19282
|
}
|
|
19187
19283
|
};
|
|
19188
19284
|
objectOrNull = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
@@ -19337,6 +19433,14 @@ var init_codex_app_server = __esm({
|
|
|
19337
19433
|
const details = objectOrNull(structured[variant]);
|
|
19338
19434
|
const rawStatus = details?.httpStatusCode;
|
|
19339
19435
|
const httpStatusCode = Number.isSafeInteger(rawStatus) && Number(rawStatus) >= 100 && Number(rawStatus) <= 599 ? Number(rawStatus) : null;
|
|
19436
|
+
if (httpStatusCode === 401) {
|
|
19437
|
+
return {
|
|
19438
|
+
code: "auth_expired",
|
|
19439
|
+
category: "auth",
|
|
19440
|
+
retryable: false,
|
|
19441
|
+
httpStatusCode
|
|
19442
|
+
};
|
|
19443
|
+
}
|
|
19340
19444
|
if (httpStatusCode === 429) {
|
|
19341
19445
|
return {
|
|
19342
19446
|
code: "codex_rate_limited",
|
|
@@ -19345,10 +19449,43 @@ var init_codex_app_server = __esm({
|
|
|
19345
19449
|
httpStatusCode
|
|
19346
19450
|
};
|
|
19347
19451
|
}
|
|
19452
|
+
if (httpStatusCode !== null && httpStatusCode >= 400 && httpStatusCode < 500 && httpStatusCode !== 408 && httpStatusCode !== 425) {
|
|
19453
|
+
const semanticText = JSON.stringify(details || {}).toLowerCase();
|
|
19454
|
+
if (httpStatusCode === 402 || /(quota|credit|spend|payment|subscription.*limit)/u.test(semanticText)) {
|
|
19455
|
+
return {
|
|
19456
|
+
code: "quota_exceeded",
|
|
19457
|
+
category: "model",
|
|
19458
|
+
retryable: false,
|
|
19459
|
+
httpStatusCode
|
|
19460
|
+
};
|
|
19461
|
+
}
|
|
19462
|
+
if (httpStatusCode === 403 && /(auth|account|workspace|billing|entitlement)/u.test(semanticText)) {
|
|
19463
|
+
return {
|
|
19464
|
+
code: "auth_expired",
|
|
19465
|
+
category: "auth",
|
|
19466
|
+
retryable: false,
|
|
19467
|
+
httpStatusCode
|
|
19468
|
+
};
|
|
19469
|
+
}
|
|
19470
|
+
if (httpStatusCode === 403 && /(policy|safety|cyber)/u.test(semanticText)) {
|
|
19471
|
+
return {
|
|
19472
|
+
code: "codex_policy_rejected",
|
|
19473
|
+
category: "adapter",
|
|
19474
|
+
retryable: false,
|
|
19475
|
+
httpStatusCode
|
|
19476
|
+
};
|
|
19477
|
+
}
|
|
19478
|
+
return {
|
|
19479
|
+
code: httpStatusCode === 400 ? "codex_bad_request" : "codex_http_client_error",
|
|
19480
|
+
category: "adapter",
|
|
19481
|
+
retryable: false,
|
|
19482
|
+
httpStatusCode
|
|
19483
|
+
};
|
|
19484
|
+
}
|
|
19348
19485
|
return {
|
|
19349
19486
|
code,
|
|
19350
19487
|
category: "adapter",
|
|
19351
|
-
retryable: httpStatusCode === null ?
|
|
19488
|
+
retryable: httpStatusCode === null ? true : httpStatusCode === 408 || httpStatusCode === 425 || httpStatusCode >= 500,
|
|
19352
19489
|
httpStatusCode
|
|
19353
19490
|
};
|
|
19354
19491
|
}
|
|
@@ -20396,7 +20533,7 @@ child.once('close', async () => {
|
|
|
20396
20533
|
category: error48.category,
|
|
20397
20534
|
code: error48.code,
|
|
20398
20535
|
retryable: error48.retryable,
|
|
20399
|
-
dispatchOutcome: requestWritten ?
|
|
20536
|
+
dispatchOutcome: requestWritten ? "outcome_unknown" : "not_dispatched",
|
|
20400
20537
|
cause: error48
|
|
20401
20538
|
}));
|
|
20402
20539
|
});
|
|
@@ -20599,7 +20736,7 @@ child.once('close', async () => {
|
|
|
20599
20736
|
category: error48.category,
|
|
20600
20737
|
code: error48.code,
|
|
20601
20738
|
retryable: error48.retryable,
|
|
20602
|
-
dispatchOutcome:
|
|
20739
|
+
dispatchOutcome: "outcome_unknown",
|
|
20603
20740
|
cause: error48
|
|
20604
20741
|
});
|
|
20605
20742
|
}
|
|
@@ -20694,6 +20831,7 @@ child.once('close', async () => {
|
|
|
20694
20831
|
);
|
|
20695
20832
|
const observedUsage = threadUsage ?? rawResponseUsage;
|
|
20696
20833
|
let retryAtMs = null;
|
|
20834
|
+
let observedRateLimits = null;
|
|
20697
20835
|
if (failure.code === "quota_exceeded" || failure.httpStatusCode === 429) {
|
|
20698
20836
|
const observedAtMs = Date.now();
|
|
20699
20837
|
let accountLimitReached = failure.code === "quota_exceeded";
|
|
@@ -20703,9 +20841,12 @@ child.once('close', async () => {
|
|
|
20703
20841
|
observedAtMs + 5e3
|
|
20704
20842
|
);
|
|
20705
20843
|
if (metadataDeadlineAtMs <= observedAtMs) throw new Error("rate-limit deadline elapsed");
|
|
20706
|
-
|
|
20707
|
-
|
|
20708
|
-
|
|
20844
|
+
observedRateLimits = await this.readAccountRateLimits(
|
|
20845
|
+
metadataDeadlineAtMs,
|
|
20846
|
+
request.signal
|
|
20847
|
+
);
|
|
20848
|
+
accountLimitReached = accountLimitReached || codexAccountRateLimitReached(observedRateLimits);
|
|
20849
|
+
retryAtMs = codexRateLimitRetryAtMs(observedRateLimits);
|
|
20709
20850
|
} catch {
|
|
20710
20851
|
}
|
|
20711
20852
|
if (accountLimitReached) {
|
|
@@ -20735,7 +20876,8 @@ child.once('close', async () => {
|
|
|
20735
20876
|
dispatchOutcome: "confirmed_dispatched",
|
|
20736
20877
|
httpStatusCode: failure.httpStatusCode,
|
|
20737
20878
|
retryAtMs,
|
|
20738
|
-
usage: observedUsage
|
|
20879
|
+
usage: observedUsage,
|
|
20880
|
+
rateLimits: observedRateLimits
|
|
20739
20881
|
});
|
|
20740
20882
|
}
|
|
20741
20883
|
const items = Array.isArray(terminal.items) ? terminal.items.map(objectOrNull) : [];
|
|
@@ -21567,6 +21709,23 @@ var init_codex_adapter = __esm({
|
|
|
21567
21709
|
this.adapterClosePromise = null;
|
|
21568
21710
|
this.dependencies = dependencies;
|
|
21569
21711
|
}
|
|
21712
|
+
async readAccountRateLimits(deadlineAtMs, signal) {
|
|
21713
|
+
const codexHome = this.dependencies.codexHome;
|
|
21714
|
+
if (!codexHome) {
|
|
21715
|
+
throw new CodexAppServerError({
|
|
21716
|
+
message: "Codex home is required to read account rate limits.",
|
|
21717
|
+
category: "adapter",
|
|
21718
|
+
code: "codex_home_required",
|
|
21719
|
+
retryable: false
|
|
21720
|
+
});
|
|
21721
|
+
}
|
|
21722
|
+
const durableSession = await this.acquireDurableSession(
|
|
21723
|
+
codexHome,
|
|
21724
|
+
deadlineAtMs,
|
|
21725
|
+
signal
|
|
21726
|
+
);
|
|
21727
|
+
return await durableSession.session.readAccountRateLimits(deadlineAtMs, signal);
|
|
21728
|
+
}
|
|
21570
21729
|
async startDurableSession(codexHome, deadlineAtMs) {
|
|
21571
21730
|
const binary = await (this.dependencies.resolveBinary ?? resolvePinnedCodexBinary)();
|
|
21572
21731
|
const guardianManaged = Boolean(
|
|
@@ -22354,7 +22513,7 @@ var init_crypto = __esm({
|
|
|
22354
22513
|
decryptExternalInferenceJobInput = (jobKey, input, expectedIdentity) => {
|
|
22355
22514
|
const envelope = sealedInputEnvelopeSchema.parse(input);
|
|
22356
22515
|
assertIdentity(envelope.aad, expectedIdentity);
|
|
22357
|
-
if (envelope.aad.direction !== "input" || envelope.aad.payload_schema_version !== EXTERNAL_INFERENCE_JOB_INPUT_SCHEMA_VERSION || envelope.aad.attempt_id !== null) {
|
|
22516
|
+
if (envelope.aad.direction !== "input" || envelope.aad.payload_schema_version !== EXTERNAL_INFERENCE_JOB_INPUT_SCHEMA_VERSION && envelope.aad.payload_schema_version !== LEGACY_EXTERNAL_INFERENCE_JOB_INPUT_SCHEMA_VERSION || envelope.aad.attempt_id !== null) {
|
|
22358
22517
|
throw new ExternalInferenceEnvelopeError(
|
|
22359
22518
|
"identity_mismatch",
|
|
22360
22519
|
"External inference input envelope context is invalid."
|
|
@@ -22378,6 +22537,12 @@ var init_crypto = __esm({
|
|
|
22378
22537
|
);
|
|
22379
22538
|
}
|
|
22380
22539
|
const job = immutableJobInputSchema.parse(rawJob);
|
|
22540
|
+
if (envelope.aad.payload_schema_version !== job.schema_version) {
|
|
22541
|
+
throw new ExternalInferenceEnvelopeError(
|
|
22542
|
+
"identity_mismatch",
|
|
22543
|
+
"External inference input schema identity is inconsistent."
|
|
22544
|
+
);
|
|
22545
|
+
}
|
|
22381
22546
|
if (!Buffer.from(serializeImmutableJobInput(job)).equals(plaintext)) {
|
|
22382
22547
|
throw new ExternalInferenceEnvelopeError(
|
|
22383
22548
|
"invalid_job_input",
|
|
@@ -28742,7 +28907,7 @@ function createDefaultInferenceHostRunnerDependencies(options) {
|
|
|
28742
28907
|
envelopePublicKey: options.envelopePublicKey
|
|
28743
28908
|
};
|
|
28744
28909
|
}
|
|
28745
|
-
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,
|
|
28910
|
+
var import_ajv, RUNTIME_RECEIPT_SCHEMA_VERSION, ATTEMPT_RECEIPT_SCHEMA_VERSION, DEFAULT_ADVERTISEMENT_TTL_MS, DEFAULT_ADVERTISEMENT_REFRESH_LEAD_MS, DEFAULT_HOST_HEARTBEAT_MS, DEFAULT_PROVIDER_RATE_LIMIT_REFRESH_MS, DEFAULT_ATTEMPT_HEARTBEAT_MS, DEFAULT_DRAIN_TIMEOUT_MS, DEFAULT_REMOTE_RETRY_LIMIT, MIN_SLEEP_MS, DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS, MIN_CLAIM_START_WINDOW_MS, UNBOUNDED_AVAILABLE_SLOTS, buildCodexInferenceAdvertisedModels, FileInferenceHostRuntimeReceiptStore, InferenceHostRecoveryRequiredError, InferenceHostRunnerError, defaultSleep, abortError, defaultRegisterSignalHandlers, safeInteger, exactObjectKeys, validIso, validateAttemptReceipt, validateRuntimeReceipt, sha256, stableOperationId, buildAttemptStartRequest, isoAt, providerWeeklyQuotaFromRateLimits, finitePositiveOption, validateRunnerOptions, assertLocalCredentialIdentity, retryableRemoteError, remoteRetryAfterMs, controlPlaneFatal, defaultValidateOutput, objectRecord, positiveUtf8ByteLimit, assertCompilableOutputSchema, parseOutputContract, membershipFailureDisposition, safeFailureCode, exactJson2, runnerIdentityMismatch, assertAdvertisementResult, assertHostHeartbeatResult, assertClaimResult, assertStartResult, assertJobHeartbeatResult, assertTerminalResult, classifyFailure, ambiguousHeartbeatTransport, reportedTokenUsage, reportedUsage, InferenceHostRunner;
|
|
28746
28911
|
var init_runner = __esm({
|
|
28747
28912
|
"lib/inference-host/runner.ts"() {
|
|
28748
28913
|
"use strict";
|
|
@@ -28759,13 +28924,14 @@ var init_runner = __esm({
|
|
|
28759
28924
|
DEFAULT_ADVERTISEMENT_TTL_MS = 12e4;
|
|
28760
28925
|
DEFAULT_ADVERTISEMENT_REFRESH_LEAD_MS = 3e4;
|
|
28761
28926
|
DEFAULT_HOST_HEARTBEAT_MS = 3e3;
|
|
28927
|
+
DEFAULT_PROVIDER_RATE_LIMIT_REFRESH_MS = 6e4;
|
|
28762
28928
|
DEFAULT_ATTEMPT_HEARTBEAT_MS = 3e3;
|
|
28763
28929
|
DEFAULT_DRAIN_TIMEOUT_MS = 3e4;
|
|
28764
28930
|
DEFAULT_REMOTE_RETRY_LIMIT = 3;
|
|
28765
|
-
DEFAULT_MAX_CONCURRENCY = 1;
|
|
28766
28931
|
MIN_SLEEP_MS = 10;
|
|
28767
28932
|
DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS = 5 * 60 * 1e3;
|
|
28768
28933
|
MIN_CLAIM_START_WINDOW_MS = 5e3;
|
|
28934
|
+
UNBOUNDED_AVAILABLE_SLOTS = Number.MAX_SAFE_INTEGER;
|
|
28769
28935
|
buildCodexInferenceAdvertisedModels = (capabilities, adapterRuntimeVersion) => {
|
|
28770
28936
|
const visible = capabilities.filter((capability) => !capability.hidden);
|
|
28771
28937
|
if (visible.length === 0 || visible.length > 64) {
|
|
@@ -29019,6 +29185,19 @@ var init_runner = __esm({
|
|
|
29019
29185
|
started_at: startedAt
|
|
29020
29186
|
});
|
|
29021
29187
|
isoAt = (milliseconds) => new Date(milliseconds).toISOString();
|
|
29188
|
+
providerWeeklyQuotaFromRateLimits = (rateLimits, observedAtMs, currentTimeMs = observedAtMs) => {
|
|
29189
|
+
if (!rateLimits) return null;
|
|
29190
|
+
for (const window2 of [rateLimits.rateLimits.primary, rateLimits.rateLimits.secondary]) {
|
|
29191
|
+
if (window2?.windowDurationMins !== 7 * 24 * 60 || window2.resetsAt === null || window2.resetsAt * 1e3 <= currentTimeMs) continue;
|
|
29192
|
+
return {
|
|
29193
|
+
source: "codex_app_server",
|
|
29194
|
+
used_percent: window2.usedPercent,
|
|
29195
|
+
resets_at: isoAt(window2.resetsAt * 1e3),
|
|
29196
|
+
observed_at: isoAt(observedAtMs)
|
|
29197
|
+
};
|
|
29198
|
+
}
|
|
29199
|
+
return null;
|
|
29200
|
+
};
|
|
29022
29201
|
finitePositiveOption = (value, fallback, label) => {
|
|
29023
29202
|
const result2 = value ?? fallback;
|
|
29024
29203
|
if (!Number.isSafeInteger(result2) || result2 < 1) {
|
|
@@ -29054,20 +29233,7 @@ var init_runner = __esm({
|
|
|
29054
29233
|
options.codexModelCapabilities,
|
|
29055
29234
|
options.adapterRuntimeVersion
|
|
29056
29235
|
),
|
|
29057
|
-
maxConcurrency: (
|
|
29058
|
-
const value = finitePositiveOption(
|
|
29059
|
-
options.maxConcurrency,
|
|
29060
|
-
DEFAULT_MAX_CONCURRENCY,
|
|
29061
|
-
"Maximum concurrency"
|
|
29062
|
-
);
|
|
29063
|
-
if (value > MAX_CODEX_HOST_CONCURRENCY) {
|
|
29064
|
-
throw new InferenceHostRunnerError(
|
|
29065
|
-
"invalid_configuration",
|
|
29066
|
-
`Maximum concurrency must not exceed ${MAX_CODEX_HOST_CONCURRENCY}.`
|
|
29067
|
-
);
|
|
29068
|
-
}
|
|
29069
|
-
return value;
|
|
29070
|
-
})(),
|
|
29236
|
+
maxConcurrency: options.maxConcurrency === null || options.maxConcurrency === void 0 ? null : finitePositiveOption(options.maxConcurrency, 1, "Maximum concurrency"),
|
|
29071
29237
|
advertisementTtlMs,
|
|
29072
29238
|
advertisementRefreshLeadMs,
|
|
29073
29239
|
hostHeartbeatMs: finitePositiveOption(
|
|
@@ -29075,6 +29241,11 @@ var init_runner = __esm({
|
|
|
29075
29241
|
DEFAULT_HOST_HEARTBEAT_MS,
|
|
29076
29242
|
"Host heartbeat interval"
|
|
29077
29243
|
),
|
|
29244
|
+
providerRateLimitRefreshMs: finitePositiveOption(
|
|
29245
|
+
options.providerRateLimitRefreshMs,
|
|
29246
|
+
DEFAULT_PROVIDER_RATE_LIMIT_REFRESH_MS,
|
|
29247
|
+
"Provider rate-limit refresh interval"
|
|
29248
|
+
),
|
|
29078
29249
|
attemptHeartbeatMs: finitePositiveOption(
|
|
29079
29250
|
options.attemptHeartbeatMs,
|
|
29080
29251
|
DEFAULT_ATTEMPT_HEARTBEAT_MS,
|
|
@@ -29238,6 +29409,20 @@ var init_runner = __esm({
|
|
|
29238
29409
|
providerReasoningSummarySupported
|
|
29239
29410
|
};
|
|
29240
29411
|
};
|
|
29412
|
+
membershipFailureDisposition = (failure) => {
|
|
29413
|
+
if (failure.dispatchOutcome === "outcome_unknown") return "quarantine_ambiguous";
|
|
29414
|
+
if (failure.category === "auth" || ["auth_expired", "managed_chatgpt_auth_required", "invalid_account_metadata"].includes(failure.code)) return "cascade_disable";
|
|
29415
|
+
if (failure.category === "quota" || ["quota_exceeded", "codex_rate_limited"].includes(failure.code)) return "cascade_cooldown";
|
|
29416
|
+
if (failure.retryable && (["adapter", "network", "transport"].includes(failure.category) || failure.code === "rpc_timeout")) return "retry_same_host";
|
|
29417
|
+
if (["model_unavailable", "reasoning_effort_unavailable"].includes(failure.code)) return "cascade_cooldown";
|
|
29418
|
+
if ([
|
|
29419
|
+
"codex_http_connection_failed",
|
|
29420
|
+
"codex_response_stream_connection_failed",
|
|
29421
|
+
"codex_response_stream_disconnected",
|
|
29422
|
+
"codex_provider_retry_exhausted"
|
|
29423
|
+
].includes(failure.code)) return "cascade_cooldown";
|
|
29424
|
+
return "fail_request";
|
|
29425
|
+
};
|
|
29241
29426
|
safeFailureCode = (value, fallback) => {
|
|
29242
29427
|
const normalized = value.trim().toLowerCase().replace(/[^a-z0-9._-]+/gu, "_").slice(0, 96);
|
|
29243
29428
|
return /^[a-z0-9]/u.test(normalized) ? normalized : fallback;
|
|
@@ -29405,6 +29590,20 @@ var init_runner = __esm({
|
|
|
29405
29590
|
"Inference host login is required before the runner can start."
|
|
29406
29591
|
);
|
|
29407
29592
|
}
|
|
29593
|
+
const emitDiagnostic = (event, fields = {}) => {
|
|
29594
|
+
try {
|
|
29595
|
+
this.options.emitDiagnosticEvent?.({
|
|
29596
|
+
schema_version: "vtx_inference_host_diagnostic_v1",
|
|
29597
|
+
at: isoAt(now()),
|
|
29598
|
+
event,
|
|
29599
|
+
instance_name: this.options.instanceName ?? "default",
|
|
29600
|
+
host_id: localState.host_id,
|
|
29601
|
+
display_name: this.options.displayName,
|
|
29602
|
+
...fields
|
|
29603
|
+
});
|
|
29604
|
+
} catch {
|
|
29605
|
+
}
|
|
29606
|
+
};
|
|
29408
29607
|
const accountKey = inferenceCredentialAccountKey({
|
|
29409
29608
|
issuer: localState.issuer,
|
|
29410
29609
|
clientId: localState.client_id,
|
|
@@ -29601,6 +29800,10 @@ var init_runner = __esm({
|
|
|
29601
29800
|
if (!wasRegistered && receipt.registered && (!receipt.advertisement_expires_at || Date.parse(receipt.advertisement_expires_at) - now() <= settings.advertisementRefreshLeadMs)) {
|
|
29602
29801
|
await publishAdvertisement("healthy", true);
|
|
29603
29802
|
}
|
|
29803
|
+
let providerRetryAtMs = this.options.codexRateLimits && codexAccountRateLimitReached(this.options.codexRateLimits) ? codexRateLimitRetryAtMs(this.options.codexRateLimits) ?? now() + DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS : null;
|
|
29804
|
+
let providerCooldownReason = providerRetryAtMs === null ? null : "provider_limit_snapshot";
|
|
29805
|
+
let providerRateLimits = this.options.codexRateLimits ?? null;
|
|
29806
|
+
let providerRateLimitsObservedAtMs = now();
|
|
29604
29807
|
const hostHeartbeat = async (status, requestOptions = {
|
|
29605
29808
|
signal: this.options.signal
|
|
29606
29809
|
}, retryRemote = true, allowOfflineProjection = false, definitiveReseedAttempt = 0) => {
|
|
@@ -29615,7 +29818,12 @@ var init_runner = __esm({
|
|
|
29615
29818
|
sequence,
|
|
29616
29819
|
status,
|
|
29617
29820
|
active_attempts: active.size,
|
|
29618
|
-
available_slots: Math.max(0, settings.maxConcurrency - active.size),
|
|
29821
|
+
available_slots: settings.maxConcurrency === null ? UNBOUNDED_AVAILABLE_SLOTS - active.size : Math.max(0, settings.maxConcurrency - active.size),
|
|
29822
|
+
provider_weekly_quota: providerWeeklyQuotaFromRateLimits(
|
|
29823
|
+
providerRateLimits,
|
|
29824
|
+
providerRateLimitsObservedAtMs,
|
|
29825
|
+
now()
|
|
29826
|
+
),
|
|
29619
29827
|
observed_at: isoAt(now())
|
|
29620
29828
|
};
|
|
29621
29829
|
receipt = {
|
|
@@ -29657,10 +29865,21 @@ var init_runner = __esm({
|
|
|
29657
29865
|
await hostHeartbeat("healthy");
|
|
29658
29866
|
let nextHostHeartbeatAt = now() + settings.hostHeartbeatMs;
|
|
29659
29867
|
let nextAdvertisementAttemptAt = 0;
|
|
29660
|
-
let
|
|
29868
|
+
let nextProviderRateLimitRefreshAt = now() + settings.providerRateLimitRefreshMs;
|
|
29661
29869
|
let nextClaimAt = Math.max(now(), providerRetryAtMs ?? 0);
|
|
29662
29870
|
let pendingClaimPromotions = 0;
|
|
29663
29871
|
let onceClaimed = false;
|
|
29872
|
+
emitDiagnostic("runtime_started", {
|
|
29873
|
+
max_concurrency: settings.maxConcurrency,
|
|
29874
|
+
active_attempts: active.size,
|
|
29875
|
+
provider_cooldown_reason: providerCooldownReason,
|
|
29876
|
+
provider_cooldown_until: providerRetryAtMs === null ? null : isoAt(providerRetryAtMs),
|
|
29877
|
+
provider_weekly_quota: providerWeeklyQuotaFromRateLimits(
|
|
29878
|
+
providerRateLimits,
|
|
29879
|
+
providerRateLimitsObservedAtMs,
|
|
29880
|
+
now()
|
|
29881
|
+
)
|
|
29882
|
+
});
|
|
29664
29883
|
const launchClaim = (claim, recovery, claimRequest) => {
|
|
29665
29884
|
if (!recovery) {
|
|
29666
29885
|
claimed += 1;
|
|
@@ -29704,10 +29923,37 @@ var init_runner = __esm({
|
|
|
29704
29923
|
attemptHeartbeatMs: settings.attemptHeartbeatMs,
|
|
29705
29924
|
sleep: sleep4,
|
|
29706
29925
|
now,
|
|
29707
|
-
onProviderCooldown: (retryAtMs) => {
|
|
29926
|
+
onProviderCooldown: ({ retryAtMs, reason, rateLimits }) => {
|
|
29708
29927
|
if (!Number.isSafeInteger(retryAtMs) || retryAtMs <= now()) return;
|
|
29928
|
+
const priorRetryAtMs = providerRetryAtMs;
|
|
29709
29929
|
providerRetryAtMs = Math.max(providerRetryAtMs ?? 0, retryAtMs);
|
|
29710
29930
|
nextClaimAt = Math.max(nextClaimAt, providerRetryAtMs);
|
|
29931
|
+
providerCooldownReason = reason;
|
|
29932
|
+
if (rateLimits) {
|
|
29933
|
+
providerRateLimits = rateLimits;
|
|
29934
|
+
providerRateLimitsObservedAtMs = now();
|
|
29935
|
+
}
|
|
29936
|
+
emitDiagnostic(
|
|
29937
|
+
priorRetryAtMs === null ? "provider_cooldown_started" : "provider_cooldown_extended",
|
|
29938
|
+
{
|
|
29939
|
+
reason,
|
|
29940
|
+
cooldown_until: isoAt(providerRetryAtMs),
|
|
29941
|
+
active_attempts: active.size,
|
|
29942
|
+
provider_weekly_quota: providerWeeklyQuotaFromRateLimits(
|
|
29943
|
+
providerRateLimits,
|
|
29944
|
+
providerRateLimitsObservedAtMs,
|
|
29945
|
+
now()
|
|
29946
|
+
)
|
|
29947
|
+
}
|
|
29948
|
+
);
|
|
29949
|
+
},
|
|
29950
|
+
onAttemptOutcome: (outcome) => {
|
|
29951
|
+
emitDiagnostic("attempt_finished", {
|
|
29952
|
+
...outcome,
|
|
29953
|
+
job_id: claim.job_id,
|
|
29954
|
+
attempt_id: attemptId,
|
|
29955
|
+
active_attempts: active.size
|
|
29956
|
+
});
|
|
29711
29957
|
},
|
|
29712
29958
|
resumeReceipt: recovery,
|
|
29713
29959
|
claimRequest,
|
|
@@ -29724,6 +29970,14 @@ var init_runner = __esm({
|
|
|
29724
29970
|
attemptControllers.delete(attemptId);
|
|
29725
29971
|
});
|
|
29726
29972
|
active.set(attemptId, promise2);
|
|
29973
|
+
emitDiagnostic("attempt_started", {
|
|
29974
|
+
job_id: claim.job_id,
|
|
29975
|
+
attempt_id: attemptId,
|
|
29976
|
+
attempt_index: claim.attempt_index,
|
|
29977
|
+
requested_model: claim.requested_model,
|
|
29978
|
+
requested_reasoning_effort: claim.requested_reasoning_effort,
|
|
29979
|
+
active_attempts: active.size
|
|
29980
|
+
});
|
|
29727
29981
|
return attemptId;
|
|
29728
29982
|
};
|
|
29729
29983
|
const removeRecoveredAttempt = async (attemptId) => {
|
|
@@ -29764,12 +30018,56 @@ var init_runner = __esm({
|
|
|
29764
30018
|
}
|
|
29765
30019
|
recoveryQueue.push(recovery);
|
|
29766
30020
|
}
|
|
29767
|
-
while (!drainRequested && recoveryQueue.length > 0 && active.size < settings.maxConcurrency) {
|
|
30021
|
+
while (!drainRequested && recoveryQueue.length > 0 && (settings.maxConcurrency === null || active.size < settings.maxConcurrency)) {
|
|
29768
30022
|
const recovery = recoveryQueue.shift();
|
|
29769
30023
|
launchClaim(recovery.claim, recovery);
|
|
29770
30024
|
}
|
|
29771
30025
|
while (!drainRequested) {
|
|
29772
30026
|
const currentTime = now();
|
|
30027
|
+
if (providerRetryAtMs !== null && currentTime >= providerRetryAtMs && providerCooldownReason !== null) {
|
|
30028
|
+
emitDiagnostic("provider_cooldown_cleared", {
|
|
30029
|
+
reason: providerCooldownReason,
|
|
30030
|
+
active_attempts: active.size,
|
|
30031
|
+
provider_weekly_quota: providerWeeklyQuotaFromRateLimits(
|
|
30032
|
+
providerRateLimits,
|
|
30033
|
+
providerRateLimitsObservedAtMs,
|
|
30034
|
+
currentTime
|
|
30035
|
+
)
|
|
30036
|
+
});
|
|
30037
|
+
providerRetryAtMs = null;
|
|
30038
|
+
providerCooldownReason = null;
|
|
30039
|
+
nextClaimAt = Math.min(nextClaimAt, currentTime);
|
|
30040
|
+
}
|
|
30041
|
+
if (this.dependencies.codexAdapter.readAccountRateLimits && currentTime >= nextProviderRateLimitRefreshAt) {
|
|
30042
|
+
try {
|
|
30043
|
+
providerRateLimits = await this.dependencies.codexAdapter.readAccountRateLimits(
|
|
30044
|
+
Date.now() + Math.min(2e3, settings.hostHeartbeatMs),
|
|
30045
|
+
this.options.signal
|
|
30046
|
+
);
|
|
30047
|
+
providerRateLimitsObservedAtMs = now();
|
|
30048
|
+
const refreshedRetryAt = codexAccountRateLimitReached(providerRateLimits) ? codexRateLimitRetryAtMs(providerRateLimits) ?? currentTime + DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS : null;
|
|
30049
|
+
if (refreshedRetryAt !== null && refreshedRetryAt > currentTime) {
|
|
30050
|
+
providerRetryAtMs = Math.max(providerRetryAtMs ?? 0, refreshedRetryAt);
|
|
30051
|
+
providerCooldownReason = "provider_limit_snapshot";
|
|
30052
|
+
nextClaimAt = Math.max(nextClaimAt, providerRetryAtMs);
|
|
30053
|
+
}
|
|
30054
|
+
emitDiagnostic("provider_rate_limits_refreshed", {
|
|
30055
|
+
provider_weekly_quota: providerWeeklyQuotaFromRateLimits(
|
|
30056
|
+
providerRateLimits,
|
|
30057
|
+
providerRateLimitsObservedAtMs,
|
|
30058
|
+
now()
|
|
30059
|
+
),
|
|
30060
|
+
active_attempts: active.size
|
|
30061
|
+
});
|
|
30062
|
+
} catch (error48) {
|
|
30063
|
+
emitDiagnostic("provider_rate_limits_refresh_failed", {
|
|
30064
|
+
failure_category: error48 instanceof CodexAppServerError ? error48.category : "adapter",
|
|
30065
|
+
failure_code: error48 instanceof CodexAppServerError ? error48.code : "provider_rate_limits_refresh_failed"
|
|
30066
|
+
});
|
|
30067
|
+
} finally {
|
|
30068
|
+
nextProviderRateLimitRefreshAt = now() + settings.providerRateLimitRefreshMs;
|
|
30069
|
+
}
|
|
30070
|
+
}
|
|
29773
30071
|
const expiresAt = receipt.advertisement_expires_at ? Date.parse(receipt.advertisement_expires_at) : 0;
|
|
29774
30072
|
if (currentTime >= nextAdvertisementAttemptAt && expiresAt - currentTime <= settings.advertisementRefreshLeadMs) {
|
|
29775
30073
|
try {
|
|
@@ -29812,11 +30110,11 @@ var init_runner = __esm({
|
|
|
29812
30110
|
nextHostHeartbeatAt = now() + settings.hostHeartbeatMs;
|
|
29813
30111
|
}
|
|
29814
30112
|
}
|
|
29815
|
-
while (recoveryQueue.length > 0 && active.size < settings.maxConcurrency) {
|
|
30113
|
+
while (recoveryQueue.length > 0 && (settings.maxConcurrency === null || active.size < settings.maxConcurrency)) {
|
|
29816
30114
|
const recovery = recoveryQueue.shift();
|
|
29817
30115
|
launchClaim(recovery.claim, recovery);
|
|
29818
30116
|
}
|
|
29819
|
-
while (!drainRequested && recoveryQueue.length === 0 && (!this.options.once || !onceClaimed) && active.size < settings.maxConcurrency && pendingClaimPromotions === 0 && now() >= nextClaimAt) {
|
|
30117
|
+
while (!drainRequested && recoveryQueue.length === 0 && (!this.options.once || !onceClaimed) && (settings.maxConcurrency === null || active.size < settings.maxConcurrency) && pendingClaimPromotions === 0 && now() >= nextClaimAt) {
|
|
29820
30118
|
if (!receipt.pending_claim_request) {
|
|
29821
30119
|
const claimSequence = receipt.claim_sequence + 1;
|
|
29822
30120
|
const pendingClaimRequest = {
|
|
@@ -29935,6 +30233,13 @@ var init_runner = __esm({
|
|
|
29935
30233
|
requestDrain("drain_timeout");
|
|
29936
30234
|
}
|
|
29937
30235
|
}
|
|
30236
|
+
emitDiagnostic("runtime_stopped", {
|
|
30237
|
+
claimed,
|
|
30238
|
+
completed,
|
|
30239
|
+
failed,
|
|
30240
|
+
drain_reason: drainReason,
|
|
30241
|
+
active_attempts: active.size
|
|
30242
|
+
});
|
|
29938
30243
|
return { claimed, completed, failed, drain_reason: drainReason };
|
|
29939
30244
|
} finally {
|
|
29940
30245
|
removeAbortListener();
|
|
@@ -30280,13 +30585,27 @@ var init_runner = __esm({
|
|
|
30280
30585
|
);
|
|
30281
30586
|
}
|
|
30282
30587
|
await removeAttempt();
|
|
30588
|
+
options.onAttemptOutcome?.({
|
|
30589
|
+
outcome: "completed",
|
|
30590
|
+
failure_category: null,
|
|
30591
|
+
failure_code: null,
|
|
30592
|
+
retryable: null,
|
|
30593
|
+
dispatch_outcome: completion.outcome.dispatch_outcome,
|
|
30594
|
+
response_outcome: completion.outcome.response_outcome,
|
|
30595
|
+
latency_ms: completion.latency_ms,
|
|
30596
|
+
usage: completion.usage
|
|
30597
|
+
});
|
|
30283
30598
|
return "completed";
|
|
30284
30599
|
} catch (error48) {
|
|
30285
30600
|
if (error48 instanceof InferenceHostRunnerError && error48.code === "terminal_outcome_unconfirmed") {
|
|
30286
30601
|
throw error48;
|
|
30287
30602
|
}
|
|
30288
30603
|
if (error48 instanceof CodexAppServerError && error48.retryAtMs !== null && ["quota_exceeded", "codex_rate_limited"].includes(error48.code)) {
|
|
30289
|
-
options.onProviderCooldown?.(
|
|
30604
|
+
options.onProviderCooldown?.({
|
|
30605
|
+
retryAtMs: error48.retryAtMs,
|
|
30606
|
+
reason: error48.code === "quota_exceeded" ? "quota_exceeded" : "codex_rate_limited",
|
|
30607
|
+
rateLimits: error48.rateLimits
|
|
30608
|
+
});
|
|
30290
30609
|
}
|
|
30291
30610
|
const classified = classifyFailure(heartbeatFailure ?? error48, adapterResult);
|
|
30292
30611
|
const heartbeatAmbiguous = ambiguousHeartbeatTransport(heartbeatFailure);
|
|
@@ -30342,6 +30661,7 @@ var init_runner = __esm({
|
|
|
30342
30661
|
failure_category: failure.category,
|
|
30343
30662
|
failure_code: failure.code,
|
|
30344
30663
|
retryable: failure.retryable,
|
|
30664
|
+
membership_disposition: membershipFailureDisposition(failure),
|
|
30345
30665
|
failed_at: isoAt(now())
|
|
30346
30666
|
});
|
|
30347
30667
|
await updateAttempt({
|
|
@@ -30366,6 +30686,16 @@ var init_runner = __esm({
|
|
|
30366
30686
|
);
|
|
30367
30687
|
}
|
|
30368
30688
|
await removeAttempt();
|
|
30689
|
+
options.onAttemptOutcome?.({
|
|
30690
|
+
outcome: "failed",
|
|
30691
|
+
failure_category: failureRequest.failure_category,
|
|
30692
|
+
failure_code: failureRequest.failure_code,
|
|
30693
|
+
retryable: failureRequest.retryable,
|
|
30694
|
+
dispatch_outcome: failureRequest.outcome.dispatch_outcome,
|
|
30695
|
+
response_outcome: failureRequest.outcome.response_outcome,
|
|
30696
|
+
latency_ms: adapterResult?.latencyMs ?? null,
|
|
30697
|
+
usage: failureRequest.usage
|
|
30698
|
+
});
|
|
30369
30699
|
return "failed";
|
|
30370
30700
|
} finally {
|
|
30371
30701
|
heartbeatStopped = true;
|
|
@@ -30406,7 +30736,7 @@ import { createWriteStream, readFileSync } from "node:fs";
|
|
|
30406
30736
|
import { access as access3, chmod as chmod3, mkdir as mkdir3, readFile as readFile5, rm as rm4, writeFile as writeFile2 } from "node:fs/promises";
|
|
30407
30737
|
import { homedir as homedir2 } from "node:os";
|
|
30408
30738
|
import { dirname as dirname4, join as join5, resolve as resolve4 } from "node:path";
|
|
30409
|
-
var SERVICE_NAME, SYSTEMD_UNIT, LAUNCHD_LABEL, SERVICE_COOPERATIVE_STOP_SECONDS, isWindowsSubsystemForLinux, inferenceHostServiceManifestPath, inferenceHostServiceDesiredPath, inferenceHostServiceLogPath, xmlEscape, plistEscape, systemdQuote, defaultRunCommand, managerName, assertRuntimeEnvironment, assertServicePath, assertWorker, assertManifest, assertDesiredState, readInferenceHostServiceManifest, readInferenceHostServiceDesired, readDesiredAcrossAtomicReplacement, writeDesired, runtimeEnvironment, serviceArguments, windowsOwnedCommandLine, vbScriptString, windowsServiceLauncher, windowsTaskXml, systemdUnit, launchAgentPlist, InferenceHostServiceManager, appendServiceLog, spawnServiceChild, runInferenceHostServiceSupervisor;
|
|
30739
|
+
var SERVICE_NAME, SYSTEMD_UNIT, LAUNCHD_LABEL, SERVICE_COOPERATIVE_STOP_SECONDS, inferenceHostServiceChildEnvironment, isWindowsSubsystemForLinux, inferenceHostServiceManifestPath, inferenceHostServiceDesiredPath, inferenceHostServiceLogPath, xmlEscape, plistEscape, systemdQuote, defaultRunCommand, managerName, assertRuntimeEnvironment, withoutConcurrencyLimit, assertServicePath, assertWorker, assertManifest, assertDesiredState, readInferenceHostServiceManifest, readInferenceHostServiceDesired, readDesiredAcrossAtomicReplacement, writeDesired, runtimeEnvironment, serviceArguments, windowsOwnedCommandLine, vbScriptString, windowsServiceLauncher, windowsTaskXml, systemdUnit, launchAgentPlist, InferenceHostServiceManager, appendServiceLog, spawnServiceChild, runInferenceHostServiceSupervisor;
|
|
30410
30740
|
var init_service = __esm({
|
|
30411
30741
|
"lib/inference-host/service.ts"() {
|
|
30412
30742
|
"use strict";
|
|
@@ -30415,6 +30745,15 @@ var init_service = __esm({
|
|
|
30415
30745
|
SYSTEMD_UNIT = "vtx-inference-host.service";
|
|
30416
30746
|
LAUNCHD_LABEL = "com.vtxmacro.inference-host";
|
|
30417
30747
|
SERVICE_COOPERATIVE_STOP_SECONDS = 75;
|
|
30748
|
+
inferenceHostServiceChildEnvironment = (runtimeEnvironment2, inheritedEnvironment = process.env) => {
|
|
30749
|
+
const environment = { ...inheritedEnvironment };
|
|
30750
|
+
for (const key of Object.keys(environment)) {
|
|
30751
|
+
if (key === "VTX_API_URL" || key.startsWith("VTX_INFERENCE_HOST_")) {
|
|
30752
|
+
delete environment[key];
|
|
30753
|
+
}
|
|
30754
|
+
}
|
|
30755
|
+
return { ...environment, ...runtimeEnvironment2 };
|
|
30756
|
+
};
|
|
30418
30757
|
isWindowsSubsystemForLinux = (env = process.env, kernelRelease) => Boolean(
|
|
30419
30758
|
String(env.WSL_INTEROP || "").trim() || String(env.WSL_DISTRO_NAME || "").trim() || /microsoft/iu.test(kernelRelease ?? (() => {
|
|
30420
30759
|
try {
|
|
@@ -30467,6 +30806,10 @@ var init_service = __esm({
|
|
|
30467
30806
|
}
|
|
30468
30807
|
return value;
|
|
30469
30808
|
};
|
|
30809
|
+
withoutConcurrencyLimit = (environment) => {
|
|
30810
|
+
const { VTX_INFERENCE_HOST_MAX_CONCURRENCY: _removed, ...rest } = environment;
|
|
30811
|
+
return rest;
|
|
30812
|
+
};
|
|
30470
30813
|
assertServicePath = (value) => {
|
|
30471
30814
|
if (typeof value !== "string" || !value || /[\r\n\0]/u.test(value)) {
|
|
30472
30815
|
throw new Error("Inference-host service manifest paths contain control characters.");
|
|
@@ -30478,14 +30821,14 @@ var init_service = __esm({
|
|
|
30478
30821
|
throw new Error("Inference-host service worker is invalid.");
|
|
30479
30822
|
}
|
|
30480
30823
|
const record2 = value;
|
|
30481
|
-
if (typeof record2.instance_name !== "string" || !/^[a-z0-9](?:[a-z0-9-]{0,46}[a-z0-9])?$/u.test(record2.instance_name) || record2.adapter !== "codex" || typeof record2.display_name !== "string" || !record2.display_name || !Number.isSafeInteger(record2.max_concurrency) || Number(record2.max_concurrency) < 1
|
|
30824
|
+
if (typeof record2.instance_name !== "string" || !/^[a-z0-9](?:[a-z0-9-]{0,46}[a-z0-9])?$/u.test(record2.instance_name) || record2.adapter !== "codex" || typeof record2.display_name !== "string" || !record2.display_name || record2.max_concurrency !== null && (!Number.isSafeInteger(record2.max_concurrency) || Number(record2.max_concurrency) < 1) || record2.authenticated_account_email !== null && typeof record2.authenticated_account_email !== "string" || record2.authenticated_account_plan !== null && typeof record2.authenticated_account_plan !== "string") {
|
|
30482
30825
|
throw new Error("Inference-host service worker is invalid.");
|
|
30483
30826
|
}
|
|
30484
30827
|
return {
|
|
30485
30828
|
instance_name: record2.instance_name,
|
|
30486
30829
|
adapter: "codex",
|
|
30487
30830
|
display_name: record2.display_name,
|
|
30488
|
-
max_concurrency: Number(record2.max_concurrency),
|
|
30831
|
+
max_concurrency: record2.max_concurrency === null ? null : Number(record2.max_concurrency),
|
|
30489
30832
|
authenticated_account_email: record2.authenticated_account_email,
|
|
30490
30833
|
authenticated_account_plan: record2.authenticated_account_plan,
|
|
30491
30834
|
runtime_environment: assertRuntimeEnvironment(record2.runtime_environment)
|
|
@@ -30499,18 +30842,20 @@ var init_service = __esm({
|
|
|
30499
30842
|
if (record2.schema_version === "vtx_inference_service_v1") {
|
|
30500
30843
|
const legacy = record2;
|
|
30501
30844
|
if (legacy.adapter !== "codex" || typeof legacy.installed_at !== "string" || !Number.isFinite(Date.parse(legacy.installed_at)) || typeof legacy.executable !== "string" || !legacy.executable || typeof legacy.script !== "string" || !legacy.script || typeof legacy.display_name !== "string" || !legacy.display_name || typeof legacy.log_path !== "string" || !legacy.log_path) throw new Error("Inference-host service manifest is invalid.");
|
|
30502
|
-
const runtime_environment =
|
|
30845
|
+
const runtime_environment = withoutConcurrencyLimit(
|
|
30846
|
+
assertRuntimeEnvironment(legacy.runtime_environment)
|
|
30847
|
+
);
|
|
30503
30848
|
const worker = assertWorker({
|
|
30504
30849
|
instance_name: "default",
|
|
30505
30850
|
adapter: "codex",
|
|
30506
30851
|
display_name: legacy.display_name,
|
|
30507
|
-
max_concurrency:
|
|
30852
|
+
max_concurrency: null,
|
|
30508
30853
|
authenticated_account_email: null,
|
|
30509
30854
|
authenticated_account_plan: null,
|
|
30510
30855
|
runtime_environment
|
|
30511
30856
|
});
|
|
30512
30857
|
return {
|
|
30513
|
-
schema_version: "
|
|
30858
|
+
schema_version: "vtx_inference_service_v3",
|
|
30514
30859
|
installed_at: legacy.installed_at,
|
|
30515
30860
|
executable: assertServicePath(legacy.executable),
|
|
30516
30861
|
script: assertServicePath(legacy.script),
|
|
@@ -30518,7 +30863,40 @@ var init_service = __esm({
|
|
|
30518
30863
|
workers: [worker]
|
|
30519
30864
|
};
|
|
30520
30865
|
}
|
|
30521
|
-
if (record2.schema_version
|
|
30866
|
+
if (record2.schema_version === "vtx_inference_service_v2") {
|
|
30867
|
+
const legacy = record2;
|
|
30868
|
+
if (typeof legacy.installed_at !== "string" || !Number.isFinite(Date.parse(legacy.installed_at)) || typeof legacy.executable !== "string" || !legacy.executable || typeof legacy.script !== "string" || !legacy.script || typeof legacy.log_path !== "string" || !legacy.log_path || !Array.isArray(legacy.workers) || legacy.workers.length < 1) {
|
|
30869
|
+
throw new Error("Inference-host service manifest is invalid.");
|
|
30870
|
+
}
|
|
30871
|
+
const workers2 = legacy.workers.map((worker) => {
|
|
30872
|
+
if (!worker || typeof worker !== "object" || Array.isArray(worker)) {
|
|
30873
|
+
throw new Error("Inference-host service worker is invalid.");
|
|
30874
|
+
}
|
|
30875
|
+
const legacyWorker = worker;
|
|
30876
|
+
if (!Number.isSafeInteger(legacyWorker.max_concurrency) || Number(legacyWorker.max_concurrency) < 1) {
|
|
30877
|
+
throw new Error("Inference-host service worker is invalid.");
|
|
30878
|
+
}
|
|
30879
|
+
return assertWorker({
|
|
30880
|
+
...legacyWorker,
|
|
30881
|
+
max_concurrency: null,
|
|
30882
|
+
runtime_environment: withoutConcurrencyLimit(
|
|
30883
|
+
assertRuntimeEnvironment(legacyWorker.runtime_environment)
|
|
30884
|
+
)
|
|
30885
|
+
});
|
|
30886
|
+
});
|
|
30887
|
+
if (new Set(workers2.map((worker) => worker.instance_name)).size !== workers2.length) {
|
|
30888
|
+
throw new Error("Inference-host service worker names must be unique.");
|
|
30889
|
+
}
|
|
30890
|
+
return {
|
|
30891
|
+
schema_version: "vtx_inference_service_v3",
|
|
30892
|
+
installed_at: legacy.installed_at,
|
|
30893
|
+
executable: assertServicePath(legacy.executable),
|
|
30894
|
+
script: assertServicePath(legacy.script),
|
|
30895
|
+
log_path: assertServicePath(legacy.log_path),
|
|
30896
|
+
workers: workers2
|
|
30897
|
+
};
|
|
30898
|
+
}
|
|
30899
|
+
if (record2.schema_version !== "vtx_inference_service_v3" || typeof record2.installed_at !== "string" || !Number.isFinite(Date.parse(record2.installed_at)) || typeof record2.executable !== "string" || !record2.executable || typeof record2.script !== "string" || !record2.script || typeof record2.log_path !== "string" || !record2.log_path || !Array.isArray(record2.workers) || record2.workers.length < 1) {
|
|
30522
30900
|
throw new Error("Inference-host service manifest is invalid.");
|
|
30523
30901
|
}
|
|
30524
30902
|
assertServicePath(record2.executable);
|
|
@@ -30587,9 +30965,11 @@ var init_service = __esm({
|
|
|
30587
30965
|
VTX_INFERENCE_HOST_INSTANCE: config2.instanceName,
|
|
30588
30966
|
VTX_INFERENCE_HOST_CREDENTIAL_STORE: config2.credentialStoreMode,
|
|
30589
30967
|
VTX_INFERENCE_HOST_STATE_PATH: config2.statePath,
|
|
30590
|
-
VTX_INFERENCE_HOST_LOCK_PATH: config2.processLockPath
|
|
30591
|
-
VTX_INFERENCE_HOST_MAX_CONCURRENCY: String(maxConcurrency)
|
|
30968
|
+
VTX_INFERENCE_HOST_LOCK_PATH: config2.processLockPath
|
|
30592
30969
|
};
|
|
30970
|
+
if (maxConcurrency !== null) {
|
|
30971
|
+
result2.VTX_INFERENCE_HOST_MAX_CONCURRENCY = String(maxConcurrency);
|
|
30972
|
+
}
|
|
30593
30973
|
if (config2.credentialFilePath) {
|
|
30594
30974
|
result2.VTX_INFERENCE_HOST_CREDENTIAL_FILE = config2.credentialFilePath;
|
|
30595
30975
|
}
|
|
@@ -30905,7 +31285,7 @@ ${cleanup.stderr}`)) {
|
|
|
30905
31285
|
}
|
|
30906
31286
|
await access3(this.executable);
|
|
30907
31287
|
await access3(this.script);
|
|
30908
|
-
const maxConcurrency = options.maxConcurrency ??
|
|
31288
|
+
const maxConcurrency = options.maxConcurrency ?? null;
|
|
30909
31289
|
const workers = [
|
|
30910
31290
|
...existing?.workers.filter((worker) => worker.instance_name !== this.config.instanceName) ?? [],
|
|
30911
31291
|
{
|
|
@@ -30919,7 +31299,7 @@ ${cleanup.stderr}`)) {
|
|
|
30919
31299
|
}
|
|
30920
31300
|
].sort((left, right) => left.instance_name.localeCompare(right.instance_name));
|
|
30921
31301
|
const manifest = assertManifest({
|
|
30922
|
-
schema_version: "
|
|
31302
|
+
schema_version: "vtx_inference_service_v3",
|
|
30923
31303
|
installed_at: this.now().toISOString(),
|
|
30924
31304
|
executable: this.executable,
|
|
30925
31305
|
script: this.script,
|
|
@@ -31016,13 +31396,22 @@ ${result2.stderr}`)) {
|
|
|
31016
31396
|
})) ?? []
|
|
31017
31397
|
};
|
|
31018
31398
|
}
|
|
31019
|
-
async logs(lines = 100) {
|
|
31399
|
+
async logs(lines = 100, instanceName) {
|
|
31020
31400
|
const manifest = await readInferenceHostServiceManifest(this.manifestPath());
|
|
31021
31401
|
const path = manifest?.log_path ?? this.logPath();
|
|
31022
31402
|
try {
|
|
31023
31403
|
const contents = await readFile5(path, "utf8");
|
|
31024
|
-
|
|
31025
|
-
|
|
31404
|
+
const logLines = contents.trimEnd().split(/\r?\n/u);
|
|
31405
|
+
const filtered = instanceName ? logLines.filter((line) => {
|
|
31406
|
+
try {
|
|
31407
|
+
const parsed = JSON.parse(line);
|
|
31408
|
+
return parsed.instance_name === instanceName || Array.isArray(parsed.instances) && parsed.instances.includes(instanceName);
|
|
31409
|
+
} catch {
|
|
31410
|
+
return false;
|
|
31411
|
+
}
|
|
31412
|
+
}) : logLines;
|
|
31413
|
+
return filtered.length > 0 ? `${filtered.slice(-lines).join("\n")}
|
|
31414
|
+
` : "";
|
|
31026
31415
|
} catch (error48) {
|
|
31027
31416
|
if (error48.code === "ENOENT") return "";
|
|
31028
31417
|
throw error48;
|
|
@@ -31102,26 +31491,61 @@ ${result2.stderr}`)) {
|
|
|
31102
31491
|
const log = createWriteStream(manifest.log_path, { flags: "a", mode: 384 });
|
|
31103
31492
|
return await new Promise((resolvePromise, reject) => {
|
|
31104
31493
|
let stdout = "";
|
|
31494
|
+
const pending = { stdout: "", stderr: "" };
|
|
31495
|
+
const writeTaggedOutput = (stream, text, flush = false) => {
|
|
31496
|
+
const lines = `${pending[stream]}${text}`.split(/\r?\n/u);
|
|
31497
|
+
const remainder = lines.pop() ?? "";
|
|
31498
|
+
pending[stream] = flush ? "" : remainder;
|
|
31499
|
+
if (flush && remainder) lines.push(remainder);
|
|
31500
|
+
if (flush && lines.at(-1) === "") lines.pop();
|
|
31501
|
+
for (const line of lines) {
|
|
31502
|
+
if (!line) continue;
|
|
31503
|
+
try {
|
|
31504
|
+
const parsed = JSON.parse(line);
|
|
31505
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
31506
|
+
log.write(`${JSON.stringify({
|
|
31507
|
+
...parsed,
|
|
31508
|
+
instance_name: worker.instance_name
|
|
31509
|
+
})}
|
|
31510
|
+
`);
|
|
31511
|
+
continue;
|
|
31512
|
+
}
|
|
31513
|
+
} catch {
|
|
31514
|
+
}
|
|
31515
|
+
log.write(`${JSON.stringify({
|
|
31516
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
31517
|
+
event: "worker_output",
|
|
31518
|
+
instance_name: worker.instance_name,
|
|
31519
|
+
stream,
|
|
31520
|
+
message: line.slice(0, 4096)
|
|
31521
|
+
})}
|
|
31522
|
+
`);
|
|
31523
|
+
}
|
|
31524
|
+
};
|
|
31105
31525
|
const child = spawn5(manifest.executable, args, {
|
|
31106
|
-
env:
|
|
31526
|
+
env: inferenceHostServiceChildEnvironment(worker.runtime_environment),
|
|
31107
31527
|
windowsHide: true,
|
|
31108
31528
|
stdio: ["ignore", "pipe", "pipe"]
|
|
31109
31529
|
});
|
|
31110
31530
|
child.stdout.on("data", (chunk) => {
|
|
31111
31531
|
const text = chunk.toString("utf8");
|
|
31112
|
-
|
|
31532
|
+
writeTaggedOutput("stdout", text);
|
|
31113
31533
|
stdout = `${stdout}${text}`.slice(-65536);
|
|
31114
31534
|
});
|
|
31115
|
-
child.stderr.on("data", (chunk) =>
|
|
31535
|
+
child.stderr.on("data", (chunk) => writeTaggedOutput("stderr", chunk.toString("utf8")));
|
|
31116
31536
|
const onAbort = () => child.kill("SIGTERM");
|
|
31117
31537
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
31118
31538
|
child.once("error", (error48) => {
|
|
31119
31539
|
signal.removeEventListener("abort", onAbort);
|
|
31540
|
+
writeTaggedOutput("stdout", "", true);
|
|
31541
|
+
writeTaggedOutput("stderr", "", true);
|
|
31120
31542
|
log.end();
|
|
31121
31543
|
reject(error48);
|
|
31122
31544
|
});
|
|
31123
31545
|
child.once("exit", (code) => {
|
|
31124
31546
|
signal.removeEventListener("abort", onAbort);
|
|
31547
|
+
writeTaggedOutput("stdout", "", true);
|
|
31548
|
+
writeTaggedOutput("stderr", "", true);
|
|
31125
31549
|
log.end();
|
|
31126
31550
|
let drainReason = null;
|
|
31127
31551
|
for (const line of stdout.trim().split("\n").reverse()) {
|
|
@@ -31407,7 +31831,7 @@ Commands:
|
|
|
31407
31831
|
Common options:
|
|
31408
31832
|
--json Emit machine-readable JSON
|
|
31409
31833
|
--instance NAME Target an isolated local subscription instance (default: default)
|
|
31410
|
-
--max-concurrency N
|
|
31834
|
+
--max-concurrency N Optional positive-integer Codex slot limit (default: unlimited)
|
|
31411
31835
|
--help, -h Show this help
|
|
31412
31836
|
|
|
31413
31837
|
If the OS credential store cannot retain the VTX grant, set
|
|
@@ -31426,18 +31850,16 @@ Durable service:
|
|
|
31426
31850
|
`;
|
|
31427
31851
|
parseHostConcurrency = (raw, label) => {
|
|
31428
31852
|
const value = Number(raw);
|
|
31429
|
-
if (!Number.isSafeInteger(value) || value < 1
|
|
31430
|
-
throw new Error(`${label} must be
|
|
31853
|
+
if (!Number.isSafeInteger(value) || value < 1) {
|
|
31854
|
+
throw new Error(`${label} must be a positive safe integer.`);
|
|
31431
31855
|
}
|
|
31432
31856
|
return value;
|
|
31433
31857
|
};
|
|
31434
31858
|
parseInferenceHostArgs = (argv2, env) => {
|
|
31435
31859
|
let json2 = String(env.VTX_OUTPUT_JSON || "").trim().toLowerCase() === "true";
|
|
31436
31860
|
let once = false;
|
|
31437
|
-
|
|
31438
|
-
|
|
31439
|
-
"VTX_INFERENCE_HOST_MAX_CONCURRENCY"
|
|
31440
|
-
);
|
|
31861
|
+
const configuredConcurrency = String(env.VTX_INFERENCE_HOST_MAX_CONCURRENCY || "").trim();
|
|
31862
|
+
let maxConcurrency = configuredConcurrency ? parseHostConcurrency(configuredConcurrency, "VTX_INFERENCE_HOST_MAX_CONCURRENCY") : null;
|
|
31441
31863
|
let instanceName = String(env.VTX_INFERENCE_HOST_INSTANCE || "default").trim();
|
|
31442
31864
|
let instanceExplicit = Boolean(String(env.VTX_INFERENCE_HOST_INSTANCE || "").trim());
|
|
31443
31865
|
let displayName = String(env.VTX_INFERENCE_HOST_DISPLAY_NAME || "").trim() || "Codex subscription host";
|
|
@@ -31693,6 +32115,7 @@ Durable service:
|
|
|
31693
32115
|
...dependencies,
|
|
31694
32116
|
acquireProcessLock: async () => borrowedProcessLock
|
|
31695
32117
|
}, {
|
|
32118
|
+
instanceName: options.config.instanceName,
|
|
31696
32119
|
displayName: options.displayName,
|
|
31697
32120
|
authenticatedAccountEmail: options.authenticatedAccountEmail,
|
|
31698
32121
|
authenticatedAccountPlan: options.authenticatedAccountPlan,
|
|
@@ -31702,6 +32125,7 @@ Durable service:
|
|
|
31702
32125
|
adapterRuntimeVersion: INFERENCE_HOST_CLI_VERSION,
|
|
31703
32126
|
maxConcurrency: options.maxConcurrency,
|
|
31704
32127
|
once: options.once,
|
|
32128
|
+
emitDiagnosticEvent: options.emitDiagnosticEvent,
|
|
31705
32129
|
signal: options.signal
|
|
31706
32130
|
}).run();
|
|
31707
32131
|
};
|
|
@@ -32203,6 +32627,10 @@ Waiting for approval...
|
|
|
32203
32627
|
once: parsed.once,
|
|
32204
32628
|
env,
|
|
32205
32629
|
processLock,
|
|
32630
|
+
emitDiagnosticEvent: parsed.json ? (event) => (dependencies.emitStdout ?? ((text) => {
|
|
32631
|
+
process.stdout.write(text);
|
|
32632
|
+
}))(`${JSON.stringify(event)}
|
|
32633
|
+
`) : void 0,
|
|
32206
32634
|
signal: cancellation.signal
|
|
32207
32635
|
});
|
|
32208
32636
|
return {
|
|
@@ -32739,7 +33167,14 @@ Waiting for approval...
|
|
|
32739
33167
|
throw new Error("Service adapter and model options are accepted only by service install.");
|
|
32740
33168
|
}
|
|
32741
33169
|
if (action === "logs") {
|
|
32742
|
-
return {
|
|
33170
|
+
return {
|
|
33171
|
+
exitCode: 0,
|
|
33172
|
+
stdout: await manager.logs(
|
|
33173
|
+
parsed.lines,
|
|
33174
|
+
parsed.instanceExplicit ? config2.instanceName : void 0
|
|
33175
|
+
),
|
|
33176
|
+
stderr: ""
|
|
33177
|
+
};
|
|
32743
33178
|
}
|
|
32744
33179
|
if (action === "start") {
|
|
32745
33180
|
return { exitCode: 0, stdout: render({ status: "service_started", ...await manager.start() }, parsed.json), stderr: "" };
|