@vtxmacro/cli 2026.8.53 → 2026.8.55

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 +44 -16
  2. package/bin/vtx.js +1460 -146
  3. package/package.json +52 -4
package/bin/vtx.js CHANGED
@@ -47,13 +47,67 @@ var init_agent_cli_release = __esm({
47
47
  "agent-cli-release.json"() {
48
48
  agent_cli_release_default = {
49
49
  package_name: "@vtxmacro/cli",
50
- package_version: "2026.8.53",
50
+ package_version: "2026.8.55",
51
51
  codex_package_name: "@openai/codex",
52
52
  codex_version: "0.147.0",
53
53
  copilot_sdk_package_name: "@github/copilot-sdk",
54
54
  copilot_sdk_version: "1.0.0-beta.8",
55
55
  copilot_cli_package_name: "@github/copilot",
56
56
  copilot_cli_version: "1.0.80",
57
+ deepseek_harness_version: "0.1.1-rc.2",
58
+ deepseek_harness_packages: [
59
+ "@deepseek-ai/dsh-agent",
60
+ "@deepseek-ai/dsh-agent-instructions",
61
+ "@deepseek-ai/dsh-agent-loop",
62
+ "@deepseek-ai/dsh-agent-spine-demo",
63
+ "@deepseek-ai/dsh-anonymous-user-id",
64
+ "@deepseek-ai/dsh-atomic-write",
65
+ "@deepseek-ai/dsh-attachment",
66
+ "@deepseek-ai/dsh-brand",
67
+ "@deepseek-ai/dsh-code-runtime",
68
+ "@deepseek-ai/dsh-credentials",
69
+ "@deepseek-ai/dsh-fs",
70
+ "@deepseek-ai/dsh-goal",
71
+ "@deepseek-ai/dsh-goal-round-driver",
72
+ "@deepseek-ai/dsh-home-paths",
73
+ "@deepseek-ai/dsh-invariants",
74
+ "@deepseek-ai/dsh-jobs",
75
+ "@deepseek-ai/dsh-jobs-local",
76
+ "@deepseek-ai/dsh-launch-environment",
77
+ "@deepseek-ai/dsh-llm",
78
+ "@deepseek-ai/dsh-llm-deepseek",
79
+ "@deepseek-ai/dsh-llm-retry",
80
+ "@deepseek-ai/dsh-output-retention",
81
+ "@deepseek-ai/dsh-sandbox",
82
+ "@deepseek-ai/dsh-sandbox-policy",
83
+ "@deepseek-ai/dsh-scope",
84
+ "@deepseek-ai/dsh-session",
85
+ "@deepseek-ai/dsh-session-checkpoint-policy",
86
+ "@deepseek-ai/dsh-session-persistence",
87
+ "@deepseek-ai/dsh-session-persistence-jsonl",
88
+ "@deepseek-ai/dsh-session-projection",
89
+ "@deepseek-ai/dsh-session-title",
90
+ "@deepseek-ai/dsh-settings",
91
+ "@deepseek-ai/dsh-shell",
92
+ "@deepseek-ai/dsh-shell-env",
93
+ "@deepseek-ai/dsh-skill",
94
+ "@deepseek-ai/dsh-skill-filesystem",
95
+ "@deepseek-ai/dsh-subprocess",
96
+ "@deepseek-ai/dsh-system-prompt",
97
+ "@deepseek-ai/dsh-timeout",
98
+ "@deepseek-ai/dsh-tool-bash",
99
+ "@deepseek-ai/dsh-tool-goal",
100
+ "@deepseek-ai/dsh-tool-jobs",
101
+ "@deepseek-ai/dsh-tool-skill",
102
+ "@deepseek-ai/dsh-tools",
103
+ "@deepseek-ai/dsh-typert-protocol",
104
+ "@deepseek-ai/dsh-user-approval"
105
+ ],
106
+ deepseek_cordis_package_name: "@deepseek-ai/cordis",
107
+ deepseek_cordis_version: "4.0.1",
108
+ deepseek_support_packages: {
109
+ "@deepseek-ai/cordis-plugin-timer": "1.1.3"
110
+ },
57
111
  platforms: {
58
112
  "linux-x64": {
59
113
  package_name: "@openai/codex-linux-x64",
@@ -14388,7 +14442,7 @@ var init_zod = __esm({
14388
14442
  });
14389
14443
 
14390
14444
  // lib/external-inference-contract.ts
14391
- var EXTERNAL_INFERENCE_CONTRACT_VERSION, EXTERNAL_INFERENCE_CONTROLLER_SCHEMA_VERSION, EXTERNAL_INFERENCE_CONTROLLER_SCHEMA_VERSION_V2, 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, processExitCodeSchema, externalInferenceAdapterIdSchema, reasoningEffortSchema, modelNameSchema, displayNameSchema, authenticatedAccountEmailSchema, protocolVersionSchema, base64UrlAlphabet, isCanonicalBase64Url, base64Url32BytesSchema, base64UrlNonceSchema, base64UrlCiphertextSchema, claimHandleSchema, boundedJsonTextSchema, boundedPromptTextSchema, laneSchema, botModeSchema, executionModeSchema, responseModeSchema, controlModeSchema, dispatchOutcomeSchema, responseOutcomeSchema, nativeModelControllerSchema, legacyExternalAgentModelControllerSchema, externalAgentModelControllerSchema, boundExternalAgentModelControllerSchema, externalAgentUnboundControllerSchema, externalAgentUnboundControllerV2Schema, orderedFallbackHostIdsSchema, externalInferenceFallbackHostIdsSchema, 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, codexProcessExitDiagnosticsSchema, 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;
14445
+ var EXTERNAL_INFERENCE_CONTRACT_VERSION, EXTERNAL_INFERENCE_CONTROLLER_SCHEMA_VERSION, EXTERNAL_INFERENCE_CONTROLLER_SCHEMA_VERSION_V2, 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_PROFILE_EXTERNAL_INFERENCE_FALLBACKS_PER_LANE, 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, processExitCodeSchema, externalInferenceAdapterIdSchema, reasoningEffortSchema, modelNameSchema, displayNameSchema, authenticatedAccountEmailSchema, protocolVersionSchema, base64UrlAlphabet, isCanonicalBase64Url, base64Url32BytesSchema, base64UrlNonceSchema, base64UrlCiphertextSchema, claimHandleSchema, boundedJsonTextSchema, boundedPromptTextSchema, laneSchema, botModeSchema, executionModeSchema, responseModeSchema, controlModeSchema, dispatchOutcomeSchema, responseOutcomeSchema, nativeModelControllerSchema, legacyExternalAgentModelControllerSchema, externalAgentModelControllerSchema, boundExternalAgentModelControllerSchema, externalAgentUnboundControllerSchema, externalAgentUnboundControllerV2Schema, orderedFallbackHostIdsSchema, externalInferenceFallbackHostIdsSchema, 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, codexProcessExitDiagnosticsSchema, 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;
14392
14446
  var init_external_inference_contract = __esm({
14393
14447
  "lib/external-inference-contract.ts"() {
14394
14448
  "use strict";
@@ -14403,6 +14457,7 @@ var init_external_inference_contract = __esm({
14403
14457
  EXTERNAL_INFERENCE_USAGE_SCHEMA_VERSION = "external_inference_usage_v1";
14404
14458
  EXTERNAL_INFERENCE_INPUT_HASH_DOMAIN = "vtx.external-inference.input-sha256.v1\0";
14405
14459
  MAX_EXTERNAL_INFERENCE_STATUS_HOSTS = 640;
14460
+ MAX_PROFILE_EXTERNAL_INFERENCE_FALLBACKS_PER_LANE = 127;
14406
14461
  MAX_GENERATION = 2147483647;
14407
14462
  MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER;
14408
14463
  MAX_PROMPT_BYTES = 3e5;
@@ -14684,7 +14739,7 @@ var init_external_inference_contract = __esm({
14684
14739
  control_mode_hint: controlModeSchema,
14685
14740
  binding_state: external_exports.literal("rebind_required")
14686
14741
  });
14687
- orderedFallbackHostIdsSchema = external_exports.array(identifierSchema).max(127).refine(
14742
+ orderedFallbackHostIdsSchema = external_exports.array(identifierSchema).max(MAX_PROFILE_EXTERNAL_INFERENCE_FALLBACKS_PER_LANE).refine(
14688
14743
  (values) => new Set(values).size === values.length,
14689
14744
  { message: "fallback host IDs must be unique" }
14690
14745
  );
@@ -15762,6 +15817,8 @@ var init_external_inference_contract = __esm({
15762
15817
  authenticated_account_identity: safeCodeSchema.nullable().optional(),
15763
15818
  authenticated_account_email: authenticatedAccountEmailSchema.nullable().optional(),
15764
15819
  authenticated_account_plan: safeCodeSchema.nullable().optional(),
15820
+ account_identity_status: external_exports.enum(["reported", "not_reported"]).default("not_reported"),
15821
+ membership_identity_sha256: sha256HexSchema.nullable().optional(),
15765
15822
  adapter: externalInferenceAdapterIdSchema,
15766
15823
  status: external_exports.enum(["online", "degraded", "offline", "draining", "revoked"]),
15767
15824
  host_generation: generationSchema,
@@ -15775,7 +15832,8 @@ var init_external_inference_contract = __esm({
15775
15832
  lane: laneSchema,
15776
15833
  controller: liveModelControllerSchema,
15777
15834
  availability: external_exports.enum(["available", "host_offline", "model_unavailable", "rebind_required"]),
15778
- reason_code: safeCodeSchema.nullable()
15835
+ reason_code: safeCodeSchema.nullable(),
15836
+ membership_host_ids: external_exports.array(identifierSchema).max(MAX_PROFILE_EXTERNAL_INFERENCE_FALLBACKS_PER_LANE + 1).default([])
15779
15837
  });
15780
15838
  queueStatusReadSchema = external_exports.strictObject({
15781
15839
  queued: nonNegativeSafeIntegerSchema,
@@ -19695,6 +19753,34 @@ var init_agent_client = __esm({
19695
19753
  });
19696
19754
 
19697
19755
  // lib/inference-host/agent-state.ts
19756
+ async function readInferenceAgentFailureFence(statePath) {
19757
+ const raw = await readInferencePrivateFile(
19758
+ inferenceAgentFailureFencePath(statePath),
19759
+ "Inference Agent failure fence"
19760
+ );
19761
+ if (raw === null) return null;
19762
+ try {
19763
+ return assertInferenceAgentFailureFence(JSON.parse(raw));
19764
+ } catch (error48) {
19765
+ if (error48 instanceof SyntaxError) {
19766
+ throw new Error("Inference Agent failure fence is not valid JSON.");
19767
+ }
19768
+ throw error48;
19769
+ }
19770
+ }
19771
+ async function writeInferenceAgentFailureFence(statePath, value) {
19772
+ await writeAtomicInferencePrivateFile(
19773
+ inferenceAgentFailureFencePath(statePath),
19774
+ `${JSON.stringify(assertInferenceAgentFailureFence(value), null, 2)}
19775
+ `
19776
+ );
19777
+ }
19778
+ async function clearInferenceAgentFailureFence(statePath) {
19779
+ await clearInferencePrivateFile(
19780
+ inferenceAgentFailureFencePath(statePath),
19781
+ "Inference Agent failure fence"
19782
+ );
19783
+ }
19698
19784
  async function readInferenceAgentRuntimeState(statePath) {
19699
19785
  const raw = await readInferencePrivateFile(
19700
19786
  inferenceAgentRuntimeStatePath(statePath),
@@ -19807,7 +19893,7 @@ async function clearInferenceAgentNextState(statePath) {
19807
19893
  "Agent-driven inference next recovery state"
19808
19894
  );
19809
19895
  }
19810
- var inferenceAgentAttemptStatePath, inferenceAgentNextStatePath, inferenceAgentRuntimeStatePath, isIsoTimestamp, assertPlainObject, hasExactKeys, assertInferenceAgentRuntimeState, readCodexAgentRuntimeState, clearCodexAgentRuntimeState, foregroundAgentControlStatePath, assertRuntimeAssignment, assertForegroundAgentControlState, assertNextState, assertAttemptState;
19896
+ var inferenceAgentAttemptStatePath, inferenceAgentNextStatePath, inferenceAgentRuntimeStatePath, inferenceAgentFailureFencePath, isIsoTimestamp, assertPlainObject, hasExactKeys, assertInferenceAgentFailureFence, assertInferenceAgentRuntimeState, readCodexAgentRuntimeState, clearCodexAgentRuntimeState, foregroundAgentControlStatePath, assertRuntimeAssignment, assertForegroundAgentControlState, assertNextState, assertAttemptState;
19811
19897
  var init_agent_state = __esm({
19812
19898
  "lib/inference-host/agent-state.ts"() {
19813
19899
  "use strict";
@@ -19816,12 +19902,31 @@ var init_agent_state = __esm({
19816
19902
  inferenceAgentAttemptStatePath = (statePath) => `${statePath}.agent-attempt.json`;
19817
19903
  inferenceAgentNextStatePath = (statePath) => `${statePath}.agent-next.json`;
19818
19904
  inferenceAgentRuntimeStatePath = (statePath) => `${statePath}.codex-agent-runtime.json`;
19905
+ inferenceAgentFailureFencePath = (statePath) => `${statePath}.agent-failure-fence.json`;
19819
19906
  isIsoTimestamp = (value) => typeof value === "string" && Number.isFinite(Date.parse(value));
19820
19907
  assertPlainObject = (value, message) => {
19821
19908
  if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(message);
19822
19909
  return value;
19823
19910
  };
19824
19911
  hasExactKeys = (record2, keys) => Object.keys(record2).sort().join("\0") === [...keys].sort().join("\0");
19912
+ assertInferenceAgentFailureFence = (value) => {
19913
+ const message = "Inference Agent failure fence is invalid.";
19914
+ const fence = assertPlainObject(value, message);
19915
+ if (!hasExactKeys(fence, [
19916
+ "schema_version",
19917
+ "adapter_id",
19918
+ "host_id",
19919
+ "assignment_id",
19920
+ "failure_category",
19921
+ "failure_code",
19922
+ "dispatch_outcome",
19923
+ "retry_at",
19924
+ "created_at"
19925
+ ]) || fence.schema_version !== "vtx_inference_agent_failure_fence_v1" || typeof fence.adapter_id !== "string" || !/^[a-z0-9][a-z0-9._-]{0,63}$/u.test(fence.adapter_id) || typeof fence.host_id !== "string" || !fence.host_id || fence.assignment_id !== null && (typeof fence.assignment_id !== "string" || !fence.assignment_id) || typeof fence.failure_category !== "string" || !/^[a-z0-9][a-z0-9._-]{0,159}$/u.test(fence.failure_category) || typeof fence.failure_code !== "string" || !/^[a-z0-9][a-z0-9._-]{0,159}$/u.test(fence.failure_code) || !["not_dispatched", "confirmed_dispatched", "outcome_unknown"].includes(
19926
+ String(fence.dispatch_outcome)
19927
+ ) || fence.retry_at !== null && !isIsoTimestamp(fence.retry_at) || !isIsoTimestamp(fence.created_at)) throw new Error(message);
19928
+ return fence;
19929
+ };
19825
19930
  assertInferenceAgentRuntimeState = (value) => {
19826
19931
  const message = "Inference Agent runtime recovery state is invalid.";
19827
19932
  const state = assertPlainObject(value, message);
@@ -24722,6 +24827,995 @@ ${JSON.stringify(input.outputSchema)}`
24722
24827
  }
24723
24828
  });
24724
24829
 
24830
+ // lib/inference-host/deepseek-transport-proxy.ts
24831
+ import { createServer as createServer2 } from "node:http";
24832
+ import { randomBytes as randomBytes4 } from "node:crypto";
24833
+ var MAX_REQUEST_BYTES, DeepSeekTransportProxy;
24834
+ var init_deepseek_transport_proxy = __esm({
24835
+ "lib/inference-host/deepseek-transport-proxy.ts"() {
24836
+ "use strict";
24837
+ MAX_REQUEST_BYTES = 8 * 1024 * 1024;
24838
+ DeepSeekTransportProxy = class {
24839
+ constructor(apiKey, expectedModel, expectedEffort, upstreamBaseUrl = "https://api.deepseek.com", fetchImpl = fetch) {
24840
+ this.apiKey = apiKey;
24841
+ this.expectedModel = expectedModel;
24842
+ this.expectedEffort = expectedEffort;
24843
+ this.upstreamBaseUrl = upstreamBaseUrl;
24844
+ this.fetchImpl = fetchImpl;
24845
+ this.server = null;
24846
+ this.urlValue = null;
24847
+ this.receiptsValue = [];
24848
+ this.controllers = /* @__PURE__ */ new Set();
24849
+ this.token = randomBytes4(24).toString("hex");
24850
+ this.upstreamRequestStartedValue = false;
24851
+ this.providerResponseObservedValue = false;
24852
+ this.unansweredUpstreamRequestsValue = 0;
24853
+ }
24854
+ get baseUrl() {
24855
+ if (!this.urlValue) throw new Error("deepseek_transport_proxy_not_started");
24856
+ return `${this.urlValue}/${this.token}`;
24857
+ }
24858
+ get receipts() {
24859
+ return [...this.receiptsValue];
24860
+ }
24861
+ get providerResponseObserved() {
24862
+ return this.providerResponseObservedValue;
24863
+ }
24864
+ get upstreamRequestStarted() {
24865
+ return this.upstreamRequestStartedValue;
24866
+ }
24867
+ get unansweredUpstreamRequest() {
24868
+ return this.unansweredUpstreamRequestsValue > 0;
24869
+ }
24870
+ async start() {
24871
+ if (this.server) return;
24872
+ this.server = createServer2(async (request, response) => {
24873
+ try {
24874
+ const prefix = `/${this.token}`;
24875
+ const requestUrl = request.url ?? "";
24876
+ if (request.method !== "POST" || requestUrl !== `${prefix}/chat/completions`) {
24877
+ response.writeHead(404).end();
24878
+ return;
24879
+ }
24880
+ const chunks = [];
24881
+ let requestBytes = 0;
24882
+ for await (const chunk of request) {
24883
+ const buffer = Buffer.from(chunk);
24884
+ requestBytes += buffer.byteLength;
24885
+ if (requestBytes > MAX_REQUEST_BYTES) throw new Error("deepseek_proxy_request_too_large");
24886
+ chunks.push(buffer);
24887
+ }
24888
+ const body = Buffer.concat(chunks);
24889
+ let requestedModel = "";
24890
+ let requestedEffort = "off";
24891
+ const payload = JSON.parse(body.toString("utf8"));
24892
+ requestedModel = String(payload.model ?? "");
24893
+ const thinking = payload.thinking;
24894
+ requestedEffort = thinking?.type === "disabled" ? "off" : String(payload.reasoning_effort ?? "");
24895
+ if (requestedModel !== this.expectedModel || requestedEffort !== this.expectedEffort) throw new Error("deepseek_outbound_model_or_effort_mismatch");
24896
+ const controller = new AbortController();
24897
+ this.controllers.add(controller);
24898
+ try {
24899
+ this.upstreamRequestStartedValue = true;
24900
+ this.unansweredUpstreamRequestsValue += 1;
24901
+ const upstream = await this.fetchImpl(
24902
+ `${this.upstreamBaseUrl}/chat/completions`,
24903
+ {
24904
+ method: request.method,
24905
+ headers: {
24906
+ "authorization": `Bearer ${this.apiKey}`,
24907
+ "content-type": String(request.headers["content-type"] ?? "application/json"),
24908
+ "accept": String(request.headers.accept ?? "application/json"),
24909
+ "user-agent": String(request.headers["user-agent"] ?? "@vtxmacro/cli")
24910
+ },
24911
+ body,
24912
+ signal: controller.signal
24913
+ }
24914
+ );
24915
+ this.unansweredUpstreamRequestsValue -= 1;
24916
+ this.providerResponseObservedValue = true;
24917
+ const headers = {};
24918
+ upstream.headers.forEach((value, name) => {
24919
+ if (!["connection", "transfer-encoding", "content-length"].includes(name)) {
24920
+ headers[name] = value;
24921
+ }
24922
+ });
24923
+ response.writeHead(upstream.status, headers);
24924
+ if (!upstream.body) {
24925
+ response.end();
24926
+ return;
24927
+ }
24928
+ if (!upstream.ok) {
24929
+ const errorReader = upstream.body.getReader();
24930
+ while (true) {
24931
+ const part = await errorReader.read();
24932
+ if (part.done) break;
24933
+ response.write(Buffer.from(part.value));
24934
+ }
24935
+ response.end();
24936
+ return;
24937
+ }
24938
+ const reader = upstream.body.getReader();
24939
+ const decoder2 = new TextDecoder();
24940
+ let pending = "";
24941
+ let observedId = "";
24942
+ let terminalObserved = false;
24943
+ const forwardLine = (line) => {
24944
+ if (!line.startsWith("data:")) {
24945
+ response.write(`${line}
24946
+ `);
24947
+ return;
24948
+ }
24949
+ const value = line.slice(5).trim();
24950
+ if (!value) {
24951
+ response.write(`${line}
24952
+ `);
24953
+ return;
24954
+ }
24955
+ if (value === "[DONE]") {
24956
+ if (terminalObserved || !observedId) {
24957
+ throw new Error("deepseek_provider_receipt_missing_or_mismatched");
24958
+ }
24959
+ terminalObserved = true;
24960
+ this.receiptsValue.push({
24961
+ id: observedId,
24962
+ model: this.expectedModel,
24963
+ requestedModel,
24964
+ requestedReasoningEffort: requestedEffort
24965
+ });
24966
+ response.write(`${line}
24967
+ `);
24968
+ return;
24969
+ }
24970
+ const event = JSON.parse(value);
24971
+ const eventId = typeof event.id === "string" ? event.id.trim() : "";
24972
+ const eventModel = typeof event.model === "string" ? event.model.trim() : "";
24973
+ if (!eventId || eventModel !== this.expectedModel || observedId && eventId !== observedId) throw new Error("deepseek_provider_receipt_missing_or_mismatched");
24974
+ observedId = eventId;
24975
+ response.write(`${line}
24976
+ `);
24977
+ };
24978
+ while (true) {
24979
+ const part = await reader.read();
24980
+ if (part.done) break;
24981
+ pending += decoder2.decode(part.value, { stream: true });
24982
+ const lines = pending.split(/\r?\n/u);
24983
+ pending = lines.pop() ?? "";
24984
+ for (const line of lines) forwardLine(line);
24985
+ }
24986
+ pending += decoder2.decode();
24987
+ if (pending) forwardLine(pending);
24988
+ if (!terminalObserved) {
24989
+ throw new Error("deepseek_provider_receipt_missing_or_mismatched");
24990
+ }
24991
+ response.end();
24992
+ } finally {
24993
+ this.controllers.delete(controller);
24994
+ }
24995
+ } catch {
24996
+ if (!response.headersSent) response.writeHead(502);
24997
+ response.end();
24998
+ }
24999
+ });
25000
+ await new Promise((resolve6, reject) => {
25001
+ this.server.once("error", reject);
25002
+ this.server.listen(0, "127.0.0.1", () => resolve6());
25003
+ });
25004
+ const address = this.server.address();
25005
+ if (!address || typeof address === "string") throw new Error("deepseek_proxy_bind_failed");
25006
+ this.urlValue = `http://127.0.0.1:${address.port}`;
25007
+ }
25008
+ async close() {
25009
+ for (const controller of this.controllers) controller.abort();
25010
+ const server = this.server;
25011
+ this.server = null;
25012
+ this.urlValue = null;
25013
+ if (!server) return;
25014
+ await new Promise((resolve6) => server.close(() => resolve6()));
25015
+ }
25016
+ };
25017
+ }
25018
+ });
25019
+
25020
+ // lib/inference-host/deepseek-harness-adapter.ts
25021
+ import { randomUUID as randomUUID2 } from "node:crypto";
25022
+ import { mkdtemp as mkdtemp3, realpath as realpath4, rm as rm5 } from "node:fs/promises";
25023
+ import { tmpdir as tmpdir4 } from "node:os";
25024
+ import { basename, dirname as dirname4, join as join6 } from "node:path";
25025
+ import { Context } from "@deepseek-ai/cordis";
25026
+ import * as AgentSpine from "@deepseek-ai/dsh-agent-spine-demo";
25027
+ import {
25028
+ createUserMessage,
25029
+ LlmError
25030
+ } from "@deepseek-ai/dsh-llm";
25031
+ import {
25032
+ DeepSeekAdapter,
25033
+ resolveAdapterOptions
25034
+ } from "@deepseek-ai/dsh-llm-deepseek";
25035
+ import * as LlmDeepSeek from "@deepseek-ai/dsh-llm-deepseek";
25036
+ import { SessionId } from "@deepseek-ai/dsh-session";
25037
+ import * as SessionCheckpointPolicy from "@deepseek-ai/dsh-session-checkpoint-policy";
25038
+ import { JsonlSessionPersistence } from "@deepseek-ai/dsh-session-persistence-jsonl";
25039
+ var DEEPSEEK_HARNESS_VERSION, MAX_RESULT_BYTES2, DEEPSEEK_MODELS, DEEPSEEK_API_BASE_URL, isSupportedNodeVersion, effortForHarness, supportedEfforts, toVtxUsage, sumUsage, textFromBlocks, validateText, createDeadlineBoundary, nonDispatchedError, proxyDispatchOutcome, mapDeepSeekFailure, createPrivateWorkspace2, directAdapter, normalizeJsonValue, DeepSeekHarnessAdapter;
25040
+ var init_deepseek_harness_adapter = __esm({
25041
+ "lib/inference-host/deepseek-harness-adapter.ts"() {
25042
+ "use strict";
25043
+ init_codex_app_server();
25044
+ init_deepseek_transport_proxy();
25045
+ DEEPSEEK_HARNESS_VERSION = "0.1.1-rc.2";
25046
+ MAX_RESULT_BYTES2 = 3e5;
25047
+ DEEPSEEK_MODELS = ["deepseek-v4-flash", "deepseek-v4-pro"];
25048
+ DEEPSEEK_API_BASE_URL = "https://api.deepseek.com";
25049
+ isSupportedNodeVersion = (version3) => {
25050
+ const [major, minor] = version3.replace(/^v/u, "").split(".").map(Number);
25051
+ return major === 22 && minor >= 19 || major >= 24;
25052
+ };
25053
+ effortForHarness = (effort) => {
25054
+ if (effort === "none") return "off";
25055
+ if (effort === "low" || effort === "high" || effort === "max") return effort;
25056
+ throw new Error(`deepseek_reasoning_effort_unsupported:${effort}`);
25057
+ };
25058
+ supportedEfforts = (model) => model === "deepseek-v4-pro" ? ["none", "high", "max"] : ["none", "low", "high", "max"];
25059
+ toVtxUsage = (usage) => {
25060
+ const cacheRead = usage.cacheReadTokens ?? 0;
25061
+ const cacheWrite = usage.cacheWriteTokens ?? 0;
25062
+ const inclusiveInput = usage.inputTokens + cacheRead + cacheWrite;
25063
+ return {
25064
+ inputTokens: inclusiveInput,
25065
+ cachedInputTokens: cacheRead,
25066
+ outputTokens: usage.outputTokens,
25067
+ reasoningOutputTokens: Math.min(usage.reasoningTokens ?? 0, usage.outputTokens),
25068
+ totalTokens: inclusiveInput + usage.outputTokens,
25069
+ cacheWriteInputTokens: usage.cacheWriteTokens ?? null,
25070
+ cacheWriteSupported: usage.cacheWriteTokens !== void 0
25071
+ };
25072
+ };
25073
+ sumUsage = (values) => toVtxUsage({
25074
+ inputTokens: values.reduce((sum, value) => sum + value.inputTokens, 0),
25075
+ outputTokens: values.reduce((sum, value) => sum + value.outputTokens, 0),
25076
+ cacheReadTokens: values.reduce((sum, value) => sum + (value.cacheReadTokens ?? 0), 0),
25077
+ cacheWriteTokens: values.some((value) => value.cacheWriteTokens !== void 0) ? values.reduce((sum, value) => sum + (value.cacheWriteTokens ?? 0), 0) : void 0,
25078
+ reasoningTokens: values.reduce((sum, value) => sum + (value.reasoningTokens ?? 0), 0)
25079
+ });
25080
+ textFromBlocks = (blocks, type) => blocks.flatMap((block) => block.type === type ? [block.text] : []).join("");
25081
+ validateText = (text, code) => {
25082
+ if (!text.trim() || Buffer.byteLength(text, "utf8") > MAX_RESULT_BYTES2) throw new Error(code);
25083
+ return text;
25084
+ };
25085
+ createDeadlineBoundary = (source, deadlineAtMs) => {
25086
+ const controller = new AbortController();
25087
+ const relayAbort = () => controller.abort(source?.reason);
25088
+ source?.addEventListener("abort", relayAbort, { once: true });
25089
+ if (source?.aborted) controller.abort(source.reason);
25090
+ const timeout = setTimeout(
25091
+ () => controller.abort(new Error("deadline_exceeded")),
25092
+ Math.max(1, deadlineAtMs - Date.now())
25093
+ );
25094
+ timeout.unref();
25095
+ return {
25096
+ signal: controller.signal,
25097
+ cleanup: () => {
25098
+ clearTimeout(timeout);
25099
+ source?.removeEventListener("abort", relayAbort);
25100
+ }
25101
+ };
25102
+ };
25103
+ nonDispatchedError = (message, category, code, retryable = false) => new CodexAppServerError({
25104
+ message,
25105
+ category,
25106
+ code,
25107
+ retryable,
25108
+ dispatchOutcome: "not_dispatched"
25109
+ });
25110
+ proxyDispatchOutcome = (proxy) => {
25111
+ if (proxy.unansweredUpstreamRequest) return "outcome_unknown";
25112
+ if (proxy.providerResponseObserved) return "confirmed_dispatched";
25113
+ return proxy.upstreamRequestStarted ? "outcome_unknown" : "not_dispatched";
25114
+ };
25115
+ mapDeepSeekFailure = (options) => {
25116
+ if (options.error instanceof CodexAppServerError) return options.error;
25117
+ if (options.cancelled || options.deadline) {
25118
+ return new CodexAppServerError({
25119
+ message: options.cancelled ? "DeepSeek Harness request was cancelled." : "DeepSeek Harness request exceeded its deadline.",
25120
+ category: options.cancelled ? "cancelled" : "timeout",
25121
+ code: options.cancelled ? "cancelled" : "deadline_exceeded",
25122
+ retryable: false,
25123
+ dispatchOutcome: options.dispatchOutcome,
25124
+ cause: options.error
25125
+ });
25126
+ }
25127
+ if (options.error instanceof LlmError) {
25128
+ const failure = options.error.failure;
25129
+ const auth = ["AUTH", "INVALID_CREDENTIAL", "MISSING_CREDENTIAL"].includes(failure.code);
25130
+ const quota = failure.code === "QUOTA" || failure.status === 402;
25131
+ const rateLimit = failure.code === "RATE_LIMIT";
25132
+ const clientError = failure.status !== void 0 && failure.status >= 400 && failure.status < 500;
25133
+ const model = !auth && !quota && !rateLimit && clientError || [
25134
+ "CONTEXT_WINDOW_EXCEEDED",
25135
+ "INVALID_REQUEST",
25136
+ "UNSUPPORTED_CONTENT",
25137
+ "UNSUPPORTED_REASONING_EFFORT"
25138
+ ].includes(failure.code);
25139
+ const transport = [
25140
+ "EMPTY_RESPONSE",
25141
+ "MALFORMED_RESPONSE",
25142
+ "SERVER",
25143
+ "STREAM_CLOSED",
25144
+ "TIMEOUT",
25145
+ "TRANSPORT"
25146
+ ].includes(failure.code) || failure.code.startsWith("HTTP_") && !clientError;
25147
+ const code = auth ? "deepseek_auth_failed" : quota ? "quota_exceeded" : rateLimit ? "provider_rate_limited" : model ? `deepseek_${failure.code.toLowerCase()}` : transport ? `deepseek_${failure.code.toLowerCase()}` : "deepseek_harness_adapter_failure";
25148
+ return new CodexAppServerError({
25149
+ message: failure.message,
25150
+ category: auth ? "auth" : model || quota || rateLimit ? "model" : transport ? "transport" : "adapter",
25151
+ code,
25152
+ retryable: transport && !quota,
25153
+ dispatchOutcome: options.dispatchOutcome,
25154
+ httpStatusCode: failure.status ?? null,
25155
+ retryAtMs: failure.providerRetryAfterMs === void 0 ? null : Date.now() + failure.providerRetryAfterMs,
25156
+ cause: options.error
25157
+ });
25158
+ }
25159
+ return new CodexAppServerError({
25160
+ message: options.error instanceof Error ? options.error.message : "DeepSeek Harness adapter failed.",
25161
+ category: "adapter",
25162
+ code: "deepseek_harness_adapter_failure",
25163
+ retryable: false,
25164
+ dispatchOutcome: options.dispatchOutcome,
25165
+ cause: options.error
25166
+ });
25167
+ };
25168
+ createPrivateWorkspace2 = async () => {
25169
+ const path = await mkdtemp3(join6(tmpdir4(), "vtx-deepseek-harness-"));
25170
+ return { path, cleanup: async () => {
25171
+ await rm5(path, { recursive: true, force: true });
25172
+ } };
25173
+ };
25174
+ directAdapter = (proxy, model, effort) => {
25175
+ const connection = resolveAdapterOptions({
25176
+ apiKeyEnv: "VTX_DSH_LOOPBACK_TOKEN",
25177
+ baseURL: proxy.baseUrl,
25178
+ reasoningEffort: effort,
25179
+ thinking: "enabled",
25180
+ models: [{ id: model }],
25181
+ retryPolicy: { mode: "normal", maxRetries: 0 }
25182
+ });
25183
+ return new DeepSeekAdapter({
25184
+ options: () => connection,
25185
+ resolveApiKey: async () => "vtx-loopback-only",
25186
+ resolveUserId: () => "vtx-macro"
25187
+ });
25188
+ };
25189
+ normalizeJsonValue = (value) => JSON.parse(JSON.stringify(value));
25190
+ DeepSeekHarnessAdapter = class {
25191
+ constructor(dependencies) {
25192
+ this.agentWorkspaces = /* @__PURE__ */ new Map();
25193
+ this.closing = false;
25194
+ this.dependencies = dependencies;
25195
+ }
25196
+ async preflight(signal) {
25197
+ if (!isSupportedNodeVersion(this.dependencies.nodeVersion ?? process.version)) {
25198
+ throw new CodexAppServerError({
25199
+ message: "DeepSeek Harness requires Node 22.19 or newer in the Node 22 line, or Node 24+.",
25200
+ category: "adapter",
25201
+ code: "deepseek_harness_node_version_unsupported",
25202
+ retryable: false
25203
+ });
25204
+ }
25205
+ const credential = await this.dependencies.credentialStore.read(signal);
25206
+ if (!credential) {
25207
+ throw new CodexAppServerError({
25208
+ message: "Import a DeepSeek API key with vtx inference-host deepseek-login first.",
25209
+ category: "auth",
25210
+ code: "deepseek_harness_credential_required",
25211
+ retryable: false
25212
+ });
25213
+ }
25214
+ const response = await (this.dependencies.fetch ?? fetch)(
25215
+ `${this.dependencies.apiBaseUrl ?? DEEPSEEK_API_BASE_URL}/models`,
25216
+ { headers: { authorization: `Bearer ${credential.apiKey}` }, signal }
25217
+ );
25218
+ if (!response.ok) {
25219
+ throw new CodexAppServerError({
25220
+ message: `DeepSeek model catalog request failed with HTTP ${response.status}.`,
25221
+ category: response.status === 401 || response.status === 403 ? "auth" : "transport",
25222
+ code: "deepseek_harness_model_catalog_failed",
25223
+ retryable: false
25224
+ });
25225
+ }
25226
+ const payload = await response.json();
25227
+ const live = new Set((payload.data ?? []).map((item) => String(item.id ?? "")));
25228
+ const models = DEEPSEEK_MODELS.filter((model) => live.has(model));
25229
+ if (models.length === 0) {
25230
+ throw new CodexAppServerError({
25231
+ message: "DeepSeek returned no VTX-supported Harness models.",
25232
+ category: "model",
25233
+ code: "deepseek_harness_model_catalog_empty",
25234
+ retryable: false
25235
+ });
25236
+ }
25237
+ return {
25238
+ adapterId: "deepseek-harness",
25239
+ runtimeVersion: DEEPSEEK_HARNESS_VERSION,
25240
+ authenticatedAccountIdentity: null,
25241
+ authenticatedAccountEmail: null,
25242
+ authenticatedAccountPlan: null,
25243
+ modelCapabilities: models.map((model, index) => ({
25244
+ id: model,
25245
+ model,
25246
+ displayName: model === "deepseek-v4-flash" ? "DeepSeek V4 Flash" : "DeepSeek V4 Pro",
25247
+ hidden: false,
25248
+ supportedReasoningEfforts: [...supportedEfforts(model)],
25249
+ defaultReasoningEffort: "high",
25250
+ isDefault: index === 0
25251
+ })),
25252
+ rateLimits: null,
25253
+ sameAttemptRecovery: false
25254
+ };
25255
+ }
25256
+ async runAttempt(input) {
25257
+ const startedAt = (this.dependencies.now ?? Date.now)();
25258
+ if (Date.now() >= input.deadlineAtMs) {
25259
+ throw nonDispatchedError(
25260
+ "DeepSeek Harness attempt exceeded its deadline.",
25261
+ "timeout",
25262
+ "deadline_exceeded"
25263
+ );
25264
+ }
25265
+ if (!DEEPSEEK_MODELS.includes(input.requestedModel)) {
25266
+ throw nonDispatchedError(
25267
+ "The requested DeepSeek Harness model is unsupported.",
25268
+ "model",
25269
+ "deepseek_model_unsupported"
25270
+ );
25271
+ }
25272
+ if (!supportedEfforts(input.requestedModel).includes(input.requestedReasoningEffort)) {
25273
+ throw nonDispatchedError(
25274
+ "The requested DeepSeek Harness reasoning effort is unsupported.",
25275
+ "model",
25276
+ "deepseek_reasoning_effort_unsupported"
25277
+ );
25278
+ }
25279
+ const effort = effortForHarness(input.requestedReasoningEffort);
25280
+ const boundary = createDeadlineBoundary(input.signal, input.deadlineAtMs);
25281
+ let credential;
25282
+ try {
25283
+ credential = await this.dependencies.credentialStore.read(boundary.signal);
25284
+ if (!credential) {
25285
+ throw nonDispatchedError(
25286
+ "Import a DeepSeek API key with vtx inference-host deepseek-login first.",
25287
+ "auth",
25288
+ "deepseek_harness_credential_required"
25289
+ );
25290
+ }
25291
+ } catch (error48) {
25292
+ const cancelled = input.signal?.aborted === true;
25293
+ const deadline = !cancelled && boundary.signal.aborted;
25294
+ boundary.cleanup();
25295
+ if (error48 instanceof CodexAppServerError) throw error48;
25296
+ throw nonDispatchedError(
25297
+ cancelled ? "DeepSeek Harness attempt was cancelled." : deadline ? "DeepSeek Harness attempt exceeded its deadline." : "DeepSeek Harness could not read its local credential.",
25298
+ cancelled ? "cancelled" : deadline ? "timeout" : "auth",
25299
+ cancelled ? "cancelled" : deadline ? "deadline_exceeded" : "deepseek_harness_credential_read_failed"
25300
+ );
25301
+ }
25302
+ const proxy = new DeepSeekTransportProxy(
25303
+ credential.apiKey,
25304
+ input.requestedModel,
25305
+ effort,
25306
+ this.dependencies.apiBaseUrl ?? DEEPSEEK_API_BASE_URL,
25307
+ this.dependencies.fetch ?? fetch
25308
+ );
25309
+ try {
25310
+ boundary.signal.throwIfAborted();
25311
+ await proxy.start();
25312
+ const adapter = directAdapter(proxy, input.requestedModel, effort);
25313
+ const blocks = [];
25314
+ let usage = null;
25315
+ let finish = null;
25316
+ for await (const chunk of adapter.stream({
25317
+ provider: "deepseek-official",
25318
+ model: input.requestedModel,
25319
+ reasoningEffort: effort,
25320
+ system: `${input.systemPrompt}
25321
+
25322
+ Return only one JSON value matching this JSON Schema exactly:
25323
+ ${input.outputSchemaJson}`,
25324
+ messages: [createUserMessage({
25325
+ content: [{ type: "text", text: input.userPrompt }],
25326
+ source: { kind: "user" }
25327
+ })],
25328
+ tools: [],
25329
+ signal: boundary.signal
25330
+ })) {
25331
+ if (chunk.type === "block-end") blocks.push(chunk.block);
25332
+ if (chunk.type === "usage") usage = chunk.usage;
25333
+ if (chunk.type === "finish") finish = chunk;
25334
+ }
25335
+ const receipts = proxy.receipts;
25336
+ if (receipts.length !== 1 || !usage || finish?.type !== "finish" || finish.reason.kind !== "stop") {
25337
+ throw new Error("deepseek_harness_terminal_receipt_invalid");
25338
+ }
25339
+ const text = validateText(textFromBlocks(blocks, "text"), "deepseek_harness_result_invalid");
25340
+ return {
25341
+ text,
25342
+ reasoningContent: textFromBlocks(blocks, "reasoning") || null,
25343
+ reasoningSummary: null,
25344
+ requestedModel: input.requestedModel,
25345
+ effectiveModel: receipts[0].model,
25346
+ requestedReasoningEffort: input.requestedReasoningEffort,
25347
+ effectiveReasoningEffort: input.requestedReasoningEffort,
25348
+ adapterRequestId: receipts[0].id,
25349
+ adapterResponseId: receipts[0].id,
25350
+ usage: toVtxUsage(usage),
25351
+ latencyMs: Math.max(0, (this.dependencies.now ?? Date.now)() - startedAt),
25352
+ timeToFirstTokenMs: null,
25353
+ terminalStatus: "completed"
25354
+ };
25355
+ } catch (error48) {
25356
+ const cancelled = input.signal?.aborted === true;
25357
+ const deadline = !cancelled && boundary.signal.aborted;
25358
+ throw mapDeepSeekFailure({
25359
+ error: error48,
25360
+ cancelled,
25361
+ deadline,
25362
+ dispatchOutcome: proxyDispatchOutcome(proxy)
25363
+ });
25364
+ } finally {
25365
+ boundary.cleanup();
25366
+ await proxy.close();
25367
+ }
25368
+ }
25369
+ async runTurn(input) {
25370
+ if (this.closing) {
25371
+ throw nonDispatchedError(
25372
+ "DeepSeek Harness Agent adapter is closing.",
25373
+ "transport",
25374
+ "transport_closed",
25375
+ true
25376
+ );
25377
+ }
25378
+ if (Date.now() >= input.deadlineAtMs) {
25379
+ throw nonDispatchedError(
25380
+ "DeepSeek Harness Agent turn exceeded its deadline.",
25381
+ "timeout",
25382
+ "deadline_exceeded"
25383
+ );
25384
+ }
25385
+ if (!DEEPSEEK_MODELS.includes(input.requestedModel)) {
25386
+ throw nonDispatchedError(
25387
+ "The requested DeepSeek Harness model is unsupported.",
25388
+ "model",
25389
+ "deepseek_model_unsupported"
25390
+ );
25391
+ }
25392
+ if (input.dataContract.length === 0 || !supportedEfforts(input.requestedModel).includes(input.requestedReasoningEffort)) {
25393
+ throw nonDispatchedError(
25394
+ "DeepSeek Harness Agent turn input is invalid.",
25395
+ "schema",
25396
+ "invalid_agent_turn_input"
25397
+ );
25398
+ }
25399
+ const startedAt = (this.dependencies.now ?? Date.now)();
25400
+ const effort = effortForHarness(input.requestedReasoningEffort);
25401
+ const boundary = createDeadlineBoundary(input.signal, input.deadlineAtMs);
25402
+ let credential;
25403
+ try {
25404
+ credential = await this.dependencies.credentialStore.read(boundary.signal);
25405
+ if (!credential) {
25406
+ throw nonDispatchedError(
25407
+ "Import a DeepSeek API key with vtx inference-host deepseek-login first.",
25408
+ "auth",
25409
+ "deepseek_harness_credential_required"
25410
+ );
25411
+ }
25412
+ } catch (error48) {
25413
+ const cancelled = input.signal?.aborted === true;
25414
+ const deadline = !cancelled && boundary.signal.aborted;
25415
+ boundary.cleanup();
25416
+ if (error48 instanceof CodexAppServerError) throw error48;
25417
+ throw nonDispatchedError(
25418
+ cancelled ? "DeepSeek Harness Agent turn was cancelled." : deadline ? "DeepSeek Harness Agent turn exceeded its deadline." : "DeepSeek Harness could not read its local credential.",
25419
+ cancelled ? "cancelled" : deadline ? "timeout" : "auth",
25420
+ cancelled ? "cancelled" : deadline ? "deadline_exceeded" : "deepseek_harness_credential_read_failed"
25421
+ );
25422
+ }
25423
+ const owned = input.durableThread ? null : await (this.dependencies.createWorkspace ?? createPrivateWorkspace2)();
25424
+ const rootPath = input.durableThread?.threadPath ?? owned.path;
25425
+ if (owned) this.agentWorkspaces.set(rootPath, owned.cleanup);
25426
+ const proxy = new DeepSeekTransportProxy(
25427
+ credential.apiKey,
25428
+ input.requestedModel,
25429
+ effort,
25430
+ this.dependencies.apiBaseUrl ?? DEEPSEEK_API_BASE_URL,
25431
+ this.dependencies.fetch ?? fetch
25432
+ );
25433
+ const ctx = new Context();
25434
+ const loopbackEnvName = `VTX_DSH_LOOPBACK_TOKEN_${randomUUID2().replaceAll("-", "").toUpperCase()}`;
25435
+ process.env[loopbackEnvName] = "vtx-loopback-only";
25436
+ let durableCheckpointed = input.durableThread !== null;
25437
+ let cleanupUnpublishedWorkspace = false;
25438
+ let removeAgentAbortListener = () => void 0;
25439
+ let cancelAgentTurn = () => void 0;
25440
+ let releaseAgentDispatch = () => void 0;
25441
+ let permitAgentDispatch = false;
25442
+ try {
25443
+ await proxy.start();
25444
+ await ctx.plugin(AgentSpine, {
25445
+ agents: [],
25446
+ maxParallelToolCalls: 1,
25447
+ includeHarnessIdentity: false,
25448
+ includeRuntimeContext: false,
25449
+ persona: `${input.systemPrompt}
25450
+
25451
+ Return only one JSON value matching this JSON Schema exactly:
25452
+ ${JSON.stringify(input.outputSchema)}`,
25453
+ tools: { mode: "native" },
25454
+ workspaceContext: false,
25455
+ skills: { enabled: false },
25456
+ toolBash: false,
25457
+ toolJobs: false,
25458
+ goals: false
25459
+ });
25460
+ await ctx.plugin(JsonlSessionPersistence, { root: rootPath, compression: "none" });
25461
+ await ctx.plugin(SessionCheckpointPolicy);
25462
+ await ctx.plugin(LlmDeepSeek, {
25463
+ apiKeyEnv: loopbackEnvName,
25464
+ baseURL: proxy.baseUrl,
25465
+ reasoningEffort: effort,
25466
+ thinking: "enabled",
25467
+ models: [{ id: input.requestedModel }],
25468
+ retryPolicy: { mode: "normal", maxRetries: 0 }
25469
+ });
25470
+ const evidence = [];
25471
+ const setup = (agentCtx) => {
25472
+ const definitions = [
25473
+ {
25474
+ name: "vtx_get_data",
25475
+ description: "Request assignment-scoped VTX data.",
25476
+ parameters: { oneOf: input.dataContract.map((entry) => ({
25477
+ type: "object",
25478
+ additionalProperties: false,
25479
+ required: ["capability", "arguments"],
25480
+ properties: { capability: { const: entry.id }, arguments: entry.input_schema }
25481
+ })) }
25482
+ },
25483
+ {
25484
+ name: "vtx_submit_decision",
25485
+ description: "Submit one VTX structured trading decision candidate.",
25486
+ parameters: { type: "object", additionalProperties: false, required: ["candidate"], properties: { candidate: input.decisionSchema } }
25487
+ },
25488
+ {
25489
+ name: "vtx_decision_status",
25490
+ description: "Resolve the durable status of a decision operation.",
25491
+ parameters: { type: "object", additionalProperties: false, required: ["operation_id"], properties: { operation_id: { type: "string", minLength: 1 } } }
25492
+ }
25493
+ ];
25494
+ for (const definition of definitions) {
25495
+ agentCtx.tools.register({
25496
+ ...definition,
25497
+ output: {
25498
+ schema: {},
25499
+ render: (_arguments, value) => [{ type: "text", text: JSON.stringify(value) }]
25500
+ },
25501
+ execute: async (argumentsValue) => {
25502
+ const argumentsRecord = argumentsValue && typeof argumentsValue === "object" && !Array.isArray(argumentsValue) ? argumentsValue : {};
25503
+ const callId = randomUUID2();
25504
+ const result2 = await input.executeTool({ callId, tool: definition.name, arguments: argumentsRecord });
25505
+ evidence.push({ callId, tool: definition.name, arguments: argumentsRecord, success: result2.success });
25506
+ return normalizeJsonValue(result2.success ? result2.value : { error: result2.value });
25507
+ }
25508
+ });
25509
+ }
25510
+ };
25511
+ const sessionId = input.durableThread ? SessionId(input.durableThread.threadId) : SessionId(`vtx-${randomUUID2()}`);
25512
+ const handle = input.durableThread ? await ctx.agents.resume({
25513
+ resumeSessionId: sessionId,
25514
+ agentOptions: { provider: "deepseek-official", model: input.requestedModel, reasoningEffort: effort },
25515
+ signal: boundary.signal,
25516
+ setup
25517
+ }) : await ctx.agents.create({
25518
+ sessionId,
25519
+ meta: { cwd: rootPath },
25520
+ agentOptions: { provider: "deepseek-official", model: input.requestedModel, reasoningEffort: effort },
25521
+ signal: boundary.signal,
25522
+ setup
25523
+ });
25524
+ const onAbort = () => handle.agent.cancel({ kind: "user" });
25525
+ cancelAgentTurn = onAbort;
25526
+ boundary.signal.addEventListener("abort", onAbort, { once: true });
25527
+ removeAgentAbortListener = () => boundary.signal.removeEventListener("abort", onAbort);
25528
+ if (boundary.signal.aborted) onAbort();
25529
+ boundary.signal.throwIfAborted();
25530
+ let checkpointReached = false;
25531
+ let resolveCheckpoint;
25532
+ const checkpoint = new Promise((resolve6) => {
25533
+ resolveCheckpoint = resolve6;
25534
+ });
25535
+ const dispatchGate = new Promise((resolve6) => {
25536
+ releaseAgentDispatch = resolve6;
25537
+ });
25538
+ ctx.on("llm/stream", (options, next) => {
25539
+ if (String(options.sessionId ?? "") !== String(sessionId)) return next();
25540
+ return (async function* () {
25541
+ await ctx.sessions.flush(handle.agent.session);
25542
+ checkpointReached = true;
25543
+ resolveCheckpoint();
25544
+ await dispatchGate;
25545
+ boundary.signal.throwIfAborted();
25546
+ if (!permitAgentDispatch) throw new Error("deepseek_agent_publication_not_committed");
25547
+ yield* next();
25548
+ })();
25549
+ });
25550
+ const thread = {
25551
+ threadId: String(sessionId),
25552
+ threadPath: rootPath,
25553
+ effectiveModel: input.requestedModel,
25554
+ effectiveReasoningEffort: input.requestedReasoningEffort
25555
+ };
25556
+ const startSeq = handle.agent.session.seq;
25557
+ handle.agent.followup(createUserMessage({
25558
+ content: [{ type: "text", text: input.userPrompt }],
25559
+ source: { kind: "user" }
25560
+ }));
25561
+ const idle = handle.agent.whenIdle();
25562
+ await Promise.race([
25563
+ checkpoint,
25564
+ idle.then(() => {
25565
+ if (!checkpointReached) throw new Error("deepseek_agent_checkpoint_not_reached");
25566
+ })
25567
+ ]);
25568
+ boundary.signal.throwIfAborted();
25569
+ if (input.onThreadReady) {
25570
+ await input.onThreadReady(thread);
25571
+ durableCheckpointed = true;
25572
+ }
25573
+ boundary.signal.throwIfAborted();
25574
+ permitAgentDispatch = true;
25575
+ releaseAgentDispatch();
25576
+ releaseAgentDispatch = () => void 0;
25577
+ await idle;
25578
+ const events = handle.agent.session.events.slice(startSeq);
25579
+ const assistantEvents = events.filter((event) => event.type === "assistant/message");
25580
+ const turnEnd = [...events].reverse().find((event) => event.type === "turn/end");
25581
+ if (!turnEnd || turnEnd.type !== "turn/end" || turnEnd.data.reason.kind !== "completed") {
25582
+ if (turnEnd?.type === "turn/end" && turnEnd.data.reason.kind === "error") {
25583
+ const failure = turnEnd.data.reason.error;
25584
+ throw new LlmError(failure.message, failure.code, {
25585
+ ...failure.status === void 0 ? {} : { status: failure.status },
25586
+ ...failure.providerRetryAfterMs === void 0 ? {} : { providerRetryAfterMs: failure.providerRetryAfterMs }
25587
+ });
25588
+ }
25589
+ const reason = turnEnd?.type === "turn/end" ? turnEnd.data.reason : { kind: "missing" };
25590
+ throw new Error(`deepseek_harness_agent_turn_incomplete:${JSON.stringify(reason)}`);
25591
+ }
25592
+ const last = assistantEvents.at(-1);
25593
+ if (!last || last.type !== "assistant/message" || last.data.interrupted) {
25594
+ throw new Error("deepseek_harness_agent_result_missing");
25595
+ }
25596
+ const usages = assistantEvents.flatMap((event) => event.type === "assistant/message" && event.data.usage ? [event.data.usage] : []);
25597
+ if (usages.length === 0 || proxy.receipts.length !== usages.length) {
25598
+ throw new Error("deepseek_harness_agent_receipt_missing");
25599
+ }
25600
+ const text = validateText(textFromBlocks(last.data.message.content, "text"), "deepseek_harness_agent_result_invalid");
25601
+ const receipts = proxy.receipts;
25602
+ await handle.dispose();
25603
+ return {
25604
+ thread,
25605
+ turn: {
25606
+ text,
25607
+ reasoningContent: textFromBlocks(last.data.message.content, "reasoning") || null,
25608
+ reasoningSummary: null,
25609
+ requestedModel: input.requestedModel,
25610
+ effectiveModel: receipts.at(-1).model,
25611
+ requestedReasoningEffort: input.requestedReasoningEffort,
25612
+ effectiveReasoningEffort: input.requestedReasoningEffort,
25613
+ adapterRequestId: receipts[0].id,
25614
+ adapterResponseId: receipts.at(-1).id,
25615
+ usage: sumUsage(usages),
25616
+ latencyMs: Math.max(0, (this.dependencies.now ?? Date.now)() - startedAt),
25617
+ timeToFirstTokenMs: null,
25618
+ terminalStatus: "completed",
25619
+ toolCalls: evidence,
25620
+ webSearches: []
25621
+ }
25622
+ };
25623
+ } catch (error48) {
25624
+ cancelAgentTurn();
25625
+ releaseAgentDispatch();
25626
+ releaseAgentDispatch = () => void 0;
25627
+ if (!durableCheckpointed && owned) {
25628
+ cleanupUnpublishedWorkspace = true;
25629
+ }
25630
+ throw mapDeepSeekFailure({
25631
+ error: error48,
25632
+ cancelled: input.signal?.aborted === true,
25633
+ deadline: input.signal?.aborted !== true && boundary.signal.aborted,
25634
+ dispatchOutcome: proxyDispatchOutcome(proxy)
25635
+ });
25636
+ } finally {
25637
+ removeAgentAbortListener();
25638
+ boundary.cleanup();
25639
+ await ctx.fiber.dispose().catch(() => void 0);
25640
+ await proxy.close();
25641
+ if (cleanupUnpublishedWorkspace && owned) {
25642
+ await owned.cleanup().catch(() => void 0);
25643
+ this.agentWorkspaces.delete(rootPath);
25644
+ }
25645
+ delete process.env[loopbackEnvName];
25646
+ }
25647
+ }
25648
+ async releaseThread(thread) {
25649
+ const cleanup = this.agentWorkspaces.get(thread.threadPath);
25650
+ if (cleanup) {
25651
+ await cleanup();
25652
+ this.agentWorkspaces.delete(thread.threadPath);
25653
+ return;
25654
+ }
25655
+ const resolved = await realpath4(thread.threadPath);
25656
+ const temporaryRoot = await realpath4(tmpdir4());
25657
+ if (dirname4(resolved) !== temporaryRoot || !basename(resolved).startsWith("vtx-deepseek-harness-")) throw new Error("deepseek_harness_thread_path_not_owned");
25658
+ await rm5(resolved, { recursive: true, force: true });
25659
+ }
25660
+ async close() {
25661
+ this.closing = true;
25662
+ }
25663
+ };
25664
+ }
25665
+ });
25666
+
25667
+ // lib/inference-host/deepseek-credential-store.ts
25668
+ import { createHash as createHash5 } from "node:crypto";
25669
+ var DEEPSEEK_CREDENTIAL_NAMESPACE, MAX_API_KEY_BYTES, validateApiKey, credentialIdentity, parseCredential, serializeCredential, platformCommands, createDeepSeekHarnessCredentialStore;
25670
+ var init_deepseek_credential_store = __esm({
25671
+ "lib/inference-host/deepseek-credential-store.ts"() {
25672
+ "use strict";
25673
+ init_config();
25674
+ init_credential_store();
25675
+ DEEPSEEK_CREDENTIAL_NAMESPACE = "vtxmacro-deepseek-harness";
25676
+ MAX_API_KEY_BYTES = 512;
25677
+ validateApiKey = (raw) => {
25678
+ const apiKey = raw.trim();
25679
+ if (apiKey.length < 16 || Buffer.byteLength(apiKey, "utf8") > MAX_API_KEY_BYTES || /[\s\u0000-\u001f\u007f]/u.test(apiKey)) {
25680
+ throw new Error("DeepSeek API key is invalid. Provide one private key through stdin.");
25681
+ }
25682
+ return apiKey;
25683
+ };
25684
+ credentialIdentity = (apiKey) => `deepseek-key-${createHash5("sha256").update(apiKey).digest("hex").slice(0, 24)}`;
25685
+ parseCredential = (raw) => {
25686
+ let value;
25687
+ try {
25688
+ value = JSON.parse(raw);
25689
+ } catch {
25690
+ throw new Error("Stored DeepSeek Harness credential is invalid JSON.");
25691
+ }
25692
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
25693
+ throw new Error("Stored DeepSeek Harness credential is invalid.");
25694
+ }
25695
+ const record2 = value;
25696
+ const apiKey = validateApiKey(String(record2.api_key ?? ""));
25697
+ const identity = credentialIdentity(apiKey);
25698
+ if (record2.schema_version !== 1 || record2.adapter !== "deepseek-harness" || record2.identity !== identity || Object.keys(record2).sort().join(",") !== "adapter,api_key,identity,schema_version") {
25699
+ throw new Error("Stored DeepSeek Harness credential failed validation.");
25700
+ }
25701
+ return { apiKey, identity };
25702
+ };
25703
+ serializeCredential = (apiKey) => {
25704
+ const validated = validateApiKey(apiKey);
25705
+ return `${JSON.stringify({
25706
+ schema_version: 1,
25707
+ adapter: "deepseek-harness",
25708
+ api_key: validated,
25709
+ identity: credentialIdentity(validated)
25710
+ })}
25711
+ `;
25712
+ };
25713
+ platformCommands = (env, platform) => {
25714
+ if (platform === "win32") return windowsInferenceCredentialCommands;
25715
+ if (platform === "linux" && String(env.WSL_INTEROP || "").trim()) {
25716
+ return windowsInferenceCredentialCommands;
25717
+ }
25718
+ if (platform === "linux") return linuxSecretServiceInferenceCredentialCommands;
25719
+ if (platform === "darwin") return macosKeychainInferenceCredentialCommands;
25720
+ return null;
25721
+ };
25722
+ createDeepSeekHarnessCredentialStore = (config2, dependencies = {}) => {
25723
+ const accountKey = `deepseek-harness:${config2.instanceName}`;
25724
+ const path = `${config2.statePath}.deepseek-harness-secret.json`;
25725
+ const env = dependencies.env ?? process.env;
25726
+ const platform = dependencies.platform ?? process.platform;
25727
+ const commands = dependencies.commands === void 0 ? platformCommands(env, platform) : dependencies.commands;
25728
+ const runner = dependencies.commandRunner ?? runCredentialCommand;
25729
+ if (config2.credentialStoreMode === "os") {
25730
+ if (!commands) {
25731
+ throw new Error("OS credential storage is unavailable for the DeepSeek API key.");
25732
+ }
25733
+ return {
25734
+ read: async (signal) => {
25735
+ const command = commands.lookup(DEEPSEEK_CREDENTIAL_NAMESPACE, accountKey);
25736
+ const result2 = await runner(command, { stdin: null, signal });
25737
+ if ((command.notFoundExitCodes ?? []).includes(result2.exitCode)) return null;
25738
+ if (result2.exitCode !== 0) throw new Error("DeepSeek OS credential lookup failed.");
25739
+ return parseCredential(result2.stdout);
25740
+ },
25741
+ write: async (apiKey, signal) => {
25742
+ const serialized = serializeCredential(apiKey);
25743
+ const priorLookup = commands.lookup(DEEPSEEK_CREDENTIAL_NAMESPACE, accountKey);
25744
+ const priorResult = await runner(priorLookup, { stdin: null, signal });
25745
+ const prior = (priorLookup.notFoundExitCodes ?? []).includes(priorResult.exitCode) ? null : priorResult.exitCode === 0 ? parseCredential(priorResult.stdout) : void 0;
25746
+ if (prior === void 0) throw new Error("DeepSeek OS credential lookup failed before write.");
25747
+ const command = commands.store(DEEPSEEK_CREDENTIAL_NAMESPACE, accountKey);
25748
+ if (command.args.some((value) => value.includes(validateApiKey(apiKey)))) {
25749
+ throw new Error("DeepSeek API key must never be passed in command arguments.");
25750
+ }
25751
+ try {
25752
+ const result2 = await runner(command, { stdin: serialized, signal });
25753
+ if (result2.exitCode !== 0) throw new Error("DeepSeek OS credential write failed.");
25754
+ const retainedCommand = commands.lookup(DEEPSEEK_CREDENTIAL_NAMESPACE, accountKey);
25755
+ const retained = await runner(retainedCommand, { stdin: null, signal });
25756
+ if (retained.exitCode !== 0) {
25757
+ throw new Error("DeepSeek OS credential write could not be verified.");
25758
+ }
25759
+ const expected = parseCredential(serialized);
25760
+ const observed = parseCredential(retained.stdout);
25761
+ if (observed.identity !== expected.identity || observed.apiKey !== expected.apiKey) {
25762
+ throw new Error("DeepSeek OS credential write could not be verified.");
25763
+ }
25764
+ return observed;
25765
+ } catch (error48) {
25766
+ const rollback = prior ? commands.store(DEEPSEEK_CREDENTIAL_NAMESPACE, accountKey) : commands.remove(DEEPSEEK_CREDENTIAL_NAMESPACE, accountKey);
25767
+ const rollbackResult = await runner(rollback, {
25768
+ stdin: prior ? serializeCredential(prior.apiKey) : null
25769
+ });
25770
+ if (rollbackResult.exitCode !== 0 && !(rollback.notFoundExitCodes ?? []).includes(rollbackResult.exitCode)) {
25771
+ throw new Error("DeepSeek OS credential write failed and rollback failed.", {
25772
+ cause: error48
25773
+ });
25774
+ }
25775
+ const verifyCommand = commands.lookup(DEEPSEEK_CREDENTIAL_NAMESPACE, accountKey);
25776
+ const verified = await runner(verifyCommand, { stdin: null });
25777
+ const absent = (verifyCommand.notFoundExitCodes ?? []).includes(verified.exitCode);
25778
+ const restored = prior && verified.exitCode === 0 ? parseCredential(verified.stdout) : null;
25779
+ if (prior === null && !absent || prior !== null && (!restored || restored.identity !== prior.identity || restored.apiKey !== prior.apiKey)) {
25780
+ throw new Error("DeepSeek OS credential write failed and rollback could not be verified.", {
25781
+ cause: error48
25782
+ });
25783
+ }
25784
+ throw error48;
25785
+ }
25786
+ },
25787
+ remove: async (signal) => {
25788
+ const command = commands.remove(DEEPSEEK_CREDENTIAL_NAMESPACE, accountKey);
25789
+ const result2 = await runner(command, { stdin: null, signal });
25790
+ if (result2.exitCode !== 0 && !(command.notFoundExitCodes ?? []).includes(result2.exitCode)) throw new Error("DeepSeek OS credential removal failed.");
25791
+ const retainedCommand = commands.lookup(DEEPSEEK_CREDENTIAL_NAMESPACE, accountKey);
25792
+ const retained = await runner(retainedCommand, { stdin: null });
25793
+ if (!(retainedCommand.notFoundExitCodes ?? []).includes(retained.exitCode)) {
25794
+ throw new Error("DeepSeek OS credential removal could not be verified.");
25795
+ }
25796
+ }
25797
+ };
25798
+ }
25799
+ return {
25800
+ read: async () => {
25801
+ const raw = await readInferencePrivateFile(path, "DeepSeek Harness credential file");
25802
+ return raw === null ? null : parseCredential(raw);
25803
+ },
25804
+ write: async (apiKey) => {
25805
+ const serialized = serializeCredential(apiKey);
25806
+ await writeAtomicInferencePrivateFile(path, serialized);
25807
+ const retained = await readInferencePrivateFile(path, "DeepSeek Harness credential file");
25808
+ if (retained !== serialized) throw new Error("DeepSeek credential write could not be verified.");
25809
+ return parseCredential(serialized);
25810
+ },
25811
+ remove: async () => {
25812
+ await clearInferencePrivateFile(path, "DeepSeek Harness credential file");
25813
+ }
25814
+ };
25815
+ };
25816
+ }
25817
+ });
25818
+
24725
25819
  // lib/inference-host/durable-adapter.ts
24726
25820
  var DURABLE_INFERENCE_ADAPTER_IDS, isDurableInferenceAdapterId, durableAdapterDisplayName;
24727
25821
  var init_durable_adapter = __esm({
@@ -24729,12 +25823,14 @@ var init_durable_adapter = __esm({
24729
25823
  "use strict";
24730
25824
  DURABLE_INFERENCE_ADAPTER_IDS = [
24731
25825
  "codex",
24732
- "copilot"
25826
+ "copilot",
25827
+ "deepseek-harness"
24733
25828
  ];
24734
25829
  isDurableInferenceAdapterId = (value) => DURABLE_INFERENCE_ADAPTER_IDS.includes(value);
24735
25830
  durableAdapterDisplayName = (adapter) => ({
24736
25831
  codex: "Codex",
24737
- copilot: "GitHub Copilot"
25832
+ copilot: "GitHub Copilot",
25833
+ "deepseek-harness": "DeepSeek Harness"
24738
25834
  })[adapter];
24739
25835
  }
24740
25836
  });
@@ -24743,13 +25839,13 @@ var init_durable_adapter = __esm({
24743
25839
  import {
24744
25840
  createCipheriv,
24745
25841
  createDecipheriv,
24746
- createHash as createHash5,
25842
+ createHash as createHash6,
24747
25843
  createPrivateKey,
24748
25844
  createPublicKey,
24749
25845
  diffieHellman,
24750
25846
  generateKeyPairSync,
24751
25847
  hkdfSync,
24752
- randomBytes as randomBytes4
25848
+ randomBytes as randomBytes5
24753
25849
  } from "node:crypto";
24754
25850
  var ENVELOPE_SUITE, JOB_KEY_PAYLOAD_SCHEMA_VERSION, WRAP_HKDF_INFO, PAYLOAD_HKDF_INFO, X25519_PKCS8_PREFIX, X25519_SPKI_PREFIX, ExternalInferenceEnvelopeError, canonicalize, canonicalEnvelopeAadBytes, externalInferenceSha256, decodeCanonicalBase64Url, rawPrivateKey, rawPublicKey, rawPublicBytes, aesGcmDecrypt, aesGcmEncrypt, assertIdentity, validatePlaintext, generateExternalInferenceEnvelopeKeyPair, externalInferenceEnvelopePublicKey, deriveKey, deriveExternalInferencePayloadKey, unwrapExternalInferenceJobKey, decryptExternalInferenceJobInput, decryptExternalInferenceClaim, sealExternalInferenceCandidate;
24755
25851
  var init_crypto = __esm({
@@ -24782,7 +25878,7 @@ var init_crypto = __esm({
24782
25878
  const aad = envelopeAadSchema.parse(input);
24783
25879
  return Buffer.from(JSON.stringify(canonicalize(aad)), "utf8");
24784
25880
  };
24785
- externalInferenceSha256 = (value) => createHash5("sha256").update(value).digest("hex");
25881
+ externalInferenceSha256 = (value) => createHash6("sha256").update(value).digest("hex");
24786
25882
  decodeCanonicalBase64Url = (value, fieldName, expectedBytes) => {
24787
25883
  if (!/^[A-Za-z0-9_-]+$/u.test(value)) {
24788
25884
  throw new ExternalInferenceEnvelopeError("invalid_encoding", `${fieldName} is invalid.`);
@@ -24881,7 +25977,7 @@ var init_crypto = __esm({
24881
25977
  return Buffer.from(hkdfSync(
24882
25978
  "sha256",
24883
25979
  root,
24884
- createHash5("sha256").update(aadBytes).digest(),
25980
+ createHash6("sha256").update(aadBytes).digest(),
24885
25981
  info,
24886
25982
  32
24887
25983
  ));
@@ -25023,7 +26119,7 @@ var init_crypto = __esm({
25023
26119
  "External inference candidate must not be empty."
25024
26120
  );
25025
26121
  }
25026
- const nonce = options.nonce ? Buffer.from(options.nonce) : randomBytes4(12);
26122
+ const nonce = options.nonce ? Buffer.from(options.nonce) : randomBytes5(12);
25027
26123
  if (nonce.length !== 12) {
25028
26124
  throw new ExternalInferenceEnvelopeError(
25029
26125
  "invalid_nonce",
@@ -31295,7 +32391,7 @@ var require_ajv = __commonJS({
31295
32391
  });
31296
32392
 
31297
32393
  // lib/inference-host/runner.ts
31298
- import { createHash as createHash6, randomUUID as randomUUID2 } from "node:crypto";
32394
+ import { createHash as createHash7, randomUUID as randomUUID3 } from "node:crypto";
31299
32395
  function createDefaultInferenceHostRunnerDependencies(options) {
31300
32396
  const fetchImpl = options.fetchImpl ?? fetch;
31301
32397
  return {
@@ -31330,7 +32426,7 @@ function createDefaultInferenceHostRunnerDependencies(options) {
31330
32426
  envelopePublicKey: options.envelopePublicKey
31331
32427
  };
31332
32428
  }
31333
- 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, MIN_HOST_HEARTBEAT_GAP_DIAGNOSTIC_MS, HOST_HEARTBEAT_GAP_DIAGNOSTIC_FACTOR, DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS, MIN_CLAIM_START_WINDOW_MS, MAX_ATTEMPT_START_RETRY_DELAY_MS, UNBOUNDED_AVAILABLE_SLOTS, buildInferenceAdvertisedModels, summarizeInferenceHostRuntimeRecovery, FileInferenceHostRuntimeReceiptStore, InferenceHostRecoveryRequiredError, InferenceHostRunnerError, defaultSleep, abortError, settlesWithin, defaultRegisterSignalHandlers, safeInteger, exactObjectKeys, validIso, validateAttemptReceipt, validateRuntimeReceipt, sha256, stableOperationId, buildAttemptStartRequest, isoAt, providerWeeklyQuotaFromRateLimits, finitePositiveOption, validateRunnerOptions, assertLocalCredentialIdentity, retryableRemoteError, remoteRetryAfterMs, controlPlaneFatal, defaultValidateOutput, objectRecord, positiveUtf8ByteLimit, assertCompilableOutputSchema, parseOutputContract, membershipFailureDisposition, safeFailureCode, attemptStartRetryFallbackMs, exactJson2, runnerIdentityMismatch, assertAdvertisementResult, assertHostHeartbeatResult, assertClaimResult, assertStartResult, assertJobHeartbeatResult, assertTerminalResult, classifyFailure, ambiguousHeartbeatTransport, reportedTokenUsage, reportedUsage, InferenceHostRunner, createInferenceAgentControlClient, INFERENCE_AGENT_SYSTEM_PROMPT, INFERENCE_AGENT_WAKE_SCHEMA, parseInferenceAgentWake, InferenceAgentRuntime;
32429
+ 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, MIN_HOST_HEARTBEAT_GAP_DIAGNOSTIC_MS, HOST_HEARTBEAT_GAP_DIAGNOSTIC_FACTOR, DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS, DEFAULT_AGENT_RATE_LIMIT_COOLDOWN_MS, DEFAULT_AGENT_QUOTA_COOLDOWN_MS, DEFAULT_AGENT_TRANSIENT_COOLDOWN_MS, MIN_CLAIM_START_WINDOW_MS, MAX_ATTEMPT_START_RETRY_DELAY_MS, UNBOUNDED_AVAILABLE_SLOTS, buildInferenceAdvertisedModels, summarizeInferenceHostRuntimeRecovery, FileInferenceHostRuntimeReceiptStore, InferenceHostRecoveryRequiredError, InferenceHostRunnerError, defaultSleep, abortError, settlesWithin, defaultRegisterSignalHandlers, safeInteger, exactObjectKeys, validIso, validateAttemptReceipt, validateRuntimeReceipt, sha256, stableOperationId, buildAttemptStartRequest, isoAt, providerWeeklyQuotaFromRateLimits, finitePositiveOption, validateRunnerOptions, assertLocalCredentialIdentity, retryableRemoteError, remoteRetryAfterMs, controlPlaneFatal, defaultValidateOutput, objectRecord, positiveUtf8ByteLimit, assertCompilableOutputSchema, parseOutputContract, membershipFailureDisposition, safeFailureCode, attemptStartRetryFallbackMs, exactJson2, runnerIdentityMismatch, assertAdvertisementResult, assertHostHeartbeatResult, assertClaimResult, assertStartResult, assertJobHeartbeatResult, assertTerminalResult, classifyFailure, ambiguousHeartbeatTransport, reportedTokenUsage, reportedUsage, InferenceHostRunner, createInferenceAgentControlClient, INFERENCE_AGENT_SYSTEM_PROMPT, INFERENCE_AGENT_WAKE_SCHEMA, parseInferenceAgentWake, InferenceAgentRuntime;
31334
32430
  var init_runner = __esm({
31335
32431
  "lib/inference-host/runner.ts"() {
31336
32432
  "use strict";
@@ -31356,6 +32452,9 @@ var init_runner = __esm({
31356
32452
  MIN_HOST_HEARTBEAT_GAP_DIAGNOSTIC_MS = 1e4;
31357
32453
  HOST_HEARTBEAT_GAP_DIAGNOSTIC_FACTOR = 3;
31358
32454
  DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS = 5 * 60 * 1e3;
32455
+ DEFAULT_AGENT_RATE_LIMIT_COOLDOWN_MS = 6e4;
32456
+ DEFAULT_AGENT_QUOTA_COOLDOWN_MS = 5 * 60 * 1e3;
32457
+ DEFAULT_AGENT_TRANSIENT_COOLDOWN_MS = 5e3;
31359
32458
  MIN_CLAIM_START_WINDOW_MS = 5e3;
31360
32459
  MAX_ATTEMPT_START_RETRY_DELAY_MS = 15e3;
31361
32460
  UNBOUNDED_AVAILABLE_SLOTS = Number.MAX_SAFE_INTEGER;
@@ -31622,7 +32721,7 @@ var init_runner = __esm({
31622
32721
  attempts
31623
32722
  };
31624
32723
  };
31625
- sha256 = (value) => createHash6("sha256").update(value, "utf8").digest("hex");
32724
+ sha256 = (value) => createHash7("sha256").update(value, "utf8").digest("hex");
31626
32725
  stableOperationId = (kind, parts) => `${kind}_${sha256(JSON.stringify(parts)).slice(0, 48)}`;
31627
32726
  buildAttemptStartRequest = (claim, attemptId, startedAt) => attemptStartRequestSchema.parse({
31628
32727
  schema_version: "external_inference_attempt_start_v1",
@@ -31895,7 +32994,7 @@ var init_runner = __esm({
31895
32994
  membershipFailureDisposition = (failure) => {
31896
32995
  if (failure.dispatchOutcome === "outcome_unknown") return "quarantine_ambiguous";
31897
32996
  if (failure.category === "auth" || ["auth_expired", "managed_chatgpt_auth_required", "invalid_account_metadata"].includes(failure.code)) return "cascade_disable";
31898
- if (failure.category === "quota" || ["quota_exceeded", "codex_rate_limited"].includes(failure.code)) return "cascade_cooldown";
32997
+ if (failure.category === "quota" || ["quota_exceeded", "codex_rate_limited", "provider_rate_limited"].includes(failure.code)) return "cascade_cooldown";
31899
32998
  if (failure.retryable && (["adapter", "network", "transport"].includes(failure.category) || failure.code === "rpc_timeout")) return "retry_same_host";
31900
32999
  if (["model_unavailable", "reasoning_effort_unavailable"].includes(failure.code)) return "cascade_cooldown";
31901
33000
  if ([
@@ -32169,6 +33268,43 @@ var init_runner = __esm({
32169
33268
  const agentRuntimeSettings = settings.agentRuntime;
32170
33269
  agentLoop = (async () => {
32171
33270
  while (!agentAbort.signal.aborted) {
33271
+ const existingFence = await readInferenceAgentFailureFence(
33272
+ agentRuntimeSettings.statePath
33273
+ );
33274
+ if (existingFence) {
33275
+ if (existingFence.adapter_id !== settings.adapterId || existingFence.host_id !== localState.host_id) {
33276
+ throw new InferenceHostRecoveryRequiredError(
33277
+ "Inference Agent failure fence belongs to another host or adapter."
33278
+ );
33279
+ }
33280
+ if (existingFence.retry_at === null) {
33281
+ emitDiagnostic("agent_runtime_quarantined", {
33282
+ assignment_id: existingFence.assignment_id,
33283
+ failure_category: existingFence.failure_category,
33284
+ failure_code: existingFence.failure_code,
33285
+ dispatch_outcome: existingFence.dispatch_outcome
33286
+ });
33287
+ return;
33288
+ }
33289
+ const retryAtMs = Date.parse(existingFence.retry_at);
33290
+ if (retryAtMs > now()) {
33291
+ emitDiagnostic("agent_runtime_cooldown", {
33292
+ assignment_id: existingFence.assignment_id,
33293
+ failure_category: existingFence.failure_category,
33294
+ failure_code: existingFence.failure_code,
33295
+ dispatch_outcome: existingFence.dispatch_outcome,
33296
+ cooldown_until: existingFence.retry_at
33297
+ });
33298
+ if (this.options.once) return;
33299
+ try {
33300
+ await sleep4(Math.max(MIN_SLEEP_MS, retryAtMs - now()), agentAbort.signal);
33301
+ } catch {
33302
+ return;
33303
+ }
33304
+ continue;
33305
+ }
33306
+ await clearInferenceAgentFailureFence(agentRuntimeSettings.statePath);
33307
+ }
32172
33308
  const agentRuntime = new InferenceAgentRuntime({
32173
33309
  adapterId: settings.adapterId,
32174
33310
  hostId: localState.host_id,
@@ -32189,6 +33325,51 @@ var init_runner = __esm({
32189
33325
  requestDrain("authority_lost");
32190
33326
  return;
32191
33327
  }
33328
+ if (error48 instanceof CodexAppServerError) {
33329
+ const failure = classifyFailure(error48);
33330
+ const providerLimited = failure.category === "auth" || failure.category === "quota" || ["quota_exceeded", "codex_rate_limited", "provider_rate_limited"].includes(failure.code);
33331
+ const deepSeekTransient = settings.adapterId === "deepseek-harness" && failure.retryable;
33332
+ if (failure.dispatchOutcome === "outcome_unknown" || providerLimited || deepSeekTransient) {
33333
+ const runtimeState = await readInferenceAgentRuntimeState(
33334
+ agentRuntimeSettings.statePath
33335
+ );
33336
+ const retryAtMs = failure.dispatchOutcome === "outcome_unknown" || failure.category === "auth" && settings.adapterId === "deepseek-harness" ? null : error48.retryAtMs !== null && error48.retryAtMs > now() ? error48.retryAtMs : now() + (failure.category === "quota" || failure.code === "quota_exceeded" ? DEFAULT_AGENT_QUOTA_COOLDOWN_MS : failure.category === "auth" ? DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS : failure.code === "provider_rate_limited" || failure.code === "codex_rate_limited" ? DEFAULT_AGENT_RATE_LIMIT_COOLDOWN_MS : DEFAULT_AGENT_TRANSIENT_COOLDOWN_MS);
33337
+ await writeInferenceAgentFailureFence(agentRuntimeSettings.statePath, {
33338
+ schema_version: "vtx_inference_agent_failure_fence_v1",
33339
+ adapter_id: settings.adapterId,
33340
+ host_id: localState.host_id,
33341
+ assignment_id: runtimeState?.schema_version === "vtx_inference_agent_runtime_v3" ? runtimeState.assignment.assignment_id : null,
33342
+ failure_category: safeFailureCode(failure.category, "adapter"),
33343
+ failure_code: safeFailureCode(failure.code, "adapter_failure"),
33344
+ dispatch_outcome: failure.dispatchOutcome,
33345
+ retry_at: retryAtMs === null ? null : isoAt(retryAtMs),
33346
+ created_at: isoAt(now())
33347
+ });
33348
+ if (failure.dispatchOutcome !== "outcome_unknown") {
33349
+ try {
33350
+ await agentRuntime.releaseAfterProviderFailure(failure.code);
33351
+ } catch {
33352
+ }
33353
+ }
33354
+ emitDiagnostic(
33355
+ retryAtMs === null ? "agent_runtime_quarantined" : "agent_runtime_cooldown",
33356
+ {
33357
+ assignment_id: runtimeState?.schema_version === "vtx_inference_agent_runtime_v3" ? runtimeState.assignment.assignment_id : null,
33358
+ failure_category: failure.category,
33359
+ failure_code: failure.code,
33360
+ dispatch_outcome: failure.dispatchOutcome,
33361
+ cooldown_until: retryAtMs === null ? null : isoAt(retryAtMs)
33362
+ }
33363
+ );
33364
+ if (this.options.once || retryAtMs === null) return;
33365
+ try {
33366
+ await sleep4(Math.max(MIN_SLEEP_MS, retryAtMs - now()), agentAbort.signal);
33367
+ } catch {
33368
+ return;
33369
+ }
33370
+ continue;
33371
+ }
33372
+ }
32192
33373
  emitDiagnostic("agent_runtime_retry", {
32193
33374
  error_code: error48 && typeof error48 === "object" && "code" in error48 ? String(error48.code) : "agent_runtime_error"
32194
33375
  });
@@ -32201,7 +33382,13 @@ var init_runner = __esm({
32201
33382
  }
32202
33383
  }
32203
33384
  })();
32204
- void agentLoop.catch(() => void 0);
33385
+ void agentLoop.catch((error48) => {
33386
+ if (agentAbort.signal.aborted) return;
33387
+ emitDiagnostic("agent_runtime_fence_failed", {
33388
+ error_code: error48 && typeof error48 === "object" && "code" in error48 ? String(error48.code) : "agent_runtime_fence_failed"
33389
+ });
33390
+ requestDrain("agent_recovery_failed");
33391
+ });
32205
33392
  }
32206
33393
  const existingReceipt = await this.dependencies.receiptStore.read();
32207
33394
  const identityMatches = existingReceipt && existingReceipt.host_id === localState.host_id && existingReceipt.host_generation === localState.host_generation && existingReceipt.key_generation === localState.key_generation;
@@ -32284,6 +33471,7 @@ var init_runner = __esm({
32284
33471
  }
32285
33472
  throw lastError;
32286
33473
  };
33474
+ let advertisementHandoff = null;
32287
33475
  const publishAdvertisement = async (health, forceAdvance, retryRemote = true, allowDefinitiveReseed = true) => {
32288
33476
  let advertisement = receipt.pending_advertisement;
32289
33477
  if (!advertisement) {
@@ -32332,6 +33520,11 @@ var init_runner = __esm({
32332
33520
  }
32333
33521
  const tool = receipt.registered ? "inference.host.advertise" : "inference.host.register";
32334
33522
  let result2;
33523
+ let releaseAdvertisementHandoff;
33524
+ const currentAdvertisementHandoff = new Promise((resolve6) => {
33525
+ releaseAdvertisementHandoff = resolve6;
33526
+ });
33527
+ advertisementHandoff = currentAdvertisementHandoff;
32335
33528
  try {
32336
33529
  const advertiseOperation = () => mcp.callTool(
32337
33530
  tool,
@@ -32339,6 +33532,15 @@ var init_runner = __esm({
32339
33532
  { signal: this.options.signal }
32340
33533
  );
32341
33534
  result2 = retryRemote ? await retryExact(advertiseOperation, { signal: this.options.signal }) : await advertiseOperation();
33535
+ assertAdvertisementResult(advertisement, result2);
33536
+ await mutateReceipt((current) => ({
33537
+ ...current,
33538
+ registered: true,
33539
+ advertisement_generation: result2.host.advertisement_generation,
33540
+ advertisement_expires_at: advertisement.expires_at,
33541
+ pending_advertisement: current.pending_advertisement?.operation_id === advertisement.operation_id ? null : current.pending_advertisement,
33542
+ updated_at: isoAt(now())
33543
+ }));
32342
33544
  } catch (error48) {
32343
33545
  const definitivelyNotApplied = error48 instanceof ExternalInferenceMcpError ? error48.definitivelyNotApplied : Boolean(error48 && typeof error48 === "object" && error48.definitivelyNotApplied === true);
32344
33546
  const expectedGeneration = receipt.registered ? receipt.advertisement_generation + 1 : receipt.advertisement_generation;
@@ -32351,16 +33553,12 @@ var init_runner = __esm({
32351
33553
  return await publishAdvertisement(health, forceAdvance, retryRemote, false);
32352
33554
  }
32353
33555
  throw error48;
33556
+ } finally {
33557
+ releaseAdvertisementHandoff();
33558
+ if (advertisementHandoff === currentAdvertisementHandoff) {
33559
+ advertisementHandoff = null;
33560
+ }
32354
33561
  }
32355
- assertAdvertisementResult(advertisement, result2);
32356
- await mutateReceipt((current) => ({
32357
- ...current,
32358
- registered: true,
32359
- advertisement_generation: result2.host.advertisement_generation,
32360
- advertisement_expires_at: advertisement.expires_at,
32361
- pending_advertisement: current.pending_advertisement?.operation_id === advertisement.operation_id ? null : current.pending_advertisement,
32362
- updated_at: isoAt(now())
32363
- }));
32364
33562
  };
32365
33563
  const wasRegistered = receipt.registered;
32366
33564
  await publishAdvertisement("healthy", wasRegistered);
@@ -32475,10 +33673,24 @@ var init_runner = __esm({
32475
33673
  if (drainRequested || hostHeartbeatAbort.signal.aborted) return;
32476
33674
  const heartbeatStartedAt = now();
32477
33675
  observeHostHeartbeatGap(heartbeatStartedAt);
33676
+ const pendingAdvertisementHandoff = advertisementHandoff;
33677
+ if (pendingAdvertisementHandoff !== null) {
33678
+ try {
33679
+ await Promise.race([
33680
+ pendingAdvertisementHandoff,
33681
+ sleep4(settings.hostHeartbeatMs, hostHeartbeatAbort.signal)
33682
+ ]);
33683
+ } catch (error48) {
33684
+ if (hostHeartbeatAbort.signal.aborted || drainRequested) return;
33685
+ throw error48;
33686
+ }
33687
+ }
33688
+ if (drainRequested || hostHeartbeatAbort.signal.aborted) return;
33689
+ const heartbeatAttemptedAt = now();
32478
33690
  const attemptedAdvertisementGeneration = receipt.advertisement_generation;
32479
33691
  try {
32480
33692
  const expiresAt = receipt.advertisement_expires_at ? Date.parse(receipt.advertisement_expires_at) : 0;
32481
- const refreshPendingAcrossExpiry = receipt.pending_advertisement !== null && expiresAt <= heartbeatStartedAt;
33693
+ const refreshPendingAcrossExpiry = receipt.pending_advertisement !== null && expiresAt <= heartbeatAttemptedAt;
32482
33694
  await hostHeartbeat(
32483
33695
  "healthy",
32484
33696
  { signal: hostHeartbeatAbort.signal },
@@ -33379,10 +34591,10 @@ var init_runner = __esm({
33379
34591
  if (error48 instanceof InferenceHostRunnerError && error48.code === "terminal_outcome_unconfirmed") {
33380
34592
  throw error48;
33381
34593
  }
33382
- if (error48 instanceof CodexAppServerError && error48.retryAtMs !== null && ["quota_exceeded", "codex_rate_limited"].includes(error48.code)) {
34594
+ if (error48 instanceof CodexAppServerError && error48.retryAtMs !== null && ["quota_exceeded", "codex_rate_limited", "provider_rate_limited"].includes(error48.code)) {
33383
34595
  options.onProviderCooldown?.({
33384
34596
  retryAtMs: error48.retryAtMs,
33385
- reason: error48.code === "quota_exceeded" ? "quota_exceeded" : "codex_rate_limited",
34597
+ reason: error48.code === "quota_exceeded" ? "quota_exceeded" : error48.code === "provider_rate_limited" ? "provider_rate_limited" : "codex_rate_limited",
33386
34598
  rateLimits: error48.rateLimits
33387
34599
  });
33388
34600
  }
@@ -33597,6 +34809,9 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33597
34809
  stop() {
33598
34810
  this.stopped = true;
33599
34811
  }
34812
+ async releaseAfterProviderFailure(reasonCode) {
34813
+ await this.releaseForHostStop(safeFailureCode(reasonCode, "provider_failure"));
34814
+ }
33600
34815
  async run(signal) {
33601
34816
  let exitedNormally = false;
33602
34817
  try {
@@ -33613,10 +34828,14 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33613
34828
  }
33614
34829
  }
33615
34830
  async runSingle(signal) {
34831
+ let exitedNormally = false;
33616
34832
  try {
33617
34833
  await this.runOnce(signal);
34834
+ exitedNormally = true;
33618
34835
  } finally {
33619
- await this.releaseForHostStop();
34836
+ if (exitedNormally || this.stopped || signal?.aborted) {
34837
+ await this.releaseForHostStop();
34838
+ }
33620
34839
  }
33621
34840
  }
33622
34841
  async runOnce(signal) {
@@ -33662,7 +34881,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33662
34881
  }
33663
34882
  if (!state) {
33664
34883
  const assignment2 = await this.options.controlClient.nextAssignment({
33665
- operation_id: randomUUID2(),
34884
+ operation_id: randomUUID3(),
33666
34885
  host_id: this.options.hostId,
33667
34886
  requested_at: nowIso()
33668
34887
  }, { signal });
@@ -33695,7 +34914,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33695
34914
  state = await this.resolvePendingDecision(state, signal);
33696
34915
  let assignment = state.assignment;
33697
34916
  const preTurnHeartbeat = await this.options.controlClient.heartbeat({
33698
- operation_id: randomUUID2(),
34917
+ operation_id: randomUUID3(),
33699
34918
  host_id: this.options.hostId,
33700
34919
  assignment_id: assignment.assignment_id,
33701
34920
  assignment_generation: assignment.assignment_generation,
@@ -33720,7 +34939,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33720
34939
  const heartbeatTask = (async () => {
33721
34940
  while (!heartbeatStopped && !turnAbort.signal.aborted) {
33722
34941
  const heartbeat = await this.options.controlClient.heartbeat({
33723
- operation_id: randomUUID2(),
34942
+ operation_id: randomUUID3(),
33724
34943
  host_id: this.options.hostId,
33725
34944
  assignment_id: assignment.assignment_id,
33726
34945
  assignment_generation: assignment.assignment_generation,
@@ -33777,7 +34996,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33777
34996
  return { success: false, value: { error: "invalid_data_request" } };
33778
34997
  }
33779
34998
  const value = await this.options.controlClient.dataCall({
33780
- operation_id: randomUUID2(),
34999
+ operation_id: randomUUID3(),
33781
35000
  host_id: this.options.hostId,
33782
35001
  assignment_id: assignment.assignment_id,
33783
35002
  assignment_generation: assignment.assignment_generation,
@@ -33801,7 +35020,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33801
35020
  return { success: false, value: { error: "decision_outcome_unresolved" } };
33802
35021
  }
33803
35022
  const pending = {
33804
- operation_id: randomUUID2(),
35023
+ operation_id: randomUUID3(),
33805
35024
  candidate,
33806
35025
  observed_at: nowIso(),
33807
35026
  provenance: {
@@ -33875,7 +35094,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33875
35094
  const nextWakeAtMs = this.now() + wakeSeconds * 1e3;
33876
35095
  const scheduledWakeAt = new Date(nextWakeAtMs).toISOString();
33877
35096
  const wakeHeartbeat = await this.options.controlClient.heartbeat({
33878
- operation_id: randomUUID2(),
35097
+ operation_id: randomUUID3(),
33879
35098
  host_id: this.options.hostId,
33880
35099
  assignment_id: assignment.assignment_id,
33881
35100
  assignment_generation: assignment.assignment_generation,
@@ -33993,7 +35212,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33993
35212
  if (state?.schema_version !== "vtx_inference_agent_runtime_v3" || state.adapter_id !== this.options.adapterId) return "cancelled";
33994
35213
  const requestedAt = new Date(this.now()).toISOString();
33995
35214
  const heartbeat = await this.options.controlClient.heartbeat({
33996
- operation_id: randomUUID2(),
35215
+ operation_id: randomUUID3(),
33997
35216
  host_id: this.options.hostId,
33998
35217
  assignment_id: state.assignment.assignment_id,
33999
35218
  assignment_generation: state.assignment.assignment_generation,
@@ -34014,7 +35233,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
34014
35233
  }
34015
35234
  return this.stopped || signal?.aborted ? "stopped" : "ready";
34016
35235
  }
34017
- async releaseForHostStop() {
35236
+ async releaseForHostStop(reasonCode = "host_stopped") {
34018
35237
  const recovered = await readInferenceAgentRuntimeState(this.options.statePath);
34019
35238
  if (!recovered) return;
34020
35239
  let state;
@@ -34040,11 +35259,11 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
34040
35259
  }
34041
35260
  if (state.pending_decision) return;
34042
35261
  await this.options.controlClient.releaseAssignment({
34043
- operation_id: randomUUID2(),
35262
+ operation_id: randomUUID3(),
34044
35263
  host_id: this.options.hostId,
34045
35264
  assignment_id: state.assignment.assignment_id,
34046
35265
  assignment_generation: state.assignment.assignment_generation,
34047
- reason_code: "host_stopped",
35266
+ reason_code: reasonCode,
34048
35267
  requested_at: new Date(this.now()).toISOString()
34049
35268
  }, {});
34050
35269
  if (state.thread) await this.options.adapter.releaseThread(state.thread);
@@ -34056,11 +35275,11 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
34056
35275
 
34057
35276
  // lib/inference-host/service.ts
34058
35277
  import { spawn as spawn6 } from "node:child_process";
34059
- import { randomUUID as randomUUID3 } from "node:crypto";
35278
+ import { randomUUID as randomUUID4 } from "node:crypto";
34060
35279
  import { createWriteStream, readFileSync } from "node:fs";
34061
- import { access as access3, chmod as chmod3, mkdir as mkdir3, readFile as readFile5, rm as rm5, writeFile as writeFile2 } from "node:fs/promises";
35280
+ import { access as access3, chmod as chmod3, mkdir as mkdir3, readFile as readFile5, rm as rm6, writeFile as writeFile2 } from "node:fs/promises";
34062
35281
  import { homedir as homedir2 } from "node:os";
34063
- import { dirname as dirname4, join as join6, resolve as resolve4 } from "node:path";
35282
+ import { dirname as dirname5, join as join7, resolve as resolve4 } from "node:path";
34064
35283
  var SERVICE_NAME, SYSTEMD_UNIT, LAUNCHD_LABEL, SERVICE_COOPERATIVE_STOP_SECONDS, INFERENCE_HOST_SERVICE_DRAIN_COMMAND, inferenceHostServiceChildEnvironment, isWindowsSubsystemForLinux, inferenceHostServiceManifestPath, inferenceHostServiceDesiredPath, inferenceHostServiceLogPath, inferenceHostServiceRuntimePath, xmlEscape, plistEscape, systemdQuote, defaultRunCommand, managerName, assertRuntimeEnvironment, withoutConcurrencyLimit, assertServicePath, manifestGeneration, assertWorker, assertManifest, assertServiceRuntimeState, assertDesiredState, readInferenceHostServiceManifest, readManifestAcrossAtomicReplacement, readInferenceHostServiceRuntime, readRuntimeAcrossAtomicReplacement, readInferenceHostServiceDesired, readDesiredAcrossAtomicReplacement, writeDesired, runtimeEnvironment, serviceArguments, windowsOwnedCommandLine, vbScriptString, windowsServiceLauncher, windowsTaskXml, systemdUnit, launchAgentPlist, sameWorker, sameServiceDefinition, sameWorkerSet, InferenceHostServiceManager, appendServiceLog, spawnInferenceHostServiceChild, runInferenceHostServiceSupervisor;
34065
35284
  var init_service = __esm({
34066
35285
  "lib/inference-host/service.ts"() {
@@ -34529,8 +35748,8 @@ WantedBy=default.target
34529
35748
  }
34530
35749
  definitionPath() {
34531
35750
  if (this.platform === "win32") return `${this.config.supervisorStatePath}.service-task.xml`;
34532
- if (this.platform === "darwin") return join6(this.home, "Library", "LaunchAgents", `${LAUNCHD_LABEL}.plist`);
34533
- return join6(this.home, ".config", "systemd", "user", SYSTEMD_UNIT);
35751
+ if (this.platform === "darwin") return join7(this.home, "Library", "LaunchAgents", `${LAUNCHD_LABEL}.plist`);
35752
+ return join7(this.home, ".config", "systemd", "user", SYSTEMD_UNIT);
34534
35753
  }
34535
35754
  windowsLauncherPath() {
34536
35755
  return `${this.config.supervisorStatePath}.service-launcher.vbs`;
@@ -34581,7 +35800,7 @@ WantedBy=default.target
34581
35800
  const previousRuntimeUpdatedAt = previousRuntime?.manifest_generation === manifest.generation ? Date.parse(previousRuntime.updated_at) : Number.NaN;
34582
35801
  const restoredManifest = preserveGeneration ? manifest : assertManifest({
34583
35802
  ...manifest,
34584
- generation: randomUUID3(),
35803
+ generation: randomUUID4(),
34585
35804
  installed_at: this.now().toISOString()
34586
35805
  });
34587
35806
  await writeAtomicInferencePrivateFile(
@@ -34663,7 +35882,7 @@ ${result2.stderr}`)) {
34663
35882
  await writeAtomicInferencePrivateFile(this.manifestPath(), `${JSON.stringify(manifest, null, 2)}
34664
35883
  `);
34665
35884
  await writeDesired(this.desiredPath(), desiredRunning, this.now());
34666
- await mkdir3(dirname4(this.definitionPath()), { recursive: true, mode: 448 });
35885
+ await mkdir3(dirname5(this.definitionPath()), { recursive: true, mode: 448 });
34667
35886
  if (this.platform === "win32") {
34668
35887
  await writeAtomicInferencePrivateFile(
34669
35888
  this.windowsLauncherPath(),
@@ -34712,13 +35931,13 @@ ${cleanup.stderr}`)) {
34712
35931
  );
34713
35932
  }
34714
35933
  }
34715
- await rm5(this.definitionPath(), { force: true }).catch(() => void 0);
35934
+ await rm6(this.definitionPath(), { force: true }).catch(() => void 0);
34716
35935
  if (this.platform === "win32") {
34717
- await rm5(this.windowsLauncherPath(), { force: true }).catch(() => void 0);
35936
+ await rm6(this.windowsLauncherPath(), { force: true }).catch(() => void 0);
34718
35937
  }
34719
- await rm5(this.manifestPath(), { force: true }).catch(() => void 0);
34720
- await rm5(this.desiredPath(), { force: true }).catch(() => void 0);
34721
- await rm5(this.runtimePath(), { force: true }).catch(() => void 0);
35938
+ await rm6(this.manifestPath(), { force: true }).catch(() => void 0);
35939
+ await rm6(this.desiredPath(), { force: true }).catch(() => void 0);
35940
+ await rm6(this.runtimePath(), { force: true }).catch(() => void 0);
34722
35941
  if (this.platform === "linux") {
34723
35942
  await this.runCommand("systemctl", ["--user", "daemon-reload"]).catch(() => void 0);
34724
35943
  }
@@ -34867,7 +36086,7 @@ ${cleanup.stderr}`)) {
34867
36086
  ].sort((left, right) => left.instance_name.localeCompare(right.instance_name));
34868
36087
  const manifest = assertManifest({
34869
36088
  schema_version: "vtx_inference_service_v3",
34870
- generation: randomUUID3(),
36089
+ generation: randomUUID4(),
34871
36090
  installed_at: this.now().toISOString(),
34872
36091
  executable: this.executable,
34873
36092
  script: this.script,
@@ -35081,7 +36300,7 @@ ${result2.stderr}`)) {
35081
36300
  if (remaining.length === 0) return await this.uninstallUnlocked();
35082
36301
  return await this.replaceManifestUnlocked({
35083
36302
  ...manifest,
35084
- generation: randomUUID3(),
36303
+ generation: randomUUID4(),
35085
36304
  installed_at: this.now().toISOString(),
35086
36305
  workers: remaining
35087
36306
  }, await readInferenceHostServiceDesired(this.desiredPath()));
@@ -35104,12 +36323,12 @@ ${result2.stderr}`)) {
35104
36323
  ${result2.stderr}`)) {
35105
36324
  throw new Error(`Background service uninstall failed: ${result2.stderr.trim()}`);
35106
36325
  }
35107
- await rm5(this.definitionPath(), { force: true });
35108
- if (this.platform === "win32") await rm5(this.windowsLauncherPath(), { force: true });
36326
+ await rm6(this.definitionPath(), { force: true });
36327
+ if (this.platform === "win32") await rm6(this.windowsLauncherPath(), { force: true });
35109
36328
  if (this.platform === "linux") await this.runCommand("systemctl", ["--user", "daemon-reload"]);
35110
- await rm5(this.manifestPath(), { force: true });
35111
- await rm5(this.desiredPath(), { force: true });
35112
- await rm5(this.runtimePath(), { force: true });
36329
+ await rm6(this.manifestPath(), { force: true });
36330
+ await rm6(this.desiredPath(), { force: true });
36331
+ await rm6(this.runtimePath(), { force: true });
35113
36332
  return {
35114
36333
  installed: false,
35115
36334
  desired_running: false,
@@ -35123,7 +36342,7 @@ ${result2.stderr}`)) {
35123
36342
  }
35124
36343
  };
35125
36344
  appendServiceLog = async (path, event, fields = {}) => {
35126
- await mkdir3(dirname4(path), { recursive: true, mode: 448 });
36345
+ await mkdir3(dirname5(path), { recursive: true, mode: 448 });
35127
36346
  const stream = createWriteStream(path, { flags: "a", mode: 384 });
35128
36347
  await new Promise((resolvePromise, reject) => {
35129
36348
  stream.once("error", reject);
@@ -35471,11 +36690,11 @@ __export(cli_exports, {
35471
36690
  registerInferenceHostServiceControlInput: () => registerInferenceHostServiceControlInput,
35472
36691
  runInferenceHostCli: () => runInferenceHostCli
35473
36692
  });
35474
- import { createHash as createHash7, randomUUID as randomUUID4 } from "node:crypto";
36693
+ import { createHash as createHash8, randomUUID as randomUUID5 } from "node:crypto";
35475
36694
  import { spawn as spawn7 } from "node:child_process";
35476
- import { lstat as lstat4, realpath as realpath4, rm as rm6 } from "node:fs/promises";
36695
+ import { lstat as lstat4, realpath as realpath5, rm as rm7 } from "node:fs/promises";
35477
36696
  import { hostname as osHostname } from "node:os";
35478
- import { join as join7, resolve as resolve5 } from "node:path";
36697
+ import { join as join8, resolve as resolve5 } from "node:path";
35479
36698
  async function runInferenceHostCli(argv2, env = process.env, dependencies = {}) {
35480
36699
  const warnings = [];
35481
36700
  try {
@@ -35505,6 +36724,9 @@ async function runInferenceHostCli(argv2, env = process.env, dependencies = {})
35505
36724
  if (parsed.command === "codex-login") {
35506
36725
  return await codexLogin(config2, parsed, env, dependencies);
35507
36726
  }
36727
+ if (parsed.command === "deepseek-login") {
36728
+ return await deepSeekLogin(config2, parsed, dependencies);
36729
+ }
35508
36730
  if (parsed.command === "run") {
35509
36731
  return await runHost(config2, parsed, env, dependencies, warnings);
35510
36732
  }
@@ -35597,11 +36819,14 @@ async function runInferenceHostCli(argv2, env = process.env, dependencies = {})
35597
36819
  if (parsed.command === "codex-logout") {
35598
36820
  return await codexLogout(config2, parsed, env, dependencies);
35599
36821
  }
36822
+ if (parsed.command === "deepseek-logout") {
36823
+ return await deepSeekLogout(config2, parsed, dependencies);
36824
+ }
35600
36825
  if (parsed.command === "revoke") {
35601
36826
  return await cleanupLogin(config2, parsed, dependencies, warnings, true);
35602
36827
  }
35603
36828
  throw new Error(
35604
- "Usage: vtx inference-host <login|codex-login|run|agent-connect|agent-run|agent-next|agent-complete|agent-fail|agent-assignment-next|agent-assignment-heartbeat|agent-data-call|agent-decision-submit|agent-decision-status|agent-assignment-release|service|status|doctor|logout|codex-logout|revoke> [--json]"
36829
+ "Usage: vtx inference-host <login|codex-login|deepseek-login|run|agent-connect|agent-run|agent-next|agent-complete|agent-fail|agent-assignment-next|agent-assignment-heartbeat|agent-data-call|agent-decision-submit|agent-decision-status|agent-assignment-release|service|status|doctor|logout|codex-logout|deepseek-logout|revoke> [--json]"
35605
36830
  );
35606
36831
  } catch (error48) {
35607
36832
  return {
@@ -35612,7 +36837,7 @@ async function runInferenceHostCli(argv2, env = process.env, dependencies = {})
35612
36837
  };
35613
36838
  }
35614
36839
  }
35615
- var INFERENCE_HOST_CLI_VERSION, runtimeReceiptPath, codexRecoveryPath, codexGuardianReceiptRoot, revocationCheckpointPath, foregroundHostLockPath, credentialLifecycleLockPath, serviceRecoveryCommandLockPath, AGENT_HEARTBEAT_INTERVAL_MS, AGENT_HEARTBEAT_MAX_RETRY_DELAY_MS, retryableAgentHeartbeatError, assertRevocationCheckpoint, readRevocationCheckpoint, writeRevocationCheckpoint, clearRevocationCheckpoint, render, INFERENCE_HOST_HELP, parseHostConcurrency, parseInferenceHostArgs, resolveDurableServiceDisplayName, defaultOpenBrowser, registerInferenceHostServiceControlInput, defaultRegisterLifecycleSignalHandlers, lifecycleCancellation, configuredCredentialStore, restoreInferenceHostCredentialContext, recoverInferenceHostCredentialContextTransition, accountKeyForState, assertCredentialMatchesState2, revocationCheckpointForCredential, assertRevocationCheckpointMatchesLocalIdentity, fileExistsPrivately, inspectCodexAuthentication, clearLocalRuntimeArtifacts, assertDurableServiceUninstalled, assertLocalRuntimeArtifactsMayBeDiscarded, defaultRunForeground, preparePortableDurableAdapter, defaultRunPortableDurableAdapter, login, codexLogin, codexLogout, localStatus, doctor, cleanupLogin, runHost, defaultReadStdin, parseAgentStdin, parseOptionalAgentStdin, agentOperationId, agentSession, agentConnect, foregroundAgentControlState, requireForegroundAgentState, assignmentFromClaim, foregroundAssignmentNext, foregroundAssignmentHeartbeat, foregroundDataCall, foregroundDecisionStatusRequest, foregroundAssignmentLeaseEnded, handleForegroundCancelledAssignment, foregroundDecisionStatus, foregroundDecisionSubmit, foregroundAssignmentRelease, agentRun, agentNext, agentComplete, agentFail, withAgentCommandLock, recoveryBackupPath, serviceRecoveryTransactionPath, readServiceRecoveryTransaction, assertResumableCodexRecoveryEvidence, recoverInstalledCodexService, serviceCommand, hasExplicitCredentialStoreConfiguration, credentialEnvironmentForIdentity, commandRequiresRetainedCredentialStore, commandUsesInstalledServiceCredentials, resolveInferenceHostCommandConfig;
36840
+ var INFERENCE_HOST_CLI_VERSION, runtimeReceiptPath, codexRecoveryPath, codexGuardianReceiptRoot, revocationCheckpointPath, foregroundHostLockPath, credentialLifecycleLockPath, serviceRecoveryCommandLockPath, AGENT_HEARTBEAT_INTERVAL_MS, AGENT_HEARTBEAT_MAX_RETRY_DELAY_MS, retryableAgentHeartbeatError, assertRevocationCheckpoint, readRevocationCheckpoint, writeRevocationCheckpoint, clearRevocationCheckpoint, render, INFERENCE_HOST_HELP, parseHostConcurrency, parseInferenceHostArgs, resolveDurableServiceDisplayName, defaultOpenBrowser, registerInferenceHostServiceControlInput, defaultRegisterLifecycleSignalHandlers, lifecycleCancellation, configuredCredentialStore, restoreInferenceHostCredentialContext, recoverInferenceHostCredentialContextTransition, accountKeyForState, assertCredentialMatchesState2, revocationCheckpointForCredential, assertRevocationCheckpointMatchesLocalIdentity, fileExistsPrivately, inspectCodexAuthentication, clearLocalRuntimeArtifacts, assertDurableServiceUninstalled, assertLocalRuntimeArtifactsMayBeDiscarded, defaultRunForeground, preparePortableDurableAdapter, defaultRunPortableDurableAdapter, login, codexLogin, codexLogout, deepSeekCredentialStore, deepSeekLogin, deepSeekLogout, localStatus, doctor, cleanupLogin, runHost, defaultReadStdin, parseAgentStdin, parseOptionalAgentStdin, agentOperationId, agentSession, agentConnect, foregroundAgentControlState, requireForegroundAgentState, assignmentFromClaim, foregroundAssignmentNext, foregroundAssignmentHeartbeat, foregroundDataCall, foregroundDecisionStatusRequest, foregroundAssignmentLeaseEnded, handleForegroundCancelledAssignment, foregroundDecisionStatus, foregroundDecisionSubmit, foregroundAssignmentRelease, agentRun, agentNext, agentComplete, agentFail, withAgentCommandLock, recoveryBackupPath, serviceRecoveryTransactionPath, readServiceRecoveryTransaction, assertResumableCodexRecoveryEvidence, recoverInstalledCodexService, serviceCommand, hasExplicitCredentialStoreConfiguration, credentialEnvironmentForIdentity, commandRequiresRetainedCredentialStore, commandUsesInstalledServiceCredentials, resolveInferenceHostCommandConfig;
35616
36841
  var init_cli = __esm({
35617
36842
  "lib/inference-host/cli.ts"() {
35618
36843
  "use strict";
@@ -35623,6 +36848,8 @@ var init_cli = __esm({
35623
36848
  init_codex_adapter();
35624
36849
  init_codex_recovery_process();
35625
36850
  init_copilot_adapter();
36851
+ init_deepseek_harness_adapter();
36852
+ init_deepseek_credential_store();
35626
36853
  init_durable_adapter();
35627
36854
  init_codex_app_server();
35628
36855
  init_codex_binary();
@@ -35706,6 +36933,7 @@ var init_cli = __esm({
35706
36933
  Commands:
35707
36934
  login Authorize the isolated VTX insights:inference grant
35708
36935
  codex-login Sign the automated Codex host into a ChatGPT subscription
36936
+ deepseek-login Import a DeepSeek API key privately from stdin
35709
36937
  run Run a supported durable inference adapter in the foreground
35710
36938
  agent-connect Advertise a model from a compatible agent harness
35711
36939
  agent-run Keep an agent-driven host online in the foreground
@@ -35724,11 +36952,12 @@ Commands:
35724
36952
  logout Remove local VTX host state without revoking the grant
35725
36953
  revoke Revoke the VTX grant and remove local host state
35726
36954
  codex-logout Remove the automated host's dedicated Codex login
36955
+ deepseek-logout Remove the locally stored DeepSeek API key
35727
36956
 
35728
36957
  Common options:
35729
36958
  --json Emit machine-readable JSON
35730
36959
  --instance NAME Target an isolated local subscription instance (default: default)
35731
- --adapter ID Durable adapter: codex or copilot
36960
+ --adapter ID Durable adapter: codex, copilot, or deepseek-harness
35732
36961
  --max-concurrency N Optional positive-integer local slot limit (default: unlimited)
35733
36962
  --help, -h Show this help
35734
36963
 
@@ -35744,6 +36973,8 @@ Durable service:
35744
36973
  vtx inference-host codex-login --instance codex-2
35745
36974
  vtx inference-host service install --instance codex-2
35746
36975
  vtx inference-host service install --adapter copilot --instance copilot-1
36976
+ vtx inference-host deepseek-login --instance deepseek-1 < /private/path/deepseek.key
36977
+ vtx inference-host service install --adapter deepseek-harness --instance deepseek-1
35747
36978
  vtx inference-host service uninstall --instance codex-2
35748
36979
  vtx inference-host service recover --instance codex-1 --force-recovery
35749
36980
  vtx inference-host service <start|stop|status|logs|recover|uninstall>
@@ -35850,7 +37081,7 @@ Durable service:
35850
37081
  if (command === "agent-connect" && !displayNameExplicit) {
35851
37082
  displayName = "Agent-driven inference host";
35852
37083
  } else if (adapter && isDurableInferenceAdapterId(adapter) && !displayNameExplicit) {
35853
- displayName = `${durableAdapterDisplayName(adapter)} subscription host`;
37084
+ displayName = `${durableAdapterDisplayName(adapter)} host`;
35854
37085
  }
35855
37086
  return {
35856
37087
  command,
@@ -36007,10 +37238,10 @@ Durable service:
36007
37238
  return raw !== null;
36008
37239
  };
36009
37240
  inspectCodexAuthentication = async (config2) => {
36010
- const path = join7(config2.codexHomePath, "auth.json");
37241
+ const path = join8(config2.codexHomePath, "auth.json");
36011
37242
  try {
36012
37243
  const before = await lstat4(path);
36013
- const canonical = await realpath4(path);
37244
+ const canonical = await realpath5(path);
36014
37245
  const isPrivate = before.isFile() && !before.isSymbolicLink() && canonical === resolve5(path) && before.size <= 8 * 1024 * 1024 && (process.platform === "win32" || (before.mode & 63) === 0 && (typeof process.getuid !== "function" || before.uid === process.getuid()));
36015
37246
  return { present: true, private: isPrivate };
36016
37247
  } catch (error48) {
@@ -36025,7 +37256,7 @@ Durable service:
36025
37256
  runtimeReceiptPath(config2),
36026
37257
  "Inference host runtime receipt file"
36027
37258
  );
36028
- await rm6(codexGuardianReceiptRoot(config2), { recursive: true, force: true });
37259
+ await rm7(codexGuardianReceiptRoot(config2), { recursive: true, force: true });
36029
37260
  await clearInferencePrivateFile(
36030
37261
  codexRecoveryPath(config2),
36031
37262
  "Codex attempt recovery file"
@@ -36034,6 +37265,7 @@ Durable service:
36034
37265
  await clearInferenceAgentNextState(config2.statePath);
36035
37266
  await clearInferenceForegroundAgentControlState(config2.statePath);
36036
37267
  await clearCodexAgentRuntimeState(config2.statePath);
37268
+ await clearInferenceAgentFailureFence(config2.statePath);
36037
37269
  await clearInferenceHostLocalState(config2.statePath);
36038
37270
  };
36039
37271
  assertDurableServiceUninstalled = async (config2) => {
@@ -36062,7 +37294,8 @@ Durable service:
36062
37294
  const agentNextRecoveryPresent = await readInferenceAgentNextState(config2.statePath) !== null;
36063
37295
  const foregroundAgentControlPresent = await readInferenceForegroundAgentControlState(config2.statePath) !== null;
36064
37296
  const codexAgentRuntimePresent = await readCodexAgentRuntimeState(config2.statePath) !== null;
36065
- if (pendingAttempts > 0 || codexRecoveryPresent || serviceRecoveryPresent || revocationCheckpointPresent || agentAttemptPresent || agentNextRecoveryPresent || foregroundAgentControlPresent || codexAgentRuntimePresent) {
37297
+ const agentFailureFencePresent = await readInferenceAgentFailureFence(config2.statePath) !== null;
37298
+ if (pendingAttempts > 0 || codexRecoveryPresent || serviceRecoveryPresent || revocationCheckpointPresent || agentAttemptPresent || agentNextRecoveryPresent || foregroundAgentControlPresent || codexAgentRuntimePresent || agentFailureFencePresent) {
36066
37299
  throw new Error(
36067
37300
  "Inference host logout refused because attempt recovery is still pending (Codex, Provider, Agent-control, or revocation recovery). Reconcile or release the exact active operation before retrying logout, or resume revoke."
36068
37301
  );
@@ -36132,8 +37365,10 @@ Durable service:
36132
37365
  signal: options.signal
36133
37366
  }).run();
36134
37367
  };
36135
- preparePortableDurableAdapter = async (adapterId, signal) => {
36136
- const adapter = new CopilotSubscriptionAdapter();
37368
+ preparePortableDurableAdapter = async (adapterId, config2, signal) => {
37369
+ const adapter = adapterId === "copilot" ? new CopilotSubscriptionAdapter() : new DeepSeekHarnessAdapter({
37370
+ credentialStore: createDeepSeekHarnessCredentialStore(config2)
37371
+ });
36137
37372
  return { adapter, preflight: await adapter.preflight(signal) };
36138
37373
  };
36139
37374
  defaultRunPortableDurableAdapter = async (options) => {
@@ -36215,7 +37450,7 @@ Durable service:
36215
37450
  await writeInferenceHostCredentialContextTransition(config2, previousCredentialContext);
36216
37451
  await writeInferenceHostCredentialContext(config2);
36217
37452
  const keyPair = generateExternalInferenceEnvelopeKeyPair();
36218
- const hostId = randomUUID4();
37453
+ const hostId = randomUUID5();
36219
37454
  const beginLogin = dependencies.beginLogin ?? beginInferenceOAuthLogin;
36220
37455
  const loginStore = {
36221
37456
  kind: store.kind,
@@ -36413,6 +37648,53 @@ Waiting for approval...
36413
37648
  cancellation.unregister();
36414
37649
  }
36415
37650
  };
37651
+ deepSeekCredentialStore = (config2, dependencies) => dependencies.createDeepSeekCredentialStore?.(config2) ?? createDeepSeekHarnessCredentialStore(config2);
37652
+ deepSeekLogin = async (config2, parsed, dependencies) => {
37653
+ await assertDurableServiceUninstalled(config2);
37654
+ if (!dependencies.readStdin && process.stdin.isTTY) {
37655
+ throw new Error("DeepSeek API key must be supplied through stdin, never as an argument.");
37656
+ }
37657
+ const cancellation = lifecycleCancellation(dependencies);
37658
+ let lock2 = null;
37659
+ try {
37660
+ lock2 = await acquireInferenceHostProcessLock(config2.processLockPath);
37661
+ const raw = await (dependencies.readStdin ?? defaultReadStdin)();
37662
+ const credential = await deepSeekCredentialStore(config2, dependencies).write(
37663
+ raw,
37664
+ cancellation.signal
37665
+ );
37666
+ const failureFence = await readInferenceAgentFailureFence(config2.statePath);
37667
+ if (failureFence?.adapter_id === "deepseek-harness" && failureFence.failure_category === "auth") {
37668
+ await clearInferenceAgentFailureFence(config2.statePath);
37669
+ }
37670
+ return {
37671
+ exitCode: 0,
37672
+ stdout: render({
37673
+ status: "deepseek_api_key_imported",
37674
+ identity: credential.identity,
37675
+ credential_store: config2.credentialStoreMode
37676
+ }, parsed.json),
37677
+ stderr: ""
37678
+ };
37679
+ } finally {
37680
+ await lock2?.release();
37681
+ cancellation.unregister();
37682
+ }
37683
+ };
37684
+ deepSeekLogout = async (config2, parsed, dependencies) => {
37685
+ await assertDurableServiceUninstalled(config2);
37686
+ const lock2 = await acquireInferenceHostProcessLock(config2.processLockPath);
37687
+ try {
37688
+ await deepSeekCredentialStore(config2, dependencies).remove();
37689
+ return {
37690
+ exitCode: 0,
37691
+ stdout: render({ status: "deepseek_api_key_removed" }, parsed.json),
37692
+ stderr: ""
37693
+ };
37694
+ } finally {
37695
+ await lock2.release();
37696
+ }
37697
+ };
36416
37698
  localStatus = async (config2, parsed, dependencies, warnings) => {
36417
37699
  const codexAuthentication = await inspectCodexAuthentication(config2);
36418
37700
  const state = await readInferenceHostLocalState(config2.statePath);
@@ -36457,6 +37739,7 @@ Waiting for approval...
36457
37739
  );
36458
37740
  const agentAttempt = await readInferenceAgentAttemptState(config2.statePath);
36459
37741
  const agentNextRecoveryPresent = await readInferenceAgentNextState(config2.statePath) !== null;
37742
+ const agentFailureFence = await readInferenceAgentFailureFence(config2.statePath);
36460
37743
  return {
36461
37744
  exitCode: 0,
36462
37745
  stdout: render({
@@ -36482,6 +37765,13 @@ Waiting for approval...
36482
37765
  deadline_at: agentAttempt.deadline_at
36483
37766
  } : null,
36484
37767
  agent_next_recovery_present: agentNextRecoveryPresent,
37768
+ agent_failure_fence: agentFailureFence ? {
37769
+ adapter: agentFailureFence.adapter_id,
37770
+ failure_category: agentFailureFence.failure_category,
37771
+ failure_code: agentFailureFence.failure_code,
37772
+ dispatch_outcome: agentFailureFence.dispatch_outcome,
37773
+ retry_at: agentFailureFence.retry_at
37774
+ } : null,
36485
37775
  codex_recovery_present: recoveryPresent,
36486
37776
  service_recovery_present: serviceRecoveryPresent,
36487
37777
  codex_auth: codexAuthentication,
@@ -36500,6 +37790,12 @@ Waiting for approval...
36500
37790
  ok: state !== null,
36501
37791
  detail: state ? "valid" : "missing"
36502
37792
  });
37793
+ const agentFailureFence = await readInferenceAgentFailureFence(config2.statePath);
37794
+ checks.push({
37795
+ name: "agent_runtime_fence",
37796
+ ok: agentFailureFence === null,
37797
+ detail: agentFailureFence === null ? "clear" : `${agentFailureFence.failure_code}:${agentFailureFence.dispatch_outcome}`
37798
+ });
36503
37799
  checks.push({
36504
37800
  name: "revocation_recovery",
36505
37801
  ok: revocationCheckpoint === null,
@@ -36538,7 +37834,8 @@ Waiting for approval...
36538
37834
  } else if (adapterId !== "codex") {
36539
37835
  try {
36540
37836
  const prepared = await (dependencies.prepareDurableAdapter ?? preparePortableDurableAdapter)(
36541
- adapterId
37837
+ adapterId,
37838
+ config2
36542
37839
  );
36543
37840
  checks.push({
36544
37841
  name: "provider_runtime",
@@ -36796,6 +38093,7 @@ Waiting for approval...
36796
38093
  if (adapterId !== "codex") {
36797
38094
  const prepared = await (dependencies.prepareDurableAdapter ?? preparePortableDurableAdapter)(
36798
38095
  adapterId,
38096
+ config2,
36799
38097
  cancellation.signal
36800
38098
  );
36801
38099
  const summary = await (dependencies.runPortableDurableAdapter ?? defaultRunPortableDurableAdapter)({
@@ -36915,7 +38213,7 @@ Waiting for approval...
36915
38213
  }
36916
38214
  return record2;
36917
38215
  };
36918
- agentOperationId = (kind) => `${kind}-${randomUUID4()}`;
38216
+ agentOperationId = (kind) => `${kind}-${randomUUID5()}`;
36919
38217
  agentSession = async (config2, dependencies, warnings, signal) => {
36920
38218
  if (await readRevocationCheckpoint(config2)) {
36921
38219
  throw new Error("Inference host revocation recovery must finish first.");
@@ -37932,7 +39230,7 @@ Waiting for approval...
37932
39230
  if (recoveryRaw === null && existingTransaction?.phase !== "reconciled") {
37933
39231
  throw new Error("Codex recovery evidence changed before service recovery began.");
37934
39232
  }
37935
- const transactionId = existingTransaction?.transaction_id ?? randomUUID4();
39233
+ const transactionId = existingTransaction?.transaction_id ?? randomUUID5();
37936
39234
  const backupPath = existingTransaction?.recovery_backup_path ?? recoveryBackupPath(config2, transactionId);
37937
39235
  if (!existingTransaction) {
37938
39236
  await writeAtomicInferencePrivateFile(backupPath, recoveryRaw);
@@ -37941,7 +39239,7 @@ Waiting for approval...
37941
39239
  backupPath,
37942
39240
  "Codex service recovery backup"
37943
39241
  );
37944
- const backupSha256 = backupRaw === null ? null : createHash7("sha256").update(backupRaw).digest("hex");
39242
+ const backupSha256 = backupRaw === null ? null : createHash8("sha256").update(backupRaw).digest("hex");
37945
39243
  if (backupSha256 === null || existingTransaction && backupSha256 !== existingTransaction.recovery_backup_sha256) {
37946
39244
  throw new Error("Codex service recovery backup is missing or changed.");
37947
39245
  }
@@ -37952,7 +39250,7 @@ Waiting for approval...
37952
39250
  existingTransaction?.cleanup_confirmed_attempt_ids ?? [],
37953
39251
  existingTransaction?.phase ?? "prepared"
37954
39252
  );
37955
- const recoverySha256 = recoveryRaw === null ? null : createHash7("sha256").update(recoveryRaw).digest("hex");
39253
+ const recoverySha256 = recoveryRaw === null ? null : createHash8("sha256").update(recoveryRaw).digest("hex");
37956
39254
  const unresolvedAttemptIds = Object.keys(backupAttempts).filter((attemptId) => !existingTransaction?.cleanup_confirmed_attempt_ids.includes(attemptId) && !initialAttempts[attemptId]?.cleanupConfirmed);
37957
39255
  const binary = unresolvedAttemptIds.length > 0 ? await (dependencies.resolveBinary ?? resolvePinnedCodexBinary)(env) : null;
37958
39256
  let activeTransaction = existingTransaction;
@@ -37991,7 +39289,7 @@ Waiting for approval...
37991
39289
  codexRecoveryPath(config2),
37992
39290
  "Codex attempt recovery file"
37993
39291
  );
37994
- if (currentRaw === null || recoverySha256 === null || createHash7("sha256").update(currentRaw).digest("hex") !== recoverySha256) {
39292
+ if (currentRaw === null || recoverySha256 === null || createHash8("sha256").update(currentRaw).digest("hex") !== recoverySha256) {
37995
39293
  throw new Error("Codex recovery evidence changed while the service was stopping.");
37996
39294
  }
37997
39295
  const proof = await (dependencies.proveCodexQuiescence ?? proveCodexSameBootQuiescence)({
@@ -38080,7 +39378,7 @@ Waiting for approval...
38080
39378
  serviceRecoveryTransactionPath(config2),
38081
39379
  "Inference-host service recovery transaction"
38082
39380
  );
38083
- await rm6(backupPath, { force: true });
39381
+ await rm7(backupPath, { force: true });
38084
39382
  }
38085
39383
  }
38086
39384
  } finally {
@@ -38161,7 +39459,8 @@ Waiting for approval...
38161
39459
  const displayName = resolveDurableServiceDisplayName(parsed, dependencies);
38162
39460
  if (adapter !== "codex") {
38163
39461
  const prepared = await (dependencies.prepareDurableAdapter ?? preparePortableDurableAdapter)(
38164
- adapter
39462
+ adapter,
39463
+ config2
38165
39464
  );
38166
39465
  try {
38167
39466
  const status2 = await manager.install({
@@ -38348,11 +39647,11 @@ Waiting for approval...
38348
39647
  });
38349
39648
 
38350
39649
  // lib/agent-core/config.ts
38351
- import { mkdir as mkdir5, readFile as readFile6, rm as rm7, writeFile as writeFile3 } from "node:fs/promises";
38352
- import { dirname as dirname5, join as join8 } from "node:path";
39650
+ import { mkdir as mkdir5, readFile as readFile6, rm as rm8, writeFile as writeFile3 } from "node:fs/promises";
39651
+ import { dirname as dirname6, join as join9 } from "node:path";
38353
39652
  import { homedir as homedir3 } from "node:os";
38354
39653
  function defaultBaseDir() {
38355
- return join8(homedir3(), ".vtx");
39654
+ return join9(homedir3(), ".vtx");
38356
39655
  }
38357
39656
  function resolveAgentCliConfig(env = process.env) {
38358
39657
  const baseDir = String(env.VTX_HOME || "").trim() || defaultBaseDir();
@@ -38360,8 +39659,8 @@ function resolveAgentCliConfig(env = process.env) {
38360
39659
  const parsedProfile = rawProfile ? Number(rawProfile) : NaN;
38361
39660
  return {
38362
39661
  apiUrl: String(env.VTX_API_URL || "http://localhost:8000").replace(/\/+$/, ""),
38363
- tokenPath: String(env.VTX_TOKEN_PATH || "").trim() || join8(baseDir, "token.json"),
38364
- statePath: String(env.VTX_RUNTIME_STATE_PATH || "").trim() || join8(baseDir, "runtime-state.json"),
39662
+ tokenPath: String(env.VTX_TOKEN_PATH || "").trim() || join9(baseDir, "token.json"),
39663
+ statePath: String(env.VTX_RUNTIME_STATE_PATH || "").trim() || join9(baseDir, "runtime-state.json"),
38365
39664
  runtimeDeviceId: String(env.VTX_RUNTIME_DEVICE_ID || "").trim() || null,
38366
39665
  activeProfileId: Number.isFinite(parsedProfile) && parsedProfile > 0 ? parsedProfile : null,
38367
39666
  outputJson: String(env.VTX_OUTPUT || "").trim().toLowerCase() === "json"
@@ -38387,12 +39686,12 @@ async function readStoredAgentAuth(path) {
38387
39686
  }
38388
39687
  }
38389
39688
  async function writeStoredAgentAuth(path, auth) {
38390
- await mkdir5(dirname5(path), { recursive: true });
39689
+ await mkdir5(dirname6(path), { recursive: true });
38391
39690
  await writeFile3(path, `${JSON.stringify(auth, null, 2)}
38392
39691
  `, { encoding: "utf8", mode: 384 });
38393
39692
  }
38394
39693
  async function clearStoredAgentAuth(path) {
38395
- await rm7(path, { force: true });
39694
+ await rm8(path, { force: true });
38396
39695
  }
38397
39696
  async function readRuntimeState(path) {
38398
39697
  try {
@@ -38422,12 +39721,12 @@ async function readRuntimeState(path) {
38422
39721
  }
38423
39722
  }
38424
39723
  async function writeRuntimeState(path, state) {
38425
- await mkdir5(dirname5(path), { recursive: true });
39724
+ await mkdir5(dirname6(path), { recursive: true });
38426
39725
  await writeFile3(path, `${JSON.stringify(state, null, 2)}
38427
39726
  `, { encoding: "utf8", mode: 384 });
38428
39727
  }
38429
39728
  async function clearRuntimeState(path) {
38430
- await rm7(path, { force: true });
39729
+ await rm8(path, { force: true });
38431
39730
  }
38432
39731
  var init_config2 = __esm({
38433
39732
  "lib/agent-core/config.ts"() {
@@ -38453,7 +39752,7 @@ var init_types = __esm({
38453
39752
  });
38454
39753
 
38455
39754
  // lib/agent-core/client.ts
38456
- import { randomUUID as randomUUID5 } from "node:crypto";
39755
+ import { randomUUID as randomUUID6 } from "node:crypto";
38457
39756
  function normalizeApiUrl(value) {
38458
39757
  const parsed = String(value || "").trim();
38459
39758
  if (!parsed) {
@@ -38715,7 +40014,7 @@ var init_client = __esm({
38715
40014
  return this.request("/trading/ai/runtime/decision", {
38716
40015
  method: "POST",
38717
40016
  profileId,
38718
- idempotencyKey: randomUUID5(),
40017
+ idempotencyKey: randomUUID6(),
38719
40018
  headers: { "x-client-runtime-lease": leaseToken },
38720
40019
  body: payload
38721
40020
  });
@@ -38724,7 +40023,7 @@ var init_client = __esm({
38724
40023
  return this.request("/trading/ai/runtime/trade-sync", {
38725
40024
  method: "POST",
38726
40025
  profileId,
38727
- idempotencyKey: randomUUID5(),
40026
+ idempotencyKey: randomUUID6(),
38728
40027
  headers: { "x-client-runtime-lease": leaseToken },
38729
40028
  body: payload
38730
40029
  });
@@ -38733,7 +40032,7 @@ var init_client = __esm({
38733
40032
  return this.request("/trading/ai/runtime/error", {
38734
40033
  method: "POST",
38735
40034
  profileId,
38736
- idempotencyKey: randomUUID5(),
40035
+ idempotencyKey: randomUUID6(),
38737
40036
  headers: { "x-client-runtime-lease": leaseToken },
38738
40037
  body: payload
38739
40038
  });
@@ -38745,7 +40044,7 @@ var init_client = __esm({
38745
40044
  return this.request("/trading/market-order", {
38746
40045
  method: "POST",
38747
40046
  profileId,
38748
- idempotencyKey: randomUUID5(),
40047
+ idempotencyKey: randomUUID6(),
38749
40048
  body: payload
38750
40049
  });
38751
40050
  }
@@ -38753,7 +40052,7 @@ var init_client = __esm({
38753
40052
  return this.request("/trading/limit-order", {
38754
40053
  method: "POST",
38755
40054
  profileId,
38756
- idempotencyKey: randomUUID5(),
40055
+ idempotencyKey: randomUUID6(),
38757
40056
  body: payload
38758
40057
  });
38759
40058
  }
@@ -38761,7 +40060,7 @@ var init_client = __esm({
38761
40060
  return this.request("/trading/cancel-order", {
38762
40061
  method: "POST",
38763
40062
  profileId,
38764
- idempotencyKey: randomUUID5(),
40063
+ idempotencyKey: randomUUID6(),
38765
40064
  body: payload
38766
40065
  });
38767
40066
  }
@@ -38780,7 +40079,7 @@ var init_client = __esm({
38780
40079
  return this.request("/trading/ai/start", {
38781
40080
  method: "POST",
38782
40081
  profileId,
38783
- idempotencyKey: randomUUID5(),
40082
+ idempotencyKey: randomUUID6(),
38784
40083
  body: payload
38785
40084
  });
38786
40085
  }
@@ -38788,7 +40087,7 @@ var init_client = __esm({
38788
40087
  return this.request("/trading/ai/stop", {
38789
40088
  method: "POST",
38790
40089
  profileId,
38791
- idempotencyKey: randomUUID5(),
40090
+ idempotencyKey: randomUUID6(),
38792
40091
  body: {}
38793
40092
  });
38794
40093
  }
@@ -38796,7 +40095,7 @@ var init_client = __esm({
38796
40095
  return this.request("/trading/ai/assistant/start", {
38797
40096
  method: "POST",
38798
40097
  profileId,
38799
- idempotencyKey: randomUUID5(),
40098
+ idempotencyKey: randomUUID6(),
38800
40099
  body: {}
38801
40100
  });
38802
40101
  }
@@ -38804,7 +40103,7 @@ var init_client = __esm({
38804
40103
  return this.request("/trading/ai/assistant/stop", {
38805
40104
  method: "POST",
38806
40105
  profileId,
38807
- idempotencyKey: randomUUID5(),
40106
+ idempotencyKey: randomUUID6(),
38808
40107
  body: {}
38809
40108
  });
38810
40109
  }
@@ -38812,7 +40111,7 @@ var init_client = __esm({
38812
40111
  return this.request("/trading/ai/runtime/session/start", {
38813
40112
  method: "POST",
38814
40113
  profileId,
38815
- idempotencyKey: randomUUID5(),
40114
+ idempotencyKey: randomUUID6(),
38816
40115
  body: payload
38817
40116
  });
38818
40117
  }
@@ -38823,7 +40122,7 @@ var init_client = __esm({
38823
40122
  return this.request("/trading/ai/runtime/session/stop", {
38824
40123
  method: "POST",
38825
40124
  profileId,
38826
- idempotencyKey: randomUUID5(),
40125
+ idempotencyKey: randomUUID6(),
38827
40126
  body: payload
38828
40127
  });
38829
40128
  }
@@ -38840,7 +40139,7 @@ var init_client = __esm({
38840
40139
  }).request("/trading/ai/runtime/session/stop", {
38841
40140
  method: "POST",
38842
40141
  profileId,
38843
- idempotencyKey: randomUUID5(),
40142
+ idempotencyKey: randomUUID6(),
38844
40143
  body: payload
38845
40144
  });
38846
40145
  }
@@ -38857,8 +40156,8 @@ import {
38857
40156
  unlinkSync,
38858
40157
  writeFileSync
38859
40158
  } from "node:fs";
38860
- import { randomUUID as randomUUID6 } from "node:crypto";
38861
- import { dirname as dirname6 } from "node:path";
40159
+ import { randomUUID as randomUUID7 } from "node:crypto";
40160
+ import { dirname as dirname7 } from "node:path";
38862
40161
  var parseStoredValues, FileBackedProtectionStorage, clientRuntimeProtectionStatePath;
38863
40162
  var init_protection_storage = __esm({
38864
40163
  "lib/agent-core/protection-storage.ts"() {
@@ -38911,10 +40210,10 @@ var init_protection_storage = __esm({
38911
40210
  }
38912
40211
  }
38913
40212
  writeValues(values) {
38914
- mkdirSync(dirname6(this.path), { recursive: true, mode: 448 });
40213
+ mkdirSync(dirname7(this.path), { recursive: true, mode: 448 });
38915
40214
  const serialized = `${JSON.stringify(values)}
38916
40215
  `;
38917
- const temporaryPath = `${this.path}.${process.pid}.${randomUUID6()}.tmp`;
40216
+ const temporaryPath = `${this.path}.${process.pid}.${randomUUID7()}.tmp`;
38918
40217
  try {
38919
40218
  writeFileSync(temporaryPath, serialized, {
38920
40219
  encoding: "utf8",
@@ -38941,7 +40240,7 @@ var init_protection_storage = __esm({
38941
40240
  });
38942
40241
 
38943
40242
  // lib/agent-core/headless-runtime.ts
38944
- import { randomUUID as randomUUID7 } from "node:crypto";
40243
+ import { randomUUID as randomUUID8 } from "node:crypto";
38945
40244
  import { setTimeout as sleep } from "node:timers/promises";
38946
40245
  function objectOrNull2(value) {
38947
40246
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
@@ -39039,8 +40338,8 @@ async function runAndReportLocalWorkCycle(options, state, leaseToken, context) {
39039
40338
  return Boolean(result2.decision || tradeSync || result2.afterDecision);
39040
40339
  }
39041
40340
  async function startHeadlessRuntime(options) {
39042
- const runtimeSessionId = randomUUID7();
39043
- const deviceId = String(options.deviceId || "").trim() || randomUUID7();
40341
+ const runtimeSessionId = randomUUID8();
40342
+ const deviceId = String(options.deviceId || "").trim() || randomUUID8();
39044
40343
  const startResponse = await options.client.startRuntime(options.profileId, {
39045
40344
  session_id: runtimeSessionId,
39046
40345
  device_id: deviceId,
@@ -43725,8 +45024,8 @@ var init_rlp_encode = __esm({
43725
45024
  });
43726
45025
 
43727
45026
  // node_modules/ethers/lib.esm/utils/uuid.js
43728
- function uuidV4(randomBytes8) {
43729
- const bytes3 = getBytes(randomBytes8, "randomBytes");
45027
+ function uuidV4(randomBytes9) {
45028
+ const bytes3 = getBytes(randomBytes9, "randomBytes");
43730
45029
  bytes3[6] = bytes3[6] & 15 | 64;
43731
45030
  bytes3[8] = bytes3[8] & 63 | 128;
43732
45031
  const value = hexlify(bytes3);
@@ -43760,7 +45059,7 @@ var init_utils = __esm({
43760
45059
  });
43761
45060
 
43762
45061
  // node_modules/ethers/lib.esm/crypto/crypto.js
43763
- import { createHash as createHash8, createHmac, pbkdf2Sync, randomBytes as randomBytes5 } from "crypto";
45062
+ import { createHash as createHash9, createHmac, pbkdf2Sync, randomBytes as randomBytes6 } from "crypto";
43764
45063
  var init_crypto2 = __esm({
43765
45064
  "node_modules/ethers/lib.esm/crypto/crypto.js"() {
43766
45065
  }
@@ -44414,7 +45713,7 @@ var init_pbkdf2 = __esm({
44414
45713
  });
44415
45714
 
44416
45715
  // node_modules/ethers/lib.esm/crypto/random.js
44417
- function randomBytes6(length) {
45716
+ function randomBytes7(length) {
44418
45717
  return __randomBytes(length);
44419
45718
  }
44420
45719
  var locked5, _randomBytes, __randomBytes;
@@ -44423,20 +45722,20 @@ var init_random = __esm({
44423
45722
  init_crypto2();
44424
45723
  locked5 = false;
44425
45724
  _randomBytes = function(length) {
44426
- return new Uint8Array(randomBytes5(length));
45725
+ return new Uint8Array(randomBytes6(length));
44427
45726
  };
44428
45727
  __randomBytes = _randomBytes;
44429
- randomBytes6._ = _randomBytes;
44430
- randomBytes6.lock = function() {
45728
+ randomBytes7._ = _randomBytes;
45729
+ randomBytes7.lock = function() {
44431
45730
  locked5 = true;
44432
45731
  };
44433
- randomBytes6.register = function(func) {
45732
+ randomBytes7.register = function(func) {
44434
45733
  if (locked5) {
44435
45734
  throw new Error("randomBytes is locked");
44436
45735
  }
44437
45736
  __randomBytes = func;
44438
45737
  };
44439
- Object.freeze(randomBytes6);
45738
+ Object.freeze(randomBytes7);
44440
45739
  }
44441
45740
  });
44442
45741
 
@@ -44974,10 +46273,10 @@ var init_sha22 = __esm({
44974
46273
  init_crypto2();
44975
46274
  init_utils();
44976
46275
  _sha256 = function(data) {
44977
- return createHash8("sha256").update(data).digest();
46276
+ return createHash9("sha256").update(data).digest();
44978
46277
  };
44979
46278
  _sha512 = function(data) {
44980
- return createHash8("sha512").update(data).digest();
46279
+ return createHash9("sha512").update(data).digest();
44981
46280
  };
44982
46281
  __sha256 = _sha256;
44983
46282
  __sha512 = _sha512;
@@ -45084,7 +46383,7 @@ function wrapConstructor2(hashCons) {
45084
46383
  hashC.create = () => hashCons();
45085
46384
  return hashC;
45086
46385
  }
45087
- function randomBytes7(bytesLength = 32) {
46386
+ function randomBytes8(bytesLength = 32) {
45088
46387
  if (crypto2 && typeof crypto2.getRandomValues === "function") {
45089
46388
  return crypto2.getRandomValues(new Uint8Array(bytesLength));
45090
46389
  }
@@ -46623,7 +47922,7 @@ function weierstrass(curveDef) {
46623
47922
  function prepSig(msgHash, privateKey, opts = defaultSigOpts) {
46624
47923
  if (["recovered", "canonical"].some((k) => k in opts))
46625
47924
  throw new Error("sign() legacy options not supported");
46626
- const { hash: hash4, randomBytes: randomBytes8 } = CURVE;
47925
+ const { hash: hash4, randomBytes: randomBytes9 } = CURVE;
46627
47926
  let { lowS, prehash, extraEntropy: ent } = opts;
46628
47927
  if (lowS == null)
46629
47928
  lowS = true;
@@ -46634,7 +47933,7 @@ function weierstrass(curveDef) {
46634
47933
  const d = normPrivateKeyToScalar(privateKey);
46635
47934
  const seedArgs = [int2octets(d), int2octets(h1int)];
46636
47935
  if (ent != null) {
46637
- const e = ent === true ? randomBytes8(Fp2.BYTES) : ent;
47936
+ const e = ent === true ? randomBytes9(Fp2.BYTES) : ent;
46638
47937
  seedArgs.push(ensureBytes("extraEntropy", e));
46639
47938
  }
46640
47939
  const seed = concatBytes2(...seedArgs);
@@ -46871,7 +48170,7 @@ function getHash(hash4) {
46871
48170
  return {
46872
48171
  hash: hash4,
46873
48172
  hmac: (key, ...msgs) => hmac2(hash4, key, concatBytes(...msgs)),
46874
- randomBytes: randomBytes7
48173
+ randomBytes: randomBytes8
46875
48174
  };
46876
48175
  }
46877
48176
  function createCurve(curveDef, defHash) {
@@ -50845,7 +52144,7 @@ async function decryptKeystoreJson(json2, _password, progress) {
50845
52144
  return getAccount(data, key);
50846
52145
  }
50847
52146
  function getEncryptKdfParams(options) {
50848
- const salt = options.salt != null ? getBytes(options.salt, "options.salt") : randomBytes6(32);
52147
+ const salt = options.salt != null ? getBytes(options.salt, "options.salt") : randomBytes7(32);
50849
52148
  let N2 = 1 << 17, r = 8, p = 1;
50850
52149
  if (options.scrypt) {
50851
52150
  if (options.scrypt.N) {
@@ -50865,9 +52164,9 @@ function getEncryptKdfParams(options) {
50865
52164
  }
50866
52165
  function _encryptKeystore(key, kdf, account, options) {
50867
52166
  const privateKey = getBytes(account.privateKey, "privateKey");
50868
- const iv = options.iv != null ? getBytes(options.iv, "options.iv") : randomBytes6(16);
52167
+ const iv = options.iv != null ? getBytes(options.iv, "options.iv") : randomBytes7(16);
50869
52168
  assertArgument(iv.length === 16, "invalid options.iv length", "options.iv", options.iv);
50870
- const uuidRandom = options.uuid != null ? getBytes(options.uuid, "options.uuid") : randomBytes6(16);
52169
+ const uuidRandom = options.uuid != null ? getBytes(options.uuid, "options.uuid") : randomBytes7(16);
50871
52170
  assertArgument(uuidRandom.length === 16, "invalid options.uuid length", "options.uuid", options.iv);
50872
52171
  const derivedKey = key.slice(0, 16);
50873
52172
  const macPrefix = key.slice(16, 32);
@@ -50901,7 +52200,7 @@ function _encryptKeystore(key, kdf, account, options) {
50901
52200
  const locale = account.mnemonic.locale || "en";
50902
52201
  const mnemonicKey = key.slice(32, 64);
50903
52202
  const entropy = getBytes(account.mnemonic.entropy, "account.mnemonic.entropy");
50904
- const mnemonicIv = randomBytes6(16);
52203
+ const mnemonicIv = randomBytes7(16);
50905
52204
  const mnemonicAesCtr = new CTR(mnemonicKey, mnemonicIv);
50906
52205
  const mnemonicCiphertext = getBytes(mnemonicAesCtr.encrypt(entropy));
50907
52206
  const now = /* @__PURE__ */ new Date();
@@ -51239,7 +52538,7 @@ var init_hdwallet = __esm({
51239
52538
  if (wordlist2 == null) {
51240
52539
  wordlist2 = LangEn.wordlist();
51241
52540
  }
51242
- const mnemonic = Mnemonic.fromEntropy(randomBytes6(16), password, wordlist2);
52541
+ const mnemonic = Mnemonic.fromEntropy(randomBytes7(16), password, wordlist2);
51243
52542
  return _HDNodeWallet.#fromSeed(mnemonic.computeSeed(), mnemonic).derivePath(path);
51244
52543
  }
51245
52544
  /**
@@ -52661,11 +53960,11 @@ var init_error_surface_contract = __esm({
52661
53960
  );
52662
53961
  let message;
52663
53962
  if (resolvedReason === "private_node_stale") {
52664
- message = `\u26A0\uFE0F The ${orderLabel} was not sent: Hyperliquid private account data was too stale to validate the signing key.`;
53963
+ message = `\u26A0\uFE0F The ${orderLabel} was not sent: VTX could not verify this profile's signing-key authorization because required Hyperliquid account data was stale. No order was submitted, and the signing key was not rejected. VTX will try again automatically if the trader is running; no action is required.`;
52665
53964
  } else if (resolvedReason === "signer_validation_unavailable") {
52666
- message = `\u26A0\uFE0F The ${orderLabel} was not sent: Hyperliquid's private account service could not validate the signing key.`;
53965
+ message = `\u26A0\uFE0F The ${orderLabel} was not sent: VTX could not verify this profile's signing-key authorization because required Hyperliquid account data was temporarily unavailable. No order was submitted, and the signing key was not rejected. VTX will try again automatically if the trader is running; no action is required.`;
52667
53966
  } else if (resolvedReason === "wallet_not_authorized") {
52668
- message = `\u26A0\uFE0F The ${orderLabel} was not sent: the signing key is not authorized for the configured wallet.`;
53967
+ message = `\u26A0\uFE0F The ${orderLabel} was not sent: Hyperliquid confirmed that the signing key is not authorized for the configured wallet. No order was submitted. Stop the trader, then reconnect the correct wallet and signing key in System.`;
52669
53968
  } else if (resolvedReason === "credentials_missing") {
52670
53969
  message = `\u26A0\uFE0F The ${orderLabel} was not sent: a wallet address and authorized signing key are required for trading.`;
52671
53970
  } else if (resolvedReason === "local_safety_block") {
@@ -53586,13 +54885,28 @@ var init_hyperliquid_client = __esm({
53586
54885
  throw new Error("Malformed Hyperliquid userRole response.");
53587
54886
  }
53588
54887
  const response = payload;
53589
- const role = String(response.role || "").trim();
53590
- if (!role) {
54888
+ const role = response.role;
54889
+ if (typeof role !== "string" || !["missing", "user", "agent", "vault", "subAccount"].includes(role)) {
54890
+ throw new Error("Malformed Hyperliquid userRole response.");
54891
+ }
54892
+ const rawData = response.data;
54893
+ if (["missing", "user", "vault"].includes(role)) {
54894
+ if (rawData !== void 0 && rawData !== null) {
54895
+ throw new Error("Malformed Hyperliquid userRole response.");
54896
+ }
54897
+ return { role, data: null };
54898
+ }
54899
+ if (!rawData || typeof rawData !== "object" || Array.isArray(rawData)) {
54900
+ throw new Error("Malformed Hyperliquid userRole response.");
54901
+ }
54902
+ const data = rawData;
54903
+ const addressKey = role === "agent" ? "user" : "master";
54904
+ if (typeof data[addressKey] !== "string" || !/^0x[0-9a-f]{40}$/i.test(data[addressKey])) {
53591
54905
  throw new Error("Malformed Hyperliquid userRole response.");
53592
54906
  }
53593
54907
  return {
53594
54908
  role,
53595
- data: response.data && typeof response.data === "object" && !Array.isArray(response.data) ? response.data : null
54909
+ data
53596
54910
  };
53597
54911
  };
53598
54912
  fetchBrowserAccountState2 = async (input) => {
@@ -54691,7 +56005,7 @@ var init_hyperliquid_signer_binding = __esm({
54691
56005
  } catch (error48) {
54692
56006
  if (input.signal?.aborted) throw error48;
54693
56007
  throw new RuntimeExecutionError(
54694
- "Hyperliquid's private account service could not validate the signing key.",
56008
+ "VTX could not verify this profile's signing-key authorization because required Hyperliquid account data was temporarily unavailable. The signing key was not rejected. Try again later; reconnecting is not required.",
54695
56009
  "signer_validation_unavailable"
54696
56010
  );
54697
56011
  }
@@ -54706,7 +56020,7 @@ var init_hyperliquid_signer_binding = __esm({
54706
56020
  if (signerRole === "agent") {
54707
56021
  const masterWallet = extractRoleAddress(
54708
56022
  roleResponse.data,
54709
- ["user", "master", "masterAddress", "master_address"]
56023
+ ["user"]
54710
56024
  );
54711
56025
  if (masterWallet === walletAddress) {
54712
56026
  return {
@@ -61592,7 +62906,7 @@ var headless_local_worker_exports = {};
61592
62906
  __export(headless_local_worker_exports, {
61593
62907
  createHeadlessLocalWorker: () => createHeadlessLocalWorker
61594
62908
  });
61595
- import { randomUUID as randomUUID8 } from "node:crypto";
62909
+ import { randomUUID as randomUUID9 } from "node:crypto";
61596
62910
  function objectOrNull3(value) {
61597
62911
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
61598
62912
  }
@@ -62009,7 +63323,7 @@ function createHeadlessLocalWorker(options) {
62009
63323
  const statusMatch = errorText.match(/\b([45]\d{2})\b/);
62010
63324
  const statusCode = statusMatch ? Number(statusMatch[1]) : null;
62011
63325
  const failedInvocation = normalizeAiInvocationTelemetry({
62012
- client_invocation_id: randomUUID8(),
63326
+ client_invocation_id: randomUUID9(),
62013
63327
  use_case: "trader",
62014
63328
  role: "primary",
62015
63329
  attempt_index: 0,
@@ -62065,7 +63379,7 @@ function createHeadlessLocalWorker(options) {
62065
63379
  billable_cached_input_tokens: normalizedUsage.cached_input_tokens
62066
63380
  };
62067
63381
  const invocation = normalizeAiInvocationTelemetry({
62068
- client_invocation_id: randomUUID8(),
63382
+ client_invocation_id: randomUUID9(),
62069
63383
  use_case: "trader",
62070
63384
  role: "primary",
62071
63385
  attempt_index: 0,
@@ -62284,7 +63598,7 @@ var vtx_exports = {};
62284
63598
  __export(vtx_exports, {
62285
63599
  runVtxCli: () => runVtxCli
62286
63600
  });
62287
- import { randomUUID as randomUUID9 } from "node:crypto";
63601
+ import { randomUUID as randomUUID10 } from "node:crypto";
62288
63602
  import { spawn as spawn8 } from "node:child_process";
62289
63603
  function render2(value, json2) {
62290
63604
  if (json2) {
@@ -62698,8 +64012,8 @@ async function runVtxCli(argv2, env = process.env) {
62698
64012
  });
62699
64013
  return { exitCode: 0, stdout: render2(redactCliOutput(response2), json2), stderr: "" };
62700
64014
  }
62701
- const runtimeSessionId = randomUUID9();
62702
- const deviceId = config2.runtimeDeviceId ?? randomUUID9();
64015
+ const runtimeSessionId = randomUUID10();
64016
+ const deviceId = config2.runtimeDeviceId ?? randomUUID10();
62703
64017
  const response = await client.startRuntime(profileId, {
62704
64018
  session_id: runtimeSessionId,
62705
64019
  device_id: deviceId,