@vtxmacro/cli 2026.8.31 → 2026.8.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -4
- package/bin/vtx.js +392 -58
- 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,13 @@ 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
|
-
Automated hosts
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
+
Automated hosts do not impose a subscription-specific profile-count or
|
|
90
|
+
concurrency limit by default. Set an explicit positive integer with
|
|
91
|
+
`--max-concurrency` when you want a local limit. Every active turn shares the live subscription
|
|
92
|
+
rate-limit gate and cooldown; unlimited local admission does not guarantee
|
|
93
|
+
capacity beyond the authenticated account's current entitlement. Updating from
|
|
94
|
+
an older bounded host removes its previous numeric limit; run
|
|
95
|
+
`service install --max-concurrency <positive-integer>` only to add one back.
|
|
89
96
|
|
|
90
97
|
This durable host uses a separate least-privilege `insights:inference`
|
|
91
98
|
OAuth grant. It also keeps its ChatGPT subscription login in a dedicated private
|
|
@@ -94,6 +101,9 @@ session. The per-user OS service starts immediately, starts again at login, and
|
|
|
94
101
|
reconnects after sleep, network loss, or a worker exit. Stopping a VTX bot leaves
|
|
95
102
|
the provider online and idle. Use `vtx inference-host run` only for foreground
|
|
96
103
|
diagnostics. VTX logout/revoke and Codex logout are intentionally separate operations.
|
|
104
|
+
JSON foreground and service logs include safe concurrency, latency, token,
|
|
105
|
+
failure-code, and cooldown events without prompts, responses, or credentials.
|
|
106
|
+
Use `service logs --instance <name>` to isolate one subscription.
|
|
97
107
|
|
|
98
108
|
Use `vtx inference-host --help` for command discovery. The VTX login verifies
|
|
99
109
|
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.32",
|
|
42
42
|
codex_package_name: "@openai/codex",
|
|
43
43
|
codex_version: "0.147.0",
|
|
44
44
|
platforms: {
|
|
@@ -14375,7 +14375,7 @@ var init_zod = __esm({
|
|
|
14375
14375
|
});
|
|
14376
14376
|
|
|
14377
14377
|
// lib/external-inference-contract.ts
|
|
14378
|
-
var EXTERNAL_INFERENCE_CONTRACT_VERSION, EXTERNAL_INFERENCE_CONTROLLER_SCHEMA_VERSION, EXTERNAL_INFERENCE_ADVERTISEMENT_SCHEMA_VERSION, EXTERNAL_INFERENCE_ENVELOPE_SCHEMA_VERSION, EXTERNAL_INFERENCE_JOB_INPUT_SCHEMA_VERSION, EXTERNAL_INFERENCE_USAGE_SCHEMA_VERSION, EXTERNAL_INFERENCE_INPUT_HASH_DOMAIN, MAX_EXTERNAL_INFERENCE_STATUS_HOSTS, MAX_GENERATION, MAX_SAFE_INTEGER, MAX_PROMPT_BYTES, MAX_IMMUTABLE_JOB_INPUT_BYTES, MAX_CANDIDATE_PLAINTEXT_BYTES, MAX_CIPHERTEXT_CHARS, SHA256_INITIAL_STATE, SHA256_ROUND_CONSTANTS, rotateRight, sha256BytesHex, sha256Utf8Hex, computeImmutableJobInputSha256, identifierSchema, operationIdentifierSchema, sha256HexSchema, generationSchema, zeroBasedGenerationSchema, nonNegativeSafeIntegerSchema, positiveSafeIntegerSchema, sqlIntegerTokenCountSchema, timestampSchema, safeCodeSchema, externalInferenceAdapterIdSchema, reasoningEffortSchema, modelNameSchema, displayNameSchema, authenticatedAccountEmailSchema, protocolVersionSchema, base64UrlAlphabet, isCanonicalBase64Url, base64Url32BytesSchema, base64UrlNonceSchema, base64UrlCiphertextSchema, claimHandleSchema, boundedJsonTextSchema, boundedPromptTextSchema, laneSchema, botModeSchema, executionModeSchema, responseModeSchema, dispatchOutcomeSchema, responseOutcomeSchema, nativeModelControllerSchema, externalAgentModelControllerSchema, externalAgentUnboundControllerSchema, liveModelControllerSchema, snapshotModelControllerSchema, modelIdentityMappingSchema, advertisedModelSchema, hostAdvertisementSchema, envelopeAadSchema, validateEnvelopeAad, commonEnvelopeShape, sealedKeyWrapEnvelopeSchema, sealedInputEnvelopeSchema, sealedCandidateEnvelopeSchema, sealedEnvelopeSchema, screenerCandidateRuntimeBindingSchema, screenerClientLeaseBindingSchema, screenerRuntimeBindingSchema, serverRuntimeBindingSchema, clientRuntimeBindingSchema, runtimeBindingSchema, immutableJobInputSchema, canonicalizeJsonValue, serializeImmutableJobInput, reportedTokenUsageSchema, unavailableTokenUsageSchema, tokenUsageSchema, agentConnectRequestSchema, agentNextRequestSchema, agentHeartbeatRequestSchema, emptyAgentNextResultSchema, claimedAgentNextResultSchema, agentNextResultSchema, agentCompleteRequestSchema, agentFailRequestSchema, requestedModelSelectionSchema, completedModelProvenanceSchema, attemptModelProvenanceSchema, hostHeartbeatRequestSchema, jobClaimRequestSchema, emptyJobClaimSchema, claimedJobSchema, jobClaimResultSchema, attemptStartRequestSchema, jobHeartbeatRequestSchema, continueHeartbeatDirectiveSchema, cancelHeartbeatDirectiveSchema, jobHeartbeatResultSchema, adapterOutcomeEvidenceSchema, completionBaseShape, validateCompletion, providerResponseCompletionSchema, decisionCandidateCompletionSchema, jobCompleteRequestSchema, jobFailRequestSchema, jobCancelRequestSchema, jobCancellationReceiptSchema, jobDeliveryRequestSchema, deliveryBaseShape, validateDeliveryCandidate, providerResponseDeliverySchema, decisionCandidateDeliverySchema, jobDeliveryResultSchema, jobConsumptionRequestSchema, jobConsumptionReceiptSchema, jobStateSchema, jobStatusReadSchema, hostStatusReadSchema, controllerBindingStatusReadSchema, queueStatusReadSchema, outcomeStatusReadSchema, externalInferenceStatusReadSchema, nativeResearchEvidenceSourceSchema, externalAgentResearchEvidenceSourceSchema, researchEvidenceSourceSchema, reportedResearchTokenUsageSchema, unavailableResearchTokenUsageSchema, researchTokenUsageSchema, externalInferenceProductLineageBaseShape, traderExternalInferenceProductLineageSchema, decisionChatExternalInferenceProductLineageSchema, screenerExternalInferenceProductLineageSchema, externalInferenceProductLineageSchema, normalProductLinkageSchema, evidenceMaterializationMarkerSchema, deliveredExternalAgentSourceIdentitySchema, deliveredRequestEvidenceSchema, researchEvidenceBaseShape, researchEvidenceBaseSchema, validateExactUtf8, validateResearchEvidence, providerResponseResearchEvidenceSchema, decisionCandidateResearchEvidenceSchema, researchEvidenceSchema;
|
|
14378
|
+
var EXTERNAL_INFERENCE_CONTRACT_VERSION, EXTERNAL_INFERENCE_CONTROLLER_SCHEMA_VERSION, EXTERNAL_INFERENCE_ADVERTISEMENT_SCHEMA_VERSION, EXTERNAL_INFERENCE_ENVELOPE_SCHEMA_VERSION, EXTERNAL_INFERENCE_JOB_INPUT_SCHEMA_VERSION, EXTERNAL_INFERENCE_USAGE_SCHEMA_VERSION, EXTERNAL_INFERENCE_INPUT_HASH_DOMAIN, MAX_EXTERNAL_INFERENCE_STATUS_HOSTS, MAX_GENERATION, MAX_SAFE_INTEGER, MAX_PROMPT_BYTES, MAX_IMMUTABLE_JOB_INPUT_BYTES, MAX_CANDIDATE_PLAINTEXT_BYTES, MAX_CIPHERTEXT_CHARS, SHA256_INITIAL_STATE, SHA256_ROUND_CONSTANTS, rotateRight, sha256BytesHex, sha256Utf8Hex, computeImmutableJobInputSha256, identifierSchema, operationIdentifierSchema, sha256HexSchema, generationSchema, zeroBasedGenerationSchema, nonNegativeSafeIntegerSchema, positiveSafeIntegerSchema, sqlIntegerTokenCountSchema, timestampSchema, safeCodeSchema, externalInferenceAdapterIdSchema, reasoningEffortSchema, modelNameSchema, displayNameSchema, authenticatedAccountEmailSchema, protocolVersionSchema, base64UrlAlphabet, isCanonicalBase64Url, base64Url32BytesSchema, base64UrlNonceSchema, base64UrlCiphertextSchema, claimHandleSchema, boundedJsonTextSchema, boundedPromptTextSchema, laneSchema, botModeSchema, executionModeSchema, responseModeSchema, dispatchOutcomeSchema, responseOutcomeSchema, nativeModelControllerSchema, externalAgentModelControllerSchema, externalAgentUnboundControllerSchema, liveModelControllerSchema, snapshotModelControllerSchema, modelIdentityMappingSchema, advertisedModelSchema, hostAdvertisementSchema, envelopeAadSchema, validateEnvelopeAad, commonEnvelopeShape, sealedKeyWrapEnvelopeSchema, sealedInputEnvelopeSchema, sealedCandidateEnvelopeSchema, sealedEnvelopeSchema, screenerCandidateRuntimeBindingSchema, screenerClientLeaseBindingSchema, screenerRuntimeBindingSchema, serverRuntimeBindingSchema, clientRuntimeBindingSchema, runtimeBindingSchema, immutableJobInputSchema, canonicalizeJsonValue, serializeImmutableJobInput, reportedTokenUsageSchema, unavailableTokenUsageSchema, tokenUsageSchema, agentConnectRequestSchema, agentNextRequestSchema, agentHeartbeatRequestSchema, emptyAgentNextResultSchema, claimedAgentNextResultSchema, agentNextResultSchema, agentCompleteRequestSchema, agentFailRequestSchema, requestedModelSelectionSchema, completedModelProvenanceSchema, attemptModelProvenanceSchema, providerWeeklyQuotaReadSchema, hostHeartbeatRequestSchema, jobClaimRequestSchema, emptyJobClaimSchema, claimedJobSchema, jobClaimResultSchema, attemptStartRequestSchema, jobHeartbeatRequestSchema, continueHeartbeatDirectiveSchema, cancelHeartbeatDirectiveSchema, jobHeartbeatResultSchema, adapterOutcomeEvidenceSchema, completionBaseShape, validateCompletion, providerResponseCompletionSchema, decisionCandidateCompletionSchema, jobCompleteRequestSchema, jobFailRequestSchema, jobCancelRequestSchema, jobCancellationReceiptSchema, jobDeliveryRequestSchema, deliveryBaseShape, validateDeliveryCandidate, providerResponseDeliverySchema, decisionCandidateDeliverySchema, jobDeliveryResultSchema, jobConsumptionRequestSchema, jobConsumptionReceiptSchema, jobStateSchema, jobStatusReadSchema, hostStatusReadSchema, controllerBindingStatusReadSchema, queueStatusReadSchema, outcomeStatusReadSchema, externalInferenceVolumeWindowReadSchema, externalInferenceFailureCountReadSchema, externalInferenceHostDiagnosticsReadSchema, externalInferenceProfileActivityReadSchema, externalInferenceStatusReadSchema, nativeResearchEvidenceSourceSchema, externalAgentResearchEvidenceSourceSchema, researchEvidenceSourceSchema, reportedResearchTokenUsageSchema, unavailableResearchTokenUsageSchema, researchTokenUsageSchema, externalInferenceProductLineageBaseShape, traderExternalInferenceProductLineageSchema, decisionChatExternalInferenceProductLineageSchema, screenerExternalInferenceProductLineageSchema, externalInferenceProductLineageSchema, normalProductLinkageSchema, evidenceMaterializationMarkerSchema, deliveredExternalAgentSourceIdentitySchema, deliveredRequestEvidenceSchema, researchEvidenceBaseShape, researchEvidenceBaseSchema, validateExactUtf8, validateResearchEvidence, providerResponseResearchEvidenceSchema, decisionCandidateResearchEvidenceSchema, researchEvidenceSchema;
|
|
14379
14379
|
var init_external_inference_contract = __esm({
|
|
14380
14380
|
"lib/external-inference-contract.ts"() {
|
|
14381
14381
|
"use strict";
|
|
@@ -15181,6 +15181,22 @@ var init_external_inference_contract = __esm({
|
|
|
15181
15181
|
});
|
|
15182
15182
|
}
|
|
15183
15183
|
});
|
|
15184
|
+
providerWeeklyQuotaReadSchema = external_exports.strictObject({
|
|
15185
|
+
source: external_exports.literal("codex_app_server"),
|
|
15186
|
+
used_percent: external_exports.number().finite().min(0).max(1e6),
|
|
15187
|
+
resets_at: timestampSchema,
|
|
15188
|
+
observed_at: timestampSchema
|
|
15189
|
+
}).superRefine((value, context) => {
|
|
15190
|
+
const observedAt = Date.parse(value.observed_at);
|
|
15191
|
+
const resetsAt = Date.parse(value.resets_at);
|
|
15192
|
+
if (resetsAt <= observedAt || resetsAt > observedAt + 8 * 24 * 60 * 60 * 1e3) {
|
|
15193
|
+
context.addIssue({
|
|
15194
|
+
code: "custom",
|
|
15195
|
+
message: "weekly quota reset must follow observation within eight days",
|
|
15196
|
+
path: ["resets_at"]
|
|
15197
|
+
});
|
|
15198
|
+
}
|
|
15199
|
+
});
|
|
15184
15200
|
hostHeartbeatRequestSchema = external_exports.strictObject({
|
|
15185
15201
|
schema_version: external_exports.literal("external_inference_host_heartbeat_v1"),
|
|
15186
15202
|
contract_version: external_exports.literal(EXTERNAL_INFERENCE_CONTRACT_VERSION),
|
|
@@ -15192,6 +15208,7 @@ var init_external_inference_contract = __esm({
|
|
|
15192
15208
|
status: external_exports.enum(["healthy", "degraded", "draining"]),
|
|
15193
15209
|
active_attempts: nonNegativeSafeIntegerSchema,
|
|
15194
15210
|
available_slots: nonNegativeSafeIntegerSchema,
|
|
15211
|
+
provider_weekly_quota: providerWeeklyQuotaReadSchema.nullable().optional(),
|
|
15195
15212
|
observed_at: timestampSchema
|
|
15196
15213
|
});
|
|
15197
15214
|
jobClaimRequestSchema = external_exports.strictObject({
|
|
@@ -15611,6 +15628,44 @@ var init_external_inference_contract = __esm({
|
|
|
15611
15628
|
cancelled: nonNegativeSafeIntegerSchema,
|
|
15612
15629
|
expired: nonNegativeSafeIntegerSchema
|
|
15613
15630
|
});
|
|
15631
|
+
externalInferenceVolumeWindowReadSchema = external_exports.strictObject({
|
|
15632
|
+
window_seconds: positiveSafeIntegerSchema,
|
|
15633
|
+
requests_started: nonNegativeSafeIntegerSchema,
|
|
15634
|
+
profiles_with_requests: nonNegativeSafeIntegerSchema,
|
|
15635
|
+
attempts_succeeded: nonNegativeSafeIntegerSchema,
|
|
15636
|
+
attempts_failed: nonNegativeSafeIntegerSchema,
|
|
15637
|
+
rate_limited: nonNegativeSafeIntegerSchema,
|
|
15638
|
+
quota_exhausted: nonNegativeSafeIntegerSchema,
|
|
15639
|
+
usage_reported: nonNegativeSafeIntegerSchema,
|
|
15640
|
+
usage_unavailable: nonNegativeSafeIntegerSchema,
|
|
15641
|
+
input_tokens: nonNegativeSafeIntegerSchema,
|
|
15642
|
+
output_tokens: nonNegativeSafeIntegerSchema,
|
|
15643
|
+
total_tokens: nonNegativeSafeIntegerSchema,
|
|
15644
|
+
reasoning_tokens: nonNegativeSafeIntegerSchema,
|
|
15645
|
+
cached_input_tokens: nonNegativeSafeIntegerSchema
|
|
15646
|
+
});
|
|
15647
|
+
externalInferenceFailureCountReadSchema = external_exports.strictObject({
|
|
15648
|
+
failure_category: safeCodeSchema.nullable(),
|
|
15649
|
+
failure_code: safeCodeSchema,
|
|
15650
|
+
count: positiveSafeIntegerSchema,
|
|
15651
|
+
last_observed_at: timestampSchema
|
|
15652
|
+
});
|
|
15653
|
+
externalInferenceHostDiagnosticsReadSchema = external_exports.strictObject({
|
|
15654
|
+
host_id: identifierSchema,
|
|
15655
|
+
active_attempts: nonNegativeSafeIntegerSchema,
|
|
15656
|
+
queue: queueStatusReadSchema,
|
|
15657
|
+
last_second: externalInferenceVolumeWindowReadSchema,
|
|
15658
|
+
last_minute: externalInferenceVolumeWindowReadSchema,
|
|
15659
|
+
last_hour: externalInferenceVolumeWindowReadSchema,
|
|
15660
|
+
last_day: externalInferenceVolumeWindowReadSchema,
|
|
15661
|
+
last_week: externalInferenceVolumeWindowReadSchema,
|
|
15662
|
+
recent_failures: external_exports.array(externalInferenceFailureCountReadSchema).max(32)
|
|
15663
|
+
});
|
|
15664
|
+
externalInferenceProfileActivityReadSchema = external_exports.strictObject({
|
|
15665
|
+
last_hour: externalInferenceVolumeWindowReadSchema,
|
|
15666
|
+
last_day: externalInferenceVolumeWindowReadSchema,
|
|
15667
|
+
last_week: externalInferenceVolumeWindowReadSchema
|
|
15668
|
+
});
|
|
15614
15669
|
externalInferenceStatusReadSchema = external_exports.strictObject({
|
|
15615
15670
|
schema_version: external_exports.literal("external_inference_status_v1"),
|
|
15616
15671
|
contract_version: external_exports.literal(EXTERNAL_INFERENCE_CONTRACT_VERSION),
|
|
@@ -15618,8 +15673,11 @@ var init_external_inference_contract = __esm({
|
|
|
15618
15673
|
catalog_generation: generationSchema,
|
|
15619
15674
|
hosts: external_exports.array(hostStatusReadSchema).max(MAX_EXTERNAL_INFERENCE_STATUS_HOSTS),
|
|
15620
15675
|
bindings: external_exports.array(controllerBindingStatusReadSchema).max(512),
|
|
15676
|
+
binding_count: nonNegativeSafeIntegerSchema.optional().default(0),
|
|
15677
|
+
bindings_truncated: external_exports.boolean().optional().default(false),
|
|
15621
15678
|
queue: queueStatusReadSchema,
|
|
15622
|
-
outcomes: outcomeStatusReadSchema
|
|
15679
|
+
outcomes: outcomeStatusReadSchema,
|
|
15680
|
+
host_diagnostics: external_exports.array(externalInferenceHostDiagnosticsReadSchema).max(MAX_EXTERNAL_INFERENCE_STATUS_HOSTS).optional().default([])
|
|
15623
15681
|
});
|
|
15624
15682
|
nativeResearchEvidenceSourceSchema = external_exports.strictObject({
|
|
15625
15683
|
source: external_exports.literal("native"),
|
|
@@ -16522,14 +16580,12 @@ async function acquireInferenceHostProcessLock(path, dependencies = {}) {
|
|
|
16522
16580
|
}
|
|
16523
16581
|
};
|
|
16524
16582
|
}
|
|
16525
|
-
var INFERENCE_CREDENTIAL_NAMESPACE, MAX_INFERENCE_PRIVATE_FILE_BYTES,
|
|
16583
|
+
var INFERENCE_CREDENTIAL_NAMESPACE, MAX_INFERENCE_PRIVATE_FILE_BYTES, WINDOWS_PRIVATE_ACL_SCRIPT, windowsPrivateAclInvocation, runWindowsPrivateAcl, windowsAclCache, windowsAclIdentity, aclCacheKey, secureWindowsPrivatePath, invalidateWindowsAclCache, rebindHardenedWindowsAclAfterRename, rebindHardenedWindowsDirectoryAfterOwnedMutation, isDefaultWindowsPrivatePath, secureExistingWindowsPath, linuxProcessIdentity, windowsProcessIdentity, darwinProcessIdentity, runSmallIdentityCommand, cachedSystemBootIdentity, readInferenceSystemBootIdentity, defaultProcessIdentity, defaultCurrentProcessIdentity, processLockObservationCache, inferenceProcessIdentitiesMatch, DEFAULT_INFERENCE_HOST_INSTANCE, SAFE_INFERENCE_HOST_INSTANCE, requireNamedInstancePath, credentialStoreIdentity;
|
|
16526
16584
|
var init_config = __esm({
|
|
16527
16585
|
"lib/inference-host/config.ts"() {
|
|
16528
16586
|
"use strict";
|
|
16529
16587
|
INFERENCE_CREDENTIAL_NAMESPACE = "vtxmacro-insights-inference";
|
|
16530
16588
|
MAX_INFERENCE_PRIVATE_FILE_BYTES = 16 * 1024 * 1024;
|
|
16531
|
-
DEFAULT_CODEX_HOST_CONCURRENCY = 3;
|
|
16532
|
-
MAX_CODEX_HOST_CONCURRENCY = 8;
|
|
16533
16589
|
WINDOWS_PRIVATE_ACL_SCRIPT = `$ErrorActionPreference='Stop'
|
|
16534
16590
|
$path=[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String($env:VTX_PRIVATE_PATH_B64))
|
|
16535
16591
|
$kind=$env:VTX_PRIVATE_PATH_KIND
|
|
@@ -19183,6 +19239,7 @@ var init_codex_app_server = __esm({
|
|
|
19183
19239
|
this.httpStatusCode = options.httpStatusCode ?? null;
|
|
19184
19240
|
this.retryAtMs = options.retryAtMs ?? null;
|
|
19185
19241
|
this.usage = options.usage ?? null;
|
|
19242
|
+
this.rateLimits = options.rateLimits ?? null;
|
|
19186
19243
|
}
|
|
19187
19244
|
};
|
|
19188
19245
|
objectOrNull = (value) => value !== null && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
@@ -20694,6 +20751,7 @@ child.once('close', async () => {
|
|
|
20694
20751
|
);
|
|
20695
20752
|
const observedUsage = threadUsage ?? rawResponseUsage;
|
|
20696
20753
|
let retryAtMs = null;
|
|
20754
|
+
let observedRateLimits = null;
|
|
20697
20755
|
if (failure.code === "quota_exceeded" || failure.httpStatusCode === 429) {
|
|
20698
20756
|
const observedAtMs = Date.now();
|
|
20699
20757
|
let accountLimitReached = failure.code === "quota_exceeded";
|
|
@@ -20703,9 +20761,12 @@ child.once('close', async () => {
|
|
|
20703
20761
|
observedAtMs + 5e3
|
|
20704
20762
|
);
|
|
20705
20763
|
if (metadataDeadlineAtMs <= observedAtMs) throw new Error("rate-limit deadline elapsed");
|
|
20706
|
-
|
|
20707
|
-
|
|
20708
|
-
|
|
20764
|
+
observedRateLimits = await this.readAccountRateLimits(
|
|
20765
|
+
metadataDeadlineAtMs,
|
|
20766
|
+
request.signal
|
|
20767
|
+
);
|
|
20768
|
+
accountLimitReached = accountLimitReached || codexAccountRateLimitReached(observedRateLimits);
|
|
20769
|
+
retryAtMs = codexRateLimitRetryAtMs(observedRateLimits);
|
|
20709
20770
|
} catch {
|
|
20710
20771
|
}
|
|
20711
20772
|
if (accountLimitReached) {
|
|
@@ -20735,7 +20796,8 @@ child.once('close', async () => {
|
|
|
20735
20796
|
dispatchOutcome: "confirmed_dispatched",
|
|
20736
20797
|
httpStatusCode: failure.httpStatusCode,
|
|
20737
20798
|
retryAtMs,
|
|
20738
|
-
usage: observedUsage
|
|
20799
|
+
usage: observedUsage,
|
|
20800
|
+
rateLimits: observedRateLimits
|
|
20739
20801
|
});
|
|
20740
20802
|
}
|
|
20741
20803
|
const items = Array.isArray(terminal.items) ? terminal.items.map(objectOrNull) : [];
|
|
@@ -21567,6 +21629,23 @@ var init_codex_adapter = __esm({
|
|
|
21567
21629
|
this.adapterClosePromise = null;
|
|
21568
21630
|
this.dependencies = dependencies;
|
|
21569
21631
|
}
|
|
21632
|
+
async readAccountRateLimits(deadlineAtMs, signal) {
|
|
21633
|
+
const codexHome = this.dependencies.codexHome;
|
|
21634
|
+
if (!codexHome) {
|
|
21635
|
+
throw new CodexAppServerError({
|
|
21636
|
+
message: "Codex home is required to read account rate limits.",
|
|
21637
|
+
category: "adapter",
|
|
21638
|
+
code: "codex_home_required",
|
|
21639
|
+
retryable: false
|
|
21640
|
+
});
|
|
21641
|
+
}
|
|
21642
|
+
const durableSession = await this.acquireDurableSession(
|
|
21643
|
+
codexHome,
|
|
21644
|
+
deadlineAtMs,
|
|
21645
|
+
signal
|
|
21646
|
+
);
|
|
21647
|
+
return await durableSession.session.readAccountRateLimits(deadlineAtMs, signal);
|
|
21648
|
+
}
|
|
21570
21649
|
async startDurableSession(codexHome, deadlineAtMs) {
|
|
21571
21650
|
const binary = await (this.dependencies.resolveBinary ?? resolvePinnedCodexBinary)();
|
|
21572
21651
|
const guardianManaged = Boolean(
|
|
@@ -28742,7 +28821,7 @@ function createDefaultInferenceHostRunnerDependencies(options) {
|
|
|
28742
28821
|
envelopePublicKey: options.envelopePublicKey
|
|
28743
28822
|
};
|
|
28744
28823
|
}
|
|
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,
|
|
28824
|
+
var import_ajv, RUNTIME_RECEIPT_SCHEMA_VERSION, ATTEMPT_RECEIPT_SCHEMA_VERSION, DEFAULT_ADVERTISEMENT_TTL_MS, DEFAULT_ADVERTISEMENT_REFRESH_LEAD_MS, DEFAULT_HOST_HEARTBEAT_MS, DEFAULT_PROVIDER_RATE_LIMIT_REFRESH_MS, DEFAULT_ATTEMPT_HEARTBEAT_MS, DEFAULT_DRAIN_TIMEOUT_MS, DEFAULT_REMOTE_RETRY_LIMIT, MIN_SLEEP_MS, DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS, MIN_CLAIM_START_WINDOW_MS, UNBOUNDED_AVAILABLE_SLOTS, buildCodexInferenceAdvertisedModels, FileInferenceHostRuntimeReceiptStore, InferenceHostRecoveryRequiredError, InferenceHostRunnerError, defaultSleep, abortError, defaultRegisterSignalHandlers, safeInteger, exactObjectKeys, validIso, validateAttemptReceipt, validateRuntimeReceipt, sha256, stableOperationId, buildAttemptStartRequest, isoAt, providerWeeklyQuotaFromRateLimits, finitePositiveOption, validateRunnerOptions, assertLocalCredentialIdentity, retryableRemoteError, remoteRetryAfterMs, controlPlaneFatal, defaultValidateOutput, objectRecord, positiveUtf8ByteLimit, assertCompilableOutputSchema, parseOutputContract, safeFailureCode, exactJson2, runnerIdentityMismatch, assertAdvertisementResult, assertHostHeartbeatResult, assertClaimResult, assertStartResult, assertJobHeartbeatResult, assertTerminalResult, classifyFailure, ambiguousHeartbeatTransport, reportedTokenUsage, reportedUsage, InferenceHostRunner;
|
|
28746
28825
|
var init_runner = __esm({
|
|
28747
28826
|
"lib/inference-host/runner.ts"() {
|
|
28748
28827
|
"use strict";
|
|
@@ -28759,13 +28838,14 @@ var init_runner = __esm({
|
|
|
28759
28838
|
DEFAULT_ADVERTISEMENT_TTL_MS = 12e4;
|
|
28760
28839
|
DEFAULT_ADVERTISEMENT_REFRESH_LEAD_MS = 3e4;
|
|
28761
28840
|
DEFAULT_HOST_HEARTBEAT_MS = 3e3;
|
|
28841
|
+
DEFAULT_PROVIDER_RATE_LIMIT_REFRESH_MS = 6e4;
|
|
28762
28842
|
DEFAULT_ATTEMPT_HEARTBEAT_MS = 3e3;
|
|
28763
28843
|
DEFAULT_DRAIN_TIMEOUT_MS = 3e4;
|
|
28764
28844
|
DEFAULT_REMOTE_RETRY_LIMIT = 3;
|
|
28765
|
-
DEFAULT_MAX_CONCURRENCY = 1;
|
|
28766
28845
|
MIN_SLEEP_MS = 10;
|
|
28767
28846
|
DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS = 5 * 60 * 1e3;
|
|
28768
28847
|
MIN_CLAIM_START_WINDOW_MS = 5e3;
|
|
28848
|
+
UNBOUNDED_AVAILABLE_SLOTS = Number.MAX_SAFE_INTEGER;
|
|
28769
28849
|
buildCodexInferenceAdvertisedModels = (capabilities, adapterRuntimeVersion) => {
|
|
28770
28850
|
const visible = capabilities.filter((capability) => !capability.hidden);
|
|
28771
28851
|
if (visible.length === 0 || visible.length > 64) {
|
|
@@ -29019,6 +29099,19 @@ var init_runner = __esm({
|
|
|
29019
29099
|
started_at: startedAt
|
|
29020
29100
|
});
|
|
29021
29101
|
isoAt = (milliseconds) => new Date(milliseconds).toISOString();
|
|
29102
|
+
providerWeeklyQuotaFromRateLimits = (rateLimits, observedAtMs, currentTimeMs = observedAtMs) => {
|
|
29103
|
+
if (!rateLimits) return null;
|
|
29104
|
+
for (const window2 of [rateLimits.rateLimits.primary, rateLimits.rateLimits.secondary]) {
|
|
29105
|
+
if (window2?.windowDurationMins !== 7 * 24 * 60 || window2.resetsAt === null || window2.resetsAt * 1e3 <= currentTimeMs) continue;
|
|
29106
|
+
return {
|
|
29107
|
+
source: "codex_app_server",
|
|
29108
|
+
used_percent: window2.usedPercent,
|
|
29109
|
+
resets_at: isoAt(window2.resetsAt * 1e3),
|
|
29110
|
+
observed_at: isoAt(observedAtMs)
|
|
29111
|
+
};
|
|
29112
|
+
}
|
|
29113
|
+
return null;
|
|
29114
|
+
};
|
|
29022
29115
|
finitePositiveOption = (value, fallback, label) => {
|
|
29023
29116
|
const result2 = value ?? fallback;
|
|
29024
29117
|
if (!Number.isSafeInteger(result2) || result2 < 1) {
|
|
@@ -29054,20 +29147,7 @@ var init_runner = __esm({
|
|
|
29054
29147
|
options.codexModelCapabilities,
|
|
29055
29148
|
options.adapterRuntimeVersion
|
|
29056
29149
|
),
|
|
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
|
-
})(),
|
|
29150
|
+
maxConcurrency: options.maxConcurrency === null || options.maxConcurrency === void 0 ? null : finitePositiveOption(options.maxConcurrency, 1, "Maximum concurrency"),
|
|
29071
29151
|
advertisementTtlMs,
|
|
29072
29152
|
advertisementRefreshLeadMs,
|
|
29073
29153
|
hostHeartbeatMs: finitePositiveOption(
|
|
@@ -29075,6 +29155,11 @@ var init_runner = __esm({
|
|
|
29075
29155
|
DEFAULT_HOST_HEARTBEAT_MS,
|
|
29076
29156
|
"Host heartbeat interval"
|
|
29077
29157
|
),
|
|
29158
|
+
providerRateLimitRefreshMs: finitePositiveOption(
|
|
29159
|
+
options.providerRateLimitRefreshMs,
|
|
29160
|
+
DEFAULT_PROVIDER_RATE_LIMIT_REFRESH_MS,
|
|
29161
|
+
"Provider rate-limit refresh interval"
|
|
29162
|
+
),
|
|
29078
29163
|
attemptHeartbeatMs: finitePositiveOption(
|
|
29079
29164
|
options.attemptHeartbeatMs,
|
|
29080
29165
|
DEFAULT_ATTEMPT_HEARTBEAT_MS,
|
|
@@ -29405,6 +29490,20 @@ var init_runner = __esm({
|
|
|
29405
29490
|
"Inference host login is required before the runner can start."
|
|
29406
29491
|
);
|
|
29407
29492
|
}
|
|
29493
|
+
const emitDiagnostic = (event, fields = {}) => {
|
|
29494
|
+
try {
|
|
29495
|
+
this.options.emitDiagnosticEvent?.({
|
|
29496
|
+
schema_version: "vtx_inference_host_diagnostic_v1",
|
|
29497
|
+
at: isoAt(now()),
|
|
29498
|
+
event,
|
|
29499
|
+
instance_name: this.options.instanceName ?? "default",
|
|
29500
|
+
host_id: localState.host_id,
|
|
29501
|
+
display_name: this.options.displayName,
|
|
29502
|
+
...fields
|
|
29503
|
+
});
|
|
29504
|
+
} catch {
|
|
29505
|
+
}
|
|
29506
|
+
};
|
|
29408
29507
|
const accountKey = inferenceCredentialAccountKey({
|
|
29409
29508
|
issuer: localState.issuer,
|
|
29410
29509
|
clientId: localState.client_id,
|
|
@@ -29601,6 +29700,10 @@ var init_runner = __esm({
|
|
|
29601
29700
|
if (!wasRegistered && receipt.registered && (!receipt.advertisement_expires_at || Date.parse(receipt.advertisement_expires_at) - now() <= settings.advertisementRefreshLeadMs)) {
|
|
29602
29701
|
await publishAdvertisement("healthy", true);
|
|
29603
29702
|
}
|
|
29703
|
+
let providerRetryAtMs = this.options.codexRateLimits && codexAccountRateLimitReached(this.options.codexRateLimits) ? codexRateLimitRetryAtMs(this.options.codexRateLimits) ?? now() + DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS : null;
|
|
29704
|
+
let providerCooldownReason = providerRetryAtMs === null ? null : "provider_limit_snapshot";
|
|
29705
|
+
let providerRateLimits = this.options.codexRateLimits ?? null;
|
|
29706
|
+
let providerRateLimitsObservedAtMs = now();
|
|
29604
29707
|
const hostHeartbeat = async (status, requestOptions = {
|
|
29605
29708
|
signal: this.options.signal
|
|
29606
29709
|
}, retryRemote = true, allowOfflineProjection = false, definitiveReseedAttempt = 0) => {
|
|
@@ -29615,7 +29718,12 @@ var init_runner = __esm({
|
|
|
29615
29718
|
sequence,
|
|
29616
29719
|
status,
|
|
29617
29720
|
active_attempts: active.size,
|
|
29618
|
-
available_slots: Math.max(0, settings.maxConcurrency - active.size),
|
|
29721
|
+
available_slots: settings.maxConcurrency === null ? UNBOUNDED_AVAILABLE_SLOTS - active.size : Math.max(0, settings.maxConcurrency - active.size),
|
|
29722
|
+
provider_weekly_quota: providerWeeklyQuotaFromRateLimits(
|
|
29723
|
+
providerRateLimits,
|
|
29724
|
+
providerRateLimitsObservedAtMs,
|
|
29725
|
+
now()
|
|
29726
|
+
),
|
|
29619
29727
|
observed_at: isoAt(now())
|
|
29620
29728
|
};
|
|
29621
29729
|
receipt = {
|
|
@@ -29657,10 +29765,21 @@ var init_runner = __esm({
|
|
|
29657
29765
|
await hostHeartbeat("healthy");
|
|
29658
29766
|
let nextHostHeartbeatAt = now() + settings.hostHeartbeatMs;
|
|
29659
29767
|
let nextAdvertisementAttemptAt = 0;
|
|
29660
|
-
let
|
|
29768
|
+
let nextProviderRateLimitRefreshAt = now() + settings.providerRateLimitRefreshMs;
|
|
29661
29769
|
let nextClaimAt = Math.max(now(), providerRetryAtMs ?? 0);
|
|
29662
29770
|
let pendingClaimPromotions = 0;
|
|
29663
29771
|
let onceClaimed = false;
|
|
29772
|
+
emitDiagnostic("runtime_started", {
|
|
29773
|
+
max_concurrency: settings.maxConcurrency,
|
|
29774
|
+
active_attempts: active.size,
|
|
29775
|
+
provider_cooldown_reason: providerCooldownReason,
|
|
29776
|
+
provider_cooldown_until: providerRetryAtMs === null ? null : isoAt(providerRetryAtMs),
|
|
29777
|
+
provider_weekly_quota: providerWeeklyQuotaFromRateLimits(
|
|
29778
|
+
providerRateLimits,
|
|
29779
|
+
providerRateLimitsObservedAtMs,
|
|
29780
|
+
now()
|
|
29781
|
+
)
|
|
29782
|
+
});
|
|
29664
29783
|
const launchClaim = (claim, recovery, claimRequest) => {
|
|
29665
29784
|
if (!recovery) {
|
|
29666
29785
|
claimed += 1;
|
|
@@ -29704,10 +29823,37 @@ var init_runner = __esm({
|
|
|
29704
29823
|
attemptHeartbeatMs: settings.attemptHeartbeatMs,
|
|
29705
29824
|
sleep: sleep4,
|
|
29706
29825
|
now,
|
|
29707
|
-
onProviderCooldown: (retryAtMs) => {
|
|
29826
|
+
onProviderCooldown: ({ retryAtMs, reason, rateLimits }) => {
|
|
29708
29827
|
if (!Number.isSafeInteger(retryAtMs) || retryAtMs <= now()) return;
|
|
29828
|
+
const priorRetryAtMs = providerRetryAtMs;
|
|
29709
29829
|
providerRetryAtMs = Math.max(providerRetryAtMs ?? 0, retryAtMs);
|
|
29710
29830
|
nextClaimAt = Math.max(nextClaimAt, providerRetryAtMs);
|
|
29831
|
+
providerCooldownReason = reason;
|
|
29832
|
+
if (rateLimits) {
|
|
29833
|
+
providerRateLimits = rateLimits;
|
|
29834
|
+
providerRateLimitsObservedAtMs = now();
|
|
29835
|
+
}
|
|
29836
|
+
emitDiagnostic(
|
|
29837
|
+
priorRetryAtMs === null ? "provider_cooldown_started" : "provider_cooldown_extended",
|
|
29838
|
+
{
|
|
29839
|
+
reason,
|
|
29840
|
+
cooldown_until: isoAt(providerRetryAtMs),
|
|
29841
|
+
active_attempts: active.size,
|
|
29842
|
+
provider_weekly_quota: providerWeeklyQuotaFromRateLimits(
|
|
29843
|
+
providerRateLimits,
|
|
29844
|
+
providerRateLimitsObservedAtMs,
|
|
29845
|
+
now()
|
|
29846
|
+
)
|
|
29847
|
+
}
|
|
29848
|
+
);
|
|
29849
|
+
},
|
|
29850
|
+
onAttemptOutcome: (outcome) => {
|
|
29851
|
+
emitDiagnostic("attempt_finished", {
|
|
29852
|
+
...outcome,
|
|
29853
|
+
job_id: claim.job_id,
|
|
29854
|
+
attempt_id: attemptId,
|
|
29855
|
+
active_attempts: active.size
|
|
29856
|
+
});
|
|
29711
29857
|
},
|
|
29712
29858
|
resumeReceipt: recovery,
|
|
29713
29859
|
claimRequest,
|
|
@@ -29724,6 +29870,14 @@ var init_runner = __esm({
|
|
|
29724
29870
|
attemptControllers.delete(attemptId);
|
|
29725
29871
|
});
|
|
29726
29872
|
active.set(attemptId, promise2);
|
|
29873
|
+
emitDiagnostic("attempt_started", {
|
|
29874
|
+
job_id: claim.job_id,
|
|
29875
|
+
attempt_id: attemptId,
|
|
29876
|
+
attempt_index: claim.attempt_index,
|
|
29877
|
+
requested_model: claim.requested_model,
|
|
29878
|
+
requested_reasoning_effort: claim.requested_reasoning_effort,
|
|
29879
|
+
active_attempts: active.size
|
|
29880
|
+
});
|
|
29727
29881
|
return attemptId;
|
|
29728
29882
|
};
|
|
29729
29883
|
const removeRecoveredAttempt = async (attemptId) => {
|
|
@@ -29764,12 +29918,56 @@ var init_runner = __esm({
|
|
|
29764
29918
|
}
|
|
29765
29919
|
recoveryQueue.push(recovery);
|
|
29766
29920
|
}
|
|
29767
|
-
while (!drainRequested && recoveryQueue.length > 0 && active.size < settings.maxConcurrency) {
|
|
29921
|
+
while (!drainRequested && recoveryQueue.length > 0 && (settings.maxConcurrency === null || active.size < settings.maxConcurrency)) {
|
|
29768
29922
|
const recovery = recoveryQueue.shift();
|
|
29769
29923
|
launchClaim(recovery.claim, recovery);
|
|
29770
29924
|
}
|
|
29771
29925
|
while (!drainRequested) {
|
|
29772
29926
|
const currentTime = now();
|
|
29927
|
+
if (providerRetryAtMs !== null && currentTime >= providerRetryAtMs && providerCooldownReason !== null) {
|
|
29928
|
+
emitDiagnostic("provider_cooldown_cleared", {
|
|
29929
|
+
reason: providerCooldownReason,
|
|
29930
|
+
active_attempts: active.size,
|
|
29931
|
+
provider_weekly_quota: providerWeeklyQuotaFromRateLimits(
|
|
29932
|
+
providerRateLimits,
|
|
29933
|
+
providerRateLimitsObservedAtMs,
|
|
29934
|
+
currentTime
|
|
29935
|
+
)
|
|
29936
|
+
});
|
|
29937
|
+
providerRetryAtMs = null;
|
|
29938
|
+
providerCooldownReason = null;
|
|
29939
|
+
nextClaimAt = Math.min(nextClaimAt, currentTime);
|
|
29940
|
+
}
|
|
29941
|
+
if (this.dependencies.codexAdapter.readAccountRateLimits && currentTime >= nextProviderRateLimitRefreshAt) {
|
|
29942
|
+
try {
|
|
29943
|
+
providerRateLimits = await this.dependencies.codexAdapter.readAccountRateLimits(
|
|
29944
|
+
Date.now() + Math.min(2e3, settings.hostHeartbeatMs),
|
|
29945
|
+
this.options.signal
|
|
29946
|
+
);
|
|
29947
|
+
providerRateLimitsObservedAtMs = now();
|
|
29948
|
+
const refreshedRetryAt = codexAccountRateLimitReached(providerRateLimits) ? codexRateLimitRetryAtMs(providerRateLimits) ?? currentTime + DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS : null;
|
|
29949
|
+
if (refreshedRetryAt !== null && refreshedRetryAt > currentTime) {
|
|
29950
|
+
providerRetryAtMs = Math.max(providerRetryAtMs ?? 0, refreshedRetryAt);
|
|
29951
|
+
providerCooldownReason = "provider_limit_snapshot";
|
|
29952
|
+
nextClaimAt = Math.max(nextClaimAt, providerRetryAtMs);
|
|
29953
|
+
}
|
|
29954
|
+
emitDiagnostic("provider_rate_limits_refreshed", {
|
|
29955
|
+
provider_weekly_quota: providerWeeklyQuotaFromRateLimits(
|
|
29956
|
+
providerRateLimits,
|
|
29957
|
+
providerRateLimitsObservedAtMs,
|
|
29958
|
+
now()
|
|
29959
|
+
),
|
|
29960
|
+
active_attempts: active.size
|
|
29961
|
+
});
|
|
29962
|
+
} catch (error48) {
|
|
29963
|
+
emitDiagnostic("provider_rate_limits_refresh_failed", {
|
|
29964
|
+
failure_category: error48 instanceof CodexAppServerError ? error48.category : "adapter",
|
|
29965
|
+
failure_code: error48 instanceof CodexAppServerError ? error48.code : "provider_rate_limits_refresh_failed"
|
|
29966
|
+
});
|
|
29967
|
+
} finally {
|
|
29968
|
+
nextProviderRateLimitRefreshAt = now() + settings.providerRateLimitRefreshMs;
|
|
29969
|
+
}
|
|
29970
|
+
}
|
|
29773
29971
|
const expiresAt = receipt.advertisement_expires_at ? Date.parse(receipt.advertisement_expires_at) : 0;
|
|
29774
29972
|
if (currentTime >= nextAdvertisementAttemptAt && expiresAt - currentTime <= settings.advertisementRefreshLeadMs) {
|
|
29775
29973
|
try {
|
|
@@ -29812,11 +30010,11 @@ var init_runner = __esm({
|
|
|
29812
30010
|
nextHostHeartbeatAt = now() + settings.hostHeartbeatMs;
|
|
29813
30011
|
}
|
|
29814
30012
|
}
|
|
29815
|
-
while (recoveryQueue.length > 0 && active.size < settings.maxConcurrency) {
|
|
30013
|
+
while (recoveryQueue.length > 0 && (settings.maxConcurrency === null || active.size < settings.maxConcurrency)) {
|
|
29816
30014
|
const recovery = recoveryQueue.shift();
|
|
29817
30015
|
launchClaim(recovery.claim, recovery);
|
|
29818
30016
|
}
|
|
29819
|
-
while (!drainRequested && recoveryQueue.length === 0 && (!this.options.once || !onceClaimed) && active.size < settings.maxConcurrency && pendingClaimPromotions === 0 && now() >= nextClaimAt) {
|
|
30017
|
+
while (!drainRequested && recoveryQueue.length === 0 && (!this.options.once || !onceClaimed) && (settings.maxConcurrency === null || active.size < settings.maxConcurrency) && pendingClaimPromotions === 0 && now() >= nextClaimAt) {
|
|
29820
30018
|
if (!receipt.pending_claim_request) {
|
|
29821
30019
|
const claimSequence = receipt.claim_sequence + 1;
|
|
29822
30020
|
const pendingClaimRequest = {
|
|
@@ -29935,6 +30133,13 @@ var init_runner = __esm({
|
|
|
29935
30133
|
requestDrain("drain_timeout");
|
|
29936
30134
|
}
|
|
29937
30135
|
}
|
|
30136
|
+
emitDiagnostic("runtime_stopped", {
|
|
30137
|
+
claimed,
|
|
30138
|
+
completed,
|
|
30139
|
+
failed,
|
|
30140
|
+
drain_reason: drainReason,
|
|
30141
|
+
active_attempts: active.size
|
|
30142
|
+
});
|
|
29938
30143
|
return { claimed, completed, failed, drain_reason: drainReason };
|
|
29939
30144
|
} finally {
|
|
29940
30145
|
removeAbortListener();
|
|
@@ -30280,13 +30485,27 @@ var init_runner = __esm({
|
|
|
30280
30485
|
);
|
|
30281
30486
|
}
|
|
30282
30487
|
await removeAttempt();
|
|
30488
|
+
options.onAttemptOutcome?.({
|
|
30489
|
+
outcome: "completed",
|
|
30490
|
+
failure_category: null,
|
|
30491
|
+
failure_code: null,
|
|
30492
|
+
retryable: null,
|
|
30493
|
+
dispatch_outcome: completion.outcome.dispatch_outcome,
|
|
30494
|
+
response_outcome: completion.outcome.response_outcome,
|
|
30495
|
+
latency_ms: completion.latency_ms,
|
|
30496
|
+
usage: completion.usage
|
|
30497
|
+
});
|
|
30283
30498
|
return "completed";
|
|
30284
30499
|
} catch (error48) {
|
|
30285
30500
|
if (error48 instanceof InferenceHostRunnerError && error48.code === "terminal_outcome_unconfirmed") {
|
|
30286
30501
|
throw error48;
|
|
30287
30502
|
}
|
|
30288
30503
|
if (error48 instanceof CodexAppServerError && error48.retryAtMs !== null && ["quota_exceeded", "codex_rate_limited"].includes(error48.code)) {
|
|
30289
|
-
options.onProviderCooldown?.(
|
|
30504
|
+
options.onProviderCooldown?.({
|
|
30505
|
+
retryAtMs: error48.retryAtMs,
|
|
30506
|
+
reason: error48.code === "quota_exceeded" ? "quota_exceeded" : "codex_rate_limited",
|
|
30507
|
+
rateLimits: error48.rateLimits
|
|
30508
|
+
});
|
|
30290
30509
|
}
|
|
30291
30510
|
const classified = classifyFailure(heartbeatFailure ?? error48, adapterResult);
|
|
30292
30511
|
const heartbeatAmbiguous = ambiguousHeartbeatTransport(heartbeatFailure);
|
|
@@ -30366,6 +30585,16 @@ var init_runner = __esm({
|
|
|
30366
30585
|
);
|
|
30367
30586
|
}
|
|
30368
30587
|
await removeAttempt();
|
|
30588
|
+
options.onAttemptOutcome?.({
|
|
30589
|
+
outcome: "failed",
|
|
30590
|
+
failure_category: failureRequest.failure_category,
|
|
30591
|
+
failure_code: failureRequest.failure_code,
|
|
30592
|
+
retryable: failureRequest.retryable,
|
|
30593
|
+
dispatch_outcome: failureRequest.outcome.dispatch_outcome,
|
|
30594
|
+
response_outcome: failureRequest.outcome.response_outcome,
|
|
30595
|
+
latency_ms: adapterResult?.latencyMs ?? null,
|
|
30596
|
+
usage: failureRequest.usage
|
|
30597
|
+
});
|
|
30369
30598
|
return "failed";
|
|
30370
30599
|
} finally {
|
|
30371
30600
|
heartbeatStopped = true;
|
|
@@ -30406,7 +30635,7 @@ import { createWriteStream, readFileSync } from "node:fs";
|
|
|
30406
30635
|
import { access as access3, chmod as chmod3, mkdir as mkdir3, readFile as readFile5, rm as rm4, writeFile as writeFile2 } from "node:fs/promises";
|
|
30407
30636
|
import { homedir as homedir2 } from "node:os";
|
|
30408
30637
|
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;
|
|
30638
|
+
var SERVICE_NAME, SYSTEMD_UNIT, LAUNCHD_LABEL, SERVICE_COOPERATIVE_STOP_SECONDS, inferenceHostServiceChildEnvironment, isWindowsSubsystemForLinux, inferenceHostServiceManifestPath, inferenceHostServiceDesiredPath, inferenceHostServiceLogPath, xmlEscape, plistEscape, systemdQuote, defaultRunCommand, managerName, assertRuntimeEnvironment, withoutConcurrencyLimit, assertServicePath, assertWorker, assertManifest, assertDesiredState, readInferenceHostServiceManifest, readInferenceHostServiceDesired, readDesiredAcrossAtomicReplacement, writeDesired, runtimeEnvironment, serviceArguments, windowsOwnedCommandLine, vbScriptString, windowsServiceLauncher, windowsTaskXml, systemdUnit, launchAgentPlist, InferenceHostServiceManager, appendServiceLog, spawnServiceChild, runInferenceHostServiceSupervisor;
|
|
30410
30639
|
var init_service = __esm({
|
|
30411
30640
|
"lib/inference-host/service.ts"() {
|
|
30412
30641
|
"use strict";
|
|
@@ -30415,6 +30644,15 @@ var init_service = __esm({
|
|
|
30415
30644
|
SYSTEMD_UNIT = "vtx-inference-host.service";
|
|
30416
30645
|
LAUNCHD_LABEL = "com.vtxmacro.inference-host";
|
|
30417
30646
|
SERVICE_COOPERATIVE_STOP_SECONDS = 75;
|
|
30647
|
+
inferenceHostServiceChildEnvironment = (runtimeEnvironment2, inheritedEnvironment = process.env) => {
|
|
30648
|
+
const environment = { ...inheritedEnvironment };
|
|
30649
|
+
for (const key of Object.keys(environment)) {
|
|
30650
|
+
if (key === "VTX_API_URL" || key.startsWith("VTX_INFERENCE_HOST_")) {
|
|
30651
|
+
delete environment[key];
|
|
30652
|
+
}
|
|
30653
|
+
}
|
|
30654
|
+
return { ...environment, ...runtimeEnvironment2 };
|
|
30655
|
+
};
|
|
30418
30656
|
isWindowsSubsystemForLinux = (env = process.env, kernelRelease) => Boolean(
|
|
30419
30657
|
String(env.WSL_INTEROP || "").trim() || String(env.WSL_DISTRO_NAME || "").trim() || /microsoft/iu.test(kernelRelease ?? (() => {
|
|
30420
30658
|
try {
|
|
@@ -30467,6 +30705,10 @@ var init_service = __esm({
|
|
|
30467
30705
|
}
|
|
30468
30706
|
return value;
|
|
30469
30707
|
};
|
|
30708
|
+
withoutConcurrencyLimit = (environment) => {
|
|
30709
|
+
const { VTX_INFERENCE_HOST_MAX_CONCURRENCY: _removed, ...rest } = environment;
|
|
30710
|
+
return rest;
|
|
30711
|
+
};
|
|
30470
30712
|
assertServicePath = (value) => {
|
|
30471
30713
|
if (typeof value !== "string" || !value || /[\r\n\0]/u.test(value)) {
|
|
30472
30714
|
throw new Error("Inference-host service manifest paths contain control characters.");
|
|
@@ -30478,14 +30720,14 @@ var init_service = __esm({
|
|
|
30478
30720
|
throw new Error("Inference-host service worker is invalid.");
|
|
30479
30721
|
}
|
|
30480
30722
|
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
|
|
30723
|
+
if (typeof record2.instance_name !== "string" || !/^[a-z0-9](?:[a-z0-9-]{0,46}[a-z0-9])?$/u.test(record2.instance_name) || record2.adapter !== "codex" || typeof record2.display_name !== "string" || !record2.display_name || record2.max_concurrency !== null && (!Number.isSafeInteger(record2.max_concurrency) || Number(record2.max_concurrency) < 1) || record2.authenticated_account_email !== null && typeof record2.authenticated_account_email !== "string" || record2.authenticated_account_plan !== null && typeof record2.authenticated_account_plan !== "string") {
|
|
30482
30724
|
throw new Error("Inference-host service worker is invalid.");
|
|
30483
30725
|
}
|
|
30484
30726
|
return {
|
|
30485
30727
|
instance_name: record2.instance_name,
|
|
30486
30728
|
adapter: "codex",
|
|
30487
30729
|
display_name: record2.display_name,
|
|
30488
|
-
max_concurrency: Number(record2.max_concurrency),
|
|
30730
|
+
max_concurrency: record2.max_concurrency === null ? null : Number(record2.max_concurrency),
|
|
30489
30731
|
authenticated_account_email: record2.authenticated_account_email,
|
|
30490
30732
|
authenticated_account_plan: record2.authenticated_account_plan,
|
|
30491
30733
|
runtime_environment: assertRuntimeEnvironment(record2.runtime_environment)
|
|
@@ -30499,18 +30741,20 @@ var init_service = __esm({
|
|
|
30499
30741
|
if (record2.schema_version === "vtx_inference_service_v1") {
|
|
30500
30742
|
const legacy = record2;
|
|
30501
30743
|
if (legacy.adapter !== "codex" || typeof legacy.installed_at !== "string" || !Number.isFinite(Date.parse(legacy.installed_at)) || typeof legacy.executable !== "string" || !legacy.executable || typeof legacy.script !== "string" || !legacy.script || typeof legacy.display_name !== "string" || !legacy.display_name || typeof legacy.log_path !== "string" || !legacy.log_path) throw new Error("Inference-host service manifest is invalid.");
|
|
30502
|
-
const runtime_environment =
|
|
30744
|
+
const runtime_environment = withoutConcurrencyLimit(
|
|
30745
|
+
assertRuntimeEnvironment(legacy.runtime_environment)
|
|
30746
|
+
);
|
|
30503
30747
|
const worker = assertWorker({
|
|
30504
30748
|
instance_name: "default",
|
|
30505
30749
|
adapter: "codex",
|
|
30506
30750
|
display_name: legacy.display_name,
|
|
30507
|
-
max_concurrency:
|
|
30751
|
+
max_concurrency: null,
|
|
30508
30752
|
authenticated_account_email: null,
|
|
30509
30753
|
authenticated_account_plan: null,
|
|
30510
30754
|
runtime_environment
|
|
30511
30755
|
});
|
|
30512
30756
|
return {
|
|
30513
|
-
schema_version: "
|
|
30757
|
+
schema_version: "vtx_inference_service_v3",
|
|
30514
30758
|
installed_at: legacy.installed_at,
|
|
30515
30759
|
executable: assertServicePath(legacy.executable),
|
|
30516
30760
|
script: assertServicePath(legacy.script),
|
|
@@ -30518,7 +30762,40 @@ var init_service = __esm({
|
|
|
30518
30762
|
workers: [worker]
|
|
30519
30763
|
};
|
|
30520
30764
|
}
|
|
30521
|
-
if (record2.schema_version
|
|
30765
|
+
if (record2.schema_version === "vtx_inference_service_v2") {
|
|
30766
|
+
const legacy = record2;
|
|
30767
|
+
if (typeof legacy.installed_at !== "string" || !Number.isFinite(Date.parse(legacy.installed_at)) || typeof legacy.executable !== "string" || !legacy.executable || typeof legacy.script !== "string" || !legacy.script || typeof legacy.log_path !== "string" || !legacy.log_path || !Array.isArray(legacy.workers) || legacy.workers.length < 1) {
|
|
30768
|
+
throw new Error("Inference-host service manifest is invalid.");
|
|
30769
|
+
}
|
|
30770
|
+
const workers2 = legacy.workers.map((worker) => {
|
|
30771
|
+
if (!worker || typeof worker !== "object" || Array.isArray(worker)) {
|
|
30772
|
+
throw new Error("Inference-host service worker is invalid.");
|
|
30773
|
+
}
|
|
30774
|
+
const legacyWorker = worker;
|
|
30775
|
+
if (!Number.isSafeInteger(legacyWorker.max_concurrency) || Number(legacyWorker.max_concurrency) < 1) {
|
|
30776
|
+
throw new Error("Inference-host service worker is invalid.");
|
|
30777
|
+
}
|
|
30778
|
+
return assertWorker({
|
|
30779
|
+
...legacyWorker,
|
|
30780
|
+
max_concurrency: null,
|
|
30781
|
+
runtime_environment: withoutConcurrencyLimit(
|
|
30782
|
+
assertRuntimeEnvironment(legacyWorker.runtime_environment)
|
|
30783
|
+
)
|
|
30784
|
+
});
|
|
30785
|
+
});
|
|
30786
|
+
if (new Set(workers2.map((worker) => worker.instance_name)).size !== workers2.length) {
|
|
30787
|
+
throw new Error("Inference-host service worker names must be unique.");
|
|
30788
|
+
}
|
|
30789
|
+
return {
|
|
30790
|
+
schema_version: "vtx_inference_service_v3",
|
|
30791
|
+
installed_at: legacy.installed_at,
|
|
30792
|
+
executable: assertServicePath(legacy.executable),
|
|
30793
|
+
script: assertServicePath(legacy.script),
|
|
30794
|
+
log_path: assertServicePath(legacy.log_path),
|
|
30795
|
+
workers: workers2
|
|
30796
|
+
};
|
|
30797
|
+
}
|
|
30798
|
+
if (record2.schema_version !== "vtx_inference_service_v3" || typeof record2.installed_at !== "string" || !Number.isFinite(Date.parse(record2.installed_at)) || typeof record2.executable !== "string" || !record2.executable || typeof record2.script !== "string" || !record2.script || typeof record2.log_path !== "string" || !record2.log_path || !Array.isArray(record2.workers) || record2.workers.length < 1) {
|
|
30522
30799
|
throw new Error("Inference-host service manifest is invalid.");
|
|
30523
30800
|
}
|
|
30524
30801
|
assertServicePath(record2.executable);
|
|
@@ -30587,9 +30864,11 @@ var init_service = __esm({
|
|
|
30587
30864
|
VTX_INFERENCE_HOST_INSTANCE: config2.instanceName,
|
|
30588
30865
|
VTX_INFERENCE_HOST_CREDENTIAL_STORE: config2.credentialStoreMode,
|
|
30589
30866
|
VTX_INFERENCE_HOST_STATE_PATH: config2.statePath,
|
|
30590
|
-
VTX_INFERENCE_HOST_LOCK_PATH: config2.processLockPath
|
|
30591
|
-
VTX_INFERENCE_HOST_MAX_CONCURRENCY: String(maxConcurrency)
|
|
30867
|
+
VTX_INFERENCE_HOST_LOCK_PATH: config2.processLockPath
|
|
30592
30868
|
};
|
|
30869
|
+
if (maxConcurrency !== null) {
|
|
30870
|
+
result2.VTX_INFERENCE_HOST_MAX_CONCURRENCY = String(maxConcurrency);
|
|
30871
|
+
}
|
|
30593
30872
|
if (config2.credentialFilePath) {
|
|
30594
30873
|
result2.VTX_INFERENCE_HOST_CREDENTIAL_FILE = config2.credentialFilePath;
|
|
30595
30874
|
}
|
|
@@ -30905,7 +31184,7 @@ ${cleanup.stderr}`)) {
|
|
|
30905
31184
|
}
|
|
30906
31185
|
await access3(this.executable);
|
|
30907
31186
|
await access3(this.script);
|
|
30908
|
-
const maxConcurrency = options.maxConcurrency ??
|
|
31187
|
+
const maxConcurrency = options.maxConcurrency ?? null;
|
|
30909
31188
|
const workers = [
|
|
30910
31189
|
...existing?.workers.filter((worker) => worker.instance_name !== this.config.instanceName) ?? [],
|
|
30911
31190
|
{
|
|
@@ -30919,7 +31198,7 @@ ${cleanup.stderr}`)) {
|
|
|
30919
31198
|
}
|
|
30920
31199
|
].sort((left, right) => left.instance_name.localeCompare(right.instance_name));
|
|
30921
31200
|
const manifest = assertManifest({
|
|
30922
|
-
schema_version: "
|
|
31201
|
+
schema_version: "vtx_inference_service_v3",
|
|
30923
31202
|
installed_at: this.now().toISOString(),
|
|
30924
31203
|
executable: this.executable,
|
|
30925
31204
|
script: this.script,
|
|
@@ -31016,13 +31295,22 @@ ${result2.stderr}`)) {
|
|
|
31016
31295
|
})) ?? []
|
|
31017
31296
|
};
|
|
31018
31297
|
}
|
|
31019
|
-
async logs(lines = 100) {
|
|
31298
|
+
async logs(lines = 100, instanceName) {
|
|
31020
31299
|
const manifest = await readInferenceHostServiceManifest(this.manifestPath());
|
|
31021
31300
|
const path = manifest?.log_path ?? this.logPath();
|
|
31022
31301
|
try {
|
|
31023
31302
|
const contents = await readFile5(path, "utf8");
|
|
31024
|
-
|
|
31025
|
-
|
|
31303
|
+
const logLines = contents.trimEnd().split(/\r?\n/u);
|
|
31304
|
+
const filtered = instanceName ? logLines.filter((line) => {
|
|
31305
|
+
try {
|
|
31306
|
+
const parsed = JSON.parse(line);
|
|
31307
|
+
return parsed.instance_name === instanceName || Array.isArray(parsed.instances) && parsed.instances.includes(instanceName);
|
|
31308
|
+
} catch {
|
|
31309
|
+
return false;
|
|
31310
|
+
}
|
|
31311
|
+
}) : logLines;
|
|
31312
|
+
return filtered.length > 0 ? `${filtered.slice(-lines).join("\n")}
|
|
31313
|
+
` : "";
|
|
31026
31314
|
} catch (error48) {
|
|
31027
31315
|
if (error48.code === "ENOENT") return "";
|
|
31028
31316
|
throw error48;
|
|
@@ -31102,26 +31390,61 @@ ${result2.stderr}`)) {
|
|
|
31102
31390
|
const log = createWriteStream(manifest.log_path, { flags: "a", mode: 384 });
|
|
31103
31391
|
return await new Promise((resolvePromise, reject) => {
|
|
31104
31392
|
let stdout = "";
|
|
31393
|
+
const pending = { stdout: "", stderr: "" };
|
|
31394
|
+
const writeTaggedOutput = (stream, text, flush = false) => {
|
|
31395
|
+
const lines = `${pending[stream]}${text}`.split(/\r?\n/u);
|
|
31396
|
+
const remainder = lines.pop() ?? "";
|
|
31397
|
+
pending[stream] = flush ? "" : remainder;
|
|
31398
|
+
if (flush && remainder) lines.push(remainder);
|
|
31399
|
+
if (flush && lines.at(-1) === "") lines.pop();
|
|
31400
|
+
for (const line of lines) {
|
|
31401
|
+
if (!line) continue;
|
|
31402
|
+
try {
|
|
31403
|
+
const parsed = JSON.parse(line);
|
|
31404
|
+
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
31405
|
+
log.write(`${JSON.stringify({
|
|
31406
|
+
...parsed,
|
|
31407
|
+
instance_name: worker.instance_name
|
|
31408
|
+
})}
|
|
31409
|
+
`);
|
|
31410
|
+
continue;
|
|
31411
|
+
}
|
|
31412
|
+
} catch {
|
|
31413
|
+
}
|
|
31414
|
+
log.write(`${JSON.stringify({
|
|
31415
|
+
at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
31416
|
+
event: "worker_output",
|
|
31417
|
+
instance_name: worker.instance_name,
|
|
31418
|
+
stream,
|
|
31419
|
+
message: line.slice(0, 4096)
|
|
31420
|
+
})}
|
|
31421
|
+
`);
|
|
31422
|
+
}
|
|
31423
|
+
};
|
|
31105
31424
|
const child = spawn5(manifest.executable, args, {
|
|
31106
|
-
env:
|
|
31425
|
+
env: inferenceHostServiceChildEnvironment(worker.runtime_environment),
|
|
31107
31426
|
windowsHide: true,
|
|
31108
31427
|
stdio: ["ignore", "pipe", "pipe"]
|
|
31109
31428
|
});
|
|
31110
31429
|
child.stdout.on("data", (chunk) => {
|
|
31111
31430
|
const text = chunk.toString("utf8");
|
|
31112
|
-
|
|
31431
|
+
writeTaggedOutput("stdout", text);
|
|
31113
31432
|
stdout = `${stdout}${text}`.slice(-65536);
|
|
31114
31433
|
});
|
|
31115
|
-
child.stderr.on("data", (chunk) =>
|
|
31434
|
+
child.stderr.on("data", (chunk) => writeTaggedOutput("stderr", chunk.toString("utf8")));
|
|
31116
31435
|
const onAbort = () => child.kill("SIGTERM");
|
|
31117
31436
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
31118
31437
|
child.once("error", (error48) => {
|
|
31119
31438
|
signal.removeEventListener("abort", onAbort);
|
|
31439
|
+
writeTaggedOutput("stdout", "", true);
|
|
31440
|
+
writeTaggedOutput("stderr", "", true);
|
|
31120
31441
|
log.end();
|
|
31121
31442
|
reject(error48);
|
|
31122
31443
|
});
|
|
31123
31444
|
child.once("exit", (code) => {
|
|
31124
31445
|
signal.removeEventListener("abort", onAbort);
|
|
31446
|
+
writeTaggedOutput("stdout", "", true);
|
|
31447
|
+
writeTaggedOutput("stderr", "", true);
|
|
31125
31448
|
log.end();
|
|
31126
31449
|
let drainReason = null;
|
|
31127
31450
|
for (const line of stdout.trim().split("\n").reverse()) {
|
|
@@ -31407,7 +31730,7 @@ Commands:
|
|
|
31407
31730
|
Common options:
|
|
31408
31731
|
--json Emit machine-readable JSON
|
|
31409
31732
|
--instance NAME Target an isolated local subscription instance (default: default)
|
|
31410
|
-
--max-concurrency N
|
|
31733
|
+
--max-concurrency N Optional positive-integer Codex slot limit (default: unlimited)
|
|
31411
31734
|
--help, -h Show this help
|
|
31412
31735
|
|
|
31413
31736
|
If the OS credential store cannot retain the VTX grant, set
|
|
@@ -31426,18 +31749,16 @@ Durable service:
|
|
|
31426
31749
|
`;
|
|
31427
31750
|
parseHostConcurrency = (raw, label) => {
|
|
31428
31751
|
const value = Number(raw);
|
|
31429
|
-
if (!Number.isSafeInteger(value) || value < 1
|
|
31430
|
-
throw new Error(`${label} must be
|
|
31752
|
+
if (!Number.isSafeInteger(value) || value < 1) {
|
|
31753
|
+
throw new Error(`${label} must be a positive safe integer.`);
|
|
31431
31754
|
}
|
|
31432
31755
|
return value;
|
|
31433
31756
|
};
|
|
31434
31757
|
parseInferenceHostArgs = (argv2, env) => {
|
|
31435
31758
|
let json2 = String(env.VTX_OUTPUT_JSON || "").trim().toLowerCase() === "true";
|
|
31436
31759
|
let once = false;
|
|
31437
|
-
|
|
31438
|
-
|
|
31439
|
-
"VTX_INFERENCE_HOST_MAX_CONCURRENCY"
|
|
31440
|
-
);
|
|
31760
|
+
const configuredConcurrency = String(env.VTX_INFERENCE_HOST_MAX_CONCURRENCY || "").trim();
|
|
31761
|
+
let maxConcurrency = configuredConcurrency ? parseHostConcurrency(configuredConcurrency, "VTX_INFERENCE_HOST_MAX_CONCURRENCY") : null;
|
|
31441
31762
|
let instanceName = String(env.VTX_INFERENCE_HOST_INSTANCE || "default").trim();
|
|
31442
31763
|
let instanceExplicit = Boolean(String(env.VTX_INFERENCE_HOST_INSTANCE || "").trim());
|
|
31443
31764
|
let displayName = String(env.VTX_INFERENCE_HOST_DISPLAY_NAME || "").trim() || "Codex subscription host";
|
|
@@ -31693,6 +32014,7 @@ Durable service:
|
|
|
31693
32014
|
...dependencies,
|
|
31694
32015
|
acquireProcessLock: async () => borrowedProcessLock
|
|
31695
32016
|
}, {
|
|
32017
|
+
instanceName: options.config.instanceName,
|
|
31696
32018
|
displayName: options.displayName,
|
|
31697
32019
|
authenticatedAccountEmail: options.authenticatedAccountEmail,
|
|
31698
32020
|
authenticatedAccountPlan: options.authenticatedAccountPlan,
|
|
@@ -31702,6 +32024,7 @@ Durable service:
|
|
|
31702
32024
|
adapterRuntimeVersion: INFERENCE_HOST_CLI_VERSION,
|
|
31703
32025
|
maxConcurrency: options.maxConcurrency,
|
|
31704
32026
|
once: options.once,
|
|
32027
|
+
emitDiagnosticEvent: options.emitDiagnosticEvent,
|
|
31705
32028
|
signal: options.signal
|
|
31706
32029
|
}).run();
|
|
31707
32030
|
};
|
|
@@ -32203,6 +32526,10 @@ Waiting for approval...
|
|
|
32203
32526
|
once: parsed.once,
|
|
32204
32527
|
env,
|
|
32205
32528
|
processLock,
|
|
32529
|
+
emitDiagnosticEvent: parsed.json ? (event) => (dependencies.emitStdout ?? ((text) => {
|
|
32530
|
+
process.stdout.write(text);
|
|
32531
|
+
}))(`${JSON.stringify(event)}
|
|
32532
|
+
`) : void 0,
|
|
32206
32533
|
signal: cancellation.signal
|
|
32207
32534
|
});
|
|
32208
32535
|
return {
|
|
@@ -32739,7 +33066,14 @@ Waiting for approval...
|
|
|
32739
33066
|
throw new Error("Service adapter and model options are accepted only by service install.");
|
|
32740
33067
|
}
|
|
32741
33068
|
if (action === "logs") {
|
|
32742
|
-
return {
|
|
33069
|
+
return {
|
|
33070
|
+
exitCode: 0,
|
|
33071
|
+
stdout: await manager.logs(
|
|
33072
|
+
parsed.lines,
|
|
33073
|
+
parsed.instanceExplicit ? config2.instanceName : void 0
|
|
33074
|
+
),
|
|
33075
|
+
stderr: ""
|
|
33076
|
+
};
|
|
32743
33077
|
}
|
|
32744
33078
|
if (action === "start") {
|
|
32745
33079
|
return { exitCode: 0, stdout: render({ status: "service_started", ...await manager.start() }, parsed.json), stderr: "" };
|