@vtxmacro/cli 2026.8.31 → 2026.8.33

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