@vtxmacro/cli 2026.8.52 → 2026.8.54

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 +83 -31
  2. package/bin/vtx.js +2427 -190
  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.52",
50
+ package_version: "2026.8.54",
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",
@@ -19695,32 +19749,88 @@ var init_agent_client = __esm({
19695
19749
  });
19696
19750
 
19697
19751
  // lib/inference-host/agent-state.ts
19698
- async function readCodexAgentRuntimeState(statePath) {
19752
+ async function readInferenceAgentFailureFence(statePath) {
19753
+ const raw = await readInferencePrivateFile(
19754
+ inferenceAgentFailureFencePath(statePath),
19755
+ "Inference Agent failure fence"
19756
+ );
19757
+ if (raw === null) return null;
19758
+ try {
19759
+ return assertInferenceAgentFailureFence(JSON.parse(raw));
19760
+ } catch (error48) {
19761
+ if (error48 instanceof SyntaxError) {
19762
+ throw new Error("Inference Agent failure fence is not valid JSON.");
19763
+ }
19764
+ throw error48;
19765
+ }
19766
+ }
19767
+ async function writeInferenceAgentFailureFence(statePath, value) {
19768
+ await writeAtomicInferencePrivateFile(
19769
+ inferenceAgentFailureFencePath(statePath),
19770
+ `${JSON.stringify(assertInferenceAgentFailureFence(value), null, 2)}
19771
+ `
19772
+ );
19773
+ }
19774
+ async function clearInferenceAgentFailureFence(statePath) {
19775
+ await clearInferencePrivateFile(
19776
+ inferenceAgentFailureFencePath(statePath),
19777
+ "Inference Agent failure fence"
19778
+ );
19779
+ }
19780
+ async function readInferenceAgentRuntimeState(statePath) {
19781
+ const raw = await readInferencePrivateFile(
19782
+ inferenceAgentRuntimeStatePath(statePath),
19783
+ "Inference Agent runtime recovery state"
19784
+ );
19785
+ if (raw === null) return null;
19786
+ try {
19787
+ return assertInferenceAgentRuntimeState(JSON.parse(raw));
19788
+ } catch (error48) {
19789
+ if (error48 instanceof SyntaxError) {
19790
+ throw new Error("Inference Agent runtime recovery state is not valid JSON.");
19791
+ }
19792
+ throw error48;
19793
+ }
19794
+ }
19795
+ async function writeInferenceAgentRuntimeState(statePath, value) {
19796
+ await writeAtomicInferencePrivateFile(
19797
+ inferenceAgentRuntimeStatePath(statePath),
19798
+ `${JSON.stringify(assertInferenceAgentRuntimeState(value), null, 2)}
19799
+ `
19800
+ );
19801
+ }
19802
+ async function clearInferenceAgentRuntimeState(statePath) {
19803
+ await clearInferencePrivateFile(
19804
+ inferenceAgentRuntimeStatePath(statePath),
19805
+ "Inference Agent runtime recovery state"
19806
+ );
19807
+ }
19808
+ async function readInferenceForegroundAgentControlState(statePath) {
19699
19809
  const raw = await readInferencePrivateFile(
19700
- codexAgentRuntimeStatePath(statePath),
19701
- "Codex Agent runtime recovery state"
19810
+ foregroundAgentControlStatePath(statePath),
19811
+ "Foreground Agent control recovery state"
19702
19812
  );
19703
19813
  if (raw === null) return null;
19704
19814
  try {
19705
- return assertCodexAgentRuntimeState(JSON.parse(raw));
19815
+ return assertForegroundAgentControlState(JSON.parse(raw));
19706
19816
  } catch (error48) {
19707
19817
  if (error48 instanceof SyntaxError) {
19708
- throw new Error("Codex Agent runtime recovery state is not valid JSON.");
19818
+ throw new Error("Foreground Agent control recovery state is not valid JSON.");
19709
19819
  }
19710
19820
  throw error48;
19711
19821
  }
19712
19822
  }
19713
- async function writeCodexAgentRuntimeState(statePath, value) {
19823
+ async function writeInferenceForegroundAgentControlState(statePath, value) {
19714
19824
  await writeAtomicInferencePrivateFile(
19715
- codexAgentRuntimeStatePath(statePath),
19716
- `${JSON.stringify(assertCodexAgentRuntimeState(value), null, 2)}
19825
+ foregroundAgentControlStatePath(statePath),
19826
+ `${JSON.stringify(assertForegroundAgentControlState(value), null, 2)}
19717
19827
  `
19718
19828
  );
19719
19829
  }
19720
- async function clearCodexAgentRuntimeState(statePath) {
19830
+ async function clearInferenceForegroundAgentControlState(statePath) {
19721
19831
  await clearInferencePrivateFile(
19722
- codexAgentRuntimeStatePath(statePath),
19723
- "Codex Agent runtime recovery state"
19832
+ foregroundAgentControlStatePath(statePath),
19833
+ "Foreground Agent control recovery state"
19724
19834
  );
19725
19835
  }
19726
19836
  async function readInferenceAgentAttemptState(statePath) {
@@ -19779,7 +19889,7 @@ async function clearInferenceAgentNextState(statePath) {
19779
19889
  "Agent-driven inference next recovery state"
19780
19890
  );
19781
19891
  }
19782
- var inferenceAgentAttemptStatePath, inferenceAgentNextStatePath, codexAgentRuntimeStatePath, isIsoTimestamp, assertPlainObject, hasExactKeys, assertCodexAgentRuntimeState, assertNextState, assertAttemptState;
19892
+ var inferenceAgentAttemptStatePath, inferenceAgentNextStatePath, inferenceAgentRuntimeStatePath, inferenceAgentFailureFencePath, isIsoTimestamp, assertPlainObject, hasExactKeys, assertInferenceAgentFailureFence, assertInferenceAgentRuntimeState, readCodexAgentRuntimeState, clearCodexAgentRuntimeState, foregroundAgentControlStatePath, assertRuntimeAssignment, assertForegroundAgentControlState, assertNextState, assertAttemptState;
19783
19893
  var init_agent_state = __esm({
19784
19894
  "lib/inference-host/agent-state.ts"() {
19785
19895
  "use strict";
@@ -19787,18 +19897,39 @@ var init_agent_state = __esm({
19787
19897
  init_external_inference_contract();
19788
19898
  inferenceAgentAttemptStatePath = (statePath) => `${statePath}.agent-attempt.json`;
19789
19899
  inferenceAgentNextStatePath = (statePath) => `${statePath}.agent-next.json`;
19790
- codexAgentRuntimeStatePath = (statePath) => `${statePath}.codex-agent-runtime.json`;
19900
+ inferenceAgentRuntimeStatePath = (statePath) => `${statePath}.codex-agent-runtime.json`;
19901
+ inferenceAgentFailureFencePath = (statePath) => `${statePath}.agent-failure-fence.json`;
19791
19902
  isIsoTimestamp = (value) => typeof value === "string" && Number.isFinite(Date.parse(value));
19792
19903
  assertPlainObject = (value, message) => {
19793
19904
  if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error(message);
19794
19905
  return value;
19795
19906
  };
19796
19907
  hasExactKeys = (record2, keys) => Object.keys(record2).sort().join("\0") === [...keys].sort().join("\0");
19797
- assertCodexAgentRuntimeState = (value) => {
19798
- const message = "Codex Agent runtime recovery state is invalid.";
19908
+ assertInferenceAgentFailureFence = (value) => {
19909
+ const message = "Inference Agent failure fence is invalid.";
19910
+ const fence = assertPlainObject(value, message);
19911
+ if (!hasExactKeys(fence, [
19912
+ "schema_version",
19913
+ "adapter_id",
19914
+ "host_id",
19915
+ "assignment_id",
19916
+ "failure_category",
19917
+ "failure_code",
19918
+ "dispatch_outcome",
19919
+ "retry_at",
19920
+ "created_at"
19921
+ ]) || 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(
19922
+ String(fence.dispatch_outcome)
19923
+ ) || fence.retry_at !== null && !isIsoTimestamp(fence.retry_at) || !isIsoTimestamp(fence.created_at)) throw new Error(message);
19924
+ return fence;
19925
+ };
19926
+ assertInferenceAgentRuntimeState = (value) => {
19927
+ const message = "Inference Agent runtime recovery state is invalid.";
19799
19928
  const state = assertPlainObject(value, message);
19929
+ const generic = state.schema_version === "vtx_inference_agent_runtime_v3";
19800
19930
  if (!hasExactKeys(state, [
19801
19931
  "schema_version",
19932
+ ...generic ? ["adapter_id"] : [],
19802
19933
  "host_id",
19803
19934
  "assignment",
19804
19935
  "thread",
@@ -19807,9 +19938,13 @@ var init_agent_state = __esm({
19807
19938
  "updated_at"
19808
19939
  ])) throw new Error(message);
19809
19940
  const assignment = assertPlainObject(state.assignment, message);
19810
- if (!["vtx_codex_agent_runtime_v1", "vtx_codex_agent_runtime_v2"].includes(
19941
+ if (![
19942
+ "vtx_codex_agent_runtime_v1",
19943
+ "vtx_codex_agent_runtime_v2",
19944
+ "vtx_inference_agent_runtime_v3"
19945
+ ].includes(
19811
19946
  String(state.schema_version)
19812
- ) || typeof state.host_id !== "string" || !state.host_id || !isIsoTimestamp(state.next_wake_at) || !isIsoTimestamp(state.updated_at) || !hasExactKeys(
19947
+ ) || generic && (typeof state.adapter_id !== "string" || !/^[a-z0-9][a-z0-9._-]{0,63}$/u.test(state.adapter_id)) || typeof state.host_id !== "string" || !state.host_id || !isIsoTimestamp(state.next_wake_at) || !isIsoTimestamp(state.updated_at) || !hasExactKeys(
19813
19948
  assignment,
19814
19949
  [
19815
19950
  "assignment_id",
@@ -19823,10 +19958,10 @@ var init_agent_state = __esm({
19823
19958
  "minimum_wake_seconds",
19824
19959
  "maximum_wake_seconds",
19825
19960
  "lease_expires_at",
19826
- ...state.schema_version === "vtx_codex_agent_runtime_v2" ? ["data_contract"] : []
19961
+ ...state.schema_version !== "vtx_codex_agent_runtime_v1" ? ["data_contract"] : []
19827
19962
  ]
19828
19963
  ) || typeof assignment.assignment_id !== "string" || !assignment.assignment_id || !Number.isSafeInteger(assignment.assignment_generation) || Number(assignment.assignment_generation) < 1 || typeof assignment.model_id !== "string" || !assignment.model_id || typeof assignment.reasoning_effort !== "string" || !assignment.reasoning_effort || !["trader", "assistant"].includes(String(assignment.bot_mode)) || !["server", "client"].includes(String(assignment.execution_mode)) || !Array.isArray(assignment.allowed_symbols) || assignment.allowed_symbols.some((symbol2) => typeof symbol2 !== "string" || !symbol2) || !assignment.output_schema || typeof assignment.output_schema !== "object" || Array.isArray(assignment.output_schema) || !Number.isSafeInteger(assignment.minimum_wake_seconds) || Number(assignment.minimum_wake_seconds) < 1 || !Number.isSafeInteger(assignment.maximum_wake_seconds) || Number(assignment.maximum_wake_seconds) < Number(assignment.minimum_wake_seconds) || !isIsoTimestamp(assignment.lease_expires_at)) throw new Error(message);
19829
- if (state.schema_version === "vtx_codex_agent_runtime_v2") {
19964
+ if (state.schema_version !== "vtx_codex_agent_runtime_v1") {
19830
19965
  if (!Array.isArray(assignment.data_contract) || assignment.data_contract.length === 0) {
19831
19966
  throw new Error(message);
19832
19967
  }
@@ -19865,6 +20000,76 @@ var init_agent_state = __esm({
19865
20000
  }
19866
20001
  return state;
19867
20002
  };
20003
+ readCodexAgentRuntimeState = readInferenceAgentRuntimeState;
20004
+ clearCodexAgentRuntimeState = clearInferenceAgentRuntimeState;
20005
+ foregroundAgentControlStatePath = (statePath) => `${statePath}.foreground-agent-control.json`;
20006
+ assertRuntimeAssignment = (value, message) => {
20007
+ const assignment = assertPlainObject(value, message);
20008
+ if (!hasExactKeys(assignment, [
20009
+ "assignment_id",
20010
+ "assignment_generation",
20011
+ "model_id",
20012
+ "reasoning_effort",
20013
+ "bot_mode",
20014
+ "execution_mode",
20015
+ "allowed_symbols",
20016
+ "output_schema",
20017
+ "data_contract",
20018
+ "minimum_wake_seconds",
20019
+ "maximum_wake_seconds",
20020
+ "lease_expires_at"
20021
+ ]) || typeof assignment.assignment_id !== "string" || !assignment.assignment_id || !Number.isSafeInteger(assignment.assignment_generation) || Number(assignment.assignment_generation) < 1 || typeof assignment.model_id !== "string" || !assignment.model_id || typeof assignment.reasoning_effort !== "string" || !assignment.reasoning_effort || !["trader", "assistant"].includes(String(assignment.bot_mode)) || !["server", "client"].includes(String(assignment.execution_mode)) || !Array.isArray(assignment.allowed_symbols) || assignment.allowed_symbols.some((symbol2) => typeof symbol2 !== "string" || !symbol2) || !assignment.output_schema || typeof assignment.output_schema !== "object" || Array.isArray(assignment.output_schema) || !Array.isArray(assignment.data_contract) || assignment.data_contract.length === 0 || !Number.isSafeInteger(assignment.minimum_wake_seconds) || Number(assignment.minimum_wake_seconds) < 1 || !Number.isSafeInteger(assignment.maximum_wake_seconds) || Number(assignment.maximum_wake_seconds) < Number(assignment.minimum_wake_seconds) || !isIsoTimestamp(assignment.lease_expires_at)) throw new Error(message);
20022
+ const ids = assignment.data_contract.map((value2) => {
20023
+ const descriptor = assertPlainObject(value2, message);
20024
+ if (!hasExactKeys(descriptor, [
20025
+ "id",
20026
+ "title",
20027
+ "description",
20028
+ "input_schema",
20029
+ "input_schema_sha256"
20030
+ ]) || typeof descriptor.id !== "string" || !descriptor.id || typeof descriptor.title !== "string" || !descriptor.title || typeof descriptor.description !== "string" || !descriptor.description || !descriptor.input_schema || typeof descriptor.input_schema !== "object" || Array.isArray(descriptor.input_schema) || typeof descriptor.input_schema_sha256 !== "string" || !/^[0-9a-f]{64}$/u.test(descriptor.input_schema_sha256)) throw new Error(message);
20031
+ return descriptor.id;
20032
+ });
20033
+ if (new Set(ids).size !== ids.length) throw new Error(message);
20034
+ return assignment;
20035
+ };
20036
+ assertForegroundAgentControlState = (value) => {
20037
+ const message = "Foreground Agent control recovery state is invalid.";
20038
+ const state = assertPlainObject(value, message);
20039
+ if (!hasExactKeys(state, [
20040
+ "schema_version",
20041
+ "host_id",
20042
+ "assignment",
20043
+ "pending_next",
20044
+ "pending_decision",
20045
+ "next_wake_at",
20046
+ "updated_at"
20047
+ ]) || state.schema_version !== "vtx_foreground_agent_control_v1" || typeof state.host_id !== "string" || !state.host_id || state.next_wake_at !== null && !isIsoTimestamp(state.next_wake_at) || !isIsoTimestamp(state.updated_at)) throw new Error(message);
20048
+ if (state.assignment !== null) assertRuntimeAssignment(state.assignment, message);
20049
+ if (state.pending_next !== null) {
20050
+ const pending = assertPlainObject(state.pending_next, message);
20051
+ if (!hasExactKeys(pending, ["operation_id", "requested_at"]) || typeof pending.operation_id !== "string" || !pending.operation_id || !isIsoTimestamp(pending.requested_at)) throw new Error(message);
20052
+ }
20053
+ if (state.pending_decision !== null) {
20054
+ if (state.assignment === null) throw new Error(message);
20055
+ const pending = assertPlainObject(state.pending_decision, message);
20056
+ if (!hasExactKeys(pending, [
20057
+ "request",
20058
+ "first_transmit_at",
20059
+ "last_status_check_at"
20060
+ ])) throw new Error(message);
20061
+ const request = assertPlainObject(pending.request, message);
20062
+ if (!hasExactKeys(request, [
20063
+ "assignment_id",
20064
+ "assignment_generation",
20065
+ "operation_id",
20066
+ "candidate",
20067
+ "observed_at",
20068
+ "provenance"
20069
+ ]) || request.assignment_id !== state.assignment.assignment_id || request.assignment_generation !== state.assignment.assignment_generation || typeof request.operation_id !== "string" || !request.operation_id || !request.candidate || typeof request.candidate !== "object" || Array.isArray(request.candidate) || !isIsoTimestamp(request.observed_at) || !request.provenance || typeof request.provenance !== "object" || Array.isArray(request.provenance) || pending.first_transmit_at !== null && !isIsoTimestamp(pending.first_transmit_at) || pending.last_status_check_at !== null && !isIsoTimestamp(pending.last_status_check_at)) throw new Error(message);
20070
+ }
20071
+ return state;
20072
+ };
19868
20073
  assertNextState = (value) => {
19869
20074
  if (!value || typeof value !== "object" || Array.isArray(value)) {
19870
20075
  throw new Error("Agent-driven inference next recovery state is invalid.");
@@ -24019,15 +24224,17 @@ $items = @(Get-CimInstance Win32_Process | Where-Object { $_.Name -in @('node.ex
24019
24224
  });
24020
24225
 
24021
24226
  // lib/inference-host/copilot-adapter.ts
24227
+ import { randomUUID } from "node:crypto";
24022
24228
  import { mkdtemp as mkdtemp2, rm as rm4 } from "node:fs/promises";
24023
24229
  import { createRequire as createRequire2 } from "node:module";
24024
24230
  import { tmpdir as tmpdir3 } from "node:os";
24025
24231
  import { join as join5 } from "node:path";
24026
24232
  import {
24027
24233
  CopilotClient,
24028
- RuntimeConnection
24234
+ RuntimeConnection,
24235
+ defineTool
24029
24236
  } from "@github/copilot-sdk";
24030
- var COPILOT_SDK_VERSION, MAX_RESULT_BYTES, resolveRuntimePackage, copilotRuntimePackageCandidates, resolvePinnedCopilotCliPath, createPrivateWorkspace, cleanCopilotEnvironment, defaultClient, modelCapabilities, requiredUsageInteger, optionalUsageInteger, CopilotSubscriptionAdapter;
24237
+ var COPILOT_SDK_VERSION, MAX_RESULT_BYTES, resolveRuntimePackage, copilotRuntimePackageCandidates, resolvePinnedCopilotCliPath, createPrivateWorkspace, cleanCopilotEnvironment, defaultClient, modelCapabilities, requiredUsageInteger, optionalUsageInteger, copilotAgentToolDefinitions, CopilotSubscriptionAdapter;
24031
24238
  var init_copilot_adapter = __esm({
24032
24239
  "lib/inference-host/copilot-adapter.ts"() {
24033
24240
  "use strict";
@@ -24123,9 +24330,66 @@ var init_copilot_adapter = __esm({
24123
24330
  }
24124
24331
  return Number(value);
24125
24332
  };
24333
+ copilotAgentToolDefinitions = (input, evidence) => {
24334
+ const execute = async (tool, argumentsValue) => {
24335
+ const argumentsRecord = argumentsValue && typeof argumentsValue === "object" && !Array.isArray(argumentsValue) ? argumentsValue : {};
24336
+ const callId = randomUUID();
24337
+ const result2 = await input.executeTool({
24338
+ callId,
24339
+ tool,
24340
+ arguments: argumentsRecord
24341
+ });
24342
+ evidence.push({ callId, tool, arguments: argumentsRecord, success: result2.success });
24343
+ return result2.success ? result2.value : { error: result2.value };
24344
+ };
24345
+ return [
24346
+ defineTool("vtx_get_data", {
24347
+ description: "Request assignment-scoped VTX data using one exact canonical capability schema.",
24348
+ parameters: {
24349
+ oneOf: input.dataContract.map((descriptor) => ({
24350
+ type: "object",
24351
+ additionalProperties: false,
24352
+ required: ["capability", "arguments"],
24353
+ description: descriptor.description,
24354
+ properties: {
24355
+ capability: { type: "string", const: descriptor.id, title: descriptor.title },
24356
+ arguments: descriptor.input_schema
24357
+ }
24358
+ }))
24359
+ },
24360
+ skipPermission: true,
24361
+ handler: async (args) => await execute("vtx_get_data", args)
24362
+ }),
24363
+ defineTool("vtx_submit_decision", {
24364
+ description: "Submit one VTX structured trading decision candidate.",
24365
+ parameters: {
24366
+ type: "object",
24367
+ additionalProperties: false,
24368
+ required: ["candidate"],
24369
+ properties: { candidate: input.decisionSchema }
24370
+ },
24371
+ skipPermission: true,
24372
+ handler: async (args) => await execute("vtx_submit_decision", args)
24373
+ }),
24374
+ defineTool("vtx_decision_status", {
24375
+ description: "Resolve the durable status of a previously attempted decision operation.",
24376
+ parameters: {
24377
+ type: "object",
24378
+ additionalProperties: false,
24379
+ required: ["operation_id"],
24380
+ properties: { operation_id: { type: "string", minLength: 1 } }
24381
+ },
24382
+ skipPermission: true,
24383
+ handler: async (args) => await execute("vtx_decision_status", args)
24384
+ })
24385
+ ];
24386
+ };
24126
24387
  CopilotSubscriptionAdapter = class {
24127
24388
  constructor(dependencies = {}) {
24128
24389
  this.inFlight = /* @__PURE__ */ new Map();
24390
+ this.agentConnection = null;
24391
+ this.agentWorkspaceCleanups = /* @__PURE__ */ new Map();
24392
+ this.closing = false;
24129
24393
  this.dependencies = dependencies;
24130
24394
  }
24131
24395
  async preflight(signal) {
@@ -24337,6 +24601,1213 @@ ${input.outputSchemaJson}`
24337
24601
  await workspace.cleanup();
24338
24602
  }
24339
24603
  }
24604
+ async runTurn(input) {
24605
+ if (this.closing) {
24606
+ throw new CodexAppServerError({
24607
+ message: "Copilot Agent adapter is closing.",
24608
+ category: "transport",
24609
+ code: "transport_closed",
24610
+ retryable: true
24611
+ });
24612
+ }
24613
+ input.signal?.throwIfAborted();
24614
+ if (Date.now() >= input.deadlineAtMs || input.dataContract.length === 0) {
24615
+ throw new CodexAppServerError({
24616
+ message: "Copilot Agent turn input is invalid or expired.",
24617
+ category: Date.now() >= input.deadlineAtMs ? "timeout" : "schema",
24618
+ code: Date.now() >= input.deadlineAtMs ? "deadline_exceeded" : "invalid_agent_turn_input",
24619
+ retryable: false
24620
+ });
24621
+ }
24622
+ const startedAt = (this.dependencies.now ?? Date.now)();
24623
+ const ownedWorkspace = input.durableThread ? null : await (this.dependencies.createAgentWorkspace ?? this.dependencies.createWorkspace ?? createPrivateWorkspace)();
24624
+ const workspacePath = input.durableThread?.threadPath ?? ownedWorkspace.path;
24625
+ if (ownedWorkspace) this.agentWorkspaceCleanups.set(workspacePath, ownedWorkspace.cleanup);
24626
+ const client = (this.dependencies.createClient ?? defaultClient)(workspacePath);
24627
+ let session = null;
24628
+ let durableCheckpointed = input.durableThread !== null;
24629
+ let dispatchEntered = false;
24630
+ const toolEvidence = [];
24631
+ try {
24632
+ await client.start();
24633
+ const tools = copilotAgentToolDefinitions(input, toolEvidence);
24634
+ const sessionConfig = {
24635
+ clientName: "@vtxmacro/cli durable Copilot Agent host",
24636
+ model: input.requestedModel,
24637
+ ...input.requestedReasoningEffort === "none" ? {} : { reasoningEffort: input.requestedReasoningEffort },
24638
+ systemMessage: {
24639
+ mode: "replace",
24640
+ content: `${input.systemPrompt}
24641
+
24642
+ Return only one JSON value matching this JSON Schema exactly:
24643
+ ${JSON.stringify(input.outputSchema)}`
24644
+ },
24645
+ tools,
24646
+ availableTools: tools.map((tool) => tool.name),
24647
+ enableConfigDiscovery: false,
24648
+ streaming: true,
24649
+ workingDirectory: workspacePath,
24650
+ infiniteSessions: { enabled: true }
24651
+ };
24652
+ session = input.durableThread ? await client.resumeSession(input.durableThread.threadId, sessionConfig) : await client.createSession(sessionConfig);
24653
+ this.agentConnection = {
24654
+ client,
24655
+ session,
24656
+ workspacePath,
24657
+ cleanup: ownedWorkspace?.cleanup ?? null
24658
+ };
24659
+ const thread = {
24660
+ threadId: session.sessionId,
24661
+ threadPath: workspacePath,
24662
+ effectiveModel: input.requestedModel,
24663
+ effectiveReasoningEffort: input.requestedReasoningEffort
24664
+ };
24665
+ if (input.onThreadReady) {
24666
+ await input.onThreadReady(thread);
24667
+ durableCheckpointed = true;
24668
+ }
24669
+ const usageEvents = [];
24670
+ session.on((event) => {
24671
+ if (event.type === "assistant.usage" && !event.agentId) usageEvents.push(event);
24672
+ });
24673
+ const onAbort = () => {
24674
+ void session?.abort().catch(() => void 0);
24675
+ };
24676
+ input.signal?.addEventListener("abort", onAbort, { once: true });
24677
+ dispatchEntered = true;
24678
+ let response;
24679
+ try {
24680
+ response = await session.sendAndWait(
24681
+ { prompt: input.userPrompt },
24682
+ Math.max(1, input.deadlineAtMs - Date.now())
24683
+ );
24684
+ } finally {
24685
+ input.signal?.removeEventListener("abort", onAbort);
24686
+ }
24687
+ if (!response?.data.content || Buffer.byteLength(response.data.content, "utf8") > MAX_RESULT_BYTES) {
24688
+ throw new Error("copilot_agent_invalid_result");
24689
+ }
24690
+ const observedModels = /* @__PURE__ */ new Set();
24691
+ const observedEfforts = /* @__PURE__ */ new Set();
24692
+ let inputTokens = 0;
24693
+ let cachedInputTokens = 0;
24694
+ let outputTokens = 0;
24695
+ let reasoningOutputTokens = 0;
24696
+ let cacheWriteInputTokens = 0;
24697
+ let cacheWriteSupported = false;
24698
+ let timeToFirstTokenMs = null;
24699
+ let providerCallId = null;
24700
+ for (const event of usageEvents) {
24701
+ if (event.type !== "assistant.usage") continue;
24702
+ observedModels.add(event.data.model);
24703
+ if (event.data.reasoningEffort) observedEfforts.add(event.data.reasoningEffort);
24704
+ inputTokens += requiredUsageInteger(event.data.inputTokens, "input_tokens");
24705
+ cachedInputTokens += optionalUsageInteger(event.data.cacheReadTokens, "cache_read_tokens");
24706
+ outputTokens += requiredUsageInteger(event.data.outputTokens, "output_tokens");
24707
+ reasoningOutputTokens += optionalUsageInteger(event.data.reasoningTokens, "reasoning_tokens");
24708
+ if (event.data.cacheWriteTokens !== void 0) {
24709
+ cacheWriteSupported = true;
24710
+ cacheWriteInputTokens += optionalUsageInteger(event.data.cacheWriteTokens, "cache_write_tokens");
24711
+ }
24712
+ if (timeToFirstTokenMs === null && Number.isSafeInteger(event.data.timeToFirstTokenMs)) {
24713
+ timeToFirstTokenMs = Number(event.data.timeToFirstTokenMs);
24714
+ }
24715
+ providerCallId = event.data.providerCallId ?? event.data.apiCallId ?? providerCallId;
24716
+ }
24717
+ if (usageEvents.length === 0) throw new Error("copilot_agent_usage_receipt_missing");
24718
+ if (response.data.model) observedModels.add(response.data.model);
24719
+ if (observedModels.size !== 1 || !observedModels.has(input.requestedModel)) {
24720
+ throw new Error("copilot_agent_effective_model_mismatch");
24721
+ }
24722
+ const effectiveEffort = input.requestedReasoningEffort === "none" ? observedEfforts.size === 0 ? "none" : observedEfforts.size === 1 ? [...observedEfforts][0] : null : observedEfforts.size === 1 ? [...observedEfforts][0] : null;
24723
+ if (effectiveEffort !== input.requestedReasoningEffort) {
24724
+ throw new Error("copilot_agent_effective_effort_mismatch");
24725
+ }
24726
+ const usage = {
24727
+ inputTokens,
24728
+ cachedInputTokens: Math.min(cachedInputTokens, inputTokens),
24729
+ outputTokens,
24730
+ reasoningOutputTokens: Math.min(reasoningOutputTokens, outputTokens),
24731
+ totalTokens: inputTokens + outputTokens,
24732
+ cacheWriteInputTokens: cacheWriteSupported ? cacheWriteInputTokens : null,
24733
+ cacheWriteSupported
24734
+ };
24735
+ return {
24736
+ thread,
24737
+ turn: {
24738
+ text: response.data.content,
24739
+ reasoningContent: response.data.reasoningText ?? null,
24740
+ reasoningSummary: null,
24741
+ requestedModel: input.requestedModel,
24742
+ effectiveModel: input.requestedModel,
24743
+ requestedReasoningEffort: input.requestedReasoningEffort,
24744
+ effectiveReasoningEffort: effectiveEffort,
24745
+ adapterRequestId: providerCallId ?? response.data.requestId ?? response.data.messageId,
24746
+ adapterResponseId: response.data.serviceRequestId ?? response.data.messageId,
24747
+ usage,
24748
+ latencyMs: Math.max(0, (this.dependencies.now ?? Date.now)() - startedAt),
24749
+ timeToFirstTokenMs,
24750
+ terminalStatus: "completed",
24751
+ toolCalls: toolEvidence,
24752
+ webSearches: []
24753
+ }
24754
+ };
24755
+ } catch (error48) {
24756
+ if (error48 instanceof CodexAppServerError) throw error48;
24757
+ const cancelled = input.signal?.aborted === true;
24758
+ const deadline = Date.now() >= input.deadlineAtMs;
24759
+ if (dispatchEntered) await session?.abort().catch(() => void 0);
24760
+ if (session && !durableCheckpointed) {
24761
+ const abandonedSession = session;
24762
+ session = null;
24763
+ if (this.agentConnection?.session === abandonedSession) this.agentConnection = null;
24764
+ await abandonedSession.disconnect().catch(() => void 0);
24765
+ await client.deleteSession(abandonedSession.sessionId).catch(() => void 0);
24766
+ const cleanup = this.agentWorkspaceCleanups.get(workspacePath);
24767
+ if (cleanup) {
24768
+ await cleanup().catch(() => void 0);
24769
+ this.agentWorkspaceCleanups.delete(workspacePath);
24770
+ }
24771
+ }
24772
+ throw new CodexAppServerError({
24773
+ message: cancelled ? "Copilot Agent turn was cancelled." : deadline ? "Copilot Agent turn exceeded its deadline." : error48 instanceof Error ? error48.message : "Copilot Agent adapter failed.",
24774
+ category: cancelled ? "cancelled" : deadline ? "timeout" : "adapter",
24775
+ code: cancelled ? "cancelled" : deadline ? "deadline_exceeded" : "copilot_agent_adapter_failure",
24776
+ retryable: false,
24777
+ dispatchOutcome: dispatchEntered ? "confirmed_dispatched" : "not_dispatched",
24778
+ cause: error48
24779
+ });
24780
+ } finally {
24781
+ await session?.disconnect().catch(() => void 0);
24782
+ await client.stop().catch(async () => {
24783
+ await client.forceStop();
24784
+ });
24785
+ if (this.agentConnection?.session === session) this.agentConnection = null;
24786
+ }
24787
+ }
24788
+ async releaseThread(thread) {
24789
+ const active = this.agentConnection;
24790
+ if (active?.session.sessionId === thread.threadId) {
24791
+ await active.session.disconnect().catch(() => void 0);
24792
+ await active.client.stop().catch(async () => {
24793
+ await active.client.forceStop();
24794
+ });
24795
+ this.agentConnection = null;
24796
+ }
24797
+ const client = (this.dependencies.createClient ?? defaultClient)(thread.threadPath);
24798
+ await client.start();
24799
+ try {
24800
+ await client.deleteSession(thread.threadId);
24801
+ } finally {
24802
+ await client.stop().catch(async () => {
24803
+ await client.forceStop();
24804
+ });
24805
+ }
24806
+ const cleanup = this.agentWorkspaceCleanups.get(thread.threadPath);
24807
+ if (cleanup) {
24808
+ await cleanup();
24809
+ this.agentWorkspaceCleanups.delete(thread.threadPath);
24810
+ }
24811
+ }
24812
+ async close() {
24813
+ this.closing = true;
24814
+ const active = this.agentConnection;
24815
+ this.agentConnection = null;
24816
+ if (!active) return;
24817
+ await active.session.disconnect().catch(() => void 0);
24818
+ await active.client.stop().catch(async () => {
24819
+ await active.client.forceStop();
24820
+ });
24821
+ }
24822
+ };
24823
+ }
24824
+ });
24825
+
24826
+ // lib/inference-host/deepseek-transport-proxy.ts
24827
+ import { createServer as createServer2 } from "node:http";
24828
+ import { randomBytes as randomBytes4 } from "node:crypto";
24829
+ var MAX_REQUEST_BYTES, DeepSeekTransportProxy;
24830
+ var init_deepseek_transport_proxy = __esm({
24831
+ "lib/inference-host/deepseek-transport-proxy.ts"() {
24832
+ "use strict";
24833
+ MAX_REQUEST_BYTES = 8 * 1024 * 1024;
24834
+ DeepSeekTransportProxy = class {
24835
+ constructor(apiKey, expectedModel, expectedEffort, upstreamBaseUrl = "https://api.deepseek.com", fetchImpl = fetch) {
24836
+ this.apiKey = apiKey;
24837
+ this.expectedModel = expectedModel;
24838
+ this.expectedEffort = expectedEffort;
24839
+ this.upstreamBaseUrl = upstreamBaseUrl;
24840
+ this.fetchImpl = fetchImpl;
24841
+ this.server = null;
24842
+ this.urlValue = null;
24843
+ this.receiptsValue = [];
24844
+ this.controllers = /* @__PURE__ */ new Set();
24845
+ this.token = randomBytes4(24).toString("hex");
24846
+ this.upstreamRequestStartedValue = false;
24847
+ this.providerResponseObservedValue = false;
24848
+ this.unansweredUpstreamRequestsValue = 0;
24849
+ }
24850
+ get baseUrl() {
24851
+ if (!this.urlValue) throw new Error("deepseek_transport_proxy_not_started");
24852
+ return `${this.urlValue}/${this.token}`;
24853
+ }
24854
+ get receipts() {
24855
+ return [...this.receiptsValue];
24856
+ }
24857
+ get providerResponseObserved() {
24858
+ return this.providerResponseObservedValue;
24859
+ }
24860
+ get upstreamRequestStarted() {
24861
+ return this.upstreamRequestStartedValue;
24862
+ }
24863
+ get unansweredUpstreamRequest() {
24864
+ return this.unansweredUpstreamRequestsValue > 0;
24865
+ }
24866
+ async start() {
24867
+ if (this.server) return;
24868
+ this.server = createServer2(async (request, response) => {
24869
+ try {
24870
+ const prefix = `/${this.token}`;
24871
+ const requestUrl = request.url ?? "";
24872
+ if (request.method !== "POST" || requestUrl !== `${prefix}/chat/completions`) {
24873
+ response.writeHead(404).end();
24874
+ return;
24875
+ }
24876
+ const chunks = [];
24877
+ let requestBytes = 0;
24878
+ for await (const chunk of request) {
24879
+ const buffer = Buffer.from(chunk);
24880
+ requestBytes += buffer.byteLength;
24881
+ if (requestBytes > MAX_REQUEST_BYTES) throw new Error("deepseek_proxy_request_too_large");
24882
+ chunks.push(buffer);
24883
+ }
24884
+ const body = Buffer.concat(chunks);
24885
+ let requestedModel = "";
24886
+ let requestedEffort = "off";
24887
+ const payload = JSON.parse(body.toString("utf8"));
24888
+ requestedModel = String(payload.model ?? "");
24889
+ const thinking = payload.thinking;
24890
+ requestedEffort = thinking?.type === "disabled" ? "off" : String(payload.reasoning_effort ?? "");
24891
+ if (requestedModel !== this.expectedModel || requestedEffort !== this.expectedEffort) throw new Error("deepseek_outbound_model_or_effort_mismatch");
24892
+ const controller = new AbortController();
24893
+ this.controllers.add(controller);
24894
+ try {
24895
+ this.upstreamRequestStartedValue = true;
24896
+ this.unansweredUpstreamRequestsValue += 1;
24897
+ const upstream = await this.fetchImpl(
24898
+ `${this.upstreamBaseUrl}/chat/completions`,
24899
+ {
24900
+ method: request.method,
24901
+ headers: {
24902
+ "authorization": `Bearer ${this.apiKey}`,
24903
+ "content-type": String(request.headers["content-type"] ?? "application/json"),
24904
+ "accept": String(request.headers.accept ?? "application/json"),
24905
+ "user-agent": String(request.headers["user-agent"] ?? "@vtxmacro/cli")
24906
+ },
24907
+ body,
24908
+ signal: controller.signal
24909
+ }
24910
+ );
24911
+ this.unansweredUpstreamRequestsValue -= 1;
24912
+ this.providerResponseObservedValue = true;
24913
+ const headers = {};
24914
+ upstream.headers.forEach((value, name) => {
24915
+ if (!["connection", "transfer-encoding", "content-length"].includes(name)) {
24916
+ headers[name] = value;
24917
+ }
24918
+ });
24919
+ response.writeHead(upstream.status, headers);
24920
+ if (!upstream.body) {
24921
+ response.end();
24922
+ return;
24923
+ }
24924
+ if (!upstream.ok) {
24925
+ const errorReader = upstream.body.getReader();
24926
+ while (true) {
24927
+ const part = await errorReader.read();
24928
+ if (part.done) break;
24929
+ response.write(Buffer.from(part.value));
24930
+ }
24931
+ response.end();
24932
+ return;
24933
+ }
24934
+ const reader = upstream.body.getReader();
24935
+ const decoder2 = new TextDecoder();
24936
+ let pending = "";
24937
+ let observedId = "";
24938
+ let terminalObserved = false;
24939
+ const forwardLine = (line) => {
24940
+ if (!line.startsWith("data:")) {
24941
+ response.write(`${line}
24942
+ `);
24943
+ return;
24944
+ }
24945
+ const value = line.slice(5).trim();
24946
+ if (!value) {
24947
+ response.write(`${line}
24948
+ `);
24949
+ return;
24950
+ }
24951
+ if (value === "[DONE]") {
24952
+ if (terminalObserved || !observedId) {
24953
+ throw new Error("deepseek_provider_receipt_missing_or_mismatched");
24954
+ }
24955
+ terminalObserved = true;
24956
+ this.receiptsValue.push({
24957
+ id: observedId,
24958
+ model: this.expectedModel,
24959
+ requestedModel,
24960
+ requestedReasoningEffort: requestedEffort
24961
+ });
24962
+ response.write(`${line}
24963
+ `);
24964
+ return;
24965
+ }
24966
+ const event = JSON.parse(value);
24967
+ const eventId = typeof event.id === "string" ? event.id.trim() : "";
24968
+ const eventModel = typeof event.model === "string" ? event.model.trim() : "";
24969
+ if (!eventId || eventModel !== this.expectedModel || observedId && eventId !== observedId) throw new Error("deepseek_provider_receipt_missing_or_mismatched");
24970
+ observedId = eventId;
24971
+ response.write(`${line}
24972
+ `);
24973
+ };
24974
+ while (true) {
24975
+ const part = await reader.read();
24976
+ if (part.done) break;
24977
+ pending += decoder2.decode(part.value, { stream: true });
24978
+ const lines = pending.split(/\r?\n/u);
24979
+ pending = lines.pop() ?? "";
24980
+ for (const line of lines) forwardLine(line);
24981
+ }
24982
+ pending += decoder2.decode();
24983
+ if (pending) forwardLine(pending);
24984
+ if (!terminalObserved) {
24985
+ throw new Error("deepseek_provider_receipt_missing_or_mismatched");
24986
+ }
24987
+ response.end();
24988
+ } finally {
24989
+ this.controllers.delete(controller);
24990
+ }
24991
+ } catch {
24992
+ if (!response.headersSent) response.writeHead(502);
24993
+ response.end();
24994
+ }
24995
+ });
24996
+ await new Promise((resolve6, reject) => {
24997
+ this.server.once("error", reject);
24998
+ this.server.listen(0, "127.0.0.1", () => resolve6());
24999
+ });
25000
+ const address = this.server.address();
25001
+ if (!address || typeof address === "string") throw new Error("deepseek_proxy_bind_failed");
25002
+ this.urlValue = `http://127.0.0.1:${address.port}`;
25003
+ }
25004
+ async close() {
25005
+ for (const controller of this.controllers) controller.abort();
25006
+ const server = this.server;
25007
+ this.server = null;
25008
+ this.urlValue = null;
25009
+ if (!server) return;
25010
+ await new Promise((resolve6) => server.close(() => resolve6()));
25011
+ }
25012
+ };
25013
+ }
25014
+ });
25015
+
25016
+ // lib/inference-host/deepseek-harness-adapter.ts
25017
+ import { randomUUID as randomUUID2 } from "node:crypto";
25018
+ import { mkdtemp as mkdtemp3, realpath as realpath4, rm as rm5 } from "node:fs/promises";
25019
+ import { tmpdir as tmpdir4 } from "node:os";
25020
+ import { basename, dirname as dirname4, join as join6 } from "node:path";
25021
+ import { Context } from "@deepseek-ai/cordis";
25022
+ import * as AgentSpine from "@deepseek-ai/dsh-agent-spine-demo";
25023
+ import {
25024
+ createUserMessage,
25025
+ LlmError
25026
+ } from "@deepseek-ai/dsh-llm";
25027
+ import {
25028
+ DeepSeekAdapter,
25029
+ resolveAdapterOptions
25030
+ } from "@deepseek-ai/dsh-llm-deepseek";
25031
+ import * as LlmDeepSeek from "@deepseek-ai/dsh-llm-deepseek";
25032
+ import { SessionId } from "@deepseek-ai/dsh-session";
25033
+ import * as SessionCheckpointPolicy from "@deepseek-ai/dsh-session-checkpoint-policy";
25034
+ import { JsonlSessionPersistence } from "@deepseek-ai/dsh-session-persistence-jsonl";
25035
+ 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;
25036
+ var init_deepseek_harness_adapter = __esm({
25037
+ "lib/inference-host/deepseek-harness-adapter.ts"() {
25038
+ "use strict";
25039
+ init_codex_app_server();
25040
+ init_deepseek_transport_proxy();
25041
+ DEEPSEEK_HARNESS_VERSION = "0.1.1-rc.2";
25042
+ MAX_RESULT_BYTES2 = 3e5;
25043
+ DEEPSEEK_MODELS = ["deepseek-v4-flash", "deepseek-v4-pro"];
25044
+ DEEPSEEK_API_BASE_URL = "https://api.deepseek.com";
25045
+ isSupportedNodeVersion = (version3) => {
25046
+ const [major, minor] = version3.replace(/^v/u, "").split(".").map(Number);
25047
+ return major === 22 && minor >= 19 || major >= 24;
25048
+ };
25049
+ effortForHarness = (effort) => {
25050
+ if (effort === "none") return "off";
25051
+ if (effort === "low" || effort === "high" || effort === "max") return effort;
25052
+ throw new Error(`deepseek_reasoning_effort_unsupported:${effort}`);
25053
+ };
25054
+ supportedEfforts = (model) => model === "deepseek-v4-pro" ? ["none", "high", "max"] : ["none", "low", "high", "max"];
25055
+ toVtxUsage = (usage) => {
25056
+ const cacheRead = usage.cacheReadTokens ?? 0;
25057
+ const cacheWrite = usage.cacheWriteTokens ?? 0;
25058
+ const inclusiveInput = usage.inputTokens + cacheRead + cacheWrite;
25059
+ return {
25060
+ inputTokens: inclusiveInput,
25061
+ cachedInputTokens: cacheRead,
25062
+ outputTokens: usage.outputTokens,
25063
+ reasoningOutputTokens: Math.min(usage.reasoningTokens ?? 0, usage.outputTokens),
25064
+ totalTokens: inclusiveInput + usage.outputTokens,
25065
+ cacheWriteInputTokens: usage.cacheWriteTokens ?? null,
25066
+ cacheWriteSupported: usage.cacheWriteTokens !== void 0
25067
+ };
25068
+ };
25069
+ sumUsage = (values) => toVtxUsage({
25070
+ inputTokens: values.reduce((sum, value) => sum + value.inputTokens, 0),
25071
+ outputTokens: values.reduce((sum, value) => sum + value.outputTokens, 0),
25072
+ cacheReadTokens: values.reduce((sum, value) => sum + (value.cacheReadTokens ?? 0), 0),
25073
+ cacheWriteTokens: values.some((value) => value.cacheWriteTokens !== void 0) ? values.reduce((sum, value) => sum + (value.cacheWriteTokens ?? 0), 0) : void 0,
25074
+ reasoningTokens: values.reduce((sum, value) => sum + (value.reasoningTokens ?? 0), 0)
25075
+ });
25076
+ textFromBlocks = (blocks, type) => blocks.flatMap((block) => block.type === type ? [block.text] : []).join("");
25077
+ validateText = (text, code) => {
25078
+ if (!text.trim() || Buffer.byteLength(text, "utf8") > MAX_RESULT_BYTES2) throw new Error(code);
25079
+ return text;
25080
+ };
25081
+ createDeadlineBoundary = (source, deadlineAtMs) => {
25082
+ const controller = new AbortController();
25083
+ const relayAbort = () => controller.abort(source?.reason);
25084
+ source?.addEventListener("abort", relayAbort, { once: true });
25085
+ if (source?.aborted) controller.abort(source.reason);
25086
+ const timeout = setTimeout(
25087
+ () => controller.abort(new Error("deadline_exceeded")),
25088
+ Math.max(1, deadlineAtMs - Date.now())
25089
+ );
25090
+ timeout.unref();
25091
+ return {
25092
+ signal: controller.signal,
25093
+ cleanup: () => {
25094
+ clearTimeout(timeout);
25095
+ source?.removeEventListener("abort", relayAbort);
25096
+ }
25097
+ };
25098
+ };
25099
+ nonDispatchedError = (message, category, code, retryable = false) => new CodexAppServerError({
25100
+ message,
25101
+ category,
25102
+ code,
25103
+ retryable,
25104
+ dispatchOutcome: "not_dispatched"
25105
+ });
25106
+ proxyDispatchOutcome = (proxy) => {
25107
+ if (proxy.unansweredUpstreamRequest) return "outcome_unknown";
25108
+ if (proxy.providerResponseObserved) return "confirmed_dispatched";
25109
+ return proxy.upstreamRequestStarted ? "outcome_unknown" : "not_dispatched";
25110
+ };
25111
+ mapDeepSeekFailure = (options) => {
25112
+ if (options.error instanceof CodexAppServerError) return options.error;
25113
+ if (options.cancelled || options.deadline) {
25114
+ return new CodexAppServerError({
25115
+ message: options.cancelled ? "DeepSeek Harness request was cancelled." : "DeepSeek Harness request exceeded its deadline.",
25116
+ category: options.cancelled ? "cancelled" : "timeout",
25117
+ code: options.cancelled ? "cancelled" : "deadline_exceeded",
25118
+ retryable: false,
25119
+ dispatchOutcome: options.dispatchOutcome,
25120
+ cause: options.error
25121
+ });
25122
+ }
25123
+ if (options.error instanceof LlmError) {
25124
+ const failure = options.error.failure;
25125
+ const auth = ["AUTH", "INVALID_CREDENTIAL", "MISSING_CREDENTIAL"].includes(failure.code);
25126
+ const quota = failure.code === "QUOTA" || failure.status === 402;
25127
+ const rateLimit = failure.code === "RATE_LIMIT";
25128
+ const clientError = failure.status !== void 0 && failure.status >= 400 && failure.status < 500;
25129
+ const model = !auth && !quota && !rateLimit && clientError || [
25130
+ "CONTEXT_WINDOW_EXCEEDED",
25131
+ "INVALID_REQUEST",
25132
+ "UNSUPPORTED_CONTENT",
25133
+ "UNSUPPORTED_REASONING_EFFORT"
25134
+ ].includes(failure.code);
25135
+ const transport = [
25136
+ "EMPTY_RESPONSE",
25137
+ "MALFORMED_RESPONSE",
25138
+ "SERVER",
25139
+ "STREAM_CLOSED",
25140
+ "TIMEOUT",
25141
+ "TRANSPORT"
25142
+ ].includes(failure.code) || failure.code.startsWith("HTTP_") && !clientError;
25143
+ 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";
25144
+ return new CodexAppServerError({
25145
+ message: failure.message,
25146
+ category: auth ? "auth" : model || quota || rateLimit ? "model" : transport ? "transport" : "adapter",
25147
+ code,
25148
+ retryable: transport && !quota,
25149
+ dispatchOutcome: options.dispatchOutcome,
25150
+ httpStatusCode: failure.status ?? null,
25151
+ retryAtMs: failure.providerRetryAfterMs === void 0 ? null : Date.now() + failure.providerRetryAfterMs,
25152
+ cause: options.error
25153
+ });
25154
+ }
25155
+ return new CodexAppServerError({
25156
+ message: options.error instanceof Error ? options.error.message : "DeepSeek Harness adapter failed.",
25157
+ category: "adapter",
25158
+ code: "deepseek_harness_adapter_failure",
25159
+ retryable: false,
25160
+ dispatchOutcome: options.dispatchOutcome,
25161
+ cause: options.error
25162
+ });
25163
+ };
25164
+ createPrivateWorkspace2 = async () => {
25165
+ const path = await mkdtemp3(join6(tmpdir4(), "vtx-deepseek-harness-"));
25166
+ return { path, cleanup: async () => {
25167
+ await rm5(path, { recursive: true, force: true });
25168
+ } };
25169
+ };
25170
+ directAdapter = (proxy, model, effort) => {
25171
+ const connection = resolveAdapterOptions({
25172
+ apiKeyEnv: "VTX_DSH_LOOPBACK_TOKEN",
25173
+ baseURL: proxy.baseUrl,
25174
+ reasoningEffort: effort,
25175
+ thinking: "enabled",
25176
+ models: [{ id: model }],
25177
+ retryPolicy: { mode: "normal", maxRetries: 0 }
25178
+ });
25179
+ return new DeepSeekAdapter({
25180
+ options: () => connection,
25181
+ resolveApiKey: async () => "vtx-loopback-only",
25182
+ resolveUserId: () => "vtx-macro"
25183
+ });
25184
+ };
25185
+ normalizeJsonValue = (value) => JSON.parse(JSON.stringify(value));
25186
+ DeepSeekHarnessAdapter = class {
25187
+ constructor(dependencies) {
25188
+ this.agentWorkspaces = /* @__PURE__ */ new Map();
25189
+ this.closing = false;
25190
+ this.dependencies = dependencies;
25191
+ }
25192
+ async preflight(signal) {
25193
+ if (!isSupportedNodeVersion(this.dependencies.nodeVersion ?? process.version)) {
25194
+ throw new CodexAppServerError({
25195
+ message: "DeepSeek Harness requires Node 22.19 or newer in the Node 22 line, or Node 24+.",
25196
+ category: "adapter",
25197
+ code: "deepseek_harness_node_version_unsupported",
25198
+ retryable: false
25199
+ });
25200
+ }
25201
+ const credential = await this.dependencies.credentialStore.read(signal);
25202
+ if (!credential) {
25203
+ throw new CodexAppServerError({
25204
+ message: "Import a DeepSeek API key with vtx inference-host deepseek-login first.",
25205
+ category: "auth",
25206
+ code: "deepseek_harness_credential_required",
25207
+ retryable: false
25208
+ });
25209
+ }
25210
+ const response = await (this.dependencies.fetch ?? fetch)(
25211
+ `${this.dependencies.apiBaseUrl ?? DEEPSEEK_API_BASE_URL}/models`,
25212
+ { headers: { authorization: `Bearer ${credential.apiKey}` }, signal }
25213
+ );
25214
+ if (!response.ok) {
25215
+ throw new CodexAppServerError({
25216
+ message: `DeepSeek model catalog request failed with HTTP ${response.status}.`,
25217
+ category: response.status === 401 || response.status === 403 ? "auth" : "transport",
25218
+ code: "deepseek_harness_model_catalog_failed",
25219
+ retryable: false
25220
+ });
25221
+ }
25222
+ const payload = await response.json();
25223
+ const live = new Set((payload.data ?? []).map((item) => String(item.id ?? "")));
25224
+ const models = DEEPSEEK_MODELS.filter((model) => live.has(model));
25225
+ if (models.length === 0) {
25226
+ throw new CodexAppServerError({
25227
+ message: "DeepSeek returned no VTX-supported Harness models.",
25228
+ category: "model",
25229
+ code: "deepseek_harness_model_catalog_empty",
25230
+ retryable: false
25231
+ });
25232
+ }
25233
+ return {
25234
+ adapterId: "deepseek-harness",
25235
+ runtimeVersion: DEEPSEEK_HARNESS_VERSION,
25236
+ authenticatedAccountIdentity: null,
25237
+ authenticatedAccountEmail: null,
25238
+ authenticatedAccountPlan: null,
25239
+ modelCapabilities: models.map((model, index) => ({
25240
+ id: model,
25241
+ model,
25242
+ displayName: model === "deepseek-v4-flash" ? "DeepSeek V4 Flash" : "DeepSeek V4 Pro",
25243
+ hidden: false,
25244
+ supportedReasoningEfforts: [...supportedEfforts(model)],
25245
+ defaultReasoningEffort: "high",
25246
+ isDefault: index === 0
25247
+ })),
25248
+ rateLimits: null,
25249
+ sameAttemptRecovery: false
25250
+ };
25251
+ }
25252
+ async runAttempt(input) {
25253
+ const startedAt = (this.dependencies.now ?? Date.now)();
25254
+ if (Date.now() >= input.deadlineAtMs) {
25255
+ throw nonDispatchedError(
25256
+ "DeepSeek Harness attempt exceeded its deadline.",
25257
+ "timeout",
25258
+ "deadline_exceeded"
25259
+ );
25260
+ }
25261
+ if (!DEEPSEEK_MODELS.includes(input.requestedModel)) {
25262
+ throw nonDispatchedError(
25263
+ "The requested DeepSeek Harness model is unsupported.",
25264
+ "model",
25265
+ "deepseek_model_unsupported"
25266
+ );
25267
+ }
25268
+ if (!supportedEfforts(input.requestedModel).includes(input.requestedReasoningEffort)) {
25269
+ throw nonDispatchedError(
25270
+ "The requested DeepSeek Harness reasoning effort is unsupported.",
25271
+ "model",
25272
+ "deepseek_reasoning_effort_unsupported"
25273
+ );
25274
+ }
25275
+ const effort = effortForHarness(input.requestedReasoningEffort);
25276
+ const boundary = createDeadlineBoundary(input.signal, input.deadlineAtMs);
25277
+ let credential;
25278
+ try {
25279
+ credential = await this.dependencies.credentialStore.read(boundary.signal);
25280
+ if (!credential) {
25281
+ throw nonDispatchedError(
25282
+ "Import a DeepSeek API key with vtx inference-host deepseek-login first.",
25283
+ "auth",
25284
+ "deepseek_harness_credential_required"
25285
+ );
25286
+ }
25287
+ } catch (error48) {
25288
+ const cancelled = input.signal?.aborted === true;
25289
+ const deadline = !cancelled && boundary.signal.aborted;
25290
+ boundary.cleanup();
25291
+ if (error48 instanceof CodexAppServerError) throw error48;
25292
+ throw nonDispatchedError(
25293
+ cancelled ? "DeepSeek Harness attempt was cancelled." : deadline ? "DeepSeek Harness attempt exceeded its deadline." : "DeepSeek Harness could not read its local credential.",
25294
+ cancelled ? "cancelled" : deadline ? "timeout" : "auth",
25295
+ cancelled ? "cancelled" : deadline ? "deadline_exceeded" : "deepseek_harness_credential_read_failed"
25296
+ );
25297
+ }
25298
+ const proxy = new DeepSeekTransportProxy(
25299
+ credential.apiKey,
25300
+ input.requestedModel,
25301
+ effort,
25302
+ this.dependencies.apiBaseUrl ?? DEEPSEEK_API_BASE_URL,
25303
+ this.dependencies.fetch ?? fetch
25304
+ );
25305
+ try {
25306
+ boundary.signal.throwIfAborted();
25307
+ await proxy.start();
25308
+ const adapter = directAdapter(proxy, input.requestedModel, effort);
25309
+ const blocks = [];
25310
+ let usage = null;
25311
+ let finish = null;
25312
+ for await (const chunk of adapter.stream({
25313
+ provider: "deepseek-official",
25314
+ model: input.requestedModel,
25315
+ reasoningEffort: effort,
25316
+ system: `${input.systemPrompt}
25317
+
25318
+ Return only one JSON value matching this JSON Schema exactly:
25319
+ ${input.outputSchemaJson}`,
25320
+ messages: [createUserMessage({
25321
+ content: [{ type: "text", text: input.userPrompt }],
25322
+ source: { kind: "user" }
25323
+ })],
25324
+ tools: [],
25325
+ signal: boundary.signal
25326
+ })) {
25327
+ if (chunk.type === "block-end") blocks.push(chunk.block);
25328
+ if (chunk.type === "usage") usage = chunk.usage;
25329
+ if (chunk.type === "finish") finish = chunk;
25330
+ }
25331
+ const receipts = proxy.receipts;
25332
+ if (receipts.length !== 1 || !usage || finish?.type !== "finish" || finish.reason.kind !== "stop") {
25333
+ throw new Error("deepseek_harness_terminal_receipt_invalid");
25334
+ }
25335
+ const text = validateText(textFromBlocks(blocks, "text"), "deepseek_harness_result_invalid");
25336
+ return {
25337
+ text,
25338
+ reasoningContent: textFromBlocks(blocks, "reasoning") || null,
25339
+ reasoningSummary: null,
25340
+ requestedModel: input.requestedModel,
25341
+ effectiveModel: receipts[0].model,
25342
+ requestedReasoningEffort: input.requestedReasoningEffort,
25343
+ effectiveReasoningEffort: input.requestedReasoningEffort,
25344
+ adapterRequestId: receipts[0].id,
25345
+ adapterResponseId: receipts[0].id,
25346
+ usage: toVtxUsage(usage),
25347
+ latencyMs: Math.max(0, (this.dependencies.now ?? Date.now)() - startedAt),
25348
+ timeToFirstTokenMs: null,
25349
+ terminalStatus: "completed"
25350
+ };
25351
+ } catch (error48) {
25352
+ const cancelled = input.signal?.aborted === true;
25353
+ const deadline = !cancelled && boundary.signal.aborted;
25354
+ throw mapDeepSeekFailure({
25355
+ error: error48,
25356
+ cancelled,
25357
+ deadline,
25358
+ dispatchOutcome: proxyDispatchOutcome(proxy)
25359
+ });
25360
+ } finally {
25361
+ boundary.cleanup();
25362
+ await proxy.close();
25363
+ }
25364
+ }
25365
+ async runTurn(input) {
25366
+ if (this.closing) {
25367
+ throw nonDispatchedError(
25368
+ "DeepSeek Harness Agent adapter is closing.",
25369
+ "transport",
25370
+ "transport_closed",
25371
+ true
25372
+ );
25373
+ }
25374
+ if (Date.now() >= input.deadlineAtMs) {
25375
+ throw nonDispatchedError(
25376
+ "DeepSeek Harness Agent turn exceeded its deadline.",
25377
+ "timeout",
25378
+ "deadline_exceeded"
25379
+ );
25380
+ }
25381
+ if (!DEEPSEEK_MODELS.includes(input.requestedModel)) {
25382
+ throw nonDispatchedError(
25383
+ "The requested DeepSeek Harness model is unsupported.",
25384
+ "model",
25385
+ "deepseek_model_unsupported"
25386
+ );
25387
+ }
25388
+ if (input.dataContract.length === 0 || !supportedEfforts(input.requestedModel).includes(input.requestedReasoningEffort)) {
25389
+ throw nonDispatchedError(
25390
+ "DeepSeek Harness Agent turn input is invalid.",
25391
+ "schema",
25392
+ "invalid_agent_turn_input"
25393
+ );
25394
+ }
25395
+ const startedAt = (this.dependencies.now ?? Date.now)();
25396
+ const effort = effortForHarness(input.requestedReasoningEffort);
25397
+ const boundary = createDeadlineBoundary(input.signal, input.deadlineAtMs);
25398
+ let credential;
25399
+ try {
25400
+ credential = await this.dependencies.credentialStore.read(boundary.signal);
25401
+ if (!credential) {
25402
+ throw nonDispatchedError(
25403
+ "Import a DeepSeek API key with vtx inference-host deepseek-login first.",
25404
+ "auth",
25405
+ "deepseek_harness_credential_required"
25406
+ );
25407
+ }
25408
+ } catch (error48) {
25409
+ const cancelled = input.signal?.aborted === true;
25410
+ const deadline = !cancelled && boundary.signal.aborted;
25411
+ boundary.cleanup();
25412
+ if (error48 instanceof CodexAppServerError) throw error48;
25413
+ throw nonDispatchedError(
25414
+ cancelled ? "DeepSeek Harness Agent turn was cancelled." : deadline ? "DeepSeek Harness Agent turn exceeded its deadline." : "DeepSeek Harness could not read its local credential.",
25415
+ cancelled ? "cancelled" : deadline ? "timeout" : "auth",
25416
+ cancelled ? "cancelled" : deadline ? "deadline_exceeded" : "deepseek_harness_credential_read_failed"
25417
+ );
25418
+ }
25419
+ const owned = input.durableThread ? null : await (this.dependencies.createWorkspace ?? createPrivateWorkspace2)();
25420
+ const rootPath = input.durableThread?.threadPath ?? owned.path;
25421
+ if (owned) this.agentWorkspaces.set(rootPath, owned.cleanup);
25422
+ const proxy = new DeepSeekTransportProxy(
25423
+ credential.apiKey,
25424
+ input.requestedModel,
25425
+ effort,
25426
+ this.dependencies.apiBaseUrl ?? DEEPSEEK_API_BASE_URL,
25427
+ this.dependencies.fetch ?? fetch
25428
+ );
25429
+ const ctx = new Context();
25430
+ const loopbackEnvName = `VTX_DSH_LOOPBACK_TOKEN_${randomUUID2().replaceAll("-", "").toUpperCase()}`;
25431
+ process.env[loopbackEnvName] = "vtx-loopback-only";
25432
+ let durableCheckpointed = input.durableThread !== null;
25433
+ let cleanupUnpublishedWorkspace = false;
25434
+ let removeAgentAbortListener = () => void 0;
25435
+ let cancelAgentTurn = () => void 0;
25436
+ let releaseAgentDispatch = () => void 0;
25437
+ let permitAgentDispatch = false;
25438
+ try {
25439
+ await proxy.start();
25440
+ await ctx.plugin(AgentSpine, {
25441
+ agents: [],
25442
+ maxParallelToolCalls: 1,
25443
+ includeHarnessIdentity: false,
25444
+ includeRuntimeContext: false,
25445
+ persona: `${input.systemPrompt}
25446
+
25447
+ Return only one JSON value matching this JSON Schema exactly:
25448
+ ${JSON.stringify(input.outputSchema)}`,
25449
+ tools: { mode: "native" },
25450
+ workspaceContext: false,
25451
+ skills: { enabled: false },
25452
+ toolBash: false,
25453
+ toolJobs: false,
25454
+ goals: false
25455
+ });
25456
+ await ctx.plugin(JsonlSessionPersistence, { root: rootPath, compression: "none" });
25457
+ await ctx.plugin(SessionCheckpointPolicy);
25458
+ await ctx.plugin(LlmDeepSeek, {
25459
+ apiKeyEnv: loopbackEnvName,
25460
+ baseURL: proxy.baseUrl,
25461
+ reasoningEffort: effort,
25462
+ thinking: "enabled",
25463
+ models: [{ id: input.requestedModel }],
25464
+ retryPolicy: { mode: "normal", maxRetries: 0 }
25465
+ });
25466
+ const evidence = [];
25467
+ const setup = (agentCtx) => {
25468
+ const definitions = [
25469
+ {
25470
+ name: "vtx_get_data",
25471
+ description: "Request assignment-scoped VTX data.",
25472
+ parameters: { oneOf: input.dataContract.map((entry) => ({
25473
+ type: "object",
25474
+ additionalProperties: false,
25475
+ required: ["capability", "arguments"],
25476
+ properties: { capability: { const: entry.id }, arguments: entry.input_schema }
25477
+ })) }
25478
+ },
25479
+ {
25480
+ name: "vtx_submit_decision",
25481
+ description: "Submit one VTX structured trading decision candidate.",
25482
+ parameters: { type: "object", additionalProperties: false, required: ["candidate"], properties: { candidate: input.decisionSchema } }
25483
+ },
25484
+ {
25485
+ name: "vtx_decision_status",
25486
+ description: "Resolve the durable status of a decision operation.",
25487
+ parameters: { type: "object", additionalProperties: false, required: ["operation_id"], properties: { operation_id: { type: "string", minLength: 1 } } }
25488
+ }
25489
+ ];
25490
+ for (const definition of definitions) {
25491
+ agentCtx.tools.register({
25492
+ ...definition,
25493
+ output: {
25494
+ schema: {},
25495
+ render: (_arguments, value) => [{ type: "text", text: JSON.stringify(value) }]
25496
+ },
25497
+ execute: async (argumentsValue) => {
25498
+ const argumentsRecord = argumentsValue && typeof argumentsValue === "object" && !Array.isArray(argumentsValue) ? argumentsValue : {};
25499
+ const callId = randomUUID2();
25500
+ const result2 = await input.executeTool({ callId, tool: definition.name, arguments: argumentsRecord });
25501
+ evidence.push({ callId, tool: definition.name, arguments: argumentsRecord, success: result2.success });
25502
+ return normalizeJsonValue(result2.success ? result2.value : { error: result2.value });
25503
+ }
25504
+ });
25505
+ }
25506
+ };
25507
+ const sessionId = input.durableThread ? SessionId(input.durableThread.threadId) : SessionId(`vtx-${randomUUID2()}`);
25508
+ const handle = input.durableThread ? await ctx.agents.resume({
25509
+ resumeSessionId: sessionId,
25510
+ agentOptions: { provider: "deepseek-official", model: input.requestedModel, reasoningEffort: effort },
25511
+ signal: boundary.signal,
25512
+ setup
25513
+ }) : await ctx.agents.create({
25514
+ sessionId,
25515
+ meta: { cwd: rootPath },
25516
+ agentOptions: { provider: "deepseek-official", model: input.requestedModel, reasoningEffort: effort },
25517
+ signal: boundary.signal,
25518
+ setup
25519
+ });
25520
+ const onAbort = () => handle.agent.cancel({ kind: "user" });
25521
+ cancelAgentTurn = onAbort;
25522
+ boundary.signal.addEventListener("abort", onAbort, { once: true });
25523
+ removeAgentAbortListener = () => boundary.signal.removeEventListener("abort", onAbort);
25524
+ if (boundary.signal.aborted) onAbort();
25525
+ boundary.signal.throwIfAborted();
25526
+ let checkpointReached = false;
25527
+ let resolveCheckpoint;
25528
+ const checkpoint = new Promise((resolve6) => {
25529
+ resolveCheckpoint = resolve6;
25530
+ });
25531
+ const dispatchGate = new Promise((resolve6) => {
25532
+ releaseAgentDispatch = resolve6;
25533
+ });
25534
+ ctx.on("llm/stream", (options, next) => {
25535
+ if (String(options.sessionId ?? "") !== String(sessionId)) return next();
25536
+ return (async function* () {
25537
+ await ctx.sessions.flush(handle.agent.session);
25538
+ checkpointReached = true;
25539
+ resolveCheckpoint();
25540
+ await dispatchGate;
25541
+ boundary.signal.throwIfAborted();
25542
+ if (!permitAgentDispatch) throw new Error("deepseek_agent_publication_not_committed");
25543
+ yield* next();
25544
+ })();
25545
+ });
25546
+ const thread = {
25547
+ threadId: String(sessionId),
25548
+ threadPath: rootPath,
25549
+ effectiveModel: input.requestedModel,
25550
+ effectiveReasoningEffort: input.requestedReasoningEffort
25551
+ };
25552
+ const startSeq = handle.agent.session.seq;
25553
+ handle.agent.followup(createUserMessage({
25554
+ content: [{ type: "text", text: input.userPrompt }],
25555
+ source: { kind: "user" }
25556
+ }));
25557
+ const idle = handle.agent.whenIdle();
25558
+ await Promise.race([
25559
+ checkpoint,
25560
+ idle.then(() => {
25561
+ if (!checkpointReached) throw new Error("deepseek_agent_checkpoint_not_reached");
25562
+ })
25563
+ ]);
25564
+ boundary.signal.throwIfAborted();
25565
+ if (input.onThreadReady) {
25566
+ await input.onThreadReady(thread);
25567
+ durableCheckpointed = true;
25568
+ }
25569
+ boundary.signal.throwIfAborted();
25570
+ permitAgentDispatch = true;
25571
+ releaseAgentDispatch();
25572
+ releaseAgentDispatch = () => void 0;
25573
+ await idle;
25574
+ const events = handle.agent.session.events.slice(startSeq);
25575
+ const assistantEvents = events.filter((event) => event.type === "assistant/message");
25576
+ const turnEnd = [...events].reverse().find((event) => event.type === "turn/end");
25577
+ if (!turnEnd || turnEnd.type !== "turn/end" || turnEnd.data.reason.kind !== "completed") {
25578
+ if (turnEnd?.type === "turn/end" && turnEnd.data.reason.kind === "error") {
25579
+ const failure = turnEnd.data.reason.error;
25580
+ throw new LlmError(failure.message, failure.code, {
25581
+ ...failure.status === void 0 ? {} : { status: failure.status },
25582
+ ...failure.providerRetryAfterMs === void 0 ? {} : { providerRetryAfterMs: failure.providerRetryAfterMs }
25583
+ });
25584
+ }
25585
+ const reason = turnEnd?.type === "turn/end" ? turnEnd.data.reason : { kind: "missing" };
25586
+ throw new Error(`deepseek_harness_agent_turn_incomplete:${JSON.stringify(reason)}`);
25587
+ }
25588
+ const last = assistantEvents.at(-1);
25589
+ if (!last || last.type !== "assistant/message" || last.data.interrupted) {
25590
+ throw new Error("deepseek_harness_agent_result_missing");
25591
+ }
25592
+ const usages = assistantEvents.flatMap((event) => event.type === "assistant/message" && event.data.usage ? [event.data.usage] : []);
25593
+ if (usages.length === 0 || proxy.receipts.length !== usages.length) {
25594
+ throw new Error("deepseek_harness_agent_receipt_missing");
25595
+ }
25596
+ const text = validateText(textFromBlocks(last.data.message.content, "text"), "deepseek_harness_agent_result_invalid");
25597
+ const receipts = proxy.receipts;
25598
+ await handle.dispose();
25599
+ return {
25600
+ thread,
25601
+ turn: {
25602
+ text,
25603
+ reasoningContent: textFromBlocks(last.data.message.content, "reasoning") || null,
25604
+ reasoningSummary: null,
25605
+ requestedModel: input.requestedModel,
25606
+ effectiveModel: receipts.at(-1).model,
25607
+ requestedReasoningEffort: input.requestedReasoningEffort,
25608
+ effectiveReasoningEffort: input.requestedReasoningEffort,
25609
+ adapterRequestId: receipts[0].id,
25610
+ adapterResponseId: receipts.at(-1).id,
25611
+ usage: sumUsage(usages),
25612
+ latencyMs: Math.max(0, (this.dependencies.now ?? Date.now)() - startedAt),
25613
+ timeToFirstTokenMs: null,
25614
+ terminalStatus: "completed",
25615
+ toolCalls: evidence,
25616
+ webSearches: []
25617
+ }
25618
+ };
25619
+ } catch (error48) {
25620
+ cancelAgentTurn();
25621
+ releaseAgentDispatch();
25622
+ releaseAgentDispatch = () => void 0;
25623
+ if (!durableCheckpointed && owned) {
25624
+ cleanupUnpublishedWorkspace = true;
25625
+ }
25626
+ throw mapDeepSeekFailure({
25627
+ error: error48,
25628
+ cancelled: input.signal?.aborted === true,
25629
+ deadline: input.signal?.aborted !== true && boundary.signal.aborted,
25630
+ dispatchOutcome: proxyDispatchOutcome(proxy)
25631
+ });
25632
+ } finally {
25633
+ removeAgentAbortListener();
25634
+ boundary.cleanup();
25635
+ await ctx.fiber.dispose().catch(() => void 0);
25636
+ await proxy.close();
25637
+ if (cleanupUnpublishedWorkspace && owned) {
25638
+ await owned.cleanup().catch(() => void 0);
25639
+ this.agentWorkspaces.delete(rootPath);
25640
+ }
25641
+ delete process.env[loopbackEnvName];
25642
+ }
25643
+ }
25644
+ async releaseThread(thread) {
25645
+ const cleanup = this.agentWorkspaces.get(thread.threadPath);
25646
+ if (cleanup) {
25647
+ await cleanup();
25648
+ this.agentWorkspaces.delete(thread.threadPath);
25649
+ return;
25650
+ }
25651
+ const resolved = await realpath4(thread.threadPath);
25652
+ const temporaryRoot = await realpath4(tmpdir4());
25653
+ if (dirname4(resolved) !== temporaryRoot || !basename(resolved).startsWith("vtx-deepseek-harness-")) throw new Error("deepseek_harness_thread_path_not_owned");
25654
+ await rm5(resolved, { recursive: true, force: true });
25655
+ }
25656
+ async close() {
25657
+ this.closing = true;
25658
+ }
25659
+ };
25660
+ }
25661
+ });
25662
+
25663
+ // lib/inference-host/deepseek-credential-store.ts
25664
+ import { createHash as createHash5 } from "node:crypto";
25665
+ var DEEPSEEK_CREDENTIAL_NAMESPACE, MAX_API_KEY_BYTES, validateApiKey, credentialIdentity, parseCredential, serializeCredential, platformCommands, createDeepSeekHarnessCredentialStore;
25666
+ var init_deepseek_credential_store = __esm({
25667
+ "lib/inference-host/deepseek-credential-store.ts"() {
25668
+ "use strict";
25669
+ init_config();
25670
+ init_credential_store();
25671
+ DEEPSEEK_CREDENTIAL_NAMESPACE = "vtxmacro-deepseek-harness";
25672
+ MAX_API_KEY_BYTES = 512;
25673
+ validateApiKey = (raw) => {
25674
+ const apiKey = raw.trim();
25675
+ if (apiKey.length < 16 || Buffer.byteLength(apiKey, "utf8") > MAX_API_KEY_BYTES || /[\s\u0000-\u001f\u007f]/u.test(apiKey)) {
25676
+ throw new Error("DeepSeek API key is invalid. Provide one private key through stdin.");
25677
+ }
25678
+ return apiKey;
25679
+ };
25680
+ credentialIdentity = (apiKey) => `deepseek-key-${createHash5("sha256").update(apiKey).digest("hex").slice(0, 24)}`;
25681
+ parseCredential = (raw) => {
25682
+ let value;
25683
+ try {
25684
+ value = JSON.parse(raw);
25685
+ } catch {
25686
+ throw new Error("Stored DeepSeek Harness credential is invalid JSON.");
25687
+ }
25688
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
25689
+ throw new Error("Stored DeepSeek Harness credential is invalid.");
25690
+ }
25691
+ const record2 = value;
25692
+ const apiKey = validateApiKey(String(record2.api_key ?? ""));
25693
+ const identity = credentialIdentity(apiKey);
25694
+ if (record2.schema_version !== 1 || record2.adapter !== "deepseek-harness" || record2.identity !== identity || Object.keys(record2).sort().join(",") !== "adapter,api_key,identity,schema_version") {
25695
+ throw new Error("Stored DeepSeek Harness credential failed validation.");
25696
+ }
25697
+ return { apiKey, identity };
25698
+ };
25699
+ serializeCredential = (apiKey) => {
25700
+ const validated = validateApiKey(apiKey);
25701
+ return `${JSON.stringify({
25702
+ schema_version: 1,
25703
+ adapter: "deepseek-harness",
25704
+ api_key: validated,
25705
+ identity: credentialIdentity(validated)
25706
+ })}
25707
+ `;
25708
+ };
25709
+ platformCommands = (env, platform) => {
25710
+ if (platform === "win32") return windowsInferenceCredentialCommands;
25711
+ if (platform === "linux" && String(env.WSL_INTEROP || "").trim()) {
25712
+ return windowsInferenceCredentialCommands;
25713
+ }
25714
+ if (platform === "linux") return linuxSecretServiceInferenceCredentialCommands;
25715
+ if (platform === "darwin") return macosKeychainInferenceCredentialCommands;
25716
+ return null;
25717
+ };
25718
+ createDeepSeekHarnessCredentialStore = (config2, dependencies = {}) => {
25719
+ const accountKey = `deepseek-harness:${config2.instanceName}`;
25720
+ const path = `${config2.statePath}.deepseek-harness-secret.json`;
25721
+ const env = dependencies.env ?? process.env;
25722
+ const platform = dependencies.platform ?? process.platform;
25723
+ const commands = dependencies.commands === void 0 ? platformCommands(env, platform) : dependencies.commands;
25724
+ const runner = dependencies.commandRunner ?? runCredentialCommand;
25725
+ if (config2.credentialStoreMode === "os") {
25726
+ if (!commands) {
25727
+ throw new Error("OS credential storage is unavailable for the DeepSeek API key.");
25728
+ }
25729
+ return {
25730
+ read: async (signal) => {
25731
+ const command = commands.lookup(DEEPSEEK_CREDENTIAL_NAMESPACE, accountKey);
25732
+ const result2 = await runner(command, { stdin: null, signal });
25733
+ if ((command.notFoundExitCodes ?? []).includes(result2.exitCode)) return null;
25734
+ if (result2.exitCode !== 0) throw new Error("DeepSeek OS credential lookup failed.");
25735
+ return parseCredential(result2.stdout);
25736
+ },
25737
+ write: async (apiKey, signal) => {
25738
+ const serialized = serializeCredential(apiKey);
25739
+ const priorLookup = commands.lookup(DEEPSEEK_CREDENTIAL_NAMESPACE, accountKey);
25740
+ const priorResult = await runner(priorLookup, { stdin: null, signal });
25741
+ const prior = (priorLookup.notFoundExitCodes ?? []).includes(priorResult.exitCode) ? null : priorResult.exitCode === 0 ? parseCredential(priorResult.stdout) : void 0;
25742
+ if (prior === void 0) throw new Error("DeepSeek OS credential lookup failed before write.");
25743
+ const command = commands.store(DEEPSEEK_CREDENTIAL_NAMESPACE, accountKey);
25744
+ if (command.args.some((value) => value.includes(validateApiKey(apiKey)))) {
25745
+ throw new Error("DeepSeek API key must never be passed in command arguments.");
25746
+ }
25747
+ try {
25748
+ const result2 = await runner(command, { stdin: serialized, signal });
25749
+ if (result2.exitCode !== 0) throw new Error("DeepSeek OS credential write failed.");
25750
+ const retainedCommand = commands.lookup(DEEPSEEK_CREDENTIAL_NAMESPACE, accountKey);
25751
+ const retained = await runner(retainedCommand, { stdin: null, signal });
25752
+ if (retained.exitCode !== 0) {
25753
+ throw new Error("DeepSeek OS credential write could not be verified.");
25754
+ }
25755
+ const expected = parseCredential(serialized);
25756
+ const observed = parseCredential(retained.stdout);
25757
+ if (observed.identity !== expected.identity || observed.apiKey !== expected.apiKey) {
25758
+ throw new Error("DeepSeek OS credential write could not be verified.");
25759
+ }
25760
+ return observed;
25761
+ } catch (error48) {
25762
+ const rollback = prior ? commands.store(DEEPSEEK_CREDENTIAL_NAMESPACE, accountKey) : commands.remove(DEEPSEEK_CREDENTIAL_NAMESPACE, accountKey);
25763
+ const rollbackResult = await runner(rollback, {
25764
+ stdin: prior ? serializeCredential(prior.apiKey) : null
25765
+ });
25766
+ if (rollbackResult.exitCode !== 0 && !(rollback.notFoundExitCodes ?? []).includes(rollbackResult.exitCode)) {
25767
+ throw new Error("DeepSeek OS credential write failed and rollback failed.", {
25768
+ cause: error48
25769
+ });
25770
+ }
25771
+ const verifyCommand = commands.lookup(DEEPSEEK_CREDENTIAL_NAMESPACE, accountKey);
25772
+ const verified = await runner(verifyCommand, { stdin: null });
25773
+ const absent = (verifyCommand.notFoundExitCodes ?? []).includes(verified.exitCode);
25774
+ const restored = prior && verified.exitCode === 0 ? parseCredential(verified.stdout) : null;
25775
+ if (prior === null && !absent || prior !== null && (!restored || restored.identity !== prior.identity || restored.apiKey !== prior.apiKey)) {
25776
+ throw new Error("DeepSeek OS credential write failed and rollback could not be verified.", {
25777
+ cause: error48
25778
+ });
25779
+ }
25780
+ throw error48;
25781
+ }
25782
+ },
25783
+ remove: async (signal) => {
25784
+ const command = commands.remove(DEEPSEEK_CREDENTIAL_NAMESPACE, accountKey);
25785
+ const result2 = await runner(command, { stdin: null, signal });
25786
+ if (result2.exitCode !== 0 && !(command.notFoundExitCodes ?? []).includes(result2.exitCode)) throw new Error("DeepSeek OS credential removal failed.");
25787
+ const retainedCommand = commands.lookup(DEEPSEEK_CREDENTIAL_NAMESPACE, accountKey);
25788
+ const retained = await runner(retainedCommand, { stdin: null });
25789
+ if (!(retainedCommand.notFoundExitCodes ?? []).includes(retained.exitCode)) {
25790
+ throw new Error("DeepSeek OS credential removal could not be verified.");
25791
+ }
25792
+ }
25793
+ };
25794
+ }
25795
+ return {
25796
+ read: async () => {
25797
+ const raw = await readInferencePrivateFile(path, "DeepSeek Harness credential file");
25798
+ return raw === null ? null : parseCredential(raw);
25799
+ },
25800
+ write: async (apiKey) => {
25801
+ const serialized = serializeCredential(apiKey);
25802
+ await writeAtomicInferencePrivateFile(path, serialized);
25803
+ const retained = await readInferencePrivateFile(path, "DeepSeek Harness credential file");
25804
+ if (retained !== serialized) throw new Error("DeepSeek credential write could not be verified.");
25805
+ return parseCredential(serialized);
25806
+ },
25807
+ remove: async () => {
25808
+ await clearInferencePrivateFile(path, "DeepSeek Harness credential file");
25809
+ }
25810
+ };
24340
25811
  };
24341
25812
  }
24342
25813
  });
