@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.
Files changed (3) hide show
  1. package/README.md +14 -4
  2. package/bin/vtx.js +392 -58
  3. 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 use three concurrent slots per subscription by default. Set a
86
- bounded value from 1 through 8 with `--max-concurrency`. Slots share the live
87
- subscription rate-limit gate and cooldown; this does not guarantee capacity
88
- beyond the authenticated account's current entitlement.
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.31",
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, DEFAULT_CODEX_HOST_CONCURRENCY, MAX_CODEX_HOST_CONCURRENCY, 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;
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
- const rateLimits = await this.readAccountRateLimits(metadataDeadlineAtMs, request.signal);
20707
- accountLimitReached = accountLimitReached || codexAccountRateLimitReached(rateLimits);
20708
- retryAtMs = codexRateLimitRetryAtMs(rateLimits);
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, DEFAULT_MAX_CONCURRENCY, MIN_SLEEP_MS, DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS, MIN_CLAIM_START_WINDOW_MS, buildCodexInferenceAdvertisedModels, FileInferenceHostRuntimeReceiptStore, InferenceHostRecoveryRequiredError, InferenceHostRunnerError, defaultSleep, abortError, defaultRegisterSignalHandlers, safeInteger, exactObjectKeys, validIso, validateAttemptReceipt, validateRuntimeReceipt, sha256, stableOperationId, buildAttemptStartRequest, isoAt, finitePositiveOption, validateRunnerOptions, assertLocalCredentialIdentity, retryableRemoteError, remoteRetryAfterMs, controlPlaneFatal, defaultValidateOutput, objectRecord, positiveUtf8ByteLimit, assertCompilableOutputSchema, parseOutputContract, safeFailureCode, exactJson2, runnerIdentityMismatch, assertAdvertisementResult, assertHostHeartbeatResult, assertClaimResult, assertStartResult, assertJobHeartbeatResult, assertTerminalResult, classifyFailure, ambiguousHeartbeatTransport, reportedTokenUsage, reportedUsage, InferenceHostRunner;
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 providerRetryAtMs = this.options.codexRateLimits && codexAccountRateLimitReached(this.options.codexRateLimits) ? codexRateLimitRetryAtMs(this.options.codexRateLimits) ?? now() + DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS : null;
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?.(error48.retryAtMs);
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 || Number(record2.max_concurrency) > MAX_CODEX_HOST_CONCURRENCY || record2.authenticated_account_email !== null && typeof record2.authenticated_account_email !== "string" || record2.authenticated_account_plan !== null && typeof record2.authenticated_account_plan !== "string") {
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 = assertRuntimeEnvironment(legacy.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: Number(runtime_environment.VTX_INFERENCE_HOST_MAX_CONCURRENCY || 1),
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: "vtx_inference_service_v2",
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 !== "vtx_inference_service_v2" || 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) {
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 ?? 1;
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: "vtx_inference_service_v2",
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
- return `${contents.trimEnd().split(/\r?\n/u).slice(-lines).join("\n")}
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: { ...process.env, ...worker.runtime_environment },
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
- log.write(text);
31431
+ writeTaggedOutput("stdout", text);
31113
31432
  stdout = `${stdout}${text}`.slice(-65536);
31114
31433
  });
31115
- child.stderr.on("data", (chunk) => log.write(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 Automated Codex slots for this subscription (1-8; default: 3)
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 || value > MAX_CODEX_HOST_CONCURRENCY) {
31430
- throw new Error(`${label} must be an integer from 1 through ${MAX_CODEX_HOST_CONCURRENCY}.`);
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
- let maxConcurrency = parseHostConcurrency(
31438
- String(env.VTX_INFERENCE_HOST_MAX_CONCURRENCY || DEFAULT_CODEX_HOST_CONCURRENCY),
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 { exitCode: 0, stdout: await manager.logs(parsed.lines), stderr: "" };
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: "" };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vtxmacro/cli",
3
- "version": "2026.8.31",
3
+ "version": "2026.8.32",
4
4
  "description": "VTX Macro CLI, MCP server, and durable subscription inference host.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",