@vtxmacro/cli 2026.8.40 → 2026.8.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -13
- package/bin/vtx.js +572 -71
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -10,9 +10,9 @@ vtx --version
|
|
|
10
10
|
```
|
|
11
11
|
|
|
12
12
|
The host supports Windows x64 and Linux x64, including WSL. The package installs
|
|
13
|
-
the exact supported OpenAI Codex runtime
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
the exact supported OpenAI Codex runtime and GitHub Copilot SDK. The VTX host
|
|
14
|
+
verifies the Codex runtime's version and digest before use; it does not borrow a
|
|
15
|
+
Codex binary from PATH or an editor extension.
|
|
16
16
|
For Windows-login auto-start, install and configure the CLI from native Windows;
|
|
17
17
|
a CLI installed only inside WSL cannot start the WSL virtual machine at login.
|
|
18
18
|
An npm update does not replace code already loaded by a running durable service.
|
|
@@ -52,7 +52,15 @@ Both paths use a separate least-privilege `insights:inference` OAuth grant.
|
|
|
52
52
|
VTX never receives an agent vendor password, OAuth token, or subscription
|
|
53
53
|
credential.
|
|
54
54
|
|
|
55
|
-
###
|
|
55
|
+
### Durable subscription hosts
|
|
56
|
+
|
|
57
|
+
Codex remains the reference implementation and its existing App Server,
|
|
58
|
+
authentication, quota, recovery, and provider-mode path are unchanged. GitHub
|
|
59
|
+
Copilot is an additive preview adapter that uses the official SDK and validates
|
|
60
|
+
final text against VTX's immutable schema. An uncertain interrupted Copilot call
|
|
61
|
+
is quarantined as `outcome_unknown` and is never blindly repeated. A different
|
|
62
|
+
adapter cannot replace an installed Codex instance; it needs a distinct instance
|
|
63
|
+
and VTX grant.
|
|
56
64
|
|
|
57
65
|
Before the first Codex login, enable **Device code authorization for Codex** in
|
|
58
66
|
ChatGPT Security settings. Only enter a device code from a login you initiated,
|
|
@@ -80,6 +88,14 @@ vtx inference-host codex-logout
|
|
|
80
88
|
vtx inference-host revoke
|
|
81
89
|
```
|
|
82
90
|
|
|
91
|
+
For Copilot, sign in with the official Copilot CLI, then run:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
vtx inference-host login --instance copilot-1
|
|
95
|
+
vtx inference-host doctor --adapter copilot --instance copilot-1 --json
|
|
96
|
+
vtx inference-host service install --adapter copilot --instance copilot-1
|
|
97
|
+
```
|
|
98
|
+
|
|
83
99
|
To connect another Codex subscription to the same VTX account, repeat the
|
|
84
100
|
login and service-install commands with a stable local name such as
|
|
85
101
|
`--instance codex-2`. Each named instance has an isolated VTX grant, Codex
|
|
@@ -121,10 +137,10 @@ capacity beyond the authenticated account's current entitlement. Updating from
|
|
|
121
137
|
an older bounded host removes its previous numeric limit; run
|
|
122
138
|
`service install --max-concurrency <positive-integer>` only to add one back.
|
|
123
139
|
|
|
124
|
-
|
|
125
|
-
OAuth grant.
|
|
126
|
-
Codex home
|
|
127
|
-
|
|
140
|
+
Every durable host uses a separate least-privilege `insights:inference`
|
|
141
|
+
OAuth grant. Codex additionally keeps its ChatGPT subscription login in a dedicated
|
|
142
|
+
private Codex home; Copilot uses its official cached user login.
|
|
143
|
+
No vendor credential is written to the VTX service manifest. The per-user OS service starts immediately, starts again at login, and
|
|
128
144
|
reconnects after sleep, network loss, or a worker exit. Stopping a VTX bot leaves
|
|
129
145
|
the provider online and idle. Use `vtx inference-host run` only for foreground
|
|
130
146
|
diagnostics. VTX logout/revoke and Codex logout are intentionally separate operations.
|
|
@@ -184,11 +200,11 @@ Use `not_dispatched` only when no harness inference began,
|
|
|
184
200
|
`outcome_unknown` when dispatch itself cannot be confirmed. Pipe exactly one
|
|
185
201
|
object to `vtx inference-host agent-fail --json`.
|
|
186
202
|
|
|
187
|
-
Claude Code,
|
|
188
|
-
explicit foreground agent loop. Their
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
durability.
|
|
203
|
+
Claude Code, Kiro, Grok Build, Cursor, Amp, Auggie, Junie, and Warp/Oz remain on
|
|
204
|
+
the explicit foreground agent loop. Their current subscription routing,
|
|
205
|
+
effective-model identity, schema, usage, or crash-recovery contracts do not yet
|
|
206
|
+
meet every durable VTX acceptance fence. The public Insights matrix records the
|
|
207
|
+
specific limitation instead of treating headless support alone as durability.
|
|
192
208
|
|
|
193
209
|
Keep `agent-run` open in a separate terminal and keep calling `agent-next`
|
|
194
210
|
while the host should remain available. The independent keeper preserves
|
package/bin/vtx.js
CHANGED
|
@@ -38,9 +38,13 @@ var init_agent_cli_release = __esm({
|
|
|
38
38
|
"agent-cli-release.json"() {
|
|
39
39
|
agent_cli_release_default = {
|
|
40
40
|
package_name: "@vtxmacro/cli",
|
|
41
|
-
package_version: "2026.8.
|
|
41
|
+
package_version: "2026.8.42",
|
|
42
42
|
codex_package_name: "@openai/codex",
|
|
43
43
|
codex_version: "0.147.0",
|
|
44
|
+
copilot_sdk_package_name: "@github/copilot-sdk",
|
|
45
|
+
copilot_sdk_version: "1.0.0-beta.8",
|
|
46
|
+
copilot_cli_package_name: "@github/copilot",
|
|
47
|
+
copilot_cli_version: "1.0.80",
|
|
44
48
|
platforms: {
|
|
45
49
|
"linux-x64": {
|
|
46
50
|
package_name: "@openai/codex-linux-x64",
|
|
@@ -14725,6 +14729,7 @@ var init_external_inference_contract = __esm({
|
|
|
14725
14729
|
key_generation: generationSchema,
|
|
14726
14730
|
adapter: externalInferenceAdapterIdSchema,
|
|
14727
14731
|
display_name: displayNameSchema,
|
|
14732
|
+
authenticated_account_identity: safeCodeSchema.nullable().optional(),
|
|
14728
14733
|
authenticated_account_email: authenticatedAccountEmailSchema.nullable().optional(),
|
|
14729
14734
|
authenticated_account_plan: safeCodeSchema.nullable().optional(),
|
|
14730
14735
|
protocol_version: protocolVersionSchema,
|
|
@@ -15644,6 +15649,7 @@ var init_external_inference_contract = __esm({
|
|
|
15644
15649
|
hostStatusReadSchema = external_exports.strictObject({
|
|
15645
15650
|
host_id: identifierSchema,
|
|
15646
15651
|
display_name: displayNameSchema,
|
|
15652
|
+
authenticated_account_identity: safeCodeSchema.nullable().optional(),
|
|
15647
15653
|
authenticated_account_email: authenticatedAccountEmailSchema.nullable().optional(),
|
|
15648
15654
|
authenticated_account_plan: safeCodeSchema.nullable().optional(),
|
|
15649
15655
|
adapter: externalInferenceAdapterIdSchema,
|
|
@@ -18179,7 +18185,7 @@ var init_mcp_client = __esm({
|
|
|
18179
18185
|
if (!host) return invalidBoundResult(name);
|
|
18180
18186
|
if (host.host_id !== request.host_id || host.host_generation !== request.host_generation || host.advertisement_generation !== request.advertisement_generation || host.key_generation !== request.key_generation || request.adapter !== void 0 && host.adapter !== request.adapter) invalidBoundResult(name);
|
|
18181
18187
|
if (name !== "inference.host.heartbeat") {
|
|
18182
|
-
if (host.display_name !== request.display_name || host.authenticated_account_email !== void 0 && host.authenticated_account_email !== null && host.authenticated_account_email !== request.authenticated_account_email || (host.authenticated_account_plan ?? null) !== (request.authenticated_account_plan ?? null) || !exactJson(host.models, request.models) || host.status === "revoked") invalidBoundResult(name);
|
|
18188
|
+
if (host.display_name !== request.display_name || host.authenticated_account_identity !== void 0 && host.authenticated_account_identity !== null && host.authenticated_account_identity !== request.authenticated_account_identity || host.authenticated_account_email !== void 0 && host.authenticated_account_email !== null && host.authenticated_account_email !== request.authenticated_account_email || (host.authenticated_account_plan ?? null) !== (request.authenticated_account_plan ?? null) || !exactJson(host.models, request.models) || host.status === "revoked") invalidBoundResult(name);
|
|
18183
18189
|
return;
|
|
18184
18190
|
}
|
|
18185
18191
|
const expectedStatus = request.status === "healthy" ? "online" : request.status;
|
|
@@ -19478,8 +19484,8 @@ async function preflightCodexSubscription(options) {
|
|
|
19478
19484
|
});
|
|
19479
19485
|
}
|
|
19480
19486
|
const rateLimits = await session.readAccountRateLimits(options.deadlineAtMs, options.signal);
|
|
19481
|
-
const
|
|
19482
|
-
if (
|
|
19487
|
+
const modelCapabilities2 = await session.readModelCapabilities(options.deadlineAtMs, options.signal);
|
|
19488
|
+
if (modelCapabilities2.length === 0) {
|
|
19483
19489
|
throw new CodexAppServerError({
|
|
19484
19490
|
message: "Codex did not return any visible models with supported reasoning efforts.",
|
|
19485
19491
|
category: "model",
|
|
@@ -19491,7 +19497,7 @@ async function preflightCodexSubscription(options) {
|
|
|
19491
19497
|
authenticated_account_email: account.authenticatedChatGptAccount.email,
|
|
19492
19498
|
authenticated_account_plan: account.authenticatedChatGptAccount.planType,
|
|
19493
19499
|
rate_limits: rateLimits,
|
|
19494
|
-
model_capabilities:
|
|
19500
|
+
model_capabilities: modelCapabilities2
|
|
19495
19501
|
};
|
|
19496
19502
|
} finally {
|
|
19497
19503
|
await session.close();
|
|
@@ -22780,6 +22786,317 @@ $items = @(Get-CimInstance Win32_Process | Where-Object { $_.Name -in @('node.ex
|
|
|
22780
22786
|
}
|
|
22781
22787
|
});
|
|
22782
22788
|
|
|
22789
|
+
// lib/inference-host/copilot-adapter.ts
|
|
22790
|
+
import { mkdtemp as mkdtemp2, rm as rm4 } from "node:fs/promises";
|
|
22791
|
+
import { tmpdir as tmpdir3 } from "node:os";
|
|
22792
|
+
import { join as join5 } from "node:path";
|
|
22793
|
+
import { CopilotClient } from "@github/copilot-sdk";
|
|
22794
|
+
var COPILOT_SDK_VERSION, MAX_RESULT_BYTES, createPrivateWorkspace, cleanCopilotEnvironment, defaultClient, modelCapabilities, requiredUsageInteger, optionalUsageInteger, CopilotSubscriptionAdapter;
|
|
22795
|
+
var init_copilot_adapter = __esm({
|
|
22796
|
+
"lib/inference-host/copilot-adapter.ts"() {
|
|
22797
|
+
"use strict";
|
|
22798
|
+
init_codex_app_server();
|
|
22799
|
+
COPILOT_SDK_VERSION = "1.0.0-beta.8";
|
|
22800
|
+
MAX_RESULT_BYTES = 3e5;
|
|
22801
|
+
createPrivateWorkspace = async () => {
|
|
22802
|
+
const path = await mkdtemp2(join5(tmpdir3(), "vtx-copilot-"));
|
|
22803
|
+
return {
|
|
22804
|
+
path,
|
|
22805
|
+
cleanup: async () => {
|
|
22806
|
+
await rm4(path, { recursive: true, force: true });
|
|
22807
|
+
}
|
|
22808
|
+
};
|
|
22809
|
+
};
|
|
22810
|
+
cleanCopilotEnvironment = () => {
|
|
22811
|
+
const environment = { ...process.env };
|
|
22812
|
+
for (const name of [
|
|
22813
|
+
"COPILOT_GITHUB_TOKEN",
|
|
22814
|
+
"GH_TOKEN",
|
|
22815
|
+
"GITHUB_TOKEN",
|
|
22816
|
+
"COPILOT_PROVIDER_API_KEY",
|
|
22817
|
+
"COPILOT_PROVIDER_BASE_URL",
|
|
22818
|
+
"COPILOT_PROVIDER_TYPE",
|
|
22819
|
+
"COPILOT_CLI_PATH",
|
|
22820
|
+
"COPILOT_SDK_AUTH_TOKEN",
|
|
22821
|
+
"COPILOT_CONNECTION_TOKEN",
|
|
22822
|
+
"COPILOT_HOME"
|
|
22823
|
+
]) delete environment[name];
|
|
22824
|
+
return environment;
|
|
22825
|
+
};
|
|
22826
|
+
defaultClient = (workingDirectory) => new CopilotClient({
|
|
22827
|
+
workingDirectory,
|
|
22828
|
+
env: cleanCopilotEnvironment(),
|
|
22829
|
+
useLoggedInUser: true,
|
|
22830
|
+
logLevel: "error"
|
|
22831
|
+
});
|
|
22832
|
+
modelCapabilities = (models) => {
|
|
22833
|
+
const capabilities = models.filter((model) => model.policy?.state !== "disabled" && model.policy?.state !== "unconfigured").flatMap((model) => {
|
|
22834
|
+
const efforts = model.capabilities.supports.reasoningEffort ? [...model.supportedReasoningEfforts ?? []] : ["none"];
|
|
22835
|
+
if (efforts.length === 0) return [];
|
|
22836
|
+
const defaultEffort = model.defaultReasoningEffort && efforts.includes(model.defaultReasoningEffort) ? model.defaultReasoningEffort : efforts[0];
|
|
22837
|
+
return [{
|
|
22838
|
+
id: model.id,
|
|
22839
|
+
model: model.id,
|
|
22840
|
+
displayName: model.name,
|
|
22841
|
+
hidden: false,
|
|
22842
|
+
supportedReasoningEfforts: efforts,
|
|
22843
|
+
defaultReasoningEffort: defaultEffort,
|
|
22844
|
+
isDefault: false
|
|
22845
|
+
}];
|
|
22846
|
+
});
|
|
22847
|
+
return capabilities.map((capability, index) => ({
|
|
22848
|
+
...capability,
|
|
22849
|
+
isDefault: index === 0
|
|
22850
|
+
}));
|
|
22851
|
+
};
|
|
22852
|
+
requiredUsageInteger = (value, field) => {
|
|
22853
|
+
if (!Number.isSafeInteger(value) || Number(value) < 0) {
|
|
22854
|
+
throw new Error(`copilot_usage_${field}_missing`);
|
|
22855
|
+
}
|
|
22856
|
+
return Number(value);
|
|
22857
|
+
};
|
|
22858
|
+
optionalUsageInteger = (value, field) => {
|
|
22859
|
+
if (value === void 0) return 0;
|
|
22860
|
+
if (!Number.isSafeInteger(value) || Number(value) < 0) {
|
|
22861
|
+
throw new Error(`copilot_usage_${field}_invalid`);
|
|
22862
|
+
}
|
|
22863
|
+
return Number(value);
|
|
22864
|
+
};
|
|
22865
|
+
CopilotSubscriptionAdapter = class {
|
|
22866
|
+
constructor(dependencies = {}) {
|
|
22867
|
+
this.inFlight = /* @__PURE__ */ new Map();
|
|
22868
|
+
this.dependencies = dependencies;
|
|
22869
|
+
}
|
|
22870
|
+
async preflight(signal) {
|
|
22871
|
+
const workspace = await (this.dependencies.createWorkspace ?? createPrivateWorkspace)();
|
|
22872
|
+
const client = (this.dependencies.createClient ?? defaultClient)(workspace.path);
|
|
22873
|
+
try {
|
|
22874
|
+
signal?.throwIfAborted();
|
|
22875
|
+
await client.start();
|
|
22876
|
+
const [status, auth, models] = await Promise.all([
|
|
22877
|
+
client.getStatus(),
|
|
22878
|
+
client.getAuthStatus(),
|
|
22879
|
+
client.listModels()
|
|
22880
|
+
]);
|
|
22881
|
+
if (!auth.isAuthenticated || auth.authType !== "user" && auth.authType !== "gh-cli") {
|
|
22882
|
+
throw new CodexAppServerError({
|
|
22883
|
+
message: "GitHub Copilot must use a logged-in Copilot subscription, not BYOK.",
|
|
22884
|
+
category: "auth",
|
|
22885
|
+
code: "copilot_subscription_auth_required",
|
|
22886
|
+
retryable: false
|
|
22887
|
+
});
|
|
22888
|
+
}
|
|
22889
|
+
const accountIdentity = auth.login?.trim().toLowerCase() ?? "";
|
|
22890
|
+
if (!/^[a-z0-9][a-z0-9._-]{0,95}$/u.test(accountIdentity)) {
|
|
22891
|
+
throw new CodexAppServerError({
|
|
22892
|
+
message: "GitHub Copilot did not return a stable authenticated login identity.",
|
|
22893
|
+
category: "auth",
|
|
22894
|
+
code: "copilot_account_identity_required",
|
|
22895
|
+
retryable: false
|
|
22896
|
+
});
|
|
22897
|
+
}
|
|
22898
|
+
const capabilities = modelCapabilities(models);
|
|
22899
|
+
if (capabilities.length === 0) {
|
|
22900
|
+
throw new CodexAppServerError({
|
|
22901
|
+
message: "GitHub Copilot did not return an enabled model catalog.",
|
|
22902
|
+
category: "model",
|
|
22903
|
+
code: "copilot_model_catalog_empty",
|
|
22904
|
+
retryable: false
|
|
22905
|
+
});
|
|
22906
|
+
}
|
|
22907
|
+
return {
|
|
22908
|
+
adapterId: "copilot",
|
|
22909
|
+
runtimeVersion: `${COPILOT_SDK_VERSION}+cli.${status.version}.rpc${status.protocolVersion}`,
|
|
22910
|
+
authenticatedAccountIdentity: accountIdentity,
|
|
22911
|
+
authenticatedAccountEmail: null,
|
|
22912
|
+
authenticatedAccountPlan: null,
|
|
22913
|
+
modelCapabilities: capabilities,
|
|
22914
|
+
rateLimits: null,
|
|
22915
|
+
sameAttemptRecovery: false
|
|
22916
|
+
};
|
|
22917
|
+
} finally {
|
|
22918
|
+
await client.stop().catch(async () => {
|
|
22919
|
+
await client.forceStop();
|
|
22920
|
+
});
|
|
22921
|
+
await workspace.cleanup();
|
|
22922
|
+
}
|
|
22923
|
+
}
|
|
22924
|
+
runAttempt(input) {
|
|
22925
|
+
const active = this.inFlight.get(input.attemptId);
|
|
22926
|
+
if (active) return active;
|
|
22927
|
+
const promise2 = this.executeAttempt(input).finally(() => {
|
|
22928
|
+
if (this.inFlight.get(input.attemptId) === promise2) this.inFlight.delete(input.attemptId);
|
|
22929
|
+
});
|
|
22930
|
+
this.inFlight.set(input.attemptId, promise2);
|
|
22931
|
+
return promise2;
|
|
22932
|
+
}
|
|
22933
|
+
async executeAttempt(input) {
|
|
22934
|
+
const startedAt = (this.dependencies.now ?? Date.now)();
|
|
22935
|
+
const workspace = await (this.dependencies.createWorkspace ?? createPrivateWorkspace)();
|
|
22936
|
+
const client = (this.dependencies.createClient ?? defaultClient)(workspace.path);
|
|
22937
|
+
let session = null;
|
|
22938
|
+
let dispatchEntered = false;
|
|
22939
|
+
let providerReceiptObserved = false;
|
|
22940
|
+
try {
|
|
22941
|
+
input.signal?.throwIfAborted();
|
|
22942
|
+
if (Date.now() >= input.deadlineAtMs) throw new Error("deadline_exceeded");
|
|
22943
|
+
await client.start();
|
|
22944
|
+
session = await client.createSession({
|
|
22945
|
+
clientName: "@vtxmacro/cli durable Copilot inference host",
|
|
22946
|
+
model: input.requestedModel,
|
|
22947
|
+
...input.requestedReasoningEffort === "none" ? {} : { reasoningEffort: input.requestedReasoningEffort },
|
|
22948
|
+
systemMessage: {
|
|
22949
|
+
mode: "replace",
|
|
22950
|
+
content: `${input.systemPrompt}
|
|
22951
|
+
|
|
22952
|
+
Return only one JSON value matching this JSON Schema exactly:
|
|
22953
|
+
${input.outputSchemaJson}`
|
|
22954
|
+
},
|
|
22955
|
+
tools: [],
|
|
22956
|
+
availableTools: [],
|
|
22957
|
+
enableConfigDiscovery: false,
|
|
22958
|
+
enableSessionTelemetry: true,
|
|
22959
|
+
workingDirectory: workspace.path,
|
|
22960
|
+
streaming: true
|
|
22961
|
+
});
|
|
22962
|
+
const usageEvents = [];
|
|
22963
|
+
session.on((event) => {
|
|
22964
|
+
if (event.type === "assistant.usage" && !event.agentId) {
|
|
22965
|
+
providerReceiptObserved = true;
|
|
22966
|
+
usageEvents.push(event);
|
|
22967
|
+
}
|
|
22968
|
+
});
|
|
22969
|
+
const onAbort = () => {
|
|
22970
|
+
void session?.abort().catch(() => void 0);
|
|
22971
|
+
};
|
|
22972
|
+
input.signal?.addEventListener("abort", onAbort, { once: true });
|
|
22973
|
+
dispatchEntered = true;
|
|
22974
|
+
let response;
|
|
22975
|
+
try {
|
|
22976
|
+
response = await session.sendAndWait(
|
|
22977
|
+
{ prompt: input.userPrompt },
|
|
22978
|
+
Math.max(1, input.deadlineAtMs - Date.now())
|
|
22979
|
+
);
|
|
22980
|
+
providerReceiptObserved = true;
|
|
22981
|
+
} finally {
|
|
22982
|
+
input.signal?.removeEventListener("abort", onAbort);
|
|
22983
|
+
}
|
|
22984
|
+
if (!response?.data.content || Buffer.byteLength(response.data.content, "utf8") > MAX_RESULT_BYTES) {
|
|
22985
|
+
throw new Error("copilot_invalid_result");
|
|
22986
|
+
}
|
|
22987
|
+
const observedModels = /* @__PURE__ */ new Set();
|
|
22988
|
+
const observedEfforts = /* @__PURE__ */ new Set();
|
|
22989
|
+
let inputTokens = 0;
|
|
22990
|
+
let cachedInputTokens = 0;
|
|
22991
|
+
let outputTokens = 0;
|
|
22992
|
+
let reasoningOutputTokens = 0;
|
|
22993
|
+
let cacheWriteInputTokens = 0;
|
|
22994
|
+
let cacheWriteSupported = false;
|
|
22995
|
+
let timeToFirstTokenMs = null;
|
|
22996
|
+
let providerCallId = null;
|
|
22997
|
+
for (const event of usageEvents) {
|
|
22998
|
+
if (event.type !== "assistant.usage") continue;
|
|
22999
|
+
observedModels.add(event.data.model);
|
|
23000
|
+
if (event.data.reasoningEffort) observedEfforts.add(event.data.reasoningEffort);
|
|
23001
|
+
inputTokens += requiredUsageInteger(event.data.inputTokens, "input_tokens");
|
|
23002
|
+
cachedInputTokens += optionalUsageInteger(event.data.cacheReadTokens, "cache_read_tokens");
|
|
23003
|
+
outputTokens += requiredUsageInteger(event.data.outputTokens, "output_tokens");
|
|
23004
|
+
reasoningOutputTokens += optionalUsageInteger(event.data.reasoningTokens, "reasoning_tokens");
|
|
23005
|
+
if (event.data.cacheWriteTokens !== void 0) {
|
|
23006
|
+
cacheWriteSupported = true;
|
|
23007
|
+
cacheWriteInputTokens += optionalUsageInteger(
|
|
23008
|
+
event.data.cacheWriteTokens,
|
|
23009
|
+
"cache_write_tokens"
|
|
23010
|
+
);
|
|
23011
|
+
}
|
|
23012
|
+
if (timeToFirstTokenMs === null && Number.isSafeInteger(event.data.timeToFirstTokenMs)) {
|
|
23013
|
+
timeToFirstTokenMs = Number(event.data.timeToFirstTokenMs);
|
|
23014
|
+
}
|
|
23015
|
+
providerCallId = event.data.providerCallId ?? event.data.apiCallId ?? providerCallId;
|
|
23016
|
+
}
|
|
23017
|
+
if (usageEvents.length === 0) {
|
|
23018
|
+
throw new Error("copilot_usage_receipt_missing");
|
|
23019
|
+
}
|
|
23020
|
+
if (response.data.model) observedModels.add(response.data.model);
|
|
23021
|
+
if (observedModels.size !== 1 || !observedModels.has(input.requestedModel)) {
|
|
23022
|
+
throw new Error("copilot_effective_model_mismatch");
|
|
23023
|
+
}
|
|
23024
|
+
const effectiveEffort = input.requestedReasoningEffort === "none" ? observedEfforts.size === 0 ? "none" : observedEfforts.size === 1 ? [...observedEfforts][0] : null : observedEfforts.size === 1 ? [...observedEfforts][0] : null;
|
|
23025
|
+
if (effectiveEffort !== input.requestedReasoningEffort) {
|
|
23026
|
+
throw new Error("copilot_effective_effort_mismatch");
|
|
23027
|
+
}
|
|
23028
|
+
const usage = {
|
|
23029
|
+
inputTokens,
|
|
23030
|
+
cachedInputTokens: Math.min(cachedInputTokens, inputTokens),
|
|
23031
|
+
outputTokens,
|
|
23032
|
+
reasoningOutputTokens: Math.min(reasoningOutputTokens, outputTokens),
|
|
23033
|
+
totalTokens: inputTokens + outputTokens,
|
|
23034
|
+
cacheWriteInputTokens: cacheWriteSupported ? cacheWriteInputTokens : null,
|
|
23035
|
+
cacheWriteSupported
|
|
23036
|
+
};
|
|
23037
|
+
return {
|
|
23038
|
+
text: response.data.content,
|
|
23039
|
+
reasoningContent: response.data.reasoningText ?? null,
|
|
23040
|
+
reasoningSummary: null,
|
|
23041
|
+
requestedModel: input.requestedModel,
|
|
23042
|
+
effectiveModel: input.requestedModel,
|
|
23043
|
+
requestedReasoningEffort: input.requestedReasoningEffort,
|
|
23044
|
+
effectiveReasoningEffort: effectiveEffort,
|
|
23045
|
+
adapterRequestId: providerCallId ?? response.data.requestId ?? response.data.messageId,
|
|
23046
|
+
adapterResponseId: response.data.serviceRequestId ?? response.data.messageId,
|
|
23047
|
+
usage,
|
|
23048
|
+
latencyMs: Math.max(0, (this.dependencies.now ?? Date.now)() - startedAt),
|
|
23049
|
+
timeToFirstTokenMs,
|
|
23050
|
+
terminalStatus: "completed"
|
|
23051
|
+
};
|
|
23052
|
+
} catch (error48) {
|
|
23053
|
+
if (error48 instanceof CodexAppServerError) throw error48;
|
|
23054
|
+
const cancelled = input.signal?.aborted === true;
|
|
23055
|
+
const deadline = Date.now() >= input.deadlineAtMs;
|
|
23056
|
+
if (dispatchEntered && session) {
|
|
23057
|
+
await session.abort().catch(() => void 0);
|
|
23058
|
+
}
|
|
23059
|
+
throw new CodexAppServerError({
|
|
23060
|
+
message: cancelled ? "GitHub Copilot attempt was cancelled." : deadline ? "GitHub Copilot attempt exceeded its immutable deadline." : error48 instanceof Error ? error48.message : "GitHub Copilot adapter failed.",
|
|
23061
|
+
category: cancelled ? "cancelled" : deadline ? "timeout" : "adapter",
|
|
23062
|
+
code: cancelled ? "cancelled" : deadline ? "deadline_exceeded" : "copilot_adapter_failure",
|
|
23063
|
+
retryable: false,
|
|
23064
|
+
dispatchOutcome: providerReceiptObserved ? "confirmed_dispatched" : dispatchEntered ? "outcome_unknown" : "not_dispatched",
|
|
23065
|
+
cause: error48
|
|
23066
|
+
});
|
|
23067
|
+
} finally {
|
|
23068
|
+
if (session) {
|
|
23069
|
+
const sessionId = session.sessionId;
|
|
23070
|
+
await session.disconnect().catch(() => void 0);
|
|
23071
|
+
await client.deleteSession(sessionId).catch(() => void 0);
|
|
23072
|
+
}
|
|
23073
|
+
await client.stop().catch(async () => {
|
|
23074
|
+
await client.forceStop();
|
|
23075
|
+
});
|
|
23076
|
+
await workspace.cleanup();
|
|
23077
|
+
}
|
|
23078
|
+
}
|
|
23079
|
+
};
|
|
23080
|
+
}
|
|
23081
|
+
});
|
|
23082
|
+
|
|
23083
|
+
// lib/inference-host/durable-adapter.ts
|
|
23084
|
+
var DURABLE_INFERENCE_ADAPTER_IDS, isDurableInferenceAdapterId, durableAdapterDisplayName;
|
|
23085
|
+
var init_durable_adapter = __esm({
|
|
23086
|
+
"lib/inference-host/durable-adapter.ts"() {
|
|
23087
|
+
"use strict";
|
|
23088
|
+
DURABLE_INFERENCE_ADAPTER_IDS = [
|
|
23089
|
+
"codex",
|
|
23090
|
+
"copilot"
|
|
23091
|
+
];
|
|
23092
|
+
isDurableInferenceAdapterId = (value) => DURABLE_INFERENCE_ADAPTER_IDS.includes(value);
|
|
23093
|
+
durableAdapterDisplayName = (adapter) => ({
|
|
23094
|
+
codex: "Codex",
|
|
23095
|
+
copilot: "GitHub Copilot"
|
|
23096
|
+
})[adapter];
|
|
23097
|
+
}
|
|
23098
|
+
});
|
|
23099
|
+
|
|
22783
23100
|
// lib/inference-host/crypto.ts
|
|
22784
23101
|
import {
|
|
22785
23102
|
createCipheriv,
|
|
@@ -29371,7 +29688,7 @@ function createDefaultInferenceHostRunnerDependencies(options) {
|
|
|
29371
29688
|
envelopePublicKey: options.envelopePublicKey
|
|
29372
29689
|
};
|
|
29373
29690
|
}
|
|
29374
|
-
var import_ajv, RUNTIME_RECEIPT_SCHEMA_VERSION, ATTEMPT_RECEIPT_SCHEMA_VERSION, DEFAULT_ADVERTISEMENT_TTL_MS, DEFAULT_ADVERTISEMENT_REFRESH_LEAD_MS, DEFAULT_HOST_HEARTBEAT_MS, DEFAULT_PROVIDER_RATE_LIMIT_REFRESH_MS, DEFAULT_ATTEMPT_HEARTBEAT_MS, DEFAULT_DRAIN_TIMEOUT_MS, DEFAULT_REMOTE_RETRY_LIMIT, MIN_SLEEP_MS, DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS, MIN_CLAIM_START_WINDOW_MS, UNBOUNDED_AVAILABLE_SLOTS,
|
|
29691
|
+
var import_ajv, RUNTIME_RECEIPT_SCHEMA_VERSION, ATTEMPT_RECEIPT_SCHEMA_VERSION, DEFAULT_ADVERTISEMENT_TTL_MS, DEFAULT_ADVERTISEMENT_REFRESH_LEAD_MS, DEFAULT_HOST_HEARTBEAT_MS, DEFAULT_PROVIDER_RATE_LIMIT_REFRESH_MS, DEFAULT_ATTEMPT_HEARTBEAT_MS, DEFAULT_DRAIN_TIMEOUT_MS, DEFAULT_REMOTE_RETRY_LIMIT, MIN_SLEEP_MS, DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS, MIN_CLAIM_START_WINDOW_MS, UNBOUNDED_AVAILABLE_SLOTS, buildInferenceAdvertisedModels, summarizeInferenceHostRuntimeRecovery, FileInferenceHostRuntimeReceiptStore, InferenceHostRecoveryRequiredError, InferenceHostRunnerError, defaultSleep, abortError, defaultRegisterSignalHandlers, safeInteger, exactObjectKeys, validIso, validateAttemptReceipt, validateRuntimeReceipt, sha256, stableOperationId, buildAttemptStartRequest, isoAt, providerWeeklyQuotaFromRateLimits, finitePositiveOption, validateRunnerOptions, assertLocalCredentialIdentity, retryableRemoteError, remoteRetryAfterMs, controlPlaneFatal, defaultValidateOutput, objectRecord, positiveUtf8ByteLimit, assertCompilableOutputSchema, parseOutputContract, membershipFailureDisposition, safeFailureCode, exactJson2, runnerIdentityMismatch, assertAdvertisementResult, assertHostHeartbeatResult, assertClaimResult, assertStartResult, assertJobHeartbeatResult, assertTerminalResult, classifyFailure, ambiguousHeartbeatTransport, reportedTokenUsage, reportedUsage, InferenceHostRunner;
|
|
29375
29692
|
var init_runner = __esm({
|
|
29376
29693
|
"lib/inference-host/runner.ts"() {
|
|
29377
29694
|
"use strict";
|
|
@@ -29396,18 +29713,18 @@ var init_runner = __esm({
|
|
|
29396
29713
|
DEFAULT_CODEX_ACCOUNT_COOLDOWN_MS = 5 * 60 * 1e3;
|
|
29397
29714
|
MIN_CLAIM_START_WINDOW_MS = 5e3;
|
|
29398
29715
|
UNBOUNDED_AVAILABLE_SLOTS = Number.MAX_SAFE_INTEGER;
|
|
29399
|
-
|
|
29716
|
+
buildInferenceAdvertisedModels = (capabilities, adapterRuntimeVersion, adapter = "codex", structuredOutput = true, sameAttemptRecovery = adapter === "codex") => {
|
|
29400
29717
|
const visible = capabilities.filter((capability) => !capability.hidden);
|
|
29401
29718
|
if (visible.length === 0 || visible.length > 64) {
|
|
29402
29719
|
throw new InferenceHostRunnerError(
|
|
29403
29720
|
"invalid_configuration",
|
|
29404
|
-
visible.length === 0 ?
|
|
29721
|
+
visible.length === 0 ? `${adapter} did not return any visible models that VTX can advertise.` : `${adapter} returned more models than the VTX advertisement contract can represent.`
|
|
29405
29722
|
);
|
|
29406
29723
|
}
|
|
29407
29724
|
const models = visible.map((capability) => ({
|
|
29408
29725
|
model_id: capability.model,
|
|
29409
29726
|
label: capability.displayName,
|
|
29410
|
-
adapter
|
|
29727
|
+
adapter,
|
|
29411
29728
|
supported_lanes: ["main", "review", "screener"],
|
|
29412
29729
|
supported_reasoning_efforts: [...capability.supportedReasoningEfforts],
|
|
29413
29730
|
default_reasoning_effort: capability.defaultReasoningEffort,
|
|
@@ -29416,14 +29733,14 @@ var init_runner = __esm({
|
|
|
29416
29733
|
requested_model: capability.model,
|
|
29417
29734
|
effective_models: [capability.model]
|
|
29418
29735
|
}],
|
|
29419
|
-
structured_output:
|
|
29420
|
-
same_attempt_recovery:
|
|
29736
|
+
structured_output: structuredOutput,
|
|
29737
|
+
same_attempt_recovery: sameAttemptRecovery,
|
|
29421
29738
|
adapter_runtime_version: adapterRuntimeVersion
|
|
29422
29739
|
}));
|
|
29423
29740
|
if (new Set(models.map((model) => model.model_id)).size !== models.length) {
|
|
29424
29741
|
throw new InferenceHostRunnerError(
|
|
29425
29742
|
"invalid_configuration",
|
|
29426
|
-
|
|
29743
|
+
`${adapter} returned duplicate runtime model identities.`
|
|
29427
29744
|
);
|
|
29428
29745
|
}
|
|
29429
29746
|
return models;
|
|
@@ -29699,6 +30016,10 @@ var init_runner = __esm({
|
|
|
29699
30016
|
return result2;
|
|
29700
30017
|
};
|
|
29701
30018
|
validateRunnerOptions = (options) => {
|
|
30019
|
+
const adapterId = options.adapterId ?? "codex";
|
|
30020
|
+
if (!/^[a-z0-9][a-z0-9._-]{0,63}$/u.test(adapterId)) {
|
|
30021
|
+
throw new InferenceHostRunnerError("invalid_configuration", "Inference adapter ID is invalid.");
|
|
30022
|
+
}
|
|
29702
30023
|
if (!options.displayName.trim() || options.displayName.length > 128) {
|
|
29703
30024
|
throw new InferenceHostRunnerError("invalid_configuration", "Inference host display name is invalid.");
|
|
29704
30025
|
}
|
|
@@ -29722,9 +30043,15 @@ var init_runner = __esm({
|
|
|
29722
30043
|
);
|
|
29723
30044
|
}
|
|
29724
30045
|
return {
|
|
29725
|
-
|
|
30046
|
+
adapterId,
|
|
30047
|
+
usageSource: options.usageSource ?? (adapterId === "codex" ? "codex_app_server" : adapterId),
|
|
30048
|
+
sameAttemptRecovery: options.sameAttemptRecovery ?? adapterId === "codex",
|
|
30049
|
+
advertisedModels: buildInferenceAdvertisedModels(
|
|
29726
30050
|
options.codexModelCapabilities,
|
|
29727
|
-
options.adapterRuntimeVersion
|
|
30051
|
+
options.adapterRuntimeVersion,
|
|
30052
|
+
adapterId,
|
|
30053
|
+
options.structuredOutput ?? adapterId === "codex",
|
|
30054
|
+
options.sameAttemptRecovery ?? adapterId === "codex"
|
|
29728
30055
|
),
|
|
29729
30056
|
maxConcurrency: options.maxConcurrency === null || options.maxConcurrency === void 0 ? null : finitePositiveOption(options.maxConcurrency, 1, "Maximum concurrency"),
|
|
29730
30057
|
advertisementTtlMs,
|
|
@@ -29929,12 +30256,12 @@ var init_runner = __esm({
|
|
|
29929
30256
|
};
|
|
29930
30257
|
assertAdvertisementResult = (advertisement, result2) => {
|
|
29931
30258
|
const host = result2.host;
|
|
29932
|
-
if (host.host_id !== advertisement.host_id || host.host_generation !== advertisement.host_generation || host.advertisement_generation !== advertisement.advertisement_generation || host.key_generation !== advertisement.key_generation || host.display_name !== advertisement.display_name || host.authenticated_account_email !== void 0 && host.authenticated_account_email !== null && host.authenticated_account_email !== advertisement.authenticated_account_email || (host.authenticated_account_plan ?? null) !== (advertisement.authenticated_account_plan ?? null) || host.adapter !== advertisement.adapter || host.status === "revoked" || !exactJson2(host.models, advertisement.models)) runnerIdentityMismatch("Host advertisement");
|
|
30259
|
+
if (host.host_id !== advertisement.host_id || host.host_generation !== advertisement.host_generation || host.advertisement_generation !== advertisement.advertisement_generation || host.key_generation !== advertisement.key_generation || host.display_name !== advertisement.display_name || host.authenticated_account_identity !== void 0 && host.authenticated_account_identity !== null && host.authenticated_account_identity !== advertisement.authenticated_account_identity || host.authenticated_account_email !== void 0 && host.authenticated_account_email !== null && host.authenticated_account_email !== advertisement.authenticated_account_email || (host.authenticated_account_plan ?? null) !== (advertisement.authenticated_account_plan ?? null) || host.adapter !== advertisement.adapter || host.status === "revoked" || !exactJson2(host.models, advertisement.models)) runnerIdentityMismatch("Host advertisement");
|
|
29933
30260
|
};
|
|
29934
|
-
assertHostHeartbeatResult = (request, result2, allowOfflineProjection = false) => {
|
|
30261
|
+
assertHostHeartbeatResult = (request, result2, expectedAdapter, allowOfflineProjection = false) => {
|
|
29935
30262
|
const expectedStatus = request.status === "healthy" ? "online" : request.status;
|
|
29936
30263
|
const expectedTemporaryOffline = allowOfflineProjection && request.status === "healthy" && result2.host.status === "offline";
|
|
29937
|
-
if (result2.host.host_id !== request.host_id || result2.host.host_generation !== request.host_generation || result2.host.advertisement_generation !== request.advertisement_generation || result2.host.key_generation !== request.key_generation || result2.host.adapter !==
|
|
30264
|
+
if (result2.host.host_id !== request.host_id || result2.host.host_generation !== request.host_generation || result2.host.advertisement_generation !== request.advertisement_generation || result2.host.key_generation !== request.key_generation || result2.host.adapter !== expectedAdapter || result2.host.status !== expectedStatus && !expectedTemporaryOffline) runnerIdentityMismatch("Host heartbeat");
|
|
29938
30265
|
};
|
|
29939
30266
|
assertClaimResult = (request, result2) => {
|
|
29940
30267
|
if (result2.claim_request_id !== request.claim_request_id) {
|
|
@@ -30010,10 +30337,10 @@ var init_runner = __esm({
|
|
|
30010
30337
|
"authentication_timeout"
|
|
30011
30338
|
].includes(code);
|
|
30012
30339
|
};
|
|
30013
|
-
reportedTokenUsage = (usage) => ({
|
|
30340
|
+
reportedTokenUsage = (usage, source = "codex_app_server") => ({
|
|
30014
30341
|
schema_version: EXTERNAL_INFERENCE_USAGE_SCHEMA_VERSION,
|
|
30015
30342
|
availability: "reported",
|
|
30016
|
-
source
|
|
30343
|
+
source,
|
|
30017
30344
|
input_tokens: usage.inputTokens,
|
|
30018
30345
|
cached_input_tokens: usage.cachedInputTokens,
|
|
30019
30346
|
output_tokens: usage.outputTokens,
|
|
@@ -30022,7 +30349,7 @@ var init_runner = __esm({
|
|
|
30022
30349
|
cache_write_input_tokens: usage.cacheWriteInputTokens,
|
|
30023
30350
|
cache_write_support: usage.cacheWriteSupported ? "reported" : "unsupported"
|
|
30024
30351
|
});
|
|
30025
|
-
reportedUsage = (result2) => reportedTokenUsage(result2.usage);
|
|
30352
|
+
reportedUsage = (result2, source) => reportedTokenUsage(result2.usage, source);
|
|
30026
30353
|
InferenceHostRunner = class {
|
|
30027
30354
|
constructor(dependencies, options) {
|
|
30028
30355
|
this.receiptWriteChain = Promise.resolve();
|
|
@@ -30252,8 +30579,9 @@ var init_runner = __esm({
|
|
|
30252
30579
|
host_generation: localState.host_generation,
|
|
30253
30580
|
advertisement_generation: generation,
|
|
30254
30581
|
key_generation: localState.key_generation,
|
|
30255
|
-
adapter:
|
|
30582
|
+
adapter: settings.adapterId,
|
|
30256
30583
|
display_name: this.options.displayName.trim(),
|
|
30584
|
+
...this.options.authenticatedAccountIdentity ? { authenticated_account_identity: this.options.authenticatedAccountIdentity } : {},
|
|
30257
30585
|
authenticated_account_email: this.options.authenticatedAccountEmail ?? null,
|
|
30258
30586
|
authenticated_account_plan: this.options.authenticatedAccountPlan ?? null,
|
|
30259
30587
|
protocol_version: this.options.protocolVersion,
|
|
@@ -30362,7 +30690,7 @@ var init_runner = __esm({
|
|
|
30362
30690
|
}
|
|
30363
30691
|
throw error48;
|
|
30364
30692
|
}
|
|
30365
|
-
assertHostHeartbeatResult(request, result2, allowOfflineProjection);
|
|
30693
|
+
assertHostHeartbeatResult(request, result2, settings.adapterId, allowOfflineProjection);
|
|
30366
30694
|
if (result2.host.status === "revoked" || result2.host.status === "offline" && !allowOfflineProjection) {
|
|
30367
30695
|
const error48 = new InferenceHostRunnerError(
|
|
30368
30696
|
result2.host.status === "revoked" ? "host_revoked" : "host_offline",
|
|
@@ -30806,6 +31134,9 @@ var init_runner = __esm({
|
|
|
30806
31134
|
signal,
|
|
30807
31135
|
now
|
|
30808
31136
|
} = options;
|
|
31137
|
+
const adapterId = this.options.adapterId ?? "codex";
|
|
31138
|
+
const usageSource = this.options.usageSource ?? (adapterId === "codex" ? "codex_app_server" : adapterId);
|
|
31139
|
+
const sameAttemptRecovery = this.options.sameAttemptRecovery ?? adapterId === "codex";
|
|
30809
31140
|
const decryptClaim = this.dependencies.decryptClaim ?? decryptExternalInferenceClaim;
|
|
30810
31141
|
const sealCandidate = this.dependencies.sealCandidate ?? sealExternalInferenceCandidate;
|
|
30811
31142
|
const validateOutput = this.dependencies.validateOutput ?? defaultValidateOutput;
|
|
@@ -30982,6 +31313,15 @@ var init_runner = __esm({
|
|
|
30982
31313
|
phase: "dispatched",
|
|
30983
31314
|
dispatch_outcome: "outcome_unknown"
|
|
30984
31315
|
});
|
|
31316
|
+
if (options.resumeReceipt?.phase === "dispatched" && !sameAttemptRecovery) {
|
|
31317
|
+
throw new CodexAppServerError({
|
|
31318
|
+
message: `${adapterId} cannot prove the exact result of the interrupted attempt.`,
|
|
31319
|
+
category: "adapter",
|
|
31320
|
+
code: "same_attempt_recovery_unavailable",
|
|
31321
|
+
retryable: false,
|
|
31322
|
+
dispatchOutcome: "outcome_unknown"
|
|
31323
|
+
});
|
|
31324
|
+
}
|
|
30985
31325
|
adapterResult = await this.dependencies.codexAdapter.runAttempt({
|
|
30986
31326
|
attemptId,
|
|
30987
31327
|
inputSha256: jobInput.input_sha256,
|
|
@@ -31007,7 +31347,7 @@ var init_runner = __esm({
|
|
|
31007
31347
|
} catch (error48) {
|
|
31008
31348
|
throw new InferenceHostRunnerError(
|
|
31009
31349
|
"invalid_structured_output",
|
|
31010
|
-
|
|
31350
|
+
`${adapterId} did not return valid structured JSON.`,
|
|
31011
31351
|
{ cause: error48 }
|
|
31012
31352
|
);
|
|
31013
31353
|
}
|
|
@@ -31019,7 +31359,7 @@ var init_runner = __esm({
|
|
|
31019
31359
|
if (Buffer.byteLength(adapterResult.text, "utf8") > outputContract.providerResponseTextMaxUtf8Bytes) {
|
|
31020
31360
|
throw new InferenceHostRunnerError(
|
|
31021
31361
|
"output_schema_response_text_too_large",
|
|
31022
|
-
|
|
31362
|
+
`${adapterId} response text exceeds the immutable provider-response UTF-8 byte limit.`
|
|
31023
31363
|
);
|
|
31024
31364
|
}
|
|
31025
31365
|
if (outputContract.providerReasoningContentSupported && outputContract.providerReasoningContentMaxUtf8Bytes !== null && adapterResult.reasoningContent !== null && Buffer.byteLength(adapterResult.reasoningContent, "utf8") > outputContract.providerReasoningContentMaxUtf8Bytes) {
|
|
@@ -31092,7 +31432,7 @@ var init_runner = __esm({
|
|
|
31092
31432
|
adapter_request_id: adapterResult.adapterRequestId,
|
|
31093
31433
|
adapter_response_id: adapterResult.adapterResponseId
|
|
31094
31434
|
},
|
|
31095
|
-
usage: reportedUsage(adapterResult),
|
|
31435
|
+
usage: reportedUsage(adapterResult, usageSource),
|
|
31096
31436
|
outcome: {
|
|
31097
31437
|
dispatch_outcome: "confirmed_dispatched",
|
|
31098
31438
|
response_outcome: "completed"
|
|
@@ -31207,7 +31547,7 @@ var init_runner = __esm({
|
|
|
31207
31547
|
adapter_request_id: canReportEffective ? adapterResult?.adapterRequestId ?? null : null,
|
|
31208
31548
|
adapter_response_id: canReportEffective ? adapterResult?.adapterResponseId ?? null : null
|
|
31209
31549
|
},
|
|
31210
|
-
usage: adapterResult ? reportedUsage(adapterResult) : error48 instanceof CodexAppServerError && error48.usage ? reportedTokenUsage(error48.usage) : null,
|
|
31550
|
+
usage: adapterResult ? reportedUsage(adapterResult, usageSource) : error48 instanceof CodexAppServerError && error48.usage ? reportedTokenUsage(error48.usage, usageSource) : null,
|
|
31211
31551
|
failure_category: failure.category,
|
|
31212
31552
|
failure_code: failure.code,
|
|
31213
31553
|
retryable: failure.retryable,
|
|
@@ -31274,7 +31614,7 @@ var init_runner = __esm({
|
|
|
31274
31614
|
if (result2.requestedModel !== jobInput.requested_model || result2.requestedReasoningEffort !== jobInput.requested_reasoning_effort || !mapping?.effective_models.includes(result2.effectiveModel) || !jobInput.allowed_effective_reasoning_efforts.includes(result2.effectiveReasoningEffort)) {
|
|
31275
31615
|
throw new InferenceHostRunnerError(
|
|
31276
31616
|
"effective_model_mismatch",
|
|
31277
|
-
"
|
|
31617
|
+
"The effective adapter model provenance did not match the immutable allowance."
|
|
31278
31618
|
);
|
|
31279
31619
|
}
|
|
31280
31620
|
}
|
|
@@ -31286,13 +31626,14 @@ var init_runner = __esm({
|
|
|
31286
31626
|
import { spawn as spawn6 } from "node:child_process";
|
|
31287
31627
|
import { randomUUID } from "node:crypto";
|
|
31288
31628
|
import { createWriteStream, readFileSync } from "node:fs";
|
|
31289
|
-
import { access as access3, chmod as chmod3, mkdir as mkdir3, readFile as readFile5, rm as
|
|
31629
|
+
import { access as access3, chmod as chmod3, mkdir as mkdir3, readFile as readFile5, rm as rm5, writeFile as writeFile2 } from "node:fs/promises";
|
|
31290
31630
|
import { homedir as homedir2 } from "node:os";
|
|
31291
|
-
import { dirname as dirname4, join as
|
|
31631
|
+
import { dirname as dirname4, join as join6, resolve as resolve4 } from "node:path";
|
|
31292
31632
|
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;
|
|
31293
31633
|
var init_service = __esm({
|
|
31294
31634
|
"lib/inference-host/service.ts"() {
|
|
31295
31635
|
"use strict";
|
|
31636
|
+
init_durable_adapter();
|
|
31296
31637
|
init_config();
|
|
31297
31638
|
SERVICE_NAME = "VTX Macro Inference Host";
|
|
31298
31639
|
SYSTEMD_UNIT = "vtx-inference-host.service";
|
|
@@ -31381,14 +31722,15 @@ var init_service = __esm({
|
|
|
31381
31722
|
throw new Error("Inference-host service worker is invalid.");
|
|
31382
31723
|
}
|
|
31383
31724
|
const record2 = value;
|
|
31384
|
-
if (typeof record2.instance_name !== "string" || !/^[a-z0-9](?:[a-z0-9-]{0,46}[a-z0-9])?$/u.test(record2.instance_name) || record2.adapter !== "
|
|
31725
|
+
if (typeof record2.instance_name !== "string" || !/^[a-z0-9](?:[a-z0-9-]{0,46}[a-z0-9])?$/u.test(record2.instance_name) || typeof record2.adapter !== "string" || !isDurableInferenceAdapterId(record2.adapter) || typeof record2.display_name !== "string" || !record2.display_name || record2.max_concurrency !== null && (!Number.isSafeInteger(record2.max_concurrency) || Number(record2.max_concurrency) < 1) || record2.authenticated_account_email !== null && typeof record2.authenticated_account_email !== "string" || record2.authenticated_account_identity !== void 0 && record2.authenticated_account_identity !== null && typeof record2.authenticated_account_identity !== "string" || record2.authenticated_account_plan !== null && typeof record2.authenticated_account_plan !== "string") {
|
|
31385
31726
|
throw new Error("Inference-host service worker is invalid.");
|
|
31386
31727
|
}
|
|
31387
31728
|
return {
|
|
31388
31729
|
instance_name: record2.instance_name,
|
|
31389
|
-
adapter:
|
|
31730
|
+
adapter: record2.adapter,
|
|
31390
31731
|
display_name: record2.display_name,
|
|
31391
31732
|
max_concurrency: record2.max_concurrency === null ? null : Number(record2.max_concurrency),
|
|
31733
|
+
authenticated_account_identity: record2.authenticated_account_identity,
|
|
31392
31734
|
authenticated_account_email: record2.authenticated_account_email,
|
|
31393
31735
|
authenticated_account_plan: record2.authenticated_account_plan,
|
|
31394
31736
|
runtime_environment: assertRuntimeEnvironment(record2.runtime_environment)
|
|
@@ -31755,8 +32097,8 @@ WantedBy=default.target
|
|
|
31755
32097
|
}
|
|
31756
32098
|
definitionPath() {
|
|
31757
32099
|
if (this.platform === "win32") return `${this.config.supervisorStatePath}.service-task.xml`;
|
|
31758
|
-
if (this.platform === "darwin") return
|
|
31759
|
-
return
|
|
32100
|
+
if (this.platform === "darwin") return join6(this.home, "Library", "LaunchAgents", `${LAUNCHD_LABEL}.plist`);
|
|
32101
|
+
return join6(this.home, ".config", "systemd", "user", SYSTEMD_UNIT);
|
|
31760
32102
|
}
|
|
31761
32103
|
windowsLauncherPath() {
|
|
31762
32104
|
return `${this.config.supervisorStatePath}.service-launcher.vbs`;
|
|
@@ -31938,13 +32280,13 @@ ${cleanup.stderr}`)) {
|
|
|
31938
32280
|
);
|
|
31939
32281
|
}
|
|
31940
32282
|
}
|
|
31941
|
-
await
|
|
32283
|
+
await rm5(this.definitionPath(), { force: true }).catch(() => void 0);
|
|
31942
32284
|
if (this.platform === "win32") {
|
|
31943
|
-
await
|
|
32285
|
+
await rm5(this.windowsLauncherPath(), { force: true }).catch(() => void 0);
|
|
31944
32286
|
}
|
|
31945
|
-
await
|
|
31946
|
-
await
|
|
31947
|
-
await
|
|
32287
|
+
await rm5(this.manifestPath(), { force: true }).catch(() => void 0);
|
|
32288
|
+
await rm5(this.desiredPath(), { force: true }).catch(() => void 0);
|
|
32289
|
+
await rm5(this.runtimePath(), { force: true }).catch(() => void 0);
|
|
31948
32290
|
if (this.platform === "linux") {
|
|
31949
32291
|
await this.runCommand("systemctl", ["--user", "daemon-reload"]).catch(() => void 0);
|
|
31950
32292
|
}
|
|
@@ -32040,18 +32382,31 @@ ${cleanup.stderr}`)) {
|
|
|
32040
32382
|
}
|
|
32041
32383
|
async installUnlocked(options) {
|
|
32042
32384
|
const existing = await readInferenceHostServiceManifest(this.manifestPath());
|
|
32385
|
+
const currentWorker = existing?.workers.find(
|
|
32386
|
+
(worker) => worker.instance_name === this.config.instanceName
|
|
32387
|
+
);
|
|
32388
|
+
if (currentWorker && currentWorker.adapter !== options.adapter) {
|
|
32389
|
+
throw new Error(
|
|
32390
|
+
`Inference-host instance ${this.config.instanceName} is already bound to ${currentWorker.adapter}; install ${options.adapter} under a distinct --instance and VTX grant.`
|
|
32391
|
+
);
|
|
32392
|
+
}
|
|
32043
32393
|
const normalizedEmail = options.authenticatedAccountEmail?.trim().toLowerCase() || null;
|
|
32394
|
+
const normalizedAccountIdentity = options.authenticatedAccountIdentity?.trim().toLowerCase() || null;
|
|
32395
|
+
const normalizedIdentity = normalizedAccountIdentity || normalizedEmail;
|
|
32044
32396
|
const otherWorkers = existing?.workers.filter(
|
|
32045
32397
|
(worker) => worker.instance_name !== this.config.instanceName
|
|
32046
32398
|
) ?? [];
|
|
32047
|
-
|
|
32399
|
+
const peerAdapterWorkers = otherWorkers.filter(
|
|
32400
|
+
(worker) => worker.adapter === options.adapter
|
|
32401
|
+
);
|
|
32402
|
+
if (peerAdapterWorkers.length > 0 && (!normalizedIdentity || peerAdapterWorkers.some((worker) => !(worker.authenticated_account_identity || worker.authenticated_account_email)))) {
|
|
32048
32403
|
throw new Error(
|
|
32049
|
-
|
|
32404
|
+
`Cannot prove that every installed ${options.adapter} instance uses a distinct subscription identity.`
|
|
32050
32405
|
);
|
|
32051
32406
|
}
|
|
32052
|
-
if (
|
|
32407
|
+
if (normalizedIdentity && peerAdapterWorkers.some((worker) => (worker.authenticated_account_identity || worker.authenticated_account_email)?.trim().toLowerCase() === normalizedIdentity)) {
|
|
32053
32408
|
throw new Error(
|
|
32054
|
-
|
|
32409
|
+
`This ${options.adapter} subscription is already installed under another inference-host instance.`
|
|
32055
32410
|
);
|
|
32056
32411
|
}
|
|
32057
32412
|
if (this.config.credentialFilePath && otherWorkers.some((worker) => {
|
|
@@ -32072,6 +32427,7 @@ ${cleanup.stderr}`)) {
|
|
|
32072
32427
|
adapter: options.adapter,
|
|
32073
32428
|
display_name: options.displayName,
|
|
32074
32429
|
max_concurrency: maxConcurrency,
|
|
32430
|
+
...normalizedAccountIdentity ? { authenticated_account_identity: normalizedAccountIdentity } : {},
|
|
32075
32431
|
authenticated_account_email: normalizedEmail,
|
|
32076
32432
|
authenticated_account_plan: options.authenticatedAccountPlan ?? null,
|
|
32077
32433
|
runtime_environment: runtimeEnvironment(this.config, maxConcurrency)
|
|
@@ -32245,12 +32601,14 @@ ${result2.stderr}`)) {
|
|
|
32245
32601
|
manager_active: managerActive,
|
|
32246
32602
|
manager: managerName(this.platform),
|
|
32247
32603
|
manager_state: result2.exitCode === 0 ? output3 || "installed" : "not-installed",
|
|
32248
|
-
adapter: manifest ?
|
|
32604
|
+
adapter: manifest && new Set(manifest.workers.map((worker) => worker.adapter)).size === 1 ? manifest.workers[0]?.adapter ?? null : null,
|
|
32249
32605
|
log_path: manifest?.log_path ?? this.logPath(),
|
|
32250
32606
|
workers: manifest?.workers.map((worker) => ({
|
|
32251
32607
|
instance_name: worker.instance_name,
|
|
32608
|
+
adapter: worker.adapter,
|
|
32252
32609
|
display_name: worker.display_name,
|
|
32253
32610
|
max_concurrency: worker.max_concurrency,
|
|
32611
|
+
authenticated_account_identity: worker.authenticated_account_identity ?? null,
|
|
32254
32612
|
authenticated_account_email: worker.authenticated_account_email,
|
|
32255
32613
|
authenticated_account_plan: worker.authenticated_account_plan,
|
|
32256
32614
|
runtime_state: runtime?.manifest_generation === manifest.generation && managerActive ? runtime.workers.find((item) => item.instance_name === worker.instance_name)?.state ?? "unknown" : "unknown"
|
|
@@ -32314,12 +32672,12 @@ ${result2.stderr}`)) {
|
|
|
32314
32672
|
${result2.stderr}`)) {
|
|
32315
32673
|
throw new Error(`Background service uninstall failed: ${result2.stderr.trim()}`);
|
|
32316
32674
|
}
|
|
32317
|
-
await
|
|
32318
|
-
if (this.platform === "win32") await
|
|
32675
|
+
await rm5(this.definitionPath(), { force: true });
|
|
32676
|
+
if (this.platform === "win32") await rm5(this.windowsLauncherPath(), { force: true });
|
|
32319
32677
|
if (this.platform === "linux") await this.runCommand("systemctl", ["--user", "daemon-reload"]);
|
|
32320
|
-
await
|
|
32321
|
-
await
|
|
32322
|
-
await
|
|
32678
|
+
await rm5(this.manifestPath(), { force: true });
|
|
32679
|
+
await rm5(this.desiredPath(), { force: true });
|
|
32680
|
+
await rm5(this.runtimePath(), { force: true });
|
|
32323
32681
|
return {
|
|
32324
32682
|
installed: false,
|
|
32325
32683
|
desired_running: false,
|
|
@@ -32348,6 +32706,8 @@ ${result2.stderr}`)) {
|
|
|
32348
32706
|
"inference-host",
|
|
32349
32707
|
"run",
|
|
32350
32708
|
"--json",
|
|
32709
|
+
"--adapter",
|
|
32710
|
+
worker.adapter,
|
|
32351
32711
|
"--display-name",
|
|
32352
32712
|
worker.display_name
|
|
32353
32713
|
];
|
|
@@ -32460,7 +32820,7 @@ ${result2.stderr}`)) {
|
|
|
32460
32820
|
});
|
|
32461
32821
|
const launch = options.runWorker ?? options.spawnChild ?? spawnInferenceHostServiceChild;
|
|
32462
32822
|
await appendServiceLog(initialManifest.log_path, "service_supervisor_started", {
|
|
32463
|
-
|
|
32823
|
+
adapters: [...new Set(initialManifest.workers.map((worker) => worker.adapter))].sort(),
|
|
32464
32824
|
instances: initialManifest.workers.map((worker) => worker.instance_name)
|
|
32465
32825
|
});
|
|
32466
32826
|
const workers = /* @__PURE__ */ new Map();
|
|
@@ -32681,8 +33041,8 @@ __export(cli_exports, {
|
|
|
32681
33041
|
});
|
|
32682
33042
|
import { createHash as createHash7, randomUUID as randomUUID2 } from "node:crypto";
|
|
32683
33043
|
import { spawn as spawn7 } from "node:child_process";
|
|
32684
|
-
import { lstat as lstat4, realpath as realpath4, rm as
|
|
32685
|
-
import { join as
|
|
33044
|
+
import { lstat as lstat4, realpath as realpath4, rm as rm6 } from "node:fs/promises";
|
|
33045
|
+
import { join as join7, resolve as resolve5 } from "node:path";
|
|
32686
33046
|
async function runInferenceHostCli(argv2, env = process.env, dependencies = {}) {
|
|
32687
33047
|
const warnings = [];
|
|
32688
33048
|
try {
|
|
@@ -32783,7 +33143,7 @@ async function runInferenceHostCli(argv2, env = process.env, dependencies = {})
|
|
|
32783
33143
|
};
|
|
32784
33144
|
}
|
|
32785
33145
|
}
|
|
32786
|
-
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, defaultOpenBrowser, registerInferenceHostServiceControlInput, defaultRegisterLifecycleSignalHandlers, lifecycleCancellation, configuredCredentialStore, restoreInferenceHostCredentialContext, recoverInferenceHostCredentialContextTransition, accountKeyForState, assertCredentialMatchesState2, revocationCheckpointForCredential, assertRevocationCheckpointMatchesLocalIdentity, fileExistsPrivately, inspectCodexAuthentication, clearLocalRuntimeArtifacts, assertDurableServiceUninstalled, assertLocalRuntimeArtifactsMayBeDiscarded, defaultRunForeground, 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;
|
|
33146
|
+
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, 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;
|
|
32787
33147
|
var init_cli = __esm({
|
|
32788
33148
|
"lib/inference-host/cli.ts"() {
|
|
32789
33149
|
"use strict";
|
|
@@ -32793,6 +33153,8 @@ var init_cli = __esm({
|
|
|
32793
33153
|
init_agent_state();
|
|
32794
33154
|
init_codex_adapter();
|
|
32795
33155
|
init_codex_recovery_process();
|
|
33156
|
+
init_copilot_adapter();
|
|
33157
|
+
init_durable_adapter();
|
|
32796
33158
|
init_codex_app_server();
|
|
32797
33159
|
init_codex_binary();
|
|
32798
33160
|
init_config();
|
|
@@ -32875,7 +33237,7 @@ var init_cli = __esm({
|
|
|
32875
33237
|
Commands:
|
|
32876
33238
|
login Authorize the isolated VTX insights:inference grant
|
|
32877
33239
|
codex-login Sign the automated Codex host into a ChatGPT subscription
|
|
32878
|
-
run Run
|
|
33240
|
+
run Run a supported durable inference adapter in the foreground
|
|
32879
33241
|
agent-connect Advertise a model from a compatible agent harness
|
|
32880
33242
|
agent-run Keep an agent-driven host online in the foreground
|
|
32881
33243
|
agent-next Claim the next exact VTX inference request
|
|
@@ -32883,7 +33245,7 @@ Commands:
|
|
|
32883
33245
|
agent-fail Submit one truthful agent failure from stdin
|
|
32884
33246
|
service Install and control the durable background host
|
|
32885
33247
|
status Inspect local host and credential state
|
|
32886
|
-
doctor Verify credentials,
|
|
33248
|
+
doctor Verify credentials, provider runtime, and private state
|
|
32887
33249
|
logout Remove local VTX host state without revoking the grant
|
|
32888
33250
|
revoke Revoke the VTX grant and remove local host state
|
|
32889
33251
|
codex-logout Remove the automated host's dedicated Codex login
|
|
@@ -32891,7 +33253,8 @@ Commands:
|
|
|
32891
33253
|
Common options:
|
|
32892
33254
|
--json Emit machine-readable JSON
|
|
32893
33255
|
--instance NAME Target an isolated local subscription instance (default: default)
|
|
32894
|
-
--
|
|
33256
|
+
--adapter ID Durable adapter: codex or copilot
|
|
33257
|
+
--max-concurrency N Optional positive-integer local slot limit (default: unlimited)
|
|
32895
33258
|
--help, -h Show this help
|
|
32896
33259
|
|
|
32897
33260
|
If the OS credential store cannot retain the VTX grant, set
|
|
@@ -32905,6 +33268,7 @@ Durable service:
|
|
|
32905
33268
|
vtx inference-host login --instance codex-2
|
|
32906
33269
|
vtx inference-host codex-login --instance codex-2
|
|
32907
33270
|
vtx inference-host service install --instance codex-2
|
|
33271
|
+
vtx inference-host service install --adapter copilot --instance copilot-1
|
|
32908
33272
|
vtx inference-host service uninstall --instance codex-2
|
|
32909
33273
|
vtx inference-host service recover --instance codex-1 --force-recovery
|
|
32910
33274
|
vtx inference-host service <start|stop|status|logs|recover|uninstall>
|
|
@@ -33010,6 +33374,8 @@ Durable service:
|
|
|
33010
33374
|
}
|
|
33011
33375
|
if (command === "agent-connect" && !displayNameExplicit) {
|
|
33012
33376
|
displayName = "Agent-driven inference host";
|
|
33377
|
+
} else if (adapter && isDurableInferenceAdapterId(adapter) && !displayNameExplicit) {
|
|
33378
|
+
displayName = `${durableAdapterDisplayName(adapter)} subscription host`;
|
|
33013
33379
|
}
|
|
33014
33380
|
return {
|
|
33015
33381
|
command,
|
|
@@ -33154,7 +33520,7 @@ Durable service:
|
|
|
33154
33520
|
return raw !== null;
|
|
33155
33521
|
};
|
|
33156
33522
|
inspectCodexAuthentication = async (config2) => {
|
|
33157
|
-
const path =
|
|
33523
|
+
const path = join7(config2.codexHomePath, "auth.json");
|
|
33158
33524
|
try {
|
|
33159
33525
|
const before = await lstat4(path);
|
|
33160
33526
|
const canonical = await realpath4(path);
|
|
@@ -33172,7 +33538,7 @@ Durable service:
|
|
|
33172
33538
|
runtimeReceiptPath(config2),
|
|
33173
33539
|
"Inference host runtime receipt file"
|
|
33174
33540
|
);
|
|
33175
|
-
await
|
|
33541
|
+
await rm6(codexGuardianReceiptRoot(config2), { recursive: true, force: true });
|
|
33176
33542
|
await clearInferencePrivateFile(
|
|
33177
33543
|
codexRecoveryPath(config2),
|
|
33178
33544
|
"Codex attempt recovery file"
|
|
@@ -33254,6 +33620,49 @@ Durable service:
|
|
|
33254
33620
|
signal: options.signal
|
|
33255
33621
|
}).run();
|
|
33256
33622
|
};
|
|
33623
|
+
preparePortableDurableAdapter = async (adapterId, signal) => {
|
|
33624
|
+
const adapter = new CopilotSubscriptionAdapter();
|
|
33625
|
+
return { adapter, preflight: await adapter.preflight(signal) };
|
|
33626
|
+
};
|
|
33627
|
+
defaultRunPortableDurableAdapter = async (options) => {
|
|
33628
|
+
const dependencies = createDefaultInferenceHostRunnerDependencies({
|
|
33629
|
+
apiUrl: options.config.apiUrl,
|
|
33630
|
+
statePath: options.config.statePath,
|
|
33631
|
+
processLockPath: options.config.processLockPath,
|
|
33632
|
+
credentialStore: options.credentialStore,
|
|
33633
|
+
codexAdapter: options.adapter,
|
|
33634
|
+
envelopePublicKey: (credential) => externalInferenceEnvelopePublicKey(credential.x25519_private_key),
|
|
33635
|
+
clientVersion: INFERENCE_HOST_CLI_VERSION,
|
|
33636
|
+
runtimeReceiptPath: runtimeReceiptPath(options.config)
|
|
33637
|
+
});
|
|
33638
|
+
const borrowedProcessLock = {
|
|
33639
|
+
path: options.processLock.path,
|
|
33640
|
+
ownerToken: options.processLock.ownerToken,
|
|
33641
|
+
release: async () => void 0
|
|
33642
|
+
};
|
|
33643
|
+
return await new InferenceHostRunner({
|
|
33644
|
+
...dependencies,
|
|
33645
|
+
acquireProcessLock: async () => borrowedProcessLock
|
|
33646
|
+
}, {
|
|
33647
|
+
adapterId: options.preflight.adapterId,
|
|
33648
|
+
usageSource: options.preflight.adapterId,
|
|
33649
|
+
structuredOutput: false,
|
|
33650
|
+
sameAttemptRecovery: options.preflight.sameAttemptRecovery,
|
|
33651
|
+
instanceName: options.config.instanceName,
|
|
33652
|
+
displayName: options.displayName,
|
|
33653
|
+
authenticatedAccountIdentity: options.preflight.authenticatedAccountIdentity,
|
|
33654
|
+
authenticatedAccountEmail: options.preflight.authenticatedAccountEmail,
|
|
33655
|
+
authenticatedAccountPlan: options.preflight.authenticatedAccountPlan,
|
|
33656
|
+
codexRateLimits: options.preflight.rateLimits,
|
|
33657
|
+
codexModelCapabilities: options.preflight.modelCapabilities,
|
|
33658
|
+
protocolVersion: EXTERNAL_INFERENCE_CONTRACT_VERSION,
|
|
33659
|
+
adapterRuntimeVersion: options.preflight.runtimeVersion,
|
|
33660
|
+
maxConcurrency: options.maxConcurrency,
|
|
33661
|
+
once: options.once,
|
|
33662
|
+
emitDiagnosticEvent: options.emitDiagnosticEvent,
|
|
33663
|
+
signal: options.signal
|
|
33664
|
+
}).run();
|
|
33665
|
+
};
|
|
33257
33666
|
login = async (config2, parsed, env, dependencies, warnings) => {
|
|
33258
33667
|
const credentialLock = await acquireInferenceHostProcessLock(
|
|
33259
33668
|
credentialLifecycleLockPath(config2)
|
|
@@ -33601,6 +34010,35 @@ Waiting for approval...
|
|
|
33601
34010
|
detail: error48 instanceof Error ? error48.message : "unavailable"
|
|
33602
34011
|
});
|
|
33603
34012
|
}
|
|
34013
|
+
const adapterId = parsed.adapter ?? "codex";
|
|
34014
|
+
if (!isDurableInferenceAdapterId(adapterId)) {
|
|
34015
|
+
checks.push({ name: "provider_runtime", ok: false, detail: "unsupported-adapter" });
|
|
34016
|
+
} else if (adapterId !== "codex") {
|
|
34017
|
+
try {
|
|
34018
|
+
const prepared = await (dependencies.prepareDurableAdapter ?? preparePortableDurableAdapter)(
|
|
34019
|
+
adapterId
|
|
34020
|
+
);
|
|
34021
|
+
checks.push({
|
|
34022
|
+
name: "provider_runtime",
|
|
34023
|
+
ok: true,
|
|
34024
|
+
detail: `${adapterId}:${prepared.preflight.runtimeVersion}:${prepared.preflight.modelCapabilities.length}-models`
|
|
34025
|
+
});
|
|
34026
|
+
await prepared.adapter.close?.();
|
|
34027
|
+
} catch (error48) {
|
|
34028
|
+
checks.push({
|
|
34029
|
+
name: "provider_runtime",
|
|
34030
|
+
ok: false,
|
|
34031
|
+
detail: error48 instanceof Error ? error48.message : "unavailable"
|
|
34032
|
+
});
|
|
34033
|
+
}
|
|
34034
|
+
const healthy2 = checks.every((check2) => check2.ok);
|
|
34035
|
+
return {
|
|
34036
|
+
exitCode: healthy2 ? 0 : 1,
|
|
34037
|
+
stdout: render({ healthy: healthy2, adapter: adapterId, checks, source: "local_only" }, parsed.json),
|
|
34038
|
+
stderr: warnings.length > 0 ? `${warnings.join("\n")}
|
|
34039
|
+
` : ""
|
|
34040
|
+
};
|
|
34041
|
+
}
|
|
33604
34042
|
try {
|
|
33605
34043
|
const binary = await (dependencies.resolveBinary ?? resolvePinnedCodexBinary)(env);
|
|
33606
34044
|
checks.push({
|
|
@@ -33817,6 +34255,37 @@ Waiting for approval...
|
|
|
33817
34255
|
if (await store.readRecovery?.()) {
|
|
33818
34256
|
throw new Error("Inference host credential recovery is required before the runner can start.");
|
|
33819
34257
|
}
|
|
34258
|
+
const adapterId = parsed.adapter ?? "codex";
|
|
34259
|
+
if (!isDurableInferenceAdapterId(adapterId)) {
|
|
34260
|
+
throw new Error(`Adapter ${adapterId} does not have a supported durable integration.`);
|
|
34261
|
+
}
|
|
34262
|
+
const emitDiagnosticEvent = parsed.json ? (event) => (dependencies.emitStdout ?? ((text) => {
|
|
34263
|
+
process.stdout.write(text);
|
|
34264
|
+
}))(`${JSON.stringify(event)}
|
|
34265
|
+
`) : void 0;
|
|
34266
|
+
if (adapterId !== "codex") {
|
|
34267
|
+
const prepared = await (dependencies.prepareDurableAdapter ?? preparePortableDurableAdapter)(
|
|
34268
|
+
adapterId,
|
|
34269
|
+
cancellation.signal
|
|
34270
|
+
);
|
|
34271
|
+
const summary = await (dependencies.runPortableDurableAdapter ?? defaultRunPortableDurableAdapter)({
|
|
34272
|
+
config: config2,
|
|
34273
|
+
credentialStore: store,
|
|
34274
|
+
...prepared,
|
|
34275
|
+
displayName: parsed.displayName,
|
|
34276
|
+
maxConcurrency: parsed.maxConcurrency,
|
|
34277
|
+
once: parsed.once,
|
|
34278
|
+
processLock,
|
|
34279
|
+
emitDiagnosticEvent,
|
|
34280
|
+
signal: cancellation.signal
|
|
34281
|
+
});
|
|
34282
|
+
return {
|
|
34283
|
+
exitCode: 0,
|
|
34284
|
+
stdout: render({ status: "stopped", ...summary }, parsed.json),
|
|
34285
|
+
stderr: warnings.length > 0 ? `${warnings.join("\n")}
|
|
34286
|
+
` : ""
|
|
34287
|
+
};
|
|
34288
|
+
}
|
|
33820
34289
|
const verifiedBinary = await (dependencies.resolveBinary ?? resolvePinnedCodexBinary)(env);
|
|
33821
34290
|
cancellation.signal.throwIfAborted();
|
|
33822
34291
|
await reconcileCodexAttemptRecovery({
|
|
@@ -33847,10 +34316,7 @@ Waiting for approval...
|
|
|
33847
34316
|
once: parsed.once,
|
|
33848
34317
|
env,
|
|
33849
34318
|
processLock,
|
|
33850
|
-
emitDiagnosticEvent
|
|
33851
|
-
process.stdout.write(text);
|
|
33852
|
-
}))(`${JSON.stringify(event)}
|
|
33853
|
-
`) : void 0,
|
|
34319
|
+
emitDiagnosticEvent,
|
|
33854
34320
|
signal: cancellation.signal
|
|
33855
34321
|
});
|
|
33856
34322
|
return {
|
|
@@ -34399,6 +34865,17 @@ Waiting for approval...
|
|
|
34399
34865
|
credentialLifecycleLockPath(config2)
|
|
34400
34866
|
);
|
|
34401
34867
|
try {
|
|
34868
|
+
const installedManifest = await readInferenceHostServiceManifest(
|
|
34869
|
+
`${config2.supervisorStatePath}.service.json`
|
|
34870
|
+
);
|
|
34871
|
+
const installedWorker = installedManifest?.workers.find(
|
|
34872
|
+
(worker) => worker.instance_name === config2.instanceName
|
|
34873
|
+
);
|
|
34874
|
+
if (installedWorker && installedWorker.adapter !== "codex") {
|
|
34875
|
+
throw new Error(
|
|
34876
|
+
`Guarded same-attempt recovery is not supported for ${installedWorker.adapter}; interrupted attempts remain quarantined as outcome_unknown.`
|
|
34877
|
+
);
|
|
34878
|
+
}
|
|
34402
34879
|
const recoveryStore = new FileCodexAttemptRecoveryStore(codexRecoveryPath(config2));
|
|
34403
34880
|
const existingTransaction = await readServiceRecoveryTransaction(config2);
|
|
34404
34881
|
if (existingTransaction && existingTransaction.instance_name !== config2.instanceName) {
|
|
@@ -34584,7 +35061,7 @@ Waiting for approval...
|
|
|
34584
35061
|
serviceRecoveryTransactionPath(config2),
|
|
34585
35062
|
"Inference-host service recovery transaction"
|
|
34586
35063
|
);
|
|
34587
|
-
await
|
|
35064
|
+
await rm6(backupPath, { force: true });
|
|
34588
35065
|
}
|
|
34589
35066
|
}
|
|
34590
35067
|
} finally {
|
|
@@ -34648,7 +35125,7 @@ Waiting for approval...
|
|
|
34648
35125
|
);
|
|
34649
35126
|
}
|
|
34650
35127
|
const adapter = parsed.adapter || "codex";
|
|
34651
|
-
if (adapter
|
|
35128
|
+
if (!isDurableInferenceAdapterId(adapter)) {
|
|
34652
35129
|
throw new Error(
|
|
34653
35130
|
`Adapter ${adapter} does not have a supported durable service integration. Use foreground agent-run instead.`
|
|
34654
35131
|
);
|
|
@@ -34660,7 +35137,31 @@ Waiting for approval...
|
|
|
34660
35137
|
if (!credential) throw new Error("Inference-host credential is missing. Run login again.");
|
|
34661
35138
|
assertCredentialMatchesState2(state, credential);
|
|
34662
35139
|
if (parsed.modelId || parsed.modelLabel || parsed.reasoningEffort) {
|
|
34663
|
-
throw new Error("
|
|
35140
|
+
throw new Error("Durable services discover their exact model and effort catalog from the authenticated runtime.");
|
|
35141
|
+
}
|
|
35142
|
+
if (adapter !== "codex") {
|
|
35143
|
+
const prepared = await (dependencies.prepareDurableAdapter ?? preparePortableDurableAdapter)(
|
|
35144
|
+
adapter
|
|
35145
|
+
);
|
|
35146
|
+
try {
|
|
35147
|
+
const status2 = await manager.install({
|
|
35148
|
+
adapter,
|
|
35149
|
+
displayName: parsed.displayName,
|
|
35150
|
+
maxConcurrency: parsed.maxConcurrency,
|
|
35151
|
+
authenticatedAccountIdentity: prepared.preflight.authenticatedAccountIdentity,
|
|
35152
|
+
authenticatedAccountEmail: prepared.preflight.authenticatedAccountEmail,
|
|
35153
|
+
authenticatedAccountPlan: prepared.preflight.authenticatedAccountPlan
|
|
35154
|
+
});
|
|
35155
|
+
await writeInferenceHostCredentialContext(config2);
|
|
35156
|
+
return {
|
|
35157
|
+
exitCode: 0,
|
|
35158
|
+
stdout: render({ status: "service_installed", ...status2 }, parsed.json),
|
|
35159
|
+
stderr: warnings.length > 0 ? `${warnings.join("\n")}
|
|
35160
|
+
` : ""
|
|
35161
|
+
};
|
|
35162
|
+
} finally {
|
|
35163
|
+
await prepared.adapter.close?.();
|
|
35164
|
+
}
|
|
34664
35165
|
}
|
|
34665
35166
|
const auth = await inspectCodexAuthentication(config2);
|
|
34666
35167
|
if (!auth.present || !auth.private) {
|
|
@@ -34827,11 +35328,11 @@ Waiting for approval...
|
|
|
34827
35328
|
});
|
|
34828
35329
|
|
|
34829
35330
|
// lib/agent-core/config.ts
|
|
34830
|
-
import { mkdir as mkdir5, readFile as readFile6, rm as
|
|
34831
|
-
import { dirname as dirname5, join as
|
|
35331
|
+
import { mkdir as mkdir5, readFile as readFile6, rm as rm7, writeFile as writeFile3 } from "node:fs/promises";
|
|
35332
|
+
import { dirname as dirname5, join as join8 } from "node:path";
|
|
34832
35333
|
import { homedir as homedir3 } from "node:os";
|
|
34833
35334
|
function defaultBaseDir() {
|
|
34834
|
-
return
|
|
35335
|
+
return join8(homedir3(), ".vtx");
|
|
34835
35336
|
}
|
|
34836
35337
|
function resolveAgentCliConfig(env = process.env) {
|
|
34837
35338
|
const baseDir = String(env.VTX_HOME || "").trim() || defaultBaseDir();
|
|
@@ -34839,8 +35340,8 @@ function resolveAgentCliConfig(env = process.env) {
|
|
|
34839
35340
|
const parsedProfile = rawProfile ? Number(rawProfile) : NaN;
|
|
34840
35341
|
return {
|
|
34841
35342
|
apiUrl: String(env.VTX_API_URL || "http://localhost:8000").replace(/\/+$/, ""),
|
|
34842
|
-
tokenPath: String(env.VTX_TOKEN_PATH || "").trim() ||
|
|
34843
|
-
statePath: String(env.VTX_RUNTIME_STATE_PATH || "").trim() ||
|
|
35343
|
+
tokenPath: String(env.VTX_TOKEN_PATH || "").trim() || join8(baseDir, "token.json"),
|
|
35344
|
+
statePath: String(env.VTX_RUNTIME_STATE_PATH || "").trim() || join8(baseDir, "runtime-state.json"),
|
|
34844
35345
|
runtimeDeviceId: String(env.VTX_RUNTIME_DEVICE_ID || "").trim() || null,
|
|
34845
35346
|
activeProfileId: Number.isFinite(parsedProfile) && parsedProfile > 0 ? parsedProfile : null,
|
|
34846
35347
|
outputJson: String(env.VTX_OUTPUT || "").trim().toLowerCase() === "json"
|
|
@@ -34871,7 +35372,7 @@ async function writeStoredAgentAuth(path, auth) {
|
|
|
34871
35372
|
`, { encoding: "utf8", mode: 384 });
|
|
34872
35373
|
}
|
|
34873
35374
|
async function clearStoredAgentAuth(path) {
|
|
34874
|
-
await
|
|
35375
|
+
await rm7(path, { force: true });
|
|
34875
35376
|
}
|
|
34876
35377
|
async function readRuntimeState(path) {
|
|
34877
35378
|
try {
|
|
@@ -34904,7 +35405,7 @@ async function writeRuntimeState(path, state) {
|
|
|
34904
35405
|
`, { encoding: "utf8", mode: 384 });
|
|
34905
35406
|
}
|
|
34906
35407
|
async function clearRuntimeState(path) {
|
|
34907
|
-
await
|
|
35408
|
+
await rm7(path, { force: true });
|
|
34908
35409
|
}
|
|
34909
35410
|
var init_config2 = __esm({
|
|
34910
35411
|
"lib/agent-core/config.ts"() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vtxmacro/cli",
|
|
3
|
-
"version": "2026.8.
|
|
3
|
+
"version": "2026.8.42",
|
|
4
4
|
"description": "VTX Macro CLI, MCP server, and durable subscription inference host.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -20,7 +20,9 @@
|
|
|
20
20
|
"node": ">=20.0.0"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@openai/codex": "0.147.0"
|
|
23
|
+
"@openai/codex": "0.147.0",
|
|
24
|
+
"@github/copilot-sdk": "1.0.0-beta.8",
|
|
25
|
+
"@github/copilot": "1.0.80"
|
|
24
26
|
},
|
|
25
27
|
"files": [
|
|
26
28
|
"bin",
|