@@ -24348,12 +25819,14 @@ var init_durable_adapter = __esm({
24348
25819
  "use strict";
24349
25820
  DURABLE_INFERENCE_ADAPTER_IDS = [
24350
25821
  "codex",
24351
- "copilot"
25822
+ "copilot",
25823
+ "deepseek-harness"
24352
25824
  ];
24353
25825
  isDurableInferenceAdapterId = (value) => DURABLE_INFERENCE_ADAPTER_IDS.includes(value);
24354
25826
  durableAdapterDisplayName = (adapter) => ({
24355
25827
  codex: "Codex",
24356
- copilot: "GitHub Copilot"
25828
+ copilot: "GitHub Copilot",
25829
+ "deepseek-harness": "DeepSeek Harness"
24357
25830
  })[adapter];
24358
25831
  }
24359
25832
  });
@@ -24362,13 +25835,13 @@ var init_durable_adapter = __esm({
24362
25835
  import {
24363
25836
  createCipheriv,
24364
25837
  createDecipheriv,
24365
- createHash as createHash5,
25838
+ createHash as createHash6,
24366
25839
  createPrivateKey,
24367
25840
  createPublicKey,
24368
25841
  diffieHellman,
24369
25842
  generateKeyPairSync,
24370
25843
  hkdfSync,
24371
- randomBytes as randomBytes4
25844
+ randomBytes as randomBytes5
24372
25845
  } from "node:crypto";
24373
25846
  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;
24374
25847
  var init_crypto = __esm({
@@ -24401,7 +25874,7 @@ var init_crypto = __esm({
24401
25874
  const aad = envelopeAadSchema.parse(input);
24402
25875
  return Buffer.from(JSON.stringify(canonicalize(aad)), "utf8");
24403
25876
  };
24404
- externalInferenceSha256 = (value) => createHash5("sha256").update(value).digest("hex");
25877
+ externalInferenceSha256 = (value) => createHash6("sha256").update(value).digest("hex");
24405
25878
  decodeCanonicalBase64Url = (value, fieldName, expectedBytes) => {
24406
25879
  if (!/^[A-Za-z0-9_-]+$/u.test(value)) {
24407
25880
  throw new ExternalInferenceEnvelopeError("invalid_encoding", `${fieldName} is invalid.`);
@@ -24500,7 +25973,7 @@ var init_crypto = __esm({
24500
25973
  return Buffer.from(hkdfSync(
24501
25974
  "sha256",
24502
25975
  root,
24503
- createHash5("sha256").update(aadBytes).digest(),
25976
+ createHash6("sha256").update(aadBytes).digest(),
24504
25977
  info,
24505
25978
  32
24506
25979
  ));
@@ -24642,7 +26115,7 @@ var init_crypto = __esm({
24642
26115
  "External inference candidate must not be empty."
24643
26116
  );
24644
26117
  }
24645
- const nonce = options.nonce ? Buffer.from(options.nonce) : randomBytes4(12);
26118
+ const nonce = options.nonce ? Buffer.from(options.nonce) : randomBytes5(12);
24646
26119
  if (nonce.length !== 12) {
24647
26120
  throw new ExternalInferenceEnvelopeError(
24648
26121
  "invalid_nonce",
@@ -30914,7 +32387,7 @@ var require_ajv = __commonJS({
30914
32387
  });
30915
32388
 
30916
32389
  // lib/inference-host/runner.ts
30917
- import { createHash as createHash6, randomUUID } from "node:crypto";
32390
+ import { createHash as createHash7, randomUUID as randomUUID3 } from "node:crypto";
30918
32391
  function createDefaultInferenceHostRunnerDependencies(options) {
30919
32392
  const fetchImpl = options.fetchImpl ?? fetch;
30920
32393
  return {
@@ -30949,7 +32422,7 @@ function createDefaultInferenceHostRunnerDependencies(options) {
30949
32422
  envelopePublicKey: options.envelopePublicKey
30950
32423
  };
30951
32424
  }
30952
- 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, createCodexAgentControlClient, CODEX_AGENT_SYSTEM_PROMPT, CODEX_AGENT_WAKE_SCHEMA, parseCodexAgentWake, CodexAgentRuntime;
32425
+ 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;
30953
32426
  var init_runner = __esm({
30954
32427
  "lib/inference-host/runner.ts"() {
30955
32428
  "use strict";
@@ -30975,6 +32448,9 @@ var init_runner = __esm({
30975
32448
  MIN_HOST_HEARTBEAT_GAP_DIAGNOSTIC_MS = 1e4;
30976
32449
  HOST_HEARTBEAT_GAP_DIAGNOSTIC_FACTOR = 3;
30977
32450
  DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS = 5 * 60 * 1e3;
32451
+ DEFAULT_AGENT_RATE_LIMIT_COOLDOWN_MS = 6e4;
32452
+ DEFAULT_AGENT_QUOTA_COOLDOWN_MS = 5 * 60 * 1e3;
32453
+ DEFAULT_AGENT_TRANSIENT_COOLDOWN_MS = 5e3;
30978
32454
  MIN_CLAIM_START_WINDOW_MS = 5e3;
30979
32455
  MAX_ATTEMPT_START_RETRY_DELAY_MS = 15e3;
30980
32456
  UNBOUNDED_AVAILABLE_SLOTS = Number.MAX_SAFE_INTEGER;
@@ -31241,7 +32717,7 @@ var init_runner = __esm({
31241
32717
  attempts
31242
32718
  };
31243
32719
  };
31244
- sha256 = (value) => createHash6("sha256").update(value, "utf8").digest("hex");
32720
+ sha256 = (value) => createHash7("sha256").update(value, "utf8").digest("hex");
31245
32721
  stableOperationId = (kind, parts) => `${kind}_${sha256(JSON.stringify(parts)).slice(0, 48)}`;
31246
32722
  buildAttemptStartRequest = (claim, attemptId, startedAt) => attemptStartRequestSchema.parse({
31247
32723
  schema_version: "external_inference_attempt_start_v1",
@@ -31333,7 +32809,7 @@ var init_runner = __esm({
31333
32809
  adapterId,
31334
32810
  options.structuredOutput ?? adapterId === "codex",
31335
32811
  options.sameAttemptRecovery ?? adapterId === "codex",
31336
- options.agentRuntime && adapterId === "codex" ? ["provider", "agent"] : ["provider"]
32812
+ options.agentRuntime ? ["provider", "agent"] : ["provider"]
31337
32813
  ),
31338
32814
  maxConcurrency: options.maxConcurrency === null || options.maxConcurrency === void 0 ? null : finitePositiveOption(options.maxConcurrency, 1, "Maximum concurrency"),
31339
32815
  advertisementTtlMs,
@@ -31514,7 +32990,7 @@ var init_runner = __esm({
31514
32990
  membershipFailureDisposition = (failure) => {
31515
32991
  if (failure.dispatchOutcome === "outcome_unknown") return "quarantine_ambiguous";
31516
32992
  if (failure.category === "auth" || ["auth_expired", "managed_chatgpt_auth_required", "invalid_account_metadata"].includes(failure.code)) return "cascade_disable";
31517
- if (failure.category === "quota" || ["quota_exceeded", "codex_rate_limited"].includes(failure.code)) return "cascade_cooldown";
32993
+ if (failure.category === "quota" || ["quota_exceeded", "codex_rate_limited", "provider_rate_limited"].includes(failure.code)) return "cascade_cooldown";
31518
32994
  if (failure.retryable && (["adapter", "network", "transport"].includes(failure.category) || failure.code === "rpc_timeout")) return "retry_same_host";
31519
32995
  if (["model_unavailable", "reasoning_effort_unavailable"].includes(failure.code)) return "cascade_cooldown";
31520
32996
  if ([
@@ -31788,10 +33264,48 @@ var init_runner = __esm({
31788
33264
  const agentRuntimeSettings = settings.agentRuntime;
31789
33265
  agentLoop = (async () => {
31790
33266
  while (!agentAbort.signal.aborted) {
31791
- const agentRuntime = new CodexAgentRuntime({
33267
+ const existingFence = await readInferenceAgentFailureFence(
33268
+ agentRuntimeSettings.statePath
33269
+ );
33270
+ if (existingFence) {
33271
+ if (existingFence.adapter_id !== settings.adapterId || existingFence.host_id !== localState.host_id) {
33272
+ throw new InferenceHostRecoveryRequiredError(
33273
+ "Inference Agent failure fence belongs to another host or adapter."
33274
+ );
33275
+ }
33276
+ if (existingFence.retry_at === null) {
33277
+ emitDiagnostic("agent_runtime_quarantined", {
33278
+ assignment_id: existingFence.assignment_id,
33279
+ failure_category: existingFence.failure_category,
33280
+ failure_code: existingFence.failure_code,
33281
+ dispatch_outcome: existingFence.dispatch_outcome
33282
+ });
33283
+ return;
33284
+ }
33285
+ const retryAtMs = Date.parse(existingFence.retry_at);
33286
+ if (retryAtMs > now()) {
33287
+ emitDiagnostic("agent_runtime_cooldown", {
33288
+ assignment_id: existingFence.assignment_id,
33289
+ failure_category: existingFence.failure_category,
33290
+ failure_code: existingFence.failure_code,
33291
+ dispatch_outcome: existingFence.dispatch_outcome,
33292
+ cooldown_until: existingFence.retry_at
33293
+ });
33294
+ if (this.options.once) return;
33295
+ try {
33296
+ await sleep4(Math.max(MIN_SLEEP_MS, retryAtMs - now()), agentAbort.signal);
33297
+ } catch {
33298
+ return;
33299
+ }
33300
+ continue;
33301
+ }
33302
+ await clearInferenceAgentFailureFence(agentRuntimeSettings.statePath);
33303
+ }
33304
+ const agentRuntime = new InferenceAgentRuntime({
33305
+ adapterId: settings.adapterId,
31792
33306
  hostId: localState.host_id,
31793
33307
  statePath: agentRuntimeSettings.statePath,
31794
- controlClient: createCodexAgentControlClient(mcp),
33308
+ controlClient: createInferenceAgentControlClient(mcp),
31795
33309
  adapter: agentRuntimeSettings.adapter
31796
33310
  });
31797
33311
  try {
@@ -31807,6 +33321,51 @@ var init_runner = __esm({
31807
33321
  requestDrain("authority_lost");
31808
33322
  return;
31809
33323
  }
33324
+ if (error48 instanceof CodexAppServerError) {
33325
+ const failure = classifyFailure(error48);
33326
+ const providerLimited = failure.category === "auth" || failure.category === "quota" || ["quota_exceeded", "codex_rate_limited", "provider_rate_limited"].includes(failure.code);
33327
+ const deepSeekTransient = settings.adapterId === "deepseek-harness" && failure.retryable;
33328
+ if (failure.dispatchOutcome === "outcome_unknown" || providerLimited || deepSeekTransient) {
33329
+ const runtimeState = await readInferenceAgentRuntimeState(
33330
+ agentRuntimeSettings.statePath
33331
+ );
33332
+ 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);
33333
+ await writeInferenceAgentFailureFence(agentRuntimeSettings.statePath, {
33334
+ schema_version: "vtx_inference_agent_failure_fence_v1",
33335
+ adapter_id: settings.adapterId,
33336
+ host_id: localState.host_id,
33337
+ assignment_id: runtimeState?.schema_version === "vtx_inference_agent_runtime_v3" ? runtimeState.assignment.assignment_id : null,
33338
+ failure_category: safeFailureCode(failure.category, "adapter"),
33339
+ failure_code: safeFailureCode(failure.code, "adapter_failure"),
33340
+ dispatch_outcome: failure.dispatchOutcome,
33341
+ retry_at: retryAtMs === null ? null : isoAt(retryAtMs),
33342
+ created_at: isoAt(now())
33343
+ });
33344
+ if (failure.dispatchOutcome !== "outcome_unknown") {
33345
+ try {
33346
+ await agentRuntime.releaseAfterProviderFailure(failure.code);
33347
+ } catch {
33348
+ }
33349
+ }
33350
+ emitDiagnostic(
33351
+ retryAtMs === null ? "agent_runtime_quarantined" : "agent_runtime_cooldown",
33352
+ {
33353
+ assignment_id: runtimeState?.schema_version === "vtx_inference_agent_runtime_v3" ? runtimeState.assignment.assignment_id : null,
33354
+ failure_category: failure.category,
33355
+ failure_code: failure.code,
33356
+ dispatch_outcome: failure.dispatchOutcome,
33357
+ cooldown_until: retryAtMs === null ? null : isoAt(retryAtMs)
33358
+ }
33359
+ );
33360
+ if (this.options.once || retryAtMs === null) return;
33361
+ try {
33362
+ await sleep4(Math.max(MIN_SLEEP_MS, retryAtMs - now()), agentAbort.signal);
33363
+ } catch {
33364
+ return;
33365
+ }
33366
+ continue;
33367
+ }
33368
+ }
31810
33369
  emitDiagnostic("agent_runtime_retry", {
31811
33370
  error_code: error48 && typeof error48 === "object" && "code" in error48 ? String(error48.code) : "agent_runtime_error"
31812
33371
  });
@@ -31819,7 +33378,13 @@ var init_runner = __esm({
31819
33378
  }
31820
33379
  }
31821
33380
  })();
31822
- void agentLoop.catch(() => void 0);
33381
+ void agentLoop.catch((error48) => {
33382
+ if (agentAbort.signal.aborted) return;
33383
+ emitDiagnostic("agent_runtime_fence_failed", {
33384
+ error_code: error48 && typeof error48 === "object" && "code" in error48 ? String(error48.code) : "agent_runtime_fence_failed"
33385
+ });
33386
+ requestDrain("agent_recovery_failed");
33387
+ });
31823
33388
  }
31824
33389
  const existingReceipt = await this.dependencies.receiptStore.read();
31825
33390
  const identityMatches = existingReceipt && existingReceipt.host_id === localState.host_id && existingReceipt.host_generation === localState.host_generation && existingReceipt.key_generation === localState.key_generation;
@@ -32997,10 +34562,10 @@ var init_runner = __esm({
32997
34562
  if (error48 instanceof InferenceHostRunnerError && error48.code === "terminal_outcome_unconfirmed") {
32998
34563
  throw error48;
32999
34564
  }
33000
- if (error48 instanceof CodexAppServerError && error48.retryAtMs !== null && ["quota_exceeded", "codex_rate_limited"].includes(error48.code)) {
34565
+ if (error48 instanceof CodexAppServerError && error48.retryAtMs !== null && ["quota_exceeded", "codex_rate_limited", "provider_rate_limited"].includes(error48.code)) {
33001
34566
  options.onProviderCooldown?.({
33002
34567
  retryAtMs: error48.retryAtMs,
33003
- reason: error48.code === "quota_exceeded" ? "quota_exceeded" : "codex_rate_limited",
34568
+ reason: error48.code === "quota_exceeded" ? "quota_exceeded" : error48.code === "provider_rate_limited" ? "provider_rate_limited" : "codex_rate_limited",
33004
34569
  rateLimits: error48.rateLimits
33005
34570
  });
33006
34571
  }
@@ -33129,7 +34694,7 @@ var init_runner = __esm({
33129
34694
  }
33130
34695
  }
33131
34696
  };
33132
- createCodexAgentControlClient = (mcp) => ({
34697
+ createInferenceAgentControlClient = (mcp) => ({
33133
34698
  nextAssignment: async (request, options) => {
33134
34699
  const result2 = await mcp.callTool("inference.agent.assignment.next", {
33135
34700
  ...request,
@@ -33172,9 +34737,9 @@ var init_runner = __esm({
33172
34737
  await mcp.callTool("inference.agent.assignment.release", request, options);
33173
34738
  }
33174
34739
  });
33175
- CODEX_AGENT_SYSTEM_PROMPT = `You autonomously control one running VTX bot.
34740
+ INFERENCE_AGENT_SYSTEM_PROMPT = `You autonomously control one running VTX bot.
33176
34741
  VTX supplies no trading prompt or prepared market context. At your own cadence, request zero, some, or all assignment-scoped data with vtx_get_data and independently use web search when useful. Submit trading instructions only through vtx_submit_decision, using the assignment's exact decision schema. VTX remains responsible for validating and executing the same structured decision used by normal Server and Client modes. You have no shell, filesystem-write, app, plugin, browser-control, or subagent authority.`;
33177
- CODEX_AGENT_WAKE_SCHEMA = {
34742
+ INFERENCE_AGENT_WAKE_SCHEMA = {
33178
34743
  type: "object",
33179
34744
  additionalProperties: false,
33180
34745
  required: ["next_wake_seconds", "summary"],
@@ -33183,29 +34748,29 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33183
34748
  summary: { type: "string", minLength: 1, maxLength: 2e3 }
33184
34749
  }
33185
34750
  };
33186
- parseCodexAgentWake = (text, assignment) => {
34751
+ parseInferenceAgentWake = (text, assignment) => {
33187
34752
  let value;
33188
34753
  try {
33189
34754
  value = JSON.parse(text);
33190
34755
  } catch {
33191
34756
  throw new InferenceHostRunnerError(
33192
34757
  "invalid_agent_wake",
33193
- "Codex Agent returned invalid wake JSON."
34758
+ "Inference Agent returned invalid wake JSON."
33194
34759
  );
33195
34760
  }
33196
34761
  if (!value || typeof value !== "object" || Array.isArray(value)) {
33197
- throw new InferenceHostRunnerError("invalid_agent_wake", "Codex Agent wake is invalid.");
34762
+ throw new InferenceHostRunnerError("invalid_agent_wake", "Inference Agent wake is invalid.");
33198
34763
  }
33199
34764
  const seconds = value.next_wake_seconds;
33200
34765
  if (!Number.isSafeInteger(seconds) || Number(seconds) < 1) {
33201
- throw new InferenceHostRunnerError("invalid_agent_wake", "Codex Agent wake is invalid.");
34766
+ throw new InferenceHostRunnerError("invalid_agent_wake", "Inference Agent wake is invalid.");
33202
34767
  }
33203
34768
  return Math.max(
33204
34769
  assignment.minimum_wake_seconds,
33205
34770
  Math.min(assignment.maximum_wake_seconds, Number(seconds))
33206
34771
  );
33207
34772
  };
33208
- CodexAgentRuntime = class {
34773
+ InferenceAgentRuntime = class {
33209
34774
  constructor(options) {
33210
34775
  this.options = options;
33211
34776
  this.stopped = false;
@@ -33215,6 +34780,9 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33215
34780
  stop() {
33216
34781
  this.stopped = true;
33217
34782
  }
34783
+ async releaseAfterProviderFailure(reasonCode) {
34784
+ await this.releaseForHostStop(safeFailureCode(reasonCode, "provider_failure"));
34785
+ }
33218
34786
  async run(signal) {
33219
34787
  let exitedNormally = false;
33220
34788
  try {
@@ -33231,37 +34799,67 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33231
34799
  }
33232
34800
  }
33233
34801
  async runSingle(signal) {
34802
+ let exitedNormally = false;
33234
34803
  try {
33235
34804
  await this.runOnce(signal);
34805
+ exitedNormally = true;
33236
34806
  } finally {
33237
- await this.releaseForHostStop();
34807
+ if (exitedNormally || this.stopped || signal?.aborted) {
34808
+ await this.releaseForHostStop();
34809
+ }
33238
34810
  }
33239
34811
  }
33240
34812
  async runOnce(signal) {
33241
34813
  const nowIso = () => new Date(this.now()).toISOString();
33242
- const recoveredState = await readCodexAgentRuntimeState(this.options.statePath);
34814
+ const recoveredState = await readInferenceAgentRuntimeState(this.options.statePath);
33243
34815
  if (recoveredState && recoveredState.host_id !== this.options.hostId) {
33244
34816
  throw new InferenceHostRunnerError(
33245
34817
  "agent_recovery_scope_mismatch",
33246
- "Codex Agent recovery state belongs to another host."
34818
+ "Inference Agent recovery state belongs to another host."
33247
34819
  );
33248
34820
  }
33249
34821
  let state;
33250
34822
  if (recoveredState?.schema_version === "vtx_codex_agent_runtime_v1") {
34823
+ if (this.options.adapterId !== "codex") {
34824
+ throw new InferenceHostRunnerError(
34825
+ "agent_recovery_adapter_mismatch",
34826
+ "Legacy Codex Agent recovery state cannot be opened by another adapter."
34827
+ );
34828
+ }
33251
34829
  state = await this.upgradeLegacyRuntimeState(recoveredState, signal);
33252
34830
  if (!state) return this.now() + (this.options.idlePollMs ?? 5e3);
34831
+ } else if (recoveredState?.schema_version === "vtx_codex_agent_runtime_v2") {
34832
+ if (this.options.adapterId !== "codex") {
34833
+ throw new InferenceHostRunnerError(
34834
+ "agent_recovery_adapter_mismatch",
34835
+ "Legacy Codex Agent recovery state cannot be opened by another adapter."
34836
+ );
34837
+ }
34838
+ state = {
34839
+ ...recoveredState,
34840
+ schema_version: "vtx_inference_agent_runtime_v3",
34841
+ adapter_id: "codex"
34842
+ };
34843
+ await writeInferenceAgentRuntimeState(this.options.statePath, state);
33253
34844
  } else {
33254
34845
  state = recoveredState ?? null;
34846
+ if (state && state.adapter_id !== this.options.adapterId) {
34847
+ throw new InferenceHostRunnerError(
34848
+ "agent_recovery_adapter_mismatch",
34849
+ "Inference Agent recovery state belongs to another adapter."
34850
+ );
34851
+ }
33255
34852
  }
33256
34853
  if (!state) {
33257
34854
  const assignment2 = await this.options.controlClient.nextAssignment({
33258
- operation_id: randomUUID(),
34855
+ operation_id: randomUUID3(),
33259
34856
  host_id: this.options.hostId,
33260
34857
  requested_at: nowIso()
33261
34858
  }, { signal });
33262
34859
  if (!assignment2) return this.now() + (this.options.idlePollMs ?? 5e3);
33263
34860
  state = {
33264
- schema_version: "vtx_codex_agent_runtime_v2",
34861
+ schema_version: "vtx_inference_agent_runtime_v3",
34862
+ adapter_id: this.options.adapterId,
33265
34863
  host_id: this.options.hostId,
33266
34864
  assignment: assignment2,
33267
34865
  thread: null,
@@ -33269,7 +34867,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33269
34867
  pending_decision: null,
33270
34868
  updated_at: nowIso()
33271
34869
  };
33272
- await writeCodexAgentRuntimeState(this.options.statePath, state);
34870
+ await writeInferenceAgentRuntimeState(this.options.statePath, state);
33273
34871
  } else {
33274
34872
  const persistedWakeAtMs = Date.parse(state.next_wake_at);
33275
34873
  if (persistedWakeAtMs > this.now()) {
@@ -33277,8 +34875,8 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33277
34875
  if (wakeOutcome !== "ready") {
33278
34876
  return this.now() + (this.options.idlePollMs ?? 5e3);
33279
34877
  }
33280
- const rereadState = await readCodexAgentRuntimeState(this.options.statePath);
33281
- if (rereadState?.schema_version !== "vtx_codex_agent_runtime_v2") {
34878
+ const rereadState = await readInferenceAgentRuntimeState(this.options.statePath);
34879
+ if (rereadState?.schema_version !== "vtx_inference_agent_runtime_v3" || rereadState.adapter_id !== this.options.adapterId) {
33282
34880
  return this.now() + (this.options.idlePollMs ?? 5e3);
33283
34881
  }
33284
34882
  state = rereadState;
@@ -33287,7 +34885,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33287
34885
  state = await this.resolvePendingDecision(state, signal);
33288
34886
  let assignment = state.assignment;
33289
34887
  const preTurnHeartbeat = await this.options.controlClient.heartbeat({
33290
- operation_id: randomUUID(),
34888
+ operation_id: randomUUID3(),
33291
34889
  host_id: this.options.hostId,
33292
34890
  assignment_id: assignment.assignment_id,
33293
34891
  assignment_generation: assignment.assignment_generation,
@@ -33302,7 +34900,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33302
34900
  lease_expires_at: preTurnHeartbeat.lease_expires_at
33303
34901
  };
33304
34902
  state = { ...state, assignment, updated_at: nowIso() };
33305
- await writeCodexAgentRuntimeState(this.options.statePath, state);
34903
+ await writeInferenceAgentRuntimeState(this.options.statePath, state);
33306
34904
  const turnAbort = new AbortController();
33307
34905
  const relayAbort = () => turnAbort.abort();
33308
34906
  signal?.addEventListener("abort", relayAbort, { once: true });
@@ -33312,7 +34910,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33312
34910
  const heartbeatTask = (async () => {
33313
34911
  while (!heartbeatStopped && !turnAbort.signal.aborted) {
33314
34912
  const heartbeat = await this.options.controlClient.heartbeat({
33315
- operation_id: randomUUID(),
34913
+ operation_id: randomUUID3(),
33316
34914
  host_id: this.options.hostId,
33317
34915
  assignment_id: assignment.assignment_id,
33318
34916
  assignment_generation: assignment.assignment_generation,
@@ -33336,7 +34934,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33336
34934
  const deadlineAtMs = this.now() + (this.options.turnTimeoutMs ?? 10 * 6e4);
33337
34935
  const result2 = await this.options.adapter.runTurn({
33338
34936
  durableThread: state.thread,
33339
- systemPrompt: CODEX_AGENT_SYSTEM_PROMPT,
34937
+ systemPrompt: INFERENCE_AGENT_SYSTEM_PROMPT,
33340
34938
  userPrompt: JSON.stringify({
33341
34939
  assignment_id: assignment.assignment_id,
33342
34940
  assignment_generation: assignment.assignment_generation,
@@ -33350,7 +34948,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33350
34948
  maximum: assignment.maximum_wake_seconds
33351
34949
  }
33352
34950
  }),
33353
- outputSchema: CODEX_AGENT_WAKE_SCHEMA,
34951
+ outputSchema: INFERENCE_AGENT_WAKE_SCHEMA,
33354
34952
  dataContract: assignment.data_contract,
33355
34953
  decisionSchema: assignment.output_schema,
33356
34954
  requestedModel: assignment.model_id,
@@ -33359,7 +34957,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33359
34957
  signal: turnAbort.signal,
33360
34958
  onThreadReady: async (thread) => {
33361
34959
  state = { ...state, thread, updated_at: nowIso() };
33362
- await writeCodexAgentRuntimeState(this.options.statePath, state);
34960
+ await writeInferenceAgentRuntimeState(this.options.statePath, state);
33363
34961
  },
33364
34962
  executeTool: async (call) => {
33365
34963
  if (call.tool === "vtx_get_data") {
@@ -33369,7 +34967,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33369
34967
  return { success: false, value: { error: "invalid_data_request" } };
33370
34968
  }
33371
34969
  const value = await this.options.controlClient.dataCall({
33372
- operation_id: randomUUID(),
34970
+ operation_id: randomUUID3(),
33373
34971
  host_id: this.options.hostId,
33374
34972
  assignment_id: assignment.assignment_id,
33375
34973
  assignment_generation: assignment.assignment_generation,
@@ -33393,12 +34991,12 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33393
34991
  return { success: false, value: { error: "decision_outcome_unresolved" } };
33394
34992
  }
33395
34993
  const pending = {
33396
- operation_id: randomUUID(),
34994
+ operation_id: randomUUID3(),
33397
34995
  candidate,
33398
34996
  observed_at: nowIso(),
33399
34997
  provenance: {
33400
- source: "codex_agent",
33401
- codex_thread_id: liveThread.threadId,
34998
+ source: "external_agent",
34999
+ agent_run_id: liveThread.threadId,
33402
35000
  requested_model: assignment.model_id,
33403
35001
  effective_model: liveThread.effectiveModel,
33404
35002
  requested_reasoning_effort: assignment.reasoning_effort,
@@ -33408,13 +35006,13 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33408
35006
  last_status_check_at: null
33409
35007
  };
33410
35008
  state = { ...state, pending_decision: pending, updated_at: nowIso() };
33411
- await writeCodexAgentRuntimeState(this.options.statePath, state);
35009
+ await writeInferenceAgentRuntimeState(this.options.statePath, state);
33412
35010
  state = {
33413
35011
  ...state,
33414
35012
  pending_decision: { ...pending, first_transmit_at: nowIso() },
33415
35013
  updated_at: nowIso()
33416
35014
  };
33417
- await writeCodexAgentRuntimeState(this.options.statePath, state);
35015
+ await writeInferenceAgentRuntimeState(this.options.statePath, state);
33418
35016
  let submitStatus;
33419
35017
  try {
33420
35018
  submitStatus = await this.options.controlClient.submitDecision({
@@ -33431,7 +35029,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33431
35029
  }
33432
35030
  if (submitStatus.status === "applied" || submitStatus.status === "not_applied") {
33433
35031
  state = { ...state, pending_decision: null, updated_at: nowIso() };
33434
- await writeCodexAgentRuntimeState(this.options.statePath, state);
35032
+ await writeInferenceAgentRuntimeState(this.options.statePath, state);
33435
35033
  }
33436
35034
  return {
33437
35035
  success: submitStatus.status === "applied",
@@ -33455,7 +35053,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33455
35053
  pending_decision: null,
33456
35054
  updated_at: nowIso()
33457
35055
  };
33458
- await writeCodexAgentRuntimeState(this.options.statePath, state);
35056
+ await writeInferenceAgentRuntimeState(this.options.statePath, state);
33459
35057
  }
33460
35058
  return {
33461
35059
  success: status.status === "applied" || status.status === "not_applied",
@@ -33463,11 +35061,11 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33463
35061
  };
33464
35062
  }
33465
35063
  });
33466
- const wakeSeconds = parseCodexAgentWake(result2.turn.text, assignment);
35064
+ const wakeSeconds = parseInferenceAgentWake(result2.turn.text, assignment);
33467
35065
  const nextWakeAtMs = this.now() + wakeSeconds * 1e3;
33468
35066
  const scheduledWakeAt = new Date(nextWakeAtMs).toISOString();
33469
35067
  const wakeHeartbeat = await this.options.controlClient.heartbeat({
33470
- operation_id: randomUUID(),
35068
+ operation_id: randomUUID3(),
33471
35069
  host_id: this.options.hostId,
33472
35070
  assignment_id: assignment.assignment_id,
33473
35071
  assignment_generation: assignment.assignment_generation,
@@ -33477,7 +35075,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33477
35075
  if (wakeHeartbeat.directive === "cancel") {
33478
35076
  if (state.pending_decision) return this.now() + (this.options.idlePollMs ?? 5e3);
33479
35077
  await this.options.adapter.releaseThread(result2.thread).catch(() => void 0);
33480
- await clearCodexAgentRuntimeState(this.options.statePath);
35078
+ await clearInferenceAgentRuntimeState(this.options.statePath);
33481
35079
  return this.now() + (this.options.idlePollMs ?? 5e3);
33482
35080
  }
33483
35081
  latestLeaseExpiry = wakeHeartbeat.lease_expires_at;
@@ -33488,7 +35086,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33488
35086
  next_wake_at: scheduledWakeAt,
33489
35087
  updated_at: nowIso()
33490
35088
  };
33491
- await writeCodexAgentRuntimeState(this.options.statePath, state);
35089
+ await writeInferenceAgentRuntimeState(this.options.statePath, state);
33492
35090
  return nextWakeAtMs;
33493
35091
  } catch (error48) {
33494
35092
  if (!cancelled) throw error48;
@@ -33507,7 +35105,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33507
35105
  if (state.thread) {
33508
35106
  await this.options.adapter.releaseThread(state.thread).catch(() => void 0);
33509
35107
  }
33510
- await clearCodexAgentRuntimeState(this.options.statePath);
35108
+ await clearInferenceAgentRuntimeState(this.options.statePath);
33511
35109
  return null;
33512
35110
  }
33513
35111
  async resolveLegacyPendingDecision(state, signal) {
@@ -33519,7 +35117,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33519
35117
  pending_decision: { ...pending, last_status_check_at: checkedAt },
33520
35118
  updated_at: checkedAt
33521
35119
  };
33522
- await writeCodexAgentRuntimeState(this.options.statePath, checking);
35120
+ await writeInferenceAgentRuntimeState(this.options.statePath, checking);
33523
35121
  const status = await this.options.controlClient.decisionStatus({
33524
35122
  host_id: this.options.hostId,
33525
35123
  assignment_id: state.assignment.assignment_id,
@@ -33532,7 +35130,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33532
35130
  pending_decision: null,
33533
35131
  updated_at: new Date(this.now()).toISOString()
33534
35132
  };
33535
- await writeCodexAgentRuntimeState(this.options.statePath, resolved);
35133
+ await writeInferenceAgentRuntimeState(this.options.statePath, resolved);
33536
35134
  return resolved;
33537
35135
  }
33538
35136
  async resolvePendingDecision(state, signal) {
@@ -33544,7 +35142,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33544
35142
  pending_decision: { ...pending, last_status_check_at: checkedAt },
33545
35143
  updated_at: checkedAt
33546
35144
  };
33547
- await writeCodexAgentRuntimeState(this.options.statePath, checking);
35145
+ await writeInferenceAgentRuntimeState(this.options.statePath, checking);
33548
35146
  const status = await this.options.controlClient.decisionStatus({
33549
35147
  host_id: this.options.hostId,
33550
35148
  assignment_id: state.assignment.assignment_id,
@@ -33557,7 +35155,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33557
35155
  pending_decision: null,
33558
35156
  updated_at: new Date(this.now()).toISOString()
33559
35157
  };
33560
- await writeCodexAgentRuntimeState(this.options.statePath, resolved);
35158
+ await writeInferenceAgentRuntimeState(this.options.statePath, resolved);
33561
35159
  return resolved;
33562
35160
  }
33563
35161
  async handleCancelledAssignment(state, signal) {
@@ -33573,7 +35171,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33573
35171
  if (current.thread) {
33574
35172
  await this.options.adapter.releaseThread(current.thread).catch(() => void 0);
33575
35173
  }
33576
- await clearCodexAgentRuntimeState(this.options.statePath);
35174
+ await clearInferenceAgentRuntimeState(this.options.statePath);
33577
35175
  }
33578
35176
  async waitUntilWake(nextWakeAtMs, signal) {
33579
35177
  const heartbeatIntervalMs = this.options.heartbeatIntervalMs ?? 3e3;
@@ -33581,11 +35179,11 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33581
35179
  await this.sleep(Math.min(heartbeatIntervalMs, nextWakeAtMs - this.now()), signal);
33582
35180
  if (this.stopped || signal?.aborted) return "stopped";
33583
35181
  if (this.now() >= nextWakeAtMs) return "ready";
33584
- const state = await readCodexAgentRuntimeState(this.options.statePath);
33585
- if (state?.schema_version !== "vtx_codex_agent_runtime_v2") return "cancelled";
35182
+ const state = await readInferenceAgentRuntimeState(this.options.statePath);
35183
+ if (state?.schema_version !== "vtx_inference_agent_runtime_v3" || state.adapter_id !== this.options.adapterId) return "cancelled";
33586
35184
  const requestedAt = new Date(this.now()).toISOString();
33587
35185
  const heartbeat = await this.options.controlClient.heartbeat({
33588
- operation_id: randomUUID(),
35186
+ operation_id: randomUUID3(),
33589
35187
  host_id: this.options.hostId,
33590
35188
  assignment_id: state.assignment.assignment_id,
33591
35189
  assignment_generation: state.assignment.assignment_generation,
@@ -33595,7 +35193,7 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33595
35193
  await this.handleCancelledAssignment(state, signal);
33596
35194
  return "cancelled";
33597
35195
  }
33598
- await writeCodexAgentRuntimeState(this.options.statePath, {
35196
+ await writeInferenceAgentRuntimeState(this.options.statePath, {
33599
35197
  ...state,
33600
35198
  assignment: {
33601
35199
  ...state.assignment,
@@ -33606,9 +35204,25 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33606
35204
  }
33607
35205
  return this.stopped || signal?.aborted ? "stopped" : "ready";
33608
35206
  }
33609
- async releaseForHostStop() {
33610
- let state = await readCodexAgentRuntimeState(this.options.statePath);
33611
- if (!state) return;
35207
+ async releaseForHostStop(reasonCode = "host_stopped") {
35208
+ const recovered = await readInferenceAgentRuntimeState(this.options.statePath);
35209
+ if (!recovered) return;
35210
+ let state;
35211
+ if (recovered.schema_version === "vtx_codex_agent_runtime_v1") {
35212
+ if (this.options.adapterId !== "codex") return;
35213
+ state = recovered;
35214
+ } else if (recovered.schema_version === "vtx_codex_agent_runtime_v2") {
35215
+ if (this.options.adapterId !== "codex") return;
35216
+ state = {
35217
+ ...recovered,
35218
+ schema_version: "vtx_inference_agent_runtime_v3",
35219
+ adapter_id: "codex"
35220
+ };
35221
+ await writeInferenceAgentRuntimeState(this.options.statePath, state);
35222
+ } else {
35223
+ if (recovered.adapter_id !== this.options.adapterId) return;
35224
+ state = recovered;
35225
+ }
33612
35226
  try {
33613
35227
  state = state.schema_version === "vtx_codex_agent_runtime_v1" ? await this.resolveLegacyPendingDecision(state) : await this.resolvePendingDecision(state);
33614
35228
  } catch {
@@ -33616,15 +35230,15 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33616
35230
  }
33617
35231
  if (state.pending_decision) return;
33618
35232
  await this.options.controlClient.releaseAssignment({
33619
- operation_id: randomUUID(),
35233
+ operation_id: randomUUID3(),
33620
35234
  host_id: this.options.hostId,
33621
35235
  assignment_id: state.assignment.assignment_id,
33622
35236
  assignment_generation: state.assignment.assignment_generation,
33623
- reason_code: "host_stopped",
35237
+ reason_code: reasonCode,
33624
35238
  requested_at: new Date(this.now()).toISOString()
33625
35239
  }, {});
33626
35240
  if (state.thread) await this.options.adapter.releaseThread(state.thread);
33627
- await clearCodexAgentRuntimeState(this.options.statePath);
35241
+ await clearInferenceAgentRuntimeState(this.options.statePath);
33628
35242
  }
33629
35243
  };
33630
35244
  }
@@ -33632,11 +35246,11 @@ VTX supplies no trading prompt or prepared market context. At your own cadence,
33632
35246
 
33633
35247
  // lib/inference-host/service.ts
33634
35248
  import { spawn as spawn6 } from "node:child_process";
33635
- import { randomUUID as randomUUID2 } from "node:crypto";
35249
+ import { randomUUID as randomUUID4 } from "node:crypto";
33636
35250
  import { createWriteStream, readFileSync } from "node:fs";
33637
- import { access as access3, chmod as chmod3, mkdir as mkdir3, readFile as readFile5, rm as rm5, writeFile as writeFile2 } from "node:fs/promises";
35251
+ import { access as access3, chmod as chmod3, mkdir as mkdir3, readFile as readFile5, rm as rm6, writeFile as writeFile2 } from "node:fs/promises";
33638
35252
  import { homedir as homedir2 } from "node:os";
33639
- import { dirname as dirname4, join as join6, resolve as resolve4 } from "node:path";
35253
+ import { dirname as dirname5, join as join7, resolve as resolve4 } from "node:path";
33640
35254
  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;
33641
35255
  var init_service = __esm({
33642
35256
  "lib/inference-host/service.ts"() {
@@ -34105,8 +35719,8 @@ WantedBy=default.target
34105
35719
  }
34106
35720
  definitionPath() {
34107
35721
  if (this.platform === "win32") return `${this.config.supervisorStatePath}.service-task.xml`;
34108
- if (this.platform === "darwin") return join6(this.home, "Library", "LaunchAgents", `${LAUNCHD_LABEL}.plist`);
34109
- return join6(this.home, ".config", "systemd", "user", SYSTEMD_UNIT);
35722
+ if (this.platform === "darwin") return join7(this.home, "Library", "LaunchAgents", `${LAUNCHD_LABEL}.plist`);
35723
+ return join7(this.home, ".config", "systemd", "user", SYSTEMD_UNIT);
34110
35724
  }
34111
35725
  windowsLauncherPath() {
34112
35726
  return `${this.config.supervisorStatePath}.service-launcher.vbs`;
@@ -34157,7 +35771,7 @@ WantedBy=default.target
34157
35771
  const previousRuntimeUpdatedAt = previousRuntime?.manifest_generation === manifest.generation ? Date.parse(previousRuntime.updated_at) : Number.NaN;
34158
35772
  const restoredManifest = preserveGeneration ? manifest : assertManifest({
34159
35773
  ...manifest,
34160
- generation: randomUUID2(),
35774
+ generation: randomUUID4(),
34161
35775
  installed_at: this.now().toISOString()
34162
35776
  });
34163
35777
  await writeAtomicInferencePrivateFile(
@@ -34239,7 +35853,7 @@ ${result2.stderr}`)) {
34239
35853
  await writeAtomicInferencePrivateFile(this.manifestPath(), `${JSON.stringify(manifest, null, 2)}
34240
35854
  `);
34241
35855
  await writeDesired(this.desiredPath(), desiredRunning, this.now());
34242
- await mkdir3(dirname4(this.definitionPath()), { recursive: true, mode: 448 });
35856
+ await mkdir3(dirname5(this.definitionPath()), { recursive: true, mode: 448 });
34243
35857
  if (this.platform === "win32") {
34244
35858
  await writeAtomicInferencePrivateFile(
34245
35859
  this.windowsLauncherPath(),
@@ -34288,13 +35902,13 @@ ${cleanup.stderr}`)) {
34288
35902
  );
34289
35903
  }
34290
35904
  }
34291
- await rm5(this.definitionPath(), { force: true }).catch(() => void 0);
35905
+ await rm6(this.definitionPath(), { force: true }).catch(() => void 0);
34292
35906
  if (this.platform === "win32") {
34293
- await rm5(this.windowsLauncherPath(), { force: true }).catch(() => void 0);
35907
+ await rm6(this.windowsLauncherPath(), { force: true }).catch(() => void 0);
34294
35908
  }
34295
- await rm5(this.manifestPath(), { force: true }).catch(() => void 0);
34296
- await rm5(this.desiredPath(), { force: true }).catch(() => void 0);
34297
- await rm5(this.runtimePath(), { force: true }).catch(() => void 0);
35909
+ await rm6(this.manifestPath(), { force: true }).catch(() => void 0);
35910
+ await rm6(this.desiredPath(), { force: true }).catch(() => void 0);
35911
+ await rm6(this.runtimePath(), { force: true }).catch(() => void 0);
34298
35912
  if (this.platform === "linux") {
34299
35913
  await this.runCommand("systemctl", ["--user", "daemon-reload"]).catch(() => void 0);
34300
35914
  }
@@ -34443,7 +36057,7 @@ ${cleanup.stderr}`)) {
34443
36057
  ].sort((left, right) => left.instance_name.localeCompare(right.instance_name));
34444
36058
  const manifest = assertManifest({
34445
36059
  schema_version: "vtx_inference_service_v3",
34446
- generation: randomUUID2(),
36060
+ generation: randomUUID4(),
34447
36061
  installed_at: this.now().toISOString(),
34448
36062
  executable: this.executable,
34449
36063
  script: this.script,
@@ -34657,7 +36271,7 @@ ${result2.stderr}`)) {
34657
36271
  if (remaining.length === 0) return await this.uninstallUnlocked();
34658
36272
  return await this.replaceManifestUnlocked({
34659
36273
  ...manifest,
34660
- generation: randomUUID2(),
36274
+ generation: randomUUID4(),
34661
36275
  installed_at: this.now().toISOString(),
34662
36276
  workers: remaining
34663
36277
  }, await readInferenceHostServiceDesired(this.desiredPath()));
@@ -34680,12 +36294,12 @@ ${result2.stderr}`)) {
34680
36294
  ${result2.stderr}`)) {
34681
36295
  throw new Error(`Background service uninstall failed: ${result2.stderr.trim()}`);
34682
36296
  }
34683
- await rm5(this.definitionPath(), { force: true });
34684
- if (this.platform === "win32") await rm5(this.windowsLauncherPath(), { force: true });
36297
+ await rm6(this.definitionPath(), { force: true });
36298
+ if (this.platform === "win32") await rm6(this.windowsLauncherPath(), { force: true });
34685
36299
  if (this.platform === "linux") await this.runCommand("systemctl", ["--user", "daemon-reload"]);
34686
- await rm5(this.manifestPath(), { force: true });
34687
- await rm5(this.desiredPath(), { force: true });
34688
- await rm5(this.runtimePath(), { force: true });
36300
+ await rm6(this.manifestPath(), { force: true });
36301
+ await rm6(this.desiredPath(), { force: true });
36302
+ await rm6(this.runtimePath(), { force: true });
34689
36303
  return {
34690
36304
  installed: false,
34691
36305
  desired_running: false,
@@ -34699,7 +36313,7 @@ ${result2.stderr}`)) {
34699
36313
  }
34700
36314
  };
34701
36315
  appendServiceLog = async (path, event, fields = {}) => {
34702
- await mkdir3(dirname4(path), { recursive: true, mode: 448 });
36316
+ await mkdir3(dirname5(path), { recursive: true, mode: 448 });
34703
36317
  const stream = createWriteStream(path, { flags: "a", mode: 384 });
34704
36318
  await new Promise((resolvePromise, reject) => {
34705
36319
  stream.once("error", reject);
@@ -35047,11 +36661,11 @@ __export(cli_exports, {
35047
36661
  registerInferenceHostServiceControlInput: () => registerInferenceHostServiceControlInput,
35048
36662
  runInferenceHostCli: () => runInferenceHostCli
35049
36663
  });
35050
- import { createHash as createHash7, randomUUID as randomUUID3 } from "node:crypto";
36664
+ import { createHash as createHash8, randomUUID as randomUUID5 } from "node:crypto";
35051
36665
  import { spawn as spawn7 } from "node:child_process";
35052
- import { lstat as lstat4, realpath as realpath4, rm as rm6 } from "node:fs/promises";
36666
+ import { lstat as lstat4, realpath as realpath5, rm as rm7 } from "node:fs/promises";
35053
36667
  import { hostname as osHostname } from "node:os";
35054
- import { join as join7, resolve as resolve5 } from "node:path";
36668
+ import { join as join8, resolve as resolve5 } from "node:path";
35055
36669
  async function runInferenceHostCli(argv2, env = process.env, dependencies = {}) {
35056
36670
  const warnings = [];
35057
36671
  try {
@@ -35081,6 +36695,9 @@ async function runInferenceHostCli(argv2, env = process.env, dependencies = {})
35081
36695
  if (parsed.command === "codex-login") {
35082
36696
  return await codexLogin(config2, parsed, env, dependencies);
35083
36697
  }
36698
+ if (parsed.command === "deepseek-login") {
36699
+ return await deepSeekLogin(config2, parsed, dependencies);
36700
+ }
35084
36701
  if (parsed.command === "run") {
35085
36702
  return await runHost(config2, parsed, env, dependencies, warnings);
35086
36703
  }
@@ -35111,6 +36728,42 @@ async function runInferenceHostCli(argv2, env = process.env, dependencies = {})
35111
36728
  async () => await agentFail(config2, parsed, dependencies, warnings)
35112
36729
  );
35113
36730
  }
36731
+ if (parsed.command === "agent-assignment-next") {
36732
+ return await withAgentCommandLock(
36733
+ config2,
36734
+ async () => await foregroundAssignmentNext(config2, parsed, dependencies, warnings)
36735
+ );
36736
+ }
36737
+ if (parsed.command === "agent-assignment-heartbeat") {
36738
+ return await withAgentCommandLock(
36739
+ config2,
36740
+ async () => await foregroundAssignmentHeartbeat(config2, parsed, dependencies, warnings)
36741
+ );
36742
+ }
36743
+ if (parsed.command === "agent-data-call") {
36744
+ return await withAgentCommandLock(
36745
+ config2,
36746
+ async () => await foregroundDataCall(config2, parsed, dependencies, warnings)
36747
+ );
36748
+ }
36749
+ if (parsed.command === "agent-decision-submit") {
36750
+ return await withAgentCommandLock(
36751
+ config2,
36752
+ async () => await foregroundDecisionSubmit(config2, parsed, dependencies, warnings)
36753
+ );
36754
+ }
36755
+ if (parsed.command === "agent-decision-status") {
36756
+ return await withAgentCommandLock(
36757
+ config2,
36758
+ async () => await foregroundDecisionStatus(config2, parsed, dependencies, warnings)
36759
+ );
36760
+ }
36761
+ if (parsed.command === "agent-assignment-release") {
36762
+ return await withAgentCommandLock(
36763
+ config2,
36764
+ async () => await foregroundAssignmentRelease(config2, parsed, dependencies, warnings)
36765
+ );
36766
+ }
35114
36767
  if (parsed.command === "service") {
35115
36768
  const mutationActions = /* @__PURE__ */ new Set(["install", "start", "stop", "recover", "uninstall"]);
35116
36769
  if (!parsed.serviceAction || !mutationActions.has(parsed.serviceAction)) {
@@ -35137,11 +36790,14 @@ async function runInferenceHostCli(argv2, env = process.env, dependencies = {})
35137
36790
  if (parsed.command === "codex-logout") {
35138
36791
  return await codexLogout(config2, parsed, env, dependencies);
35139
36792
  }
36793
+ if (parsed.command === "deepseek-logout") {
36794
+ return await deepSeekLogout(config2, parsed, dependencies);
36795
+ }
35140
36796
  if (parsed.command === "revoke") {
35141
36797
  return await cleanupLogin(config2, parsed, dependencies, warnings, true);
35142
36798
  }
35143
36799
  throw new Error(
35144
- "Usage: vtx inference-host <login|codex-login|run|agent-connect|agent-run|agent-next|agent-complete|agent-fail|service|status|doctor|logout|codex-logout|revoke> [--json]"
36800
+ "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]"
35145
36801
  );
35146
36802
  } catch (error48) {
35147
36803
  return {
@@ -35152,7 +36808,7 @@ async function runInferenceHostCli(argv2, env = process.env, dependencies = {})
35152
36808
  };
35153
36809
  }
35154
36810
  }
35155
- 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, agentOperationId, agentSession, agentConnect, agentRun, agentNext, agentComplete, agentFail, withAgentCommandLock, recoveryBackupPath, serviceRecoveryTransactionPath, readServiceRecoveryTransaction, assertResumableCodexRecoveryEvidence, recoverInstalledCodexService, serviceCommand, hasExplicitCredentialStoreConfiguration, credentialEnvironmentForIdentity, commandRequiresRetainedCredentialStore, commandUsesInstalledServiceCredentials, resolveInferenceHostCommandConfig;
36811
+ 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;
35156
36812
  var init_cli = __esm({
35157
36813
  "lib/inference-host/cli.ts"() {
35158
36814
  "use strict";
@@ -35163,6 +36819,8 @@ var init_cli = __esm({
35163
36819
  init_codex_adapter();
35164
36820
  init_codex_recovery_process();
35165
36821
  init_copilot_adapter();
36822
+ init_deepseek_harness_adapter();
36823
+ init_deepseek_credential_store();
35166
36824
  init_durable_adapter();
35167
36825
  init_codex_app_server();
35168
36826
  init_codex_binary();
@@ -35246,23 +36904,31 @@ var init_cli = __esm({
35246
36904
  Commands:
35247
36905
  login Authorize the isolated VTX insights:inference grant
35248
36906
  codex-login Sign the automated Codex host into a ChatGPT subscription
36907
+ deepseek-login Import a DeepSeek API key privately from stdin
35249
36908
  run Run a supported durable inference adapter in the foreground
35250
36909
  agent-connect Advertise a model from a compatible agent harness
35251
36910
  agent-run Keep an agent-driven host online in the foreground
35252
36911
  agent-next Claim the next exact VTX inference request
35253
36912
  agent-complete Submit one completed agent result from stdin
35254
36913
  agent-fail Submit one truthful agent failure from stdin
36914
+ agent-assignment-next Claim the assigned Main bot for Agent control
36915
+ agent-assignment-heartbeat Renew the current Agent assignment
36916
+ agent-data-call Request allowed assignment-scoped VTX data
36917
+ agent-decision-submit Submit the normal structured trading decision
36918
+ agent-decision-status Resolve an uncertain Agent decision submission
36919
+ agent-assignment-release Release the current Agent assignment
35255
36920
  service Install and control the durable background host
35256
36921
  status Inspect local host and credential state
35257
36922
  doctor Verify credentials, provider runtime, and private state
35258
36923
  logout Remove local VTX host state without revoking the grant
35259
36924
  revoke Revoke the VTX grant and remove local host state
35260
36925
  codex-logout Remove the automated host's dedicated Codex login
36926
+ deepseek-logout Remove the locally stored DeepSeek API key
35261
36927
 
35262
36928
  Common options:
35263
36929
  --json Emit machine-readable JSON
35264
36930
  --instance NAME Target an isolated local subscription instance (default: default)
35265
- --adapter ID Durable adapter: codex or copilot
36931
+ --adapter ID Durable adapter: codex, copilot, or deepseek-harness
35266
36932
  --max-concurrency N Optional positive-integer local slot limit (default: unlimited)
35267
36933
  --help, -h Show this help
35268
36934
 
@@ -35278,6 +36944,8 @@ Durable service:
35278
36944
  vtx inference-host codex-login --instance codex-2
35279
36945
  vtx inference-host service install --instance codex-2
35280
36946
  vtx inference-host service install --adapter copilot --instance copilot-1
36947
+ vtx inference-host deepseek-login --instance deepseek-1 < /private/path/deepseek.key
36948
+ vtx inference-host service install --adapter deepseek-harness --instance deepseek-1
35281
36949
  vtx inference-host service uninstall --instance codex-2
35282
36950
  vtx inference-host service recover --instance codex-1 --force-recovery
35283
36951
  vtx inference-host service <start|stop|status|logs|recover|uninstall>
@@ -35384,7 +37052,7 @@ Durable service:
35384
37052
  if (command === "agent-connect" && !displayNameExplicit) {
35385
37053
  displayName = "Agent-driven inference host";
35386
37054
  } else if (adapter && isDurableInferenceAdapterId(adapter) && !displayNameExplicit) {
35387
- displayName = `${durableAdapterDisplayName(adapter)} subscription host`;
37055
+ displayName = `${durableAdapterDisplayName(adapter)} host`;
35388
37056
  }
35389
37057
  return {
35390
37058
  command,
@@ -35541,10 +37209,10 @@ Durable service:
35541
37209
  return raw !== null;
35542
37210
  };
35543
37211
  inspectCodexAuthentication = async (config2) => {
35544
- const path = join7(config2.codexHomePath, "auth.json");
37212
+ const path = join8(config2.codexHomePath, "auth.json");
35545
37213
  try {
35546
37214
  const before = await lstat4(path);
35547
- const canonical = await realpath4(path);
37215
+ const canonical = await realpath5(path);
35548
37216
  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()));
35549
37217
  return { present: true, private: isPrivate };
35550
37218
  } catch (error48) {
@@ -35559,14 +37227,16 @@ Durable service:
35559
37227
  runtimeReceiptPath(config2),
35560
37228
  "Inference host runtime receipt file"
35561
37229
  );
35562
- await rm6(codexGuardianReceiptRoot(config2), { recursive: true, force: true });
37230
+ await rm7(codexGuardianReceiptRoot(config2), { recursive: true, force: true });
35563
37231
  await clearInferencePrivateFile(
35564
37232
  codexRecoveryPath(config2),
35565
37233
  "Codex attempt recovery file"
35566
37234
  );
35567
37235
  await clearInferenceAgentAttemptState(config2.statePath);
35568
37236
  await clearInferenceAgentNextState(config2.statePath);
37237
+ await clearInferenceForegroundAgentControlState(config2.statePath);
35569
37238
  await clearCodexAgentRuntimeState(config2.statePath);
37239
+ await clearInferenceAgentFailureFence(config2.statePath);
35570
37240
  await clearInferenceHostLocalState(config2.statePath);
35571
37241
  };
35572
37242
  assertDurableServiceUninstalled = async (config2) => {
@@ -35593,10 +37263,12 @@ Durable service:
35593
37263
  const revocationCheckpointPresent = await readRevocationCheckpoint(config2) !== null;
35594
37264
  const agentAttemptPresent = await readInferenceAgentAttemptState(config2.statePath) !== null;
35595
37265
  const agentNextRecoveryPresent = await readInferenceAgentNextState(config2.statePath) !== null;
37266
+ const foregroundAgentControlPresent = await readInferenceForegroundAgentControlState(config2.statePath) !== null;
35596
37267
  const codexAgentRuntimePresent = await readCodexAgentRuntimeState(config2.statePath) !== null;
35597
- if (pendingAttempts > 0 || codexRecoveryPresent || serviceRecoveryPresent || revocationCheckpointPresent || agentAttemptPresent || agentNextRecoveryPresent || codexAgentRuntimePresent) {
37268
+ const agentFailureFencePresent = await readInferenceAgentFailureFence(config2.statePath) !== null;
37269
+ if (pendingAttempts > 0 || codexRecoveryPresent || serviceRecoveryPresent || revocationCheckpointPresent || agentAttemptPresent || agentNextRecoveryPresent || foregroundAgentControlPresent || codexAgentRuntimePresent || agentFailureFencePresent) {
35598
37270
  throw new Error(
35599
- "Inference host logout refused because attempt recovery is still pending (Codex, agent-driven, or revocation recovery). Rerun agent-next, complete or fail the active attempt, run the automated host to reconcile it, or resume revoke."
37271
+ "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."
35600
37272
  );
35601
37273
  }
35602
37274
  };
@@ -35664,11 +37336,19 @@ Durable service:
35664
37336
  signal: options.signal
35665
37337
  }).run();
35666
37338
  };
35667
- preparePortableDurableAdapter = async (adapterId, signal) => {
35668
- const adapter = new CopilotSubscriptionAdapter();
37339
+ preparePortableDurableAdapter = async (adapterId, config2, signal) => {
37340
+ const adapter = adapterId === "copilot" ? new CopilotSubscriptionAdapter() : new DeepSeekHarnessAdapter({
37341
+ credentialStore: createDeepSeekHarnessCredentialStore(config2)
37342
+ });
35669
37343
  return { adapter, preflight: await adapter.preflight(signal) };
35670
37344
  };
35671
37345
  defaultRunPortableDurableAdapter = async (options) => {
37346
+ const agentAdapter = options.adapter;
37347
+ if (typeof agentAdapter.runTurn !== "function" || typeof agentAdapter.releaseThread !== "function" || typeof agentAdapter.close !== "function") {
37348
+ throw new Error(
37349
+ `${options.preflight.adapterId} does not implement the durable Agent-control contract.`
37350
+ );
37351
+ }
35672
37352
  const dependencies = createDefaultInferenceHostRunnerDependencies({
35673
37353
  apiUrl: options.config.apiUrl,
35674
37354
  statePath: options.config.statePath,
@@ -35704,6 +37384,10 @@ Durable service:
35704
37384
  maxConcurrency: options.maxConcurrency,
35705
37385
  once: options.once,
35706
37386
  emitDiagnosticEvent: options.emitDiagnosticEvent,
37387
+ agentRuntime: {
37388
+ statePath: options.config.statePath,
37389
+ adapter: agentAdapter
37390
+ },
35707
37391
  signal: options.signal
35708
37392
  }).run();
35709
37393
  };
@@ -35737,7 +37421,7 @@ Durable service:
35737
37421
  await writeInferenceHostCredentialContextTransition(config2, previousCredentialContext);
35738
37422
  await writeInferenceHostCredentialContext(config2);
35739
37423
  const keyPair = generateExternalInferenceEnvelopeKeyPair();
35740
- const hostId = randomUUID3();
37424
+ const hostId = randomUUID5();
35741
37425
  const beginLogin = dependencies.beginLogin ?? beginInferenceOAuthLogin;
35742
37426
  const loginStore = {
35743
37427
  kind: store.kind,
@@ -35935,6 +37619,53 @@ Waiting for approval...
35935
37619
  cancellation.unregister();
35936
37620
  }
35937
37621
  };
37622
+ deepSeekCredentialStore = (config2, dependencies) => dependencies.createDeepSeekCredentialStore?.(config2) ?? createDeepSeekHarnessCredentialStore(config2);
37623
+ deepSeekLogin = async (config2, parsed, dependencies) => {
37624
+ await assertDurableServiceUninstalled(config2);
37625
+ if (!dependencies.readStdin && process.stdin.isTTY) {
37626
+ throw new Error("DeepSeek API key must be supplied through stdin, never as an argument.");
37627
+ }
37628
+ const cancellation = lifecycleCancellation(dependencies);
37629
+ let lock2 = null;
37630
+ try {
37631
+ lock2 = await acquireInferenceHostProcessLock(config2.processLockPath);
37632
+ const raw = await (dependencies.readStdin ?? defaultReadStdin)();
37633
+ const credential = await deepSeekCredentialStore(config2, dependencies).write(
37634
+ raw,
37635
+ cancellation.signal
37636
+ );
37637
+ const failureFence = await readInferenceAgentFailureFence(config2.statePath);
37638
+ if (failureFence?.adapter_id === "deepseek-harness" && failureFence.failure_category === "auth") {
37639
+ await clearInferenceAgentFailureFence(config2.statePath);
37640
+ }
37641
+ return {
37642
+ exitCode: 0,
37643
+ stdout: render({
37644
+ status: "deepseek_api_key_imported",
37645
+ identity: credential.identity,
37646
+ credential_store: config2.credentialStoreMode
37647
+ }, parsed.json),
37648
+ stderr: ""
37649
+ };
37650
+ } finally {
37651
+ await lock2?.release();
37652
+ cancellation.unregister();
37653
+ }
37654
+ };
37655
+ deepSeekLogout = async (config2, parsed, dependencies) => {
37656
+ await assertDurableServiceUninstalled(config2);
37657
+ const lock2 = await acquireInferenceHostProcessLock(config2.processLockPath);
37658
+ try {
37659
+ await deepSeekCredentialStore(config2, dependencies).remove();
37660
+ return {
37661
+ exitCode: 0,
37662
+ stdout: render({ status: "deepseek_api_key_removed" }, parsed.json),
37663
+ stderr: ""
37664
+ };
37665
+ } finally {
37666
+ await lock2.release();
37667
+ }
37668
+ };
35938
37669
  localStatus = async (config2, parsed, dependencies, warnings) => {
35939
37670
  const codexAuthentication = await inspectCodexAuthentication(config2);
35940
37671
  const state = await readInferenceHostLocalState(config2.statePath);
@@ -35979,6 +37710,7 @@ Waiting for approval...
35979
37710
  );
35980
37711
  const agentAttempt = await readInferenceAgentAttemptState(config2.statePath);
35981
37712
  const agentNextRecoveryPresent = await readInferenceAgentNextState(config2.statePath) !== null;
37713
+ const agentFailureFence = await readInferenceAgentFailureFence(config2.statePath);
35982
37714
  return {
35983
37715
  exitCode: 0,
35984
37716
  stdout: render({
@@ -36004,6 +37736,13 @@ Waiting for approval...
36004
37736
  deadline_at: agentAttempt.deadline_at
36005
37737
  } : null,
36006
37738
  agent_next_recovery_present: agentNextRecoveryPresent,
37739
+ agent_failure_fence: agentFailureFence ? {
37740
+ adapter: agentFailureFence.adapter_id,
37741
+ failure_category: agentFailureFence.failure_category,
37742
+ failure_code: agentFailureFence.failure_code,
37743
+ dispatch_outcome: agentFailureFence.dispatch_outcome,
37744
+ retry_at: agentFailureFence.retry_at
37745
+ } : null,
36007
37746
  codex_recovery_present: recoveryPresent,
36008
37747
  service_recovery_present: serviceRecoveryPresent,
36009
37748
  codex_auth: codexAuthentication,
@@ -36022,6 +37761,12 @@ Waiting for approval...
36022
37761
  ok: state !== null,
36023
37762
  detail: state ? "valid" : "missing"
36024
37763
  });
37764
+ const agentFailureFence = await readInferenceAgentFailureFence(config2.statePath);
37765
+ checks.push({
37766
+ name: "agent_runtime_fence",
37767
+ ok: agentFailureFence === null,
37768
+ detail: agentFailureFence === null ? "clear" : `${agentFailureFence.failure_code}:${agentFailureFence.dispatch_outcome}`
37769
+ });
36025
37770
  checks.push({
36026
37771
  name: "revocation_recovery",
36027
37772
  ok: revocationCheckpoint === null,
@@ -36060,7 +37805,8 @@ Waiting for approval...
36060
37805
  } else if (adapterId !== "codex") {
36061
37806
  try {
36062
37807
  const prepared = await (dependencies.prepareDurableAdapter ?? preparePortableDurableAdapter)(
36063
- adapterId
37808
+ adapterId,
37809
+ config2
36064
37810
  );
36065
37811
  checks.push({
36066
37812
  name: "provider_runtime",
@@ -36318,6 +38064,7 @@ Waiting for approval...
36318
38064
  if (adapterId !== "codex") {
36319
38065
  const prepared = await (dependencies.prepareDurableAdapter ?? preparePortableDurableAdapter)(
36320
38066
  adapterId,
38067
+ config2,
36321
38068
  cancellation.signal
36322
38069
  );
36323
38070
  const summary = await (dependencies.runPortableDurableAdapter ?? defaultRunPortableDurableAdapter)({
@@ -36417,7 +38164,27 @@ Waiting for approval...
36417
38164
  }
36418
38165
  return record2;
36419
38166
  };
36420
- agentOperationId = (kind) => `${kind}-${randomUUID3()}`;
38167
+ parseOptionalAgentStdin = async (dependencies, allowedKeys) => {
38168
+ if (!dependencies.readStdin && process.stdin.isTTY) return {};
38169
+ const raw = await (dependencies.readStdin ?? defaultReadStdin)();
38170
+ if (!raw.trim()) return {};
38171
+ let value;
38172
+ try {
38173
+ value = JSON.parse(raw);
38174
+ } catch {
38175
+ throw new Error("Agent-driven inference stdin must be one JSON object.");
38176
+ }
38177
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
38178
+ throw new Error("Agent-driven inference stdin must be one JSON object.");
38179
+ }
38180
+ const record2 = value;
38181
+ const unexpected = Object.keys(record2).filter((key) => !allowedKeys.includes(key));
38182
+ if (unexpected.length > 0) {
38183
+ throw new Error(`Unsupported agent-driven inference fields: ${unexpected.join(", ")}.`);
38184
+ }
38185
+ return record2;
38186
+ };
38187
+ agentOperationId = (kind) => `${kind}-${randomUUID5()}`;
36421
38188
  agentSession = async (config2, dependencies, warnings, signal) => {
36422
38189
  if (await readRevocationCheckpoint(config2)) {
36423
38190
  throw new Error("Inference host revocation recovery must finish first.");
@@ -36461,11 +38228,419 @@ Waiting for approval...
36461
38228
  reasoning_effort: result2.reasoning_effort,
36462
38229
  lanes: ["main", "review", "screener"],
36463
38230
  response_modes: ["provider_response", "decision_candidate"],
38231
+ control_modes: ["provider", "agent"],
36464
38232
  execution_modes: ["client", "server"],
36465
38233
  next_command: "vtx inference-host agent-next --wait-seconds 50 --json",
38234
+ agent_next_command: "vtx inference-host agent-assignment-next --wait-seconds 50 --json",
36466
38235
  keeper_command: "vtx inference-host agent-run"
36467
38236
  }, parsed.json),
36468
38237
  stderr: warnings.length > 0 ? `${warnings.join("\n")}
38238
+ ` : ""
38239
+ };
38240
+ };
38241
+ foregroundAgentControlState = (hostId, updatedAt) => ({
38242
+ schema_version: "vtx_foreground_agent_control_v1",
38243
+ host_id: hostId,
38244
+ assignment: null,
38245
+ pending_next: null,
38246
+ pending_decision: null,
38247
+ next_wake_at: null,
38248
+ updated_at: updatedAt
38249
+ });
38250
+ requireForegroundAgentState = async (config2, hostId) => {
38251
+ const state = await readInferenceForegroundAgentControlState(config2.statePath);
38252
+ if (!state?.assignment) {
38253
+ throw new Error("No active foreground Agent assignment. Run agent-assignment-next first.");
38254
+ }
38255
+ if (state.host_id !== hostId) {
38256
+ throw new Error("Foreground Agent assignment belongs to another inference host.");
38257
+ }
38258
+ return state;
38259
+ };
38260
+ assignmentFromClaim = (result2) => ({
38261
+ assignment_id: result2.assignment_id,
38262
+ assignment_generation: result2.assignment_generation,
38263
+ model_id: result2.model_id,
38264
+ reasoning_effort: result2.reasoning_effort,
38265
+ bot_mode: result2.bot_mode,
38266
+ execution_mode: result2.execution_mode,
38267
+ allowed_symbols: result2.allowed_symbols,
38268
+ data_contract: result2.data_contract,
38269
+ output_schema: result2.output_schema,
38270
+ minimum_wake_seconds: result2.minimum_wake_seconds,
38271
+ maximum_wake_seconds: result2.maximum_wake_seconds,
38272
+ lease_expires_at: result2.lease_expires_at
38273
+ });
38274
+ foregroundAssignmentNext = async (config2, parsed, dependencies, warnings) => {
38275
+ const session = await agentSession(config2, dependencies, warnings);
38276
+ const now = dependencies.now ?? (() => /* @__PURE__ */ new Date());
38277
+ const sleep4 = dependencies.sleep ?? (async (milliseconds) => {
38278
+ await new Promise((resolve6) => setTimeout(resolve6, milliseconds));
38279
+ });
38280
+ const stopAt = now().getTime() + parsed.waitSeconds * 1e3;
38281
+ let state = await readInferenceForegroundAgentControlState(config2.statePath) ?? foregroundAgentControlState(session.localState.host_id, now().toISOString());
38282
+ if (state.host_id !== session.localState.host_id) {
38283
+ throw new Error("Foreground Agent recovery state belongs to another inference host.");
38284
+ }
38285
+ if (state.pending_decision) {
38286
+ throw new Error("Resolve the pending Agent decision before claiming another assignment.");
38287
+ }
38288
+ while (true) {
38289
+ if (!state.pending_next) {
38290
+ const requestedAt = now().toISOString();
38291
+ state = {
38292
+ ...state,
38293
+ pending_next: {
38294
+ operation_id: agentOperationId("agent-assignment-next"),
38295
+ requested_at: requestedAt
38296
+ },
38297
+ updated_at: requestedAt
38298
+ };
38299
+ await writeInferenceForegroundAgentControlState(config2.statePath, state);
38300
+ }
38301
+ const pending = state.pending_next;
38302
+ let result2;
38303
+ try {
38304
+ result2 = await session.client.callTool("inference.agent.assignment.next", {
38305
+ operation_id: pending.operation_id,
38306
+ host_id: session.localState.host_id,
38307
+ requested_at: pending.requested_at,
38308
+ contract_version: "agent_assignment_v2",
38309
+ ...state.assignment ? {
38310
+ assignment_id: state.assignment.assignment_id,
38311
+ assignment_generation: state.assignment.assignment_generation
38312
+ } : {}
38313
+ });
38314
+ } catch (error48) {
38315
+ if (error48 && typeof error48 === "object" && error48.definitivelyNotApplied === true) {
38316
+ state = { ...state, pending_next: null, updated_at: now().toISOString() };
38317
+ await writeInferenceForegroundAgentControlState(config2.statePath, state);
38318
+ }
38319
+ throw error48;
38320
+ }
38321
+ if (result2.claim_state === "claimed") {
38322
+ const assignment = assignmentFromClaim(result2);
38323
+ state = {
38324
+ ...state,
38325
+ assignment,
38326
+ pending_next: null,
38327
+ next_wake_at: null,
38328
+ updated_at: now().toISOString()
38329
+ };
38330
+ await writeInferenceForegroundAgentControlState(config2.statePath, state);
38331
+ return {
38332
+ exitCode: 0,
38333
+ stdout: render({
38334
+ ...result2,
38335
+ instructions: "VTX supplied no trading prompt or prepared context. Choose your own cadence; use agent-data-call zero or more times, submit the exact output_schema through agent-decision-submit, then record the next wake with agent-assignment-heartbeat. Keep agent-run open for liveness.",
38336
+ data_command: "vtx inference-host agent-data-call --json",
38337
+ decision_command: "vtx inference-host agent-decision-submit --json",
38338
+ decision_input: {
38339
+ candidate: "<object matching output_schema>",
38340
+ provenance: {
38341
+ source: "external_agent",
38342
+ agent_run_id: "<stable harness run id>",
38343
+ requested_model: result2.model_id,
38344
+ effective_model: "<actual model used>",
38345
+ requested_reasoning_effort: result2.reasoning_effort,
38346
+ effective_reasoning_effort: "<actual reasoning effort used>"
38347
+ }
38348
+ },
38349
+ heartbeat_command: "vtx inference-host agent-assignment-heartbeat --json",
38350
+ release_command: "vtx inference-host agent-assignment-release --json"
38351
+ }, parsed.json),
38352
+ stderr: warnings.length > 0 ? `${warnings.join("\n")}
38353
+ ` : ""
38354
+ };
38355
+ }
38356
+ state = { ...state, pending_next: null, updated_at: now().toISOString() };
38357
+ await writeInferenceForegroundAgentControlState(config2.statePath, state);
38358
+ const remaining = stopAt - now().getTime();
38359
+ if (remaining <= 0 || parsed.waitSeconds === 0) {
38360
+ return {
38361
+ exitCode: 0,
38362
+ stdout: render(result2, parsed.json),
38363
+ stderr: warnings.length > 0 ? `${warnings.join("\n")}
38364
+ ` : ""
38365
+ };
38366
+ }
38367
+ await sleep4(Math.min(remaining, Math.max(50, result2.retry_after_ms)));
38368
+ }
38369
+ };
38370
+ foregroundAssignmentHeartbeat = async (config2, parsed, dependencies, warnings) => {
38371
+ const session = await agentSession(config2, dependencies, warnings);
38372
+ const state = await requireForegroundAgentState(
38373
+ config2,
38374
+ session.localState.host_id
38375
+ );
38376
+ const input = await parseOptionalAgentStdin(dependencies, ["next_wake_at"]);
38377
+ const nextWakeAt = input.next_wake_at;
38378
+ if (nextWakeAt !== void 0 && (typeof nextWakeAt !== "string" || !Number.isFinite(Date.parse(nextWakeAt)))) {
38379
+ throw new Error("next_wake_at must be an ISO timestamp.");
38380
+ }
38381
+ const requestedAt = (dependencies.now ?? (() => /* @__PURE__ */ new Date()))().toISOString();
38382
+ const result2 = await session.client.callTool("inference.agent.assignment.heartbeat", {
38383
+ operation_id: agentOperationId("agent-assignment-heartbeat"),
38384
+ host_id: session.localState.host_id,
38385
+ assignment_id: state.assignment.assignment_id,
38386
+ assignment_generation: state.assignment.assignment_generation,
38387
+ requested_at: requestedAt,
38388
+ ...nextWakeAt === void 0 ? {} : { next_wake_at: nextWakeAt }
38389
+ });
38390
+ if (result2.directive === "cancel") {
38391
+ await handleForegroundCancelledAssignment(config2, session, state, requestedAt);
38392
+ } else {
38393
+ await writeInferenceForegroundAgentControlState(config2.statePath, {
38394
+ ...state,
38395
+ assignment: { ...state.assignment, lease_expires_at: result2.lease_expires_at },
38396
+ next_wake_at: result2.next_wake_at ?? state.next_wake_at,
38397
+ updated_at: requestedAt
38398
+ });
38399
+ }
38400
+ return {
38401
+ exitCode: 0,
38402
+ stdout: render(result2, parsed.json),
38403
+ stderr: warnings.length > 0 ? `${warnings.join("\n")}
38404
+ ` : ""
38405
+ };
38406
+ };
38407
+ foregroundDataCall = async (config2, parsed, dependencies, warnings) => {
38408
+ const session = await agentSession(config2, dependencies, warnings);
38409
+ const state = await requireForegroundAgentState(config2, session.localState.host_id);
38410
+ const input = await parseAgentStdin(dependencies, ["capability", "arguments"]);
38411
+ const capability = typeof input.capability === "string" ? input.capability.trim() : "";
38412
+ if (!capability || !state.assignment.data_contract.some((item) => item.id === capability)) {
38413
+ throw new Error("Agent data capability is not allowed by the current assignment.");
38414
+ }
38415
+ if (!input.arguments || typeof input.arguments !== "object" || Array.isArray(input.arguments)) {
38416
+ throw new Error("Agent data arguments must be one JSON object.");
38417
+ }
38418
+ const result2 = await session.client.callTool("inference.agent.data.call", {
38419
+ operation_id: agentOperationId("agent-data-call"),
38420
+ host_id: session.localState.host_id,
38421
+ assignment_id: state.assignment.assignment_id,
38422
+ assignment_generation: state.assignment.assignment_generation,
38423
+ capability,
38424
+ arguments: input.arguments,
38425
+ requested_at: (dependencies.now ?? (() => /* @__PURE__ */ new Date()))().toISOString()
38426
+ });
38427
+ return {
38428
+ exitCode: 0,
38429
+ stdout: render(result2, parsed.json),
38430
+ stderr: warnings.length > 0 ? `${warnings.join("\n")}
38431
+ ` : ""
38432
+ };
38433
+ };
38434
+ foregroundDecisionStatusRequest = (hostId, state) => ({
38435
+ operation_id: state.pending_decision.request.operation_id,
38436
+ host_id: hostId,
38437
+ assignment_id: state.assignment.assignment_id,
38438
+ assignment_generation: state.assignment.assignment_generation
38439
+ });
38440
+ foregroundAssignmentLeaseEnded = (state, now) => Boolean(state.assignment) && Date.parse(state.assignment.lease_expires_at) <= now.getTime();
38441
+ handleForegroundCancelledAssignment = async (config2, session, state, requestedAt, signal) => {
38442
+ if (!state.pending_decision) {
38443
+ await clearInferenceForegroundAgentControlState(config2.statePath);
38444
+ return;
38445
+ }
38446
+ const cancelledState = {
38447
+ ...state,
38448
+ assignment: {
38449
+ ...state.assignment,
38450
+ lease_expires_at: requestedAt
38451
+ },
38452
+ pending_decision: {
38453
+ ...state.pending_decision,
38454
+ last_status_check_at: requestedAt
38455
+ },
38456
+ next_wake_at: null,
38457
+ updated_at: requestedAt
38458
+ };
38459
+ await writeInferenceForegroundAgentControlState(config2.statePath, cancelledState);
38460
+ try {
38461
+ await session.client.callTool(
38462
+ "inference.agent.decision.status",
38463
+ foregroundDecisionStatusRequest(session.localState.host_id, cancelledState),
38464
+ { signal }
38465
+ );
38466
+ } catch {
38467
+ return;
38468
+ }
38469
+ await clearInferenceForegroundAgentControlState(config2.statePath);
38470
+ };
38471
+ foregroundDecisionStatus = async (config2, parsed, dependencies, warnings) => {
38472
+ const session = await agentSession(config2, dependencies, warnings);
38473
+ let state = await requireForegroundAgentState(config2, session.localState.host_id);
38474
+ if (!state.pending_decision) {
38475
+ throw new Error("No uncertain foreground Agent decision requires status recovery.");
38476
+ }
38477
+ const checkedAt = (dependencies.now ?? (() => /* @__PURE__ */ new Date()))().toISOString();
38478
+ state = {
38479
+ ...state,
38480
+ pending_decision: { ...state.pending_decision, last_status_check_at: checkedAt },
38481
+ updated_at: checkedAt
38482
+ };
38483
+ await writeInferenceForegroundAgentControlState(config2.statePath, state);
38484
+ const result2 = await session.client.callTool(
38485
+ "inference.agent.decision.status",
38486
+ foregroundDecisionStatusRequest(session.localState.host_id, state)
38487
+ );
38488
+ const assignmentLeaseEnded = foregroundAssignmentLeaseEnded(state, new Date(checkedAt));
38489
+ if (result2.found || assignmentLeaseEnded) {
38490
+ if (assignmentLeaseEnded) {
38491
+ await clearInferenceForegroundAgentControlState(config2.statePath);
38492
+ } else {
38493
+ await writeInferenceForegroundAgentControlState(config2.statePath, {
38494
+ ...state,
38495
+ pending_decision: null,
38496
+ updated_at: checkedAt
38497
+ });
38498
+ }
38499
+ }
38500
+ return {
38501
+ exitCode: 0,
38502
+ stdout: render(result2, parsed.json),
38503
+ stderr: warnings.length > 0 ? `${warnings.join("\n")}
38504
+ ` : ""
38505
+ };
38506
+ };
38507
+ foregroundDecisionSubmit = async (config2, parsed, dependencies, warnings) => {
38508
+ const session = await agentSession(config2, dependencies, warnings);
38509
+ const now = dependencies.now ?? (() => /* @__PURE__ */ new Date());
38510
+ let state = await requireForegroundAgentState(config2, session.localState.host_id);
38511
+ if (!state.pending_decision) {
38512
+ const input = await parseAgentStdin(dependencies, ["candidate", "provenance"]);
38513
+ if (!input.candidate || typeof input.candidate !== "object" || Array.isArray(input.candidate)) {
38514
+ throw new Error("Agent decision candidate must be one JSON object.");
38515
+ }
38516
+ if (!input.provenance || typeof input.provenance !== "object" || Array.isArray(input.provenance)) {
38517
+ throw new Error("Agent decision provenance must be one JSON object.");
38518
+ }
38519
+ const observedAt = now().toISOString();
38520
+ state = {
38521
+ ...state,
38522
+ pending_decision: {
38523
+ request: {
38524
+ assignment_id: state.assignment.assignment_id,
38525
+ assignment_generation: state.assignment.assignment_generation,
38526
+ operation_id: agentOperationId("agent-decision-submit"),
38527
+ candidate: input.candidate,
38528
+ observed_at: observedAt,
38529
+ provenance: input.provenance
38530
+ },
38531
+ first_transmit_at: null,
38532
+ last_status_check_at: null
38533
+ },
38534
+ updated_at: observedAt
38535
+ };
38536
+ await writeInferenceForegroundAgentControlState(config2.statePath, state);
38537
+ } else {
38538
+ const checkedAt = now().toISOString();
38539
+ state = {
38540
+ ...state,
38541
+ pending_decision: { ...state.pending_decision, last_status_check_at: checkedAt },
38542
+ updated_at: checkedAt
38543
+ };
38544
+ await writeInferenceForegroundAgentControlState(config2.statePath, state);
38545
+ const status = await session.client.callTool(
38546
+ "inference.agent.decision.status",
38547
+ foregroundDecisionStatusRequest(session.localState.host_id, state)
38548
+ );
38549
+ if (status.found) {
38550
+ await writeInferenceForegroundAgentControlState(config2.statePath, {
38551
+ ...state,
38552
+ pending_decision: null,
38553
+ updated_at: checkedAt
38554
+ });
38555
+ return {
38556
+ exitCode: 0,
38557
+ stdout: render({ ...status, recovered: true }, parsed.json),
38558
+ stderr: warnings.length > 0 ? `${warnings.join("\n")}
38559
+ ` : ""
38560
+ };
38561
+ }
38562
+ }
38563
+ const transmittedAt = now().toISOString();
38564
+ state = {
38565
+ ...state,
38566
+ pending_decision: {
38567
+ ...state.pending_decision,
38568
+ first_transmit_at: state.pending_decision.first_transmit_at ?? transmittedAt
38569
+ },
38570
+ updated_at: transmittedAt
38571
+ };
38572
+ await writeInferenceForegroundAgentControlState(config2.statePath, state);
38573
+ try {
38574
+ const result2 = await session.client.callTool(
38575
+ "inference.agent.decision.submit",
38576
+ state.pending_decision.request
38577
+ );
38578
+ await writeInferenceForegroundAgentControlState(config2.statePath, {
38579
+ ...state,
38580
+ pending_decision: null,
38581
+ updated_at: now().toISOString()
38582
+ });
38583
+ return {
38584
+ exitCode: 0,
38585
+ stdout: render(result2, parsed.json),
38586
+ stderr: warnings.length > 0 ? `${warnings.join("\n")}
38587
+ ` : ""
38588
+ };
38589
+ } catch (error48) {
38590
+ const checkedAt = now().toISOString();
38591
+ state = {
38592
+ ...state,
38593
+ pending_decision: { ...state.pending_decision, last_status_check_at: checkedAt },
38594
+ updated_at: checkedAt
38595
+ };
38596
+ await writeInferenceForegroundAgentControlState(config2.statePath, state);
38597
+ try {
38598
+ const status = await session.client.callTool(
38599
+ "inference.agent.decision.status",
38600
+ foregroundDecisionStatusRequest(session.localState.host_id, state)
38601
+ );
38602
+ if (status.found) {
38603
+ await writeInferenceForegroundAgentControlState(config2.statePath, {
38604
+ ...state,
38605
+ pending_decision: null,
38606
+ updated_at: checkedAt
38607
+ });
38608
+ return {
38609
+ exitCode: 0,
38610
+ stdout: render({ ...status, recovered: true }, parsed.json),
38611
+ stderr: warnings.length > 0 ? `${warnings.join("\n")}
38612
+ ` : ""
38613
+ };
38614
+ }
38615
+ } catch {
38616
+ }
38617
+ throw error48;
38618
+ }
38619
+ };
38620
+ foregroundAssignmentRelease = async (config2, parsed, dependencies, warnings) => {
38621
+ const session = await agentSession(config2, dependencies, warnings);
38622
+ const state = await requireForegroundAgentState(config2, session.localState.host_id);
38623
+ if (state.pending_decision) {
38624
+ throw new Error("Resolve the pending Agent decision before releasing its assignment.");
38625
+ }
38626
+ const input = await parseOptionalAgentStdin(dependencies, ["reason_code"]);
38627
+ const reasonCode = input.reason_code === void 0 ? "agent_released" : input.reason_code;
38628
+ if (typeof reasonCode !== "string" || !/^[a-z0-9][a-z0-9._-]{0,95}$/u.test(reasonCode)) {
38629
+ throw new Error("reason_code must be a safe lowercase code.");
38630
+ }
38631
+ const result2 = await session.client.callTool("inference.agent.assignment.release", {
38632
+ operation_id: agentOperationId("agent-assignment-release"),
38633
+ host_id: session.localState.host_id,
38634
+ assignment_id: state.assignment.assignment_id,
38635
+ assignment_generation: state.assignment.assignment_generation,
38636
+ reason_code: reasonCode,
38637
+ requested_at: (dependencies.now ?? (() => /* @__PURE__ */ new Date()))().toISOString()
38638
+ });
38639
+ await clearInferenceForegroundAgentControlState(config2.statePath);
38640
+ return {
38641
+ exitCode: 0,
38642
+ stdout: render(result2, parsed.json),
38643
+ stderr: warnings.length > 0 ? `${warnings.join("\n")}
36469
38644
  ` : ""
36470
38645
  };
36471
38646
  };
@@ -36473,6 +38648,7 @@ Waiting for approval...
36473
38648
  const cancellation = lifecycleCancellation(dependencies);
36474
38649
  let keeperLock = null;
36475
38650
  let heartbeatCount = 0;
38651
+ let assignmentHeartbeatCount = 0;
36476
38652
  try {
36477
38653
  keeperLock = await acquireInferenceHostProcessLock(foregroundHostLockPath(config2));
36478
38654
  const store = configuredCredentialStore(config2, dependencies, (message) => {
@@ -36506,6 +38682,7 @@ Waiting for approval...
36506
38682
  }
36507
38683
  if (commandLock) {
36508
38684
  let heartbeatSuppressed = false;
38685
+ let assignmentHeartbeatComplete = true;
36509
38686
  try {
36510
38687
  const active = await readInferenceAgentAttemptState(config2.statePath);
36511
38688
  const pendingNext = await readInferenceAgentNextState(config2.statePath);
@@ -36565,10 +38742,65 @@ Waiting for approval...
36565
38742
  }
36566
38743
  }
36567
38744
  }
38745
+ const control = await readInferenceForegroundAgentControlState(config2.statePath);
38746
+ if (control && control.host_id !== session.localState.host_id) {
38747
+ throw new Error("Foreground Agent control state belongs to another inference host.");
38748
+ }
38749
+ if (control?.assignment) {
38750
+ assignmentHeartbeatComplete = false;
38751
+ try {
38752
+ const requestedAt = (dependencies.now ?? (() => /* @__PURE__ */ new Date()))().toISOString();
38753
+ const result2 = await session.client.callTool(
38754
+ "inference.agent.assignment.heartbeat",
38755
+ {
38756
+ operation_id: agentOperationId("agent-assignment-heartbeat"),
38757
+ host_id: session.localState.host_id,
38758
+ assignment_id: control.assignment.assignment_id,
38759
+ assignment_generation: control.assignment.assignment_generation,
38760
+ requested_at: requestedAt
38761
+ },
38762
+ { signal: cancellation.signal }
38763
+ );
38764
+ assignmentHeartbeatComplete = true;
38765
+ assignmentHeartbeatCount += 1;
38766
+ if (result2.directive === "cancel") {
38767
+ await handleForegroundCancelledAssignment(
38768
+ config2,
38769
+ session,
38770
+ control,
38771
+ requestedAt,
38772
+ cancellation.signal
38773
+ );
38774
+ } else {
38775
+ await writeInferenceForegroundAgentControlState(config2.statePath, {
38776
+ ...control,
38777
+ assignment: {
38778
+ ...control.assignment,
38779
+ lease_expires_at: result2.lease_expires_at
38780
+ },
38781
+ updated_at: requestedAt
38782
+ });
38783
+ }
38784
+ } catch (error48) {
38785
+ if (cancellation.signal.aborted) break;
38786
+ if (!retryableAgentHeartbeatError(error48)) throw error48;
38787
+ consecutiveHeartbeatFailures += 1;
38788
+ retryDelayMs = Math.min(
38789
+ AGENT_HEARTBEAT_INTERVAL_MS * 2 ** Math.max(0, consecutiveHeartbeatFailures - 1),
38790
+ AGENT_HEARTBEAT_MAX_RETRY_DELAY_MS
38791
+ );
38792
+ emitStderr(parsed.json ? `${JSON.stringify({
38793
+ status: "assignment_heartbeat_retry",
38794
+ retry_after_ms: retryDelayMs
38795
+ })}
38796
+ ` : `Foreground Agent assignment heartbeat was temporarily unavailable; retrying in ${retryDelayMs}ms.
38797
+ `);
38798
+ }
38799
+ }
36568
38800
  } finally {
36569
38801
  await commandLock.release();
36570
38802
  }
36571
- if (parsed.once && (heartbeatCount > 0 || heartbeatSuppressed)) break;
38803
+ if (parsed.once && (heartbeatCount > 0 || heartbeatSuppressed) && assignmentHeartbeatComplete) break;
36572
38804
  }
36573
38805
  if (parsed.once && !commandLock) break;
36574
38806
  await (dependencies.sleep ?? (async (milliseconds) => {
@@ -36577,7 +38809,11 @@ Waiting for approval...
36577
38809
  }
36578
38810
  return {
36579
38811
  exitCode: 0,
36580
- stdout: render({ status: "stopped", heartbeats: heartbeatCount }, parsed.json),
38812
+ stdout: render({
38813
+ status: "stopped",
38814
+ heartbeats: heartbeatCount,
38815
+ assignment_heartbeats: assignmentHeartbeatCount
38816
+ }, parsed.json),
36581
38817
  stderr: warnings.length > 0 ? `${warnings.join("\n")}
36582
38818
  ` : ""
36583
38819
  };
@@ -36965,7 +39201,7 @@ Waiting for approval...
36965
39201
  if (recoveryRaw === null && existingTransaction?.phase !== "reconciled") {
36966
39202
  throw new Error("Codex recovery evidence changed before service recovery began.");
36967
39203
  }
36968
- const transactionId = existingTransaction?.transaction_id ?? randomUUID3();
39204
+ const transactionId = existingTransaction?.transaction_id ?? randomUUID5();
36969
39205
  const backupPath = existingTransaction?.recovery_backup_path ?? recoveryBackupPath(config2, transactionId);
36970
39206
  if (!existingTransaction) {
36971
39207
  await writeAtomicInferencePrivateFile(backupPath, recoveryRaw);
@@ -36974,7 +39210,7 @@ Waiting for approval...
36974
39210
  backupPath,
36975
39211
  "Codex service recovery backup"
36976
39212
  );
36977
- const backupSha256 = backupRaw === null ? null : createHash7("sha256").update(backupRaw).digest("hex");
39213
+ const backupSha256 = backupRaw === null ? null : createHash8("sha256").update(backupRaw).digest("hex");
36978
39214
  if (backupSha256 === null || existingTransaction && backupSha256 !== existingTransaction.recovery_backup_sha256) {
36979
39215
  throw new Error("Codex service recovery backup is missing or changed.");
36980
39216
  }
@@ -36985,7 +39221,7 @@ Waiting for approval...
36985
39221
  existingTransaction?.cleanup_confirmed_attempt_ids ?? [],
36986
39222
  existingTransaction?.phase ?? "prepared"
36987
39223
  );
36988
- const recoverySha256 = recoveryRaw === null ? null : createHash7("sha256").update(recoveryRaw).digest("hex");
39224
+ const recoverySha256 = recoveryRaw === null ? null : createHash8("sha256").update(recoveryRaw).digest("hex");
36989
39225
  const unresolvedAttemptIds = Object.keys(backupAttempts).filter((attemptId) => !existingTransaction?.cleanup_confirmed_attempt_ids.includes(attemptId) && !initialAttempts[attemptId]?.cleanupConfirmed);
36990
39226
  const binary = unresolvedAttemptIds.length > 0 ? await (dependencies.resolveBinary ?? resolvePinnedCodexBinary)(env) : null;
36991
39227
  let activeTransaction = existingTransaction;
@@ -37024,7 +39260,7 @@ Waiting for approval...
37024
39260
  codexRecoveryPath(config2),
37025
39261
  "Codex attempt recovery file"
37026
39262
  );
37027
- if (currentRaw === null || recoverySha256 === null || createHash7("sha256").update(currentRaw).digest("hex") !== recoverySha256) {
39263
+ if (currentRaw === null || recoverySha256 === null || createHash8("sha256").update(currentRaw).digest("hex") !== recoverySha256) {
37028
39264
  throw new Error("Codex recovery evidence changed while the service was stopping.");
37029
39265
  }
37030
39266
  const proof = await (dependencies.proveCodexQuiescence ?? proveCodexSameBootQuiescence)({
@@ -37113,7 +39349,7 @@ Waiting for approval...
37113
39349
  serviceRecoveryTransactionPath(config2),
37114
39350
  "Inference-host service recovery transaction"
37115
39351
  );
37116
- await rm6(backupPath, { force: true });
39352
+ await rm7(backupPath, { force: true });
37117
39353
  }
37118
39354
  }
37119
39355
  } finally {
@@ -37194,7 +39430,8 @@ Waiting for approval...
37194
39430
  const displayName = resolveDurableServiceDisplayName(parsed, dependencies);
37195
39431
  if (adapter !== "codex") {
37196
39432
  const prepared = await (dependencies.prepareDurableAdapter ?? preparePortableDurableAdapter)(
37197
- adapter
39433
+ adapter,
39434
+ config2
37198
39435
  );
37199
39436
  try {
37200
39437
  const status2 = await manager.install({
@@ -37381,11 +39618,11 @@ Waiting for approval...
37381
39618
  });
37382
39619
 
37383
39620
  // lib/agent-core/config.ts
37384
- import { mkdir as mkdir5, readFile as readFile6, rm as rm7, writeFile as writeFile3 } from "node:fs/promises";
37385
- import { dirname as dirname5, join as join8 } from "node:path";
39621
+ import { mkdir as mkdir5, readFile as readFile6, rm as rm8, writeFile as writeFile3 } from "node:fs/promises";
39622
+ import { dirname as dirname6, join as join9 } from "node:path";
37386
39623
  import { homedir as homedir3 } from "node:os";
37387
39624
  function defaultBaseDir() {
37388
- return join8(homedir3(), ".vtx");
39625
+ return join9(homedir3(), ".vtx");
37389
39626
  }
37390
39627
  function resolveAgentCliConfig(env = process.env) {
37391
39628
  const baseDir = String(env.VTX_HOME || "").trim() || defaultBaseDir();
@@ -37393,8 +39630,8 @@ function resolveAgentCliConfig(env = process.env) {
37393
39630
  const parsedProfile = rawProfile ? Number(rawProfile) : NaN;
37394
39631
  return {
37395
39632
  apiUrl: String(env.VTX_API_URL || "http://localhost:8000").replace(/\/+$/, ""),
37396
- tokenPath: String(env.VTX_TOKEN_PATH || "").trim() || join8(baseDir, "token.json"),
37397
- statePath: String(env.VTX_RUNTIME_STATE_PATH || "").trim() || join8(baseDir, "runtime-state.json"),
39633
+ tokenPath: String(env.VTX_TOKEN_PATH || "").trim() || join9(baseDir, "token.json"),
39634
+ statePath: String(env.VTX_RUNTIME_STATE_PATH || "").trim() || join9(baseDir, "runtime-state.json"),
37398
39635
  runtimeDeviceId: String(env.VTX_RUNTIME_DEVICE_ID || "").trim() || null,
37399
39636
  activeProfileId: Number.isFinite(parsedProfile) && parsedProfile > 0 ? parsedProfile : null,
37400
39637
  outputJson: String(env.VTX_OUTPUT || "").trim().toLowerCase() === "json"
@@ -37420,12 +39657,12 @@ async function readStoredAgentAuth(path) {
37420
39657
  }
37421
39658
  }
37422
39659
  async function writeStoredAgentAuth(path, auth) {
37423
- await mkdir5(dirname5(path), { recursive: true });
39660
+ await mkdir5(dirname6(path), { recursive: true });
37424
39661
  await writeFile3(path, `${JSON.stringify(auth, null, 2)}
37425
39662
  `, { encoding: "utf8", mode: 384 });
37426
39663
  }
37427
39664
  async function clearStoredAgentAuth(path) {
37428
- await rm7(path, { force: true });
39665
+ await rm8(path, { force: true });
37429
39666
  }
37430
39667
  async function readRuntimeState(path) {
37431
39668
  try {
@@ -37455,12 +39692,12 @@ async function readRuntimeState(path) {
37455
39692
  }
37456
39693
  }
37457
39694
  async function writeRuntimeState(path, state) {
37458
- await mkdir5(dirname5(path), { recursive: true });
39695
+ await mkdir5(dirname6(path), { recursive: true });
37459
39696
  await writeFile3(path, `${JSON.stringify(state, null, 2)}
37460
39697
  `, { encoding: "utf8", mode: 384 });
37461
39698
  }
37462
39699
  async function clearRuntimeState(path) {
37463
- await rm7(path, { force: true });
39700
+ await rm8(path, { force: true });
37464
39701
  }
37465
39702
  var init_config2 = __esm({
37466
39703
  "lib/agent-core/config.ts"() {
@@ -37486,7 +39723,7 @@ var init_types = __esm({
37486
39723
  });
37487
39724
 
37488
39725
  // lib/agent-core/client.ts
37489
- import { randomUUID as randomUUID4 } from "node:crypto";
39726
+ import { randomUUID as randomUUID6 } from "node:crypto";
37490
39727
  function normalizeApiUrl(value) {
37491
39728
  const parsed = String(value || "").trim();
37492
39729
  if (!parsed) {
@@ -37748,7 +39985,7 @@ var init_client = __esm({
37748
39985
  return this.request("/trading/ai/runtime/decision", {
37749
39986
  method: "POST",
37750
39987
  profileId,
37751
- idempotencyKey: randomUUID4(),
39988
+ idempotencyKey: randomUUID6(),
37752
39989
  headers: { "x-client-runtime-lease": leaseToken },
37753
39990
  body: payload
37754
39991
  });
@@ -37757,7 +39994,7 @@ var init_client = __esm({
37757
39994
  return this.request("/trading/ai/runtime/trade-sync", {
37758
39995
  method: "POST",
37759
39996
  profileId,
37760
- idempotencyKey: randomUUID4(),
39997
+ idempotencyKey: randomUUID6(),
37761
39998
  headers: { "x-client-runtime-lease": leaseToken },
37762
39999
  body: payload
37763
40000
  });
@@ -37766,7 +40003,7 @@ var init_client = __esm({
37766
40003
  return this.request("/trading/ai/runtime/error", {
37767
40004
  method: "POST",
37768
40005
  profileId,
37769
- idempotencyKey: randomUUID4(),
40006
+ idempotencyKey: randomUUID6(),
37770
40007
  headers: { "x-client-runtime-lease": leaseToken },
37771
40008
  body: payload
37772
40009
  });
@@ -37778,7 +40015,7 @@ var init_client = __esm({
37778
40015
  return this.request("/trading/market-order", {
37779
40016
  method: "POST",
37780
40017
  profileId,
37781
- idempotencyKey: randomUUID4(),
40018
+ idempotencyKey: randomUUID6(),
37782
40019
  body: payload
37783
40020
  });
37784
40021
  }
@@ -37786,7 +40023,7 @@ var init_client = __esm({
37786
40023
  return this.request("/trading/limit-order", {
37787
40024
  method: "POST",
37788
40025
  profileId,
37789
- idempotencyKey: randomUUID4(),
40026
+ idempotencyKey: randomUUID6(),
37790
40027
  body: payload
37791
40028
  });
37792
40029
  }
@@ -37794,7 +40031,7 @@ var init_client = __esm({
37794
40031
  return this.request("/trading/cancel-order", {
37795
40032
  method: "POST",
37796
40033
  profileId,
37797
- idempotencyKey: randomUUID4(),
40034
+ idempotencyKey: randomUUID6(),
37798
40035
  body: payload
37799
40036
  });
37800
40037
  }
@@ -37813,7 +40050,7 @@ var init_client = __esm({
37813
40050
  return this.request("/trading/ai/start", {
37814
40051
  method: "POST",
37815
40052
  profileId,
37816
- idempotencyKey: randomUUID4(),
40053
+ idempotencyKey: randomUUID6(),
37817
40054
  body: payload
37818
40055
  });
37819
40056
  }
@@ -37821,7 +40058,7 @@ var init_client = __esm({
37821
40058
  return this.request("/trading/ai/stop", {
37822
40059
  method: "POST",
37823
40060
  profileId,
37824
- idempotencyKey: randomUUID4(),
40061
+ idempotencyKey: randomUUID6(),
37825
40062
  body: {}
37826
40063
  });
37827
40064
  }
@@ -37829,7 +40066,7 @@ var init_client = __esm({
37829
40066
  return this.request("/trading/ai/assistant/start", {
37830
40067
  method: "POST",
37831
40068
  profileId,
37832
- idempotencyKey: randomUUID4(),
40069
+ idempotencyKey: randomUUID6(),
37833
40070
  body: {}
37834
40071
  });
37835
40072
  }
@@ -37837,7 +40074,7 @@ var init_client = __esm({
37837
40074
  return this.request("/trading/ai/assistant/stop", {
37838
40075
  method: "POST",
37839
40076
  profileId,
37840
- idempotencyKey: randomUUID4(),
40077
+ idempotencyKey: randomUUID6(),
37841
40078
  body: {}
37842
40079
  });
37843
40080
  }
@@ -37845,7 +40082,7 @@ var init_client = __esm({
37845
40082
  return this.request("/trading/ai/runtime/session/start", {
37846
40083
  method: "POST",
37847
40084
  profileId,
37848
- idempotencyKey: randomUUID4(),
40085
+ idempotencyKey: randomUUID6(),
37849
40086
  body: payload
37850
40087
  });
37851
40088
  }
@@ -37856,7 +40093,7 @@ var init_client = __esm({
37856
40093
  return this.request("/trading/ai/runtime/session/stop", {
37857
40094
  method: "POST",
37858
40095
  profileId,
37859
- idempotencyKey: randomUUID4(),
40096
+ idempotencyKey: randomUUID6(),
37860
40097
  body: payload
37861
40098
  });
37862
40099
  }
@@ -37873,7 +40110,7 @@ var init_client = __esm({
37873
40110
  }).request("/trading/ai/runtime/session/stop", {
37874
40111
  method: "POST",
37875
40112
  profileId,
37876
- idempotencyKey: randomUUID4(),
40113
+ idempotencyKey: randomUUID6(),
37877
40114
  body: payload
37878
40115
  });
37879
40116
  }
@@ -37890,8 +40127,8 @@ import {
37890
40127
  unlinkSync,
37891
40128
  writeFileSync
37892
40129
  } from "node:fs";
37893
- import { randomUUID as randomUUID5 } from "node:crypto";
37894
- import { dirname as dirname6 } from "node:path";
40130
+ import { randomUUID as randomUUID7 } from "node:crypto";
40131
+ import { dirname as dirname7 } from "node:path";
37895
40132
  var parseStoredValues, FileBackedProtectionStorage, clientRuntimeProtectionStatePath;
37896
40133
  var init_protection_storage = __esm({
37897
40134
  "lib/agent-core/protection-storage.ts"() {
@@ -37944,10 +40181,10 @@ var init_protection_storage = __esm({
37944
40181
  }
37945
40182
  }
37946
40183
  writeValues(values) {
37947
- mkdirSync(dirname6(this.path), { recursive: true, mode: 448 });
40184
+ mkdirSync(dirname7(this.path), { recursive: true, mode: 448 });
37948
40185
  const serialized = `${JSON.stringify(values)}
37949
40186
  `;
37950
- const temporaryPath = `${this.path}.${process.pid}.${randomUUID5()}.tmp`;
40187
+ const temporaryPath = `${this.path}.${process.pid}.${randomUUID7()}.tmp`;
37951
40188
  try {
37952
40189
  writeFileSync(temporaryPath, serialized, {
37953
40190
  encoding: "utf8",
@@ -37974,7 +40211,7 @@ var init_protection_storage = __esm({
37974
40211
  });
37975
40212
 
37976
40213
  // lib/agent-core/headless-runtime.ts
37977
- import { randomUUID as randomUUID6 } from "node:crypto";
40214
+ import { randomUUID as randomUUID8 } from "node:crypto";
37978
40215
  import { setTimeout as sleep } from "node:timers/promises";
37979
40216
  function objectOrNull2(value) {
37980
40217
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
@@ -38072,8 +40309,8 @@ async function runAndReportLocalWorkCycle(options, state, leaseToken, context) {
38072
40309
  return Boolean(result2.decision || tradeSync || result2.afterDecision);
38073
40310
  }
38074
40311
  async function startHeadlessRuntime(options) {
38075
- const runtimeSessionId = randomUUID6();
38076
- const deviceId = String(options.deviceId || "").trim() || randomUUID6();
40312
+ const runtimeSessionId = randomUUID8();
40313
+ const deviceId = String(options.deviceId || "").trim() || randomUUID8();
38077
40314
  const startResponse = await options.client.startRuntime(options.profileId, {
38078
40315
  session_id: runtimeSessionId,
38079
40316
  device_id: deviceId,
@@ -42758,8 +44995,8 @@ var init_rlp_encode = __esm({
42758
44995
  });
42759
44996
 
42760
44997
  // node_modules/ethers/lib.esm/utils/uuid.js
42761
- function uuidV4(randomBytes8) {
42762
- const bytes3 = getBytes(randomBytes8, "randomBytes");
44998
+ function uuidV4(randomBytes9) {
44999
+ const bytes3 = getBytes(randomBytes9, "randomBytes");
42763
45000
  bytes3[6] = bytes3[6] & 15 | 64;
42764
45001
  bytes3[8] = bytes3[8] & 63 | 128;
42765
45002
  const value = hexlify(bytes3);
@@ -42793,7 +45030,7 @@ var init_utils = __esm({
42793
45030
  });
42794
45031
 
42795
45032
  // node_modules/ethers/lib.esm/crypto/crypto.js
42796
- import { createHash as createHash8, createHmac, pbkdf2Sync, randomBytes as randomBytes5 } from "crypto";
45033
+ import { createHash as createHash9, createHmac, pbkdf2Sync, randomBytes as randomBytes6 } from "crypto";
42797
45034
  var init_crypto2 = __esm({
42798
45035
  "node_modules/ethers/lib.esm/crypto/crypto.js"() {
42799
45036
  }
@@ -43447,7 +45684,7 @@ var init_pbkdf2 = __esm({
43447
45684
  });
43448
45685
 
43449
45686
  // node_modules/ethers/lib.esm/crypto/random.js
43450
- function randomBytes6(length) {
45687
+ function randomBytes7(length) {
43451
45688
  return __randomBytes(length);
43452
45689
  }
43453
45690
  var locked5, _randomBytes, __randomBytes;
@@ -43456,20 +45693,20 @@ var init_random = __esm({
43456
45693
  init_crypto2();
43457
45694
  locked5 = false;
43458
45695
  _randomBytes = function(length) {
43459
- return new Uint8Array(randomBytes5(length));
45696
+ return new Uint8Array(randomBytes6(length));
43460
45697
  };
43461
45698
  __randomBytes = _randomBytes;
43462
- randomBytes6._ = _randomBytes;
43463
- randomBytes6.lock = function() {
45699
+ randomBytes7._ = _randomBytes;
45700
+ randomBytes7.lock = function() {
43464
45701
  locked5 = true;
43465
45702
  };
43466
- randomBytes6.register = function(func) {
45703
+ randomBytes7.register = function(func) {
43467
45704
  if (locked5) {
43468
45705
  throw new Error("randomBytes is locked");
43469
45706
  }
43470
45707
  __randomBytes = func;
43471
45708
  };
43472
- Object.freeze(randomBytes6);
45709
+ Object.freeze(randomBytes7);
43473
45710
  }
43474
45711
  });
43475
45712
 
@@ -44007,10 +46244,10 @@ var init_sha22 = __esm({
44007
46244
  init_crypto2();
44008
46245
  init_utils();
44009
46246
  _sha256 = function(data) {
44010
- return createHash8("sha256").update(data).digest();
46247
+ return createHash9("sha256").update(data).digest();
44011
46248
  };
44012
46249
  _sha512 = function(data) {
44013
- return createHash8("sha512").update(data).digest();
46250
+ return createHash9("sha512").update(data).digest();
44014
46251
  };
44015
46252
  __sha256 = _sha256;
44016
46253
  __sha512 = _sha512;
@@ -44117,7 +46354,7 @@ function wrapConstructor2(hashCons) {
44117
46354
  hashC.create = () => hashCons();
44118
46355
  return hashC;
44119
46356
  }
44120
- function randomBytes7(bytesLength = 32) {
46357
+ function randomBytes8(bytesLength = 32) {
44121
46358
  if (crypto2 && typeof crypto2.getRandomValues === "function") {
44122
46359
  return crypto2.getRandomValues(new Uint8Array(bytesLength));
44123
46360
  }
@@ -45656,7 +47893,7 @@ function weierstrass(curveDef) {
45656
47893
  function prepSig(msgHash, privateKey, opts = defaultSigOpts) {
45657
47894
  if (["recovered", "canonical"].some((k) => k in opts))
45658
47895
  throw new Error("sign() legacy options not supported");
45659
- const { hash: hash4, randomBytes: randomBytes8 } = CURVE;
47896
+ const { hash: hash4, randomBytes: randomBytes9 } = CURVE;
45660
47897
  let { lowS, prehash, extraEntropy: ent } = opts;
45661
47898
  if (lowS == null)
45662
47899
  lowS = true;
@@ -45667,7 +47904,7 @@ function weierstrass(curveDef) {
45667
47904
  const d = normPrivateKeyToScalar(privateKey);
45668
47905
  const seedArgs = [int2octets(d), int2octets(h1int)];
45669
47906
  if (ent != null) {
45670
- const e = ent === true ? randomBytes8(Fp2.BYTES) : ent;
47907
+ const e = ent === true ? randomBytes9(Fp2.BYTES) : ent;
45671
47908
  seedArgs.push(ensureBytes("extraEntropy", e));
45672
47909
  }
45673
47910
  const seed = concatBytes2(...seedArgs);
@@ -45904,7 +48141,7 @@ function getHash(hash4) {
45904
48141
  return {
45905
48142
  hash: hash4,
45906
48143
  hmac: (key, ...msgs) => hmac2(hash4, key, concatBytes(...msgs)),
45907
- randomBytes: randomBytes7
48144
+ randomBytes: randomBytes8
45908
48145
  };
45909
48146
  }
45910
48147
  function createCurve(curveDef, defHash) {
@@ -49878,7 +52115,7 @@ async function decryptKeystoreJson(json2, _password, progress) {
49878
52115
  return getAccount(data, key);
49879
52116
  }
49880
52117
  function getEncryptKdfParams(options) {
49881
- const salt = options.salt != null ? getBytes(options.salt, "options.salt") : randomBytes6(32);
52118
+ const salt = options.salt != null ? getBytes(options.salt, "options.salt") : randomBytes7(32);
49882
52119
  let N2 = 1 << 17, r = 8, p = 1;
49883
52120
  if (options.scrypt) {
49884
52121
  if (options.scrypt.N) {
@@ -49898,9 +52135,9 @@ function getEncryptKdfParams(options) {
49898
52135
  }
49899
52136
  function _encryptKeystore(key, kdf, account, options) {
49900
52137
  const privateKey = getBytes(account.privateKey, "privateKey");
49901
- const iv = options.iv != null ? getBytes(options.iv, "options.iv") : randomBytes6(16);
52138
+ const iv = options.iv != null ? getBytes(options.iv, "options.iv") : randomBytes7(16);
49902
52139
  assertArgument(iv.length === 16, "invalid options.iv length", "options.iv", options.iv);
49903
- const uuidRandom = options.uuid != null ? getBytes(options.uuid, "options.uuid") : randomBytes6(16);
52140
+ const uuidRandom = options.uuid != null ? getBytes(options.uuid, "options.uuid") : randomBytes7(16);
49904
52141
  assertArgument(uuidRandom.length === 16, "invalid options.uuid length", "options.uuid", options.iv);
49905
52142
  const derivedKey = key.slice(0, 16);
49906
52143
  const macPrefix = key.slice(16, 32);
@@ -49934,7 +52171,7 @@ function _encryptKeystore(key, kdf, account, options) {
49934
52171
  const locale = account.mnemonic.locale || "en";
49935
52172
  const mnemonicKey = key.slice(32, 64);
49936
52173
  const entropy = getBytes(account.mnemonic.entropy, "account.mnemonic.entropy");
49937
- const mnemonicIv = randomBytes6(16);
52174
+ const mnemonicIv = randomBytes7(16);
49938
52175
  const mnemonicAesCtr = new CTR(mnemonicKey, mnemonicIv);
49939
52176
  const mnemonicCiphertext = getBytes(mnemonicAesCtr.encrypt(entropy));
49940
52177
  const now = /* @__PURE__ */ new Date();
@@ -50272,7 +52509,7 @@ var init_hdwallet = __esm({
50272
52509
  if (wordlist2 == null) {
50273
52510
  wordlist2 = LangEn.wordlist();
50274
52511
  }
50275
- const mnemonic = Mnemonic.fromEntropy(randomBytes6(16), password, wordlist2);
52512
+ const mnemonic = Mnemonic.fromEntropy(randomBytes7(16), password, wordlist2);
50276
52513
  return _HDNodeWallet.#fromSeed(mnemonic.computeSeed(), mnemonic).derivePath(path);
50277
52514
  }
50278
52515
  /**
@@ -60625,7 +62862,7 @@ var headless_local_worker_exports = {};
60625
62862
  __export(headless_local_worker_exports, {
60626
62863
  createHeadlessLocalWorker: () => createHeadlessLocalWorker
60627
62864
  });
60628
- import { randomUUID as randomUUID7 } from "node:crypto";
62865
+ import { randomUUID as randomUUID9 } from "node:crypto";
60629
62866
  function objectOrNull3(value) {
60630
62867
  return value && typeof value === "object" && !Array.isArray(value) ? value : null;
60631
62868
  }
@@ -61042,7 +63279,7 @@ function createHeadlessLocalWorker(options) {
61042
63279
  const statusMatch = errorText.match(/\b([45]\d{2})\b/);
61043
63280
  const statusCode = statusMatch ? Number(statusMatch[1]) : null;
61044
63281
  const failedInvocation = normalizeAiInvocationTelemetry({
61045
- client_invocation_id: randomUUID7(),
63282
+ client_invocation_id: randomUUID9(),
61046
63283
  use_case: "trader",
61047
63284
  role: "primary",
61048
63285
  attempt_index: 0,
@@ -61098,7 +63335,7 @@ function createHeadlessLocalWorker(options) {
61098
63335
  billable_cached_input_tokens: normalizedUsage.cached_input_tokens
61099
63336
  };
61100
63337
  const invocation = normalizeAiInvocationTelemetry({
61101
- client_invocation_id: randomUUID7(),
63338
+ client_invocation_id: randomUUID9(),
61102
63339
  use_case: "trader",
61103
63340
  role: "primary",
61104
63341
  attempt_index: 0,
@@ -61317,7 +63554,7 @@ var vtx_exports = {};
61317
63554
  __export(vtx_exports, {
61318
63555
  runVtxCli: () => runVtxCli
61319
63556
  });
61320
- import { randomUUID as randomUUID8 } from "node:crypto";
63557
+ import { randomUUID as randomUUID10 } from "node:crypto";
61321
63558
  import { spawn as spawn8 } from "node:child_process";
61322
63559
  function render2(value, json2) {
61323
63560
  if (json2) {
@@ -61731,8 +63968,8 @@ async function runVtxCli(argv2, env = process.env) {
61731
63968
  });
61732
63969
  return { exitCode: 0, stdout: render2(redactCliOutput(response2), json2), stderr: "" };
61733
63970
  }
61734
- const runtimeSessionId = randomUUID8();
61735
- const deviceId = config2.runtimeDeviceId ?? randomUUID8();
63971
+ const runtimeSessionId = randomUUID10();
63972
+ const deviceId = config2.runtimeDeviceId ?? randomUUID10();
61736
63973
  const response = await client.startRuntime(profileId, {
61737
63974
  session_id: runtimeSessionId,
61738
63975
  device_id: deviceId,