@vtxmacro/cli 2026.9.28 → 2026.9.30
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 +11 -7
- package/bin/vtx-service-bootstrap.js +341 -108
- package/bin/vtx.js +168 -39
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -16,16 +16,20 @@ verifies the Codex runtime's version and digest before use; it does not borrow a
|
|
|
16
16
|
Codex binary from PATH or an editor extension.
|
|
17
17
|
For Windows-login auto-start, install and configure the CLI from native Windows;
|
|
18
18
|
a CLI installed only inside WSL cannot start the WSL virtual machine at login.
|
|
19
|
-
New service installations use a private verified launcher. At login
|
|
20
|
-
service start, it checks the official npm registry
|
|
21
|
-
integrity and installed CLI version in a new
|
|
22
|
-
|
|
19
|
+
New service installations use a private verified launcher. At login, every
|
|
20
|
+
service start, and periodically while running, it checks the official npm registry
|
|
21
|
+
and verifies the exact release integrity and installed CLI version in a new
|
|
22
|
+
versioned directory. Before switching, it stops new admission and lets active
|
|
23
|
+
Provider calls and Agent turns finish while keeping heartbeats alive. It selects
|
|
24
|
+
the candidate only after every configured worker reports ready. A
|
|
23
25
|
failed candidate is rejected and the last working runtime resumes. The service
|
|
24
26
|
keeps only the active release and one rollback release. If the update check is
|
|
25
27
|
unavailable, it keeps the last verified runtime. An intentionally stopped
|
|
26
28
|
service stays stopped and makes no update request. Hosts installed before this
|
|
27
|
-
|
|
28
|
-
adopt it.
|
|
29
|
+
private launcher need one final normal npm update and service reinstall to
|
|
30
|
+
adopt it. Startup-only launchers adopt background checking after their next normal
|
|
31
|
+
start activates a release that includes it; publishing a release cannot replace
|
|
32
|
+
an older process that is already running.
|
|
29
33
|
|
|
30
34
|
## Configure
|
|
31
35
|
|
|
@@ -70,7 +74,7 @@ and VTX grant. VTX resolves the package-owned pinned Copilot platform runtime
|
|
|
70
74
|
explicitly and rejects an `auto`-only catalog because it cannot prove the
|
|
71
75
|
effective model.
|
|
72
76
|
|
|
73
|
-
Grok Build is a durable
|
|
77
|
+
Grok Build is a durable adapter using its package-owned official runtime and an
|
|
74
78
|
isolated local Grok OAuth session. Run `vtx inference-host grok-login --instance grok-1`
|
|
75
79
|
after the normal VTX host login, then `vtx inference-host service install --adapter grok-build --instance grok-1`.
|
|
76
80
|
Provider mode has no tools; Main Agent mode exposes only assignment-scoped VTX tools.
|
|
@@ -16,7 +16,7 @@ import { fileURLToPath } from "node:url";
|
|
|
16
16
|
// agent-cli-release.json
|
|
17
17
|
var agent_cli_release_default = {
|
|
18
18
|
package_name: "@vtxmacro/cli",
|
|
19
|
-
package_version: "2026.9.
|
|
19
|
+
package_version: "2026.9.30",
|
|
20
20
|
codex_package_name: "@openai/codex",
|
|
21
21
|
codex_version: "0.153.3",
|
|
22
22
|
copilot_sdk_package_name: "@github/copilot-sdk",
|
|
@@ -115,6 +115,121 @@ var agent_cli_release_default = {
|
|
|
115
115
|
}
|
|
116
116
|
};
|
|
117
117
|
|
|
118
|
+
// lib/runtime-policy.generated.json
|
|
119
|
+
var runtime_policy_generated_default = {
|
|
120
|
+
ui: {
|
|
121
|
+
auth_bootstrap_retry: {
|
|
122
|
+
max_attempts: 3,
|
|
123
|
+
jitter_milliseconds: 750,
|
|
124
|
+
base_delay_milliseconds: 500,
|
|
125
|
+
min_delay_milliseconds: 250,
|
|
126
|
+
max_delay_milliseconds: 1e4
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
ai_dashboard: {
|
|
130
|
+
market_news_bounds: {
|
|
131
|
+
max_items_min: 1,
|
|
132
|
+
max_items_max: 100,
|
|
133
|
+
lookback_hours_min: 1,
|
|
134
|
+
lookback_hours_max: 168,
|
|
135
|
+
max_items_steps: [
|
|
136
|
+
1,
|
|
137
|
+
2,
|
|
138
|
+
3,
|
|
139
|
+
4,
|
|
140
|
+
5,
|
|
141
|
+
6,
|
|
142
|
+
7,
|
|
143
|
+
8,
|
|
144
|
+
9,
|
|
145
|
+
10,
|
|
146
|
+
15,
|
|
147
|
+
20,
|
|
148
|
+
25,
|
|
149
|
+
30,
|
|
150
|
+
40,
|
|
151
|
+
50,
|
|
152
|
+
60,
|
|
153
|
+
75,
|
|
154
|
+
90,
|
|
155
|
+
100
|
|
156
|
+
],
|
|
157
|
+
lookback_hours_steps: [
|
|
158
|
+
1,
|
|
159
|
+
2,
|
|
160
|
+
4,
|
|
161
|
+
8,
|
|
162
|
+
12,
|
|
163
|
+
24,
|
|
164
|
+
48,
|
|
165
|
+
72,
|
|
166
|
+
168
|
|
167
|
+
]
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
trading: {
|
|
171
|
+
engine: {
|
|
172
|
+
client_runtime: {
|
|
173
|
+
recovery: {
|
|
174
|
+
resume_retry_base_delay_ms: 1e3,
|
|
175
|
+
resume_retry_max_delay_ms: 3e4,
|
|
176
|
+
transient_load_min_delay_ms: 3e4,
|
|
177
|
+
transient_load_max_delay_ms: 12e4,
|
|
178
|
+
rate_limit_buffer_ms: 1e3,
|
|
179
|
+
rate_limit_max_delay_ms: 3e5,
|
|
180
|
+
engine_stop_settle_retry_delay_ms: 250,
|
|
181
|
+
recoverable_reset_settle_retry_delay_ms: 1500,
|
|
182
|
+
local_ai_preflight_timeout_ms: 3e3,
|
|
183
|
+
surge_stagger_max_ms: 6e4,
|
|
184
|
+
surge_stagger_min_ms: 2e3,
|
|
185
|
+
surge_stagger_min_candidates: 4,
|
|
186
|
+
stagger_deadline_ttl_ms: 3e5,
|
|
187
|
+
server_active_reprobe_delay_ms: 6e4,
|
|
188
|
+
transient_load_jitter_ms: 1e4,
|
|
189
|
+
cross_host_completed_ttl_ms: 15e3,
|
|
190
|
+
telemetry_dedupe_ttl_ms: 5e3,
|
|
191
|
+
browser_presence_heartbeat_interval_ms: 3e4,
|
|
192
|
+
host_liveness_heartbeat_interval_ms: 3e4,
|
|
193
|
+
host_liveness_recovery_nudge_ttl_ms: 1e4
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
external_inference: {
|
|
199
|
+
service: {
|
|
200
|
+
update_check_interval_ms: 3e5,
|
|
201
|
+
update_registry_timeout_ms: 15e3,
|
|
202
|
+
startup_max_attempts: 40,
|
|
203
|
+
startup_poll_interval_ms: 250,
|
|
204
|
+
restart_stable_uptime_ms: 6e4,
|
|
205
|
+
restart_backoff_base_ms: 1e3,
|
|
206
|
+
restart_backoff_max_ms: 3e4,
|
|
207
|
+
restart_exponent_max: 5
|
|
208
|
+
}
|
|
209
|
+
},
|
|
210
|
+
desktop: {
|
|
211
|
+
runtime_watchdog: {
|
|
212
|
+
ping_interval_milliseconds: 15e3,
|
|
213
|
+
telemetry_interval_milliseconds: 3e5
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
screener: {
|
|
217
|
+
resource_scheduler: {
|
|
218
|
+
client_lock_ttl_milliseconds: 12e4,
|
|
219
|
+
client_poll_interval_milliseconds: 250
|
|
220
|
+
}
|
|
221
|
+
},
|
|
222
|
+
deployment: {
|
|
223
|
+
cutover_buffer: {
|
|
224
|
+
target_timeout_ms: 3e3,
|
|
225
|
+
retired_timeout_ms: 45e3,
|
|
226
|
+
max_body_bytes: 33554432,
|
|
227
|
+
max_inflight: 16,
|
|
228
|
+
max_queue: 64
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
|
|
118
233
|
// lib/inference-host/config.ts
|
|
119
234
|
import { randomBytes } from "node:crypto";
|
|
120
235
|
import { spawn } from "node:child_process";
|
|
@@ -983,6 +1098,7 @@ var UPDATE_ATTEMPTS = 3;
|
|
|
983
1098
|
var UPDATE_RETRY_MS = 2e3;
|
|
984
1099
|
var CANDIDATE_READINESS_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
985
1100
|
var SERVICE_DRAIN_COMMAND = "vtx-inference-host-service-drain-v1";
|
|
1101
|
+
var SERVICE_QUIESCE_COMMAND = "vtx-inference-host-service-quiesce-v1";
|
|
986
1102
|
var safePath = (value, label) => {
|
|
987
1103
|
if (typeof value !== "string" || !value || /[\r\n\0]/u.test(value)) {
|
|
988
1104
|
throw new Error(`Inference-host bootstrap ${label} is invalid.`);
|
|
@@ -1127,7 +1243,11 @@ var runInferenceHostBootstrapNpmCommand = async (executable, args, platform = pr
|
|
|
1127
1243
|
var defaultRunSupervisor = (executable, args) => {
|
|
1128
1244
|
const child = spawn2(executable, [...args], {
|
|
1129
1245
|
windowsHide: true,
|
|
1130
|
-
env: {
|
|
1246
|
+
env: {
|
|
1247
|
+
...process.env,
|
|
1248
|
+
VTX_INFERENCE_HOST_SERVICE_CHILD: "1",
|
|
1249
|
+
VTX_INFERENCE_HOST_BOOTSTRAP_VERSION: agent_cli_release_default.package_version
|
|
1250
|
+
},
|
|
1131
1251
|
stdio: ["pipe", "inherit", "inherit"]
|
|
1132
1252
|
});
|
|
1133
1253
|
const completion = new Promise((resolvePromise, reject) => {
|
|
@@ -1139,7 +1259,11 @@ var defaultRunSupervisor = (executable, args) => {
|
|
|
1139
1259
|
return {
|
|
1140
1260
|
completion,
|
|
1141
1261
|
requestDrain: () => {
|
|
1142
|
-
child.stdin.
|
|
1262
|
+
child.stdin.write(`${SERVICE_DRAIN_COMMAND}
|
|
1263
|
+
`);
|
|
1264
|
+
},
|
|
1265
|
+
requestQuiesce: () => {
|
|
1266
|
+
child.stdin.write(`${SERVICE_QUIESCE_COMMAND}
|
|
1143
1267
|
`);
|
|
1144
1268
|
}
|
|
1145
1269
|
};
|
|
@@ -1153,9 +1277,12 @@ var appendBootstrapLog = async (path, event, fields = {}) => {
|
|
|
1153
1277
|
{ encoding: "utf8", mode: 384 }
|
|
1154
1278
|
);
|
|
1155
1279
|
};
|
|
1156
|
-
var fetchLatestRelease = async (fetchImpl) => {
|
|
1280
|
+
var fetchLatestRelease = async (fetchImpl, signal) => {
|
|
1157
1281
|
const response = await fetchImpl(`${OFFICIAL_NPM_REGISTRY}/%40vtxmacro%2Fcli/latest`, {
|
|
1158
|
-
signal: AbortSignal.
|
|
1282
|
+
signal: AbortSignal.any([
|
|
1283
|
+
AbortSignal.timeout(runtime_policy_generated_default.external_inference.service.update_registry_timeout_ms),
|
|
1284
|
+
...signal ? [signal] : []
|
|
1285
|
+
])
|
|
1159
1286
|
});
|
|
1160
1287
|
if (!response.ok) throw new Error("registry_request_failed");
|
|
1161
1288
|
const value = await response.json();
|
|
@@ -1323,10 +1450,12 @@ var updateSelection = async (manifestPath, manifest, dependencies) => {
|
|
|
1323
1450
|
let lastError = null;
|
|
1324
1451
|
for (let attempt = 0; attempt < UPDATE_ATTEMPTS; attempt += 1) {
|
|
1325
1452
|
try {
|
|
1326
|
-
|
|
1453
|
+
if (dependencies.signal?.aborted) throw new Error("service_update_cancelled");
|
|
1454
|
+
latest = await fetchLatestRelease(dependencies.fetch, dependencies.signal);
|
|
1327
1455
|
break;
|
|
1328
1456
|
} catch (error) {
|
|
1329
1457
|
lastError = error;
|
|
1458
|
+
if (dependencies.signal?.aborted) throw error;
|
|
1330
1459
|
if (attempt + 1 < UPDATE_ATTEMPTS) await dependencies.sleep(UPDATE_RETRY_MS);
|
|
1331
1460
|
}
|
|
1332
1461
|
}
|
|
@@ -1340,7 +1469,7 @@ var updateSelection = async (manifestPath, manifest, dependencies) => {
|
|
|
1340
1469
|
}
|
|
1341
1470
|
const rejection = await parseRejection(manifestPath);
|
|
1342
1471
|
if (rejection?.package_version === latest.version) return { active, candidate: null };
|
|
1343
|
-
if (!await readDesired(manifestPath)) return { active, candidate: null };
|
|
1472
|
+
if (dependencies.signal?.aborted || !await readDesired(manifestPath)) return { active, candidate: null };
|
|
1344
1473
|
return {
|
|
1345
1474
|
active,
|
|
1346
1475
|
candidate: await stageRelease(
|
|
@@ -1353,21 +1482,23 @@ var updateSelection = async (manifestPath, manifest, dependencies) => {
|
|
|
1353
1482
|
)
|
|
1354
1483
|
};
|
|
1355
1484
|
};
|
|
1356
|
-
var waitForCandidateReadiness = async (manifestPath,
|
|
1485
|
+
var waitForCandidateReadiness = async (manifestPath, candidate, signal, timeoutMs) => {
|
|
1357
1486
|
const deadline = Date.now() + timeoutMs;
|
|
1358
1487
|
while (!signal.aborted && Date.now() < deadline) {
|
|
1488
|
+
if (!await readDesired(manifestPath)) return "aborted";
|
|
1359
1489
|
try {
|
|
1490
|
+
const currentManifest = parseManifest(JSON.parse(await readFile2(manifestPath, "utf8")));
|
|
1360
1491
|
const value = JSON.parse(await readFile2(runtimePathFor(manifestPath), "utf8"));
|
|
1361
1492
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
1362
1493
|
const runtime = value;
|
|
1363
1494
|
const workers = Array.isArray(runtime.workers) ? runtime.workers : [];
|
|
1364
1495
|
const workerNames = workers.map((worker) => worker && typeof worker === "object" && !Array.isArray(worker) ? String(worker.instance_name ?? "") : "").sort();
|
|
1365
1496
|
const everyWorkerRunning = workers.every((worker) => worker && typeof worker === "object" && !Array.isArray(worker) && worker.state === "running");
|
|
1366
|
-
if (runtime.schema_version === "vtx_inference_service_runtime_v1" && runtime.manifest_generation ===
|
|
1497
|
+
if (runtime.schema_version === "vtx_inference_service_runtime_v1" && runtime.manifest_generation === currentManifest.generation && typeof runtime.updated_at === "string" && Date.parse(runtime.updated_at) >= Date.parse(candidate.selected_at) && JSON.stringify(workerNames) === JSON.stringify(currentManifest.worker_names) && everyWorkerRunning) return "ready";
|
|
1367
1498
|
}
|
|
1368
1499
|
} catch {
|
|
1369
1500
|
}
|
|
1370
|
-
await
|
|
1501
|
+
await waitForUpdateCheck(250, signal);
|
|
1371
1502
|
}
|
|
1372
1503
|
return signal.aborted ? "aborted" : "timeout";
|
|
1373
1504
|
};
|
|
@@ -1399,6 +1530,18 @@ var supervisorArguments = (script, manifestPath) => [
|
|
|
1399
1530
|
"--service-manifest",
|
|
1400
1531
|
manifestPath
|
|
1401
1532
|
];
|
|
1533
|
+
var waitForUpdateCheck = async (milliseconds, signal) => {
|
|
1534
|
+
if (signal.aborted) return;
|
|
1535
|
+
await new Promise((resolvePromise) => {
|
|
1536
|
+
const finish = () => {
|
|
1537
|
+
clearTimeout(timer);
|
|
1538
|
+
signal.removeEventListener("abort", finish);
|
|
1539
|
+
resolvePromise();
|
|
1540
|
+
};
|
|
1541
|
+
const timer = setTimeout(finish, milliseconds);
|
|
1542
|
+
signal.addEventListener("abort", finish, { once: true });
|
|
1543
|
+
});
|
|
1544
|
+
};
|
|
1402
1545
|
var runInferenceHostServiceBootstrap = async (manifestPathValue, dependencies = {}, lockPathValue) => {
|
|
1403
1546
|
const manifestPath = resolve2(manifestPathValue);
|
|
1404
1547
|
const lockPath = safePath(
|
|
@@ -1406,127 +1549,217 @@ var runInferenceHostServiceBootstrap = async (manifestPathValue, dependencies =
|
|
|
1406
1549
|
"lock path"
|
|
1407
1550
|
);
|
|
1408
1551
|
const lock = await (dependencies.acquireProcessLock ?? acquireInferenceHostProcessLock)(lockPath);
|
|
1552
|
+
const lifetime = new AbortController();
|
|
1553
|
+
const live = { supervisor: null };
|
|
1554
|
+
const stop = () => {
|
|
1555
|
+
lifetime.abort();
|
|
1556
|
+
try {
|
|
1557
|
+
live.supervisor?.requestDrain();
|
|
1558
|
+
} catch {
|
|
1559
|
+
}
|
|
1560
|
+
};
|
|
1561
|
+
dependencies.signal?.addEventListener("abort", stop, { once: true });
|
|
1562
|
+
process.on("SIGTERM", stop);
|
|
1563
|
+
process.on("SIGINT", stop);
|
|
1564
|
+
if (dependencies.signal?.aborted) stop();
|
|
1409
1565
|
try {
|
|
1410
|
-
|
|
1411
|
-
|
|
1566
|
+
let manifest = parseManifest(JSON.parse(await readFile2(manifestPath, "utf8")));
|
|
1567
|
+
const shouldRun = async () => !lifetime.signal.aborted && await readDesired(manifestPath);
|
|
1568
|
+
if (!await shouldRun()) {
|
|
1412
1569
|
await appendBootstrapLog(manifest.log_path, "service_bootstrap_stopped");
|
|
1413
1570
|
return 0;
|
|
1414
1571
|
}
|
|
1415
1572
|
const now = dependencies.now ?? (() => /* @__PURE__ */ new Date());
|
|
1416
1573
|
const sleep = dependencies.sleep ?? (async (milliseconds) => {
|
|
1417
|
-
await
|
|
1574
|
+
await waitForUpdateCheck(milliseconds, lifetime.signal);
|
|
1418
1575
|
});
|
|
1419
1576
|
const runSupervisor = dependencies.runSupervisor ?? defaultRunSupervisor;
|
|
1420
|
-
const
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
})
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1577
|
+
const updateDependencies = {
|
|
1578
|
+
fetch: dependencies.fetch ?? fetch,
|
|
1579
|
+
now,
|
|
1580
|
+
platform: dependencies.platform ?? process.platform,
|
|
1581
|
+
runCommand: dependencies.runCommand ?? defaultRunCommand,
|
|
1582
|
+
sleep,
|
|
1583
|
+
signal: lifetime.signal
|
|
1584
|
+
};
|
|
1585
|
+
const checkUpdate = async () => {
|
|
1586
|
+
manifest = parseManifest(JSON.parse(await readFile2(manifestPath, "utf8")));
|
|
1587
|
+
const active = await parseSelection(manifestPath);
|
|
1588
|
+
try {
|
|
1589
|
+
return await updateSelection(manifestPath, manifest, updateDependencies);
|
|
1590
|
+
} catch (error) {
|
|
1591
|
+
await appendBootstrapLog(manifest.log_path, "service_update_deferred", {
|
|
1592
|
+
reason: error instanceof Error ? error.message.slice(0, 160) : "unknown"
|
|
1593
|
+
});
|
|
1594
|
+
return { active, candidate: null };
|
|
1595
|
+
}
|
|
1596
|
+
};
|
|
1439
1597
|
const launch = async (selection) => {
|
|
1598
|
+
manifest = parseManifest(JSON.parse(await readFile2(manifestPath, "utf8")));
|
|
1440
1599
|
const script = selection?.script ?? manifest.script;
|
|
1441
1600
|
await access(manifest.executable);
|
|
1442
1601
|
await access(script);
|
|
1602
|
+
if (!await shouldRun()) return null;
|
|
1443
1603
|
await appendBootstrapLog(manifest.log_path, "service_bootstrap_launch", {
|
|
1444
1604
|
package_version: selection?.package_version ?? agent_cli_release_default.package_version
|
|
1445
1605
|
});
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
).completion;
|
|
1606
|
+
if (!await shouldRun()) return null;
|
|
1607
|
+
live.supervisor = runSupervisor(manifest.executable, supervisorArguments(script, manifestPath));
|
|
1608
|
+
return live.supervisor;
|
|
1450
1609
|
};
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
let candidateFailure = "candidate_launch_failed";
|
|
1458
|
-
let candidateExitCode = 1;
|
|
1459
|
-
const readinessController = new AbortController();
|
|
1460
|
-
try {
|
|
1461
|
-
candidateSupervisor = runSupervisor(
|
|
1462
|
-
manifest.executable,
|
|
1463
|
-
supervisorArguments(candidate.script, manifestPath)
|
|
1464
|
-
);
|
|
1465
|
-
const first = await Promise.race([
|
|
1466
|
-
candidateSupervisor.completion.then(
|
|
1467
|
-
(exitCode) => ({ kind: "exit", exitCode }),
|
|
1468
|
-
() => ({ kind: "error", exitCode: 1 })
|
|
1469
|
-
),
|
|
1470
|
-
waitForCandidateReadiness(
|
|
1471
|
-
manifestPath,
|
|
1472
|
-
manifest,
|
|
1473
|
-
candidate,
|
|
1474
|
-
readinessController.signal,
|
|
1475
|
-
sleep,
|
|
1476
|
-
dependencies.readinessTimeoutMs ?? CANDIDATE_READINESS_TIMEOUT_MS
|
|
1477
|
-
).then((status) => ({ kind: status, exitCode: 1 }))
|
|
1478
|
-
]);
|
|
1479
|
-
if (first.kind === "ready") {
|
|
1480
|
-
readinessController.abort();
|
|
1481
|
-
await atomicWriteSelection(manifestPath, candidate);
|
|
1482
|
-
await rm2(rejectionPathFor(manifestPath), { force: true }).catch(() => void 0);
|
|
1483
|
-
await prunePrivateReleases(manifestPath, [candidate, updatePlan.active]).catch(
|
|
1484
|
-
async () => await appendBootstrapLog(
|
|
1485
|
-
manifest.log_path,
|
|
1486
|
-
"service_release_cleanup_deferred",
|
|
1487
|
-
{ package_version: candidate.package_version }
|
|
1488
|
-
).catch(() => void 0)
|
|
1489
|
-
);
|
|
1490
|
-
await appendBootstrapLog(manifest.log_path, "service_release_selected", {
|
|
1610
|
+
let updatePlan = await checkUpdate();
|
|
1611
|
+
while (await shouldRun()) {
|
|
1612
|
+
if (updatePlan.candidate) {
|
|
1613
|
+
const candidate = { ...updatePlan.candidate, selected_at: now().toISOString() };
|
|
1614
|
+
await rm2(runtimePathFor(manifestPath), { force: true });
|
|
1615
|
+
await appendBootstrapLog(manifest.log_path, "service_release_candidate_started", {
|
|
1491
1616
|
package_version: candidate.package_version
|
|
1492
|
-
})
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
candidateExitCode = await candidateSupervisor.completion.catch(() => 1);
|
|
1499
|
-
} else {
|
|
1500
|
-
candidateFailure = first.kind === "error" ? "candidate_launch_failed" : "candidate_exited_before_readiness";
|
|
1501
|
-
candidateExitCode = first.exitCode;
|
|
1502
|
-
}
|
|
1503
|
-
} catch {
|
|
1504
|
-
candidateFailure = "candidate_launch_failed";
|
|
1505
|
-
candidateExitCode = 1;
|
|
1506
|
-
if (candidateSupervisor) {
|
|
1617
|
+
});
|
|
1618
|
+
let candidateFailure = "candidate_launch_failed";
|
|
1619
|
+
let promoted = false;
|
|
1620
|
+
const readinessController = new AbortController();
|
|
1621
|
+
const abortReadiness = () => readinessController.abort();
|
|
1622
|
+
lifetime.signal.addEventListener("abort", abortReadiness, { once: true });
|
|
1507
1623
|
try {
|
|
1508
|
-
candidateSupervisor
|
|
1624
|
+
const candidateSupervisor = await launch(candidate);
|
|
1625
|
+
if (!candidateSupervisor) return 0;
|
|
1626
|
+
const first = await Promise.race([
|
|
1627
|
+
candidateSupervisor.completion.then(
|
|
1628
|
+
(exitCode) => ({ kind: "exit", exitCode }),
|
|
1629
|
+
() => ({ kind: "error", exitCode: 1 })
|
|
1630
|
+
),
|
|
1631
|
+
waitForCandidateReadiness(
|
|
1632
|
+
manifestPath,
|
|
1633
|
+
candidate,
|
|
1634
|
+
readinessController.signal,
|
|
1635
|
+
dependencies.readinessTimeoutMs ?? CANDIDATE_READINESS_TIMEOUT_MS
|
|
1636
|
+
).then((status) => ({ kind: status, exitCode: 1 }))
|
|
1637
|
+
]);
|
|
1638
|
+
if (first.kind === "ready" && await shouldRun()) {
|
|
1639
|
+
await atomicWriteSelection(manifestPath, candidate);
|
|
1640
|
+
await rm2(rejectionPathFor(manifestPath), { force: true }).catch(() => void 0);
|
|
1641
|
+
await prunePrivateReleases(manifestPath, [candidate, updatePlan.active]).catch(
|
|
1642
|
+
async () => await appendBootstrapLog(
|
|
1643
|
+
manifest.log_path,
|
|
1644
|
+
"service_release_cleanup_deferred",
|
|
1645
|
+
{ package_version: candidate.package_version }
|
|
1646
|
+
).catch(() => void 0)
|
|
1647
|
+
);
|
|
1648
|
+
await appendBootstrapLog(manifest.log_path, "service_release_selected", {
|
|
1649
|
+
package_version: candidate.package_version
|
|
1650
|
+
}).catch(() => void 0);
|
|
1651
|
+
updatePlan = { active: candidate, candidate: null };
|
|
1652
|
+
promoted = true;
|
|
1653
|
+
} else {
|
|
1654
|
+
candidateFailure = first.kind === "timeout" ? "candidate_readiness_timeout" : "candidate_exited_before_readiness";
|
|
1655
|
+
if (first.kind !== "exit" && first.kind !== "error") candidateSupervisor.requestDrain();
|
|
1656
|
+
await candidateSupervisor.completion.catch(() => 1);
|
|
1657
|
+
live.supervisor = null;
|
|
1658
|
+
}
|
|
1509
1659
|
} catch {
|
|
1660
|
+
candidateFailure = "candidate_launch_failed";
|
|
1661
|
+
if (live.supervisor) {
|
|
1662
|
+
live.supervisor.requestDrain();
|
|
1663
|
+
await live.supervisor.completion.catch(() => 1);
|
|
1664
|
+
live.supervisor = null;
|
|
1665
|
+
}
|
|
1666
|
+
} finally {
|
|
1667
|
+
readinessController.abort();
|
|
1668
|
+
lifetime.signal.removeEventListener("abort", abortReadiness);
|
|
1669
|
+
}
|
|
1670
|
+
if (!await shouldRun()) {
|
|
1671
|
+
if (live.supervisor) {
|
|
1672
|
+
live.supervisor.requestDrain();
|
|
1673
|
+
await live.supervisor.completion.catch(() => 1);
|
|
1674
|
+
}
|
|
1675
|
+
return 0;
|
|
1676
|
+
}
|
|
1677
|
+
if (!promoted) {
|
|
1678
|
+
await writeRejection(manifestPath, {
|
|
1679
|
+
schema_version: "vtx_inference_service_release_rejection_v1",
|
|
1680
|
+
package_version: candidate.package_version,
|
|
1681
|
+
rejected_at: now().toISOString(),
|
|
1682
|
+
reason: candidateFailure
|
|
1683
|
+
});
|
|
1684
|
+
await prunePrivateReleases(manifestPath, [updatePlan.active]);
|
|
1685
|
+
await appendBootstrapLog(manifest.log_path, "service_release_rolled_back", {
|
|
1686
|
+
package_version: candidate.package_version,
|
|
1687
|
+
reason: candidateFailure
|
|
1688
|
+
});
|
|
1689
|
+
updatePlan = { active: updatePlan.active, candidate: null };
|
|
1510
1690
|
}
|
|
1511
|
-
candidateExitCode = await candidateSupervisor.completion.catch(() => 1);
|
|
1512
1691
|
}
|
|
1513
|
-
|
|
1514
|
-
|
|
1692
|
+
const supervisor = live.supervisor ?? await launch(updatePlan.active);
|
|
1693
|
+
if (!supervisor) return 0;
|
|
1694
|
+
let exited = false;
|
|
1695
|
+
const completion = supervisor.completion.then(
|
|
1696
|
+
(exitCode) => {
|
|
1697
|
+
exited = true;
|
|
1698
|
+
return exitCode;
|
|
1699
|
+
},
|
|
1700
|
+
() => {
|
|
1701
|
+
exited = true;
|
|
1702
|
+
return 1;
|
|
1703
|
+
}
|
|
1704
|
+
);
|
|
1705
|
+
while (!exited) {
|
|
1706
|
+
const pollController = new AbortController();
|
|
1707
|
+
const abortPoll = () => pollController.abort();
|
|
1708
|
+
lifetime.signal.addEventListener("abort", abortPoll, { once: true });
|
|
1709
|
+
if (lifetime.signal.aborted) pollController.abort();
|
|
1710
|
+
try {
|
|
1711
|
+
await Promise.race([
|
|
1712
|
+
completion,
|
|
1713
|
+
waitForUpdateCheck(
|
|
1714
|
+
dependencies.updateCheckIntervalMs ?? runtime_policy_generated_default.external_inference.service.update_check_interval_ms,
|
|
1715
|
+
pollController.signal
|
|
1716
|
+
)
|
|
1717
|
+
]);
|
|
1718
|
+
} finally {
|
|
1719
|
+
pollController.abort();
|
|
1720
|
+
lifetime.signal.removeEventListener("abort", abortPoll);
|
|
1721
|
+
}
|
|
1722
|
+
if (exited) {
|
|
1723
|
+
live.supervisor = null;
|
|
1724
|
+
return await completion;
|
|
1725
|
+
}
|
|
1726
|
+
if (!await shouldRun()) {
|
|
1727
|
+
supervisor.requestDrain();
|
|
1728
|
+
return await completion;
|
|
1729
|
+
}
|
|
1730
|
+
const next = await checkUpdate();
|
|
1731
|
+
if (exited) {
|
|
1732
|
+
live.supervisor = null;
|
|
1733
|
+
return await completion;
|
|
1734
|
+
}
|
|
1735
|
+
if (!await shouldRun()) {
|
|
1736
|
+
supervisor.requestDrain();
|
|
1737
|
+
return await completion;
|
|
1738
|
+
}
|
|
1739
|
+
if (!next.candidate) continue;
|
|
1740
|
+
await appendBootstrapLog(manifest.log_path, "service_release_quiescing", {
|
|
1741
|
+
package_version: next.candidate.package_version
|
|
1742
|
+
});
|
|
1743
|
+
supervisor.requestQuiesce();
|
|
1744
|
+
await completion;
|
|
1745
|
+
live.supervisor = null;
|
|
1746
|
+
updatePlan = next;
|
|
1747
|
+
break;
|
|
1748
|
+
}
|
|
1515
1749
|
}
|
|
1516
|
-
|
|
1517
|
-
await writeRejection(manifestPath, {
|
|
1518
|
-
schema_version: "vtx_inference_service_release_rejection_v1",
|
|
1519
|
-
package_version: candidate.package_version,
|
|
1520
|
-
rejected_at: now().toISOString(),
|
|
1521
|
-
reason: candidateFailure
|
|
1522
|
-
});
|
|
1523
|
-
await prunePrivateReleases(manifestPath, [updatePlan.active]);
|
|
1524
|
-
await appendBootstrapLog(manifest.log_path, "service_release_rolled_back", {
|
|
1525
|
-
package_version: candidate.package_version,
|
|
1526
|
-
reason: candidateFailure
|
|
1527
|
-
});
|
|
1528
|
-
return await launch(updatePlan.active);
|
|
1750
|
+
return 0;
|
|
1529
1751
|
} finally {
|
|
1752
|
+
lifetime.abort();
|
|
1753
|
+
if (live.supervisor) {
|
|
1754
|
+
try {
|
|
1755
|
+
live.supervisor.requestDrain();
|
|
1756
|
+
} catch {
|
|
1757
|
+
}
|
|
1758
|
+
await live.supervisor.completion.catch(() => 1);
|
|
1759
|
+
}
|
|
1760
|
+
dependencies.signal?.removeEventListener("abort", stop);
|
|
1761
|
+
process.removeListener("SIGTERM", stop);
|
|
1762
|
+
process.removeListener("SIGINT", stop);
|
|
1530
1763
|
await lock.release();
|
|
1531
1764
|
}
|
|
1532
1765
|
};
|
package/bin/vtx.js
CHANGED
|
@@ -77,7 +77,7 @@ var init_agent_cli_release = __esm({
|
|
|
77
77
|
"agent-cli-release.json"() {
|
|
78
78
|
agent_cli_release_default = {
|
|
79
79
|
package_name: "@vtxmacro/cli",
|
|
80
|
-
package_version: "2026.9.
|
|
80
|
+
package_version: "2026.9.30",
|
|
81
81
|
codex_package_name: "@openai/codex",
|
|
82
82
|
codex_version: "0.153.3",
|
|
83
83
|
copilot_sdk_package_name: "@github/copilot-sdk",
|
|
@@ -34882,6 +34882,7 @@ var init_grok_runtime = __esm({
|
|
|
34882
34882
|
env: {
|
|
34883
34883
|
...grokRuntimeEnvironment(options.grokHome),
|
|
34884
34884
|
...options.config ? { GROK_CONFIG: JSON.stringify(options.config) } : {},
|
|
34885
|
+
...options.agentName ? { GROK_AGENT: options.agentName } : {},
|
|
34885
34886
|
...typeof grokObject(options.config?.endpoints).cli_chat_proxy_base_url === "string" ? { GROK_CLI_CHAT_PROXY_BASE_URL: String(grokObject(options.config?.endpoints).cli_chat_proxy_base_url) } : {}
|
|
34886
34887
|
},
|
|
34887
34888
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -35540,6 +35541,9 @@ var init_grok_adapter = __esm({
|
|
|
35540
35541
|
binaryPath: binary.path,
|
|
35541
35542
|
grokHome: this.grokHome,
|
|
35542
35543
|
cwd: workspace,
|
|
35544
|
+
// Explicit native selection makes the ACP profile authoritative even
|
|
35545
|
+
// when the remote model catalog recommends a different strict harness.
|
|
35546
|
+
agentName: "grok-build",
|
|
35543
35547
|
config: {
|
|
35544
35548
|
endpoints: { cli_chat_proxy_base_url: proxy.baseUrl },
|
|
35545
35549
|
features: { turn_summary: false, title_refresh: false, telemetry: false, memory: false }
|
|
@@ -35576,11 +35580,6 @@ var init_grok_adapter = __esm({
|
|
|
35576
35580
|
_meta: metadata
|
|
35577
35581
|
}, input.deadlineAtMs, input.signal);
|
|
35578
35582
|
}
|
|
35579
|
-
await session.request("session/set_model", {
|
|
35580
|
-
sessionId,
|
|
35581
|
-
modelId: input.requestedModel,
|
|
35582
|
-
_meta: { reasoningEffort: input.requestedReasoningEffort }
|
|
35583
|
-
}, input.deadlineAtMs, input.signal);
|
|
35584
35583
|
assertSelection(created, input.requestedModel, input.requestedReasoningEffort);
|
|
35585
35584
|
const thread = {
|
|
35586
35585
|
threadId: sessionId,
|
|
@@ -37894,6 +37893,13 @@ var init_runner = __esm({
|
|
|
37894
37893
|
};
|
|
37895
37894
|
let removeAbortListener = () => {
|
|
37896
37895
|
};
|
|
37896
|
+
let removeQuiesceListener = () => {
|
|
37897
|
+
};
|
|
37898
|
+
let quiesceRequested = Boolean(this.options.quiesceSignal?.aborted);
|
|
37899
|
+
let wakeQuiesce;
|
|
37900
|
+
const quiesceWake = new Promise((resolve12) => {
|
|
37901
|
+
wakeQuiesce = resolve12;
|
|
37902
|
+
});
|
|
37897
37903
|
let drainRequested = false;
|
|
37898
37904
|
let drainReason = "stopped";
|
|
37899
37905
|
let receipt;
|
|
@@ -37932,6 +37938,13 @@ var init_runner = __esm({
|
|
|
37932
37938
|
wakeDrain();
|
|
37933
37939
|
};
|
|
37934
37940
|
try {
|
|
37941
|
+
const onQuiesce = () => {
|
|
37942
|
+
quiesceRequested = true;
|
|
37943
|
+
wakeQuiesce();
|
|
37944
|
+
};
|
|
37945
|
+
this.options.quiesceSignal?.addEventListener("abort", onQuiesce, { once: true });
|
|
37946
|
+
removeQuiesceListener = () => this.options.quiesceSignal?.removeEventListener("abort", onQuiesce);
|
|
37947
|
+
if (quiesceRequested) return { claimed, completed, failed, drain_reason: "service_update" };
|
|
37935
37948
|
unregisterSignals = (this.dependencies.registerSignalHandlers ?? defaultRegisterSignalHandlers)(requestDrain);
|
|
37936
37949
|
if (this.options.signal) {
|
|
37937
37950
|
const onAbort = () => requestDrain("aborted");
|
|
@@ -38034,8 +38047,9 @@ var init_runner = __esm({
|
|
|
38034
38047
|
await mcp.initialize({ signal: this.options.signal });
|
|
38035
38048
|
if (settings.agentRuntime) {
|
|
38036
38049
|
const agentRuntimeSettings = settings.agentRuntime;
|
|
38050
|
+
const agentIdleSignal = this.options.quiesceSignal ? AbortSignal.any([agentAbort.signal, this.options.quiesceSignal]) : agentAbort.signal;
|
|
38037
38051
|
agentLoop = (async () => {
|
|
38038
|
-
while (!agentAbort.signal.aborted) {
|
|
38052
|
+
while (!agentAbort.signal.aborted && !quiesceRequested) {
|
|
38039
38053
|
const existingFence = await readInferenceAgentFailureFence(
|
|
38040
38054
|
agentRuntimeSettings.statePath
|
|
38041
38055
|
);
|
|
@@ -38068,7 +38082,7 @@ var init_runner = __esm({
|
|
|
38068
38082
|
});
|
|
38069
38083
|
if (this.options.once) return;
|
|
38070
38084
|
try {
|
|
38071
|
-
await sleep4(Math.max(MIN_SLEEP_MS, retryAtMs - now()),
|
|
38085
|
+
await sleep4(Math.max(MIN_SLEEP_MS, retryAtMs - now()), agentIdleSignal);
|
|
38072
38086
|
} catch {
|
|
38073
38087
|
return;
|
|
38074
38088
|
}
|
|
@@ -38083,7 +38097,8 @@ var init_runner = __esm({
|
|
|
38083
38097
|
statePath: agentRuntimeSettings.statePath,
|
|
38084
38098
|
controlClient: createInferenceAgentControlClient(mcp),
|
|
38085
38099
|
adapter: agentRuntimeSettings.adapter,
|
|
38086
|
-
dataRequestTimeoutMs: agentRuntimeSettings.dataRequestTimeoutMs
|
|
38100
|
+
dataRequestTimeoutMs: agentRuntimeSettings.dataRequestTimeoutMs,
|
|
38101
|
+
quiesceSignal: this.options.quiesceSignal
|
|
38087
38102
|
});
|
|
38088
38103
|
try {
|
|
38089
38104
|
if (this.options.once) {
|
|
@@ -38152,7 +38167,7 @@ var init_runner = __esm({
|
|
|
38152
38167
|
);
|
|
38153
38168
|
if (this.options.once || retryAtMs === null) return;
|
|
38154
38169
|
try {
|
|
38155
|
-
await sleep4(Math.max(MIN_SLEEP_MS, retryAtMs - now()),
|
|
38170
|
+
await sleep4(Math.max(MIN_SLEEP_MS, retryAtMs - now()), agentIdleSignal);
|
|
38156
38171
|
} catch {
|
|
38157
38172
|
return;
|
|
38158
38173
|
}
|
|
@@ -38168,7 +38183,9 @@ var init_runner = __esm({
|
|
|
38168
38183
|
const retained = await readInferenceAgentRuntimeState(agentRuntimeSettings.statePath);
|
|
38169
38184
|
if (!retained || retained.schema_version !== "vtx_inference_agent_runtime_v3" || !retained.pending_turn?.terminal_receipt) return;
|
|
38170
38185
|
if (this.options.once) return;
|
|
38171
|
-
await sleep4(1e3,
|
|
38186
|
+
await sleep4(1e3, agentIdleSignal).catch((error49) => {
|
|
38187
|
+
if (!quiesceRequested) throw error49;
|
|
38188
|
+
});
|
|
38172
38189
|
continue;
|
|
38173
38190
|
}
|
|
38174
38191
|
if (error48 instanceof InferenceHostRunnerError && error48.code === "agent_terminal_failure_fenced") {
|
|
@@ -38180,7 +38197,9 @@ var init_runner = __esm({
|
|
|
38180
38197
|
});
|
|
38181
38198
|
if (this.options.once) return;
|
|
38182
38199
|
try {
|
|
38183
|
-
await sleep4(1e3,
|
|
38200
|
+
await sleep4(1e3, agentIdleSignal).catch((error49) => {
|
|
38201
|
+
if (!quiesceRequested) throw error49;
|
|
38202
|
+
});
|
|
38184
38203
|
} catch {
|
|
38185
38204
|
return;
|
|
38186
38205
|
}
|
|
@@ -39011,11 +39030,11 @@ var init_runner = __esm({
|
|
|
39011
39030
|
)
|
|
39012
39031
|
});
|
|
39013
39032
|
}
|
|
39014
|
-
while (!drainRequested && recoveryQueue.length > 0 && (settings.maxConcurrency === null || active.size < settings.maxConcurrency)) {
|
|
39033
|
+
while (!drainRequested && !quiesceRequested && recoveryQueue.length > 0 && (settings.maxConcurrency === null || active.size < settings.maxConcurrency)) {
|
|
39015
39034
|
const recovery = recoveryQueue.shift();
|
|
39016
39035
|
launchClaim(recovery.claim, recovery);
|
|
39017
39036
|
}
|
|
39018
|
-
while (!drainRequested) {
|
|
39037
|
+
while (!drainRequested && !quiesceRequested) {
|
|
39019
39038
|
const currentTime = now();
|
|
39020
39039
|
if (providerFailureCooldownReason !== null && currentTime >= providerFailureRetryAtMs) {
|
|
39021
39040
|
emitDiagnostic("provider_cooldown_cleared", {
|
|
@@ -39139,12 +39158,12 @@ var init_runner = __esm({
|
|
|
39139
39158
|
nextClaimAt = Math.max(nextClaimAt, nextAdvertisementAttemptAt);
|
|
39140
39159
|
}
|
|
39141
39160
|
}
|
|
39142
|
-
while (recoveryQueue.length > 0 && (settings.maxConcurrency === null || active.size < settings.maxConcurrency)) {
|
|
39161
|
+
while (!quiesceRequested && recoveryQueue.length > 0 && (settings.maxConcurrency === null || active.size < settings.maxConcurrency)) {
|
|
39143
39162
|
const recovery = recoveryQueue.shift();
|
|
39144
39163
|
launchClaim(recovery.claim, recovery);
|
|
39145
39164
|
}
|
|
39146
39165
|
let claimOpportunities = 0;
|
|
39147
|
-
while (!drainRequested && (!yieldRenewalToClaim || claimOpportunities === 0) && recoveryQueue.length === 0 && (!this.options.once || !onceClaimed) && (settings.maxConcurrency === null || active.size < settings.maxConcurrency) && pendingClaimPromotions === 0 && now() >= Math.max(
|
|
39166
|
+
while (!drainRequested && !quiesceRequested && (!yieldRenewalToClaim || claimOpportunities === 0) && recoveryQueue.length === 0 && (!this.options.once || !onceClaimed) && (settings.maxConcurrency === null || active.size < settings.maxConcurrency) && pendingClaimPromotions === 0 && now() >= Math.max(
|
|
39148
39167
|
nextClaimAt,
|
|
39149
39168
|
claimAvailabilityBackoff?.untilMs ?? 0,
|
|
39150
39169
|
providerRetryAtMs ?? 0,
|
|
@@ -39166,6 +39185,7 @@ var init_runner = __esm({
|
|
|
39166
39185
|
let claim;
|
|
39167
39186
|
let claimTiming;
|
|
39168
39187
|
const claimCallStartedAtMs = now();
|
|
39188
|
+
if (quiesceRequested) break;
|
|
39169
39189
|
try {
|
|
39170
39190
|
claimOpportunities += 1;
|
|
39171
39191
|
if (claimPreparation.unsent === request) claimPreparation.unsent = null;
|
|
@@ -39416,9 +39436,14 @@ var init_runner = __esm({
|
|
|
39416
39436
|
await Promise.race([
|
|
39417
39437
|
sleep4(Math.max(MIN_SLEEP_MS, wakeAt - now())),
|
|
39418
39438
|
drainSignal,
|
|
39439
|
+
quiesceWake,
|
|
39419
39440
|
...active.values()
|
|
39420
39441
|
]);
|
|
39421
39442
|
}
|
|
39443
|
+
if (quiesceRequested && !drainRequested) {
|
|
39444
|
+
await Promise.race([Promise.allSettled([...active.values(), agentLoop]), drainSignal]);
|
|
39445
|
+
if (!drainRequested) requestDrain("service_update");
|
|
39446
|
+
}
|
|
39422
39447
|
stopHostHeartbeatLoop();
|
|
39423
39448
|
if (providerDispatchWatchdogDrainRequested) {
|
|
39424
39449
|
await settlesWithin(hostHeartbeatLoop, MIN_SLEEP_MS);
|
|
@@ -39476,6 +39501,7 @@ var init_runner = __esm({
|
|
|
39476
39501
|
await hostHeartbeatLoop;
|
|
39477
39502
|
}
|
|
39478
39503
|
removeAbortListener();
|
|
39504
|
+
removeQuiesceListener();
|
|
39479
39505
|
unregisterSignals();
|
|
39480
39506
|
try {
|
|
39481
39507
|
await this.dependencies.codexAdapter.close?.();
|
|
@@ -40509,9 +40535,9 @@ var init_runner = __esm({
|
|
|
40509
40535
|
async run(signal) {
|
|
40510
40536
|
let exitedNormally = false;
|
|
40511
40537
|
try {
|
|
40512
|
-
while (!this.stopped && !signal?.aborted) {
|
|
40538
|
+
while (!this.stopped && !signal?.aborted && !this.options.quiesceSignal?.aborted) {
|
|
40513
40539
|
const nextWakeAt = await this.runOnce(signal);
|
|
40514
|
-
if (this.stopped || signal?.aborted) break;
|
|
40540
|
+
if (this.stopped || signal?.aborted || this.options.quiesceSignal?.aborted) break;
|
|
40515
40541
|
await this.waitUntilWake(nextWakeAt, signal);
|
|
40516
40542
|
}
|
|
40517
40543
|
exitedNormally = true;
|
|
@@ -40534,6 +40560,7 @@ var init_runner = __esm({
|
|
|
40534
40560
|
}
|
|
40535
40561
|
async runOnce(signal) {
|
|
40536
40562
|
const nowIso = () => new Date(this.now()).toISOString();
|
|
40563
|
+
if (this.options.quiesceSignal?.aborted) return this.now();
|
|
40537
40564
|
const recoveredState = await readInferenceAgentRuntimeState(this.options.statePath);
|
|
40538
40565
|
const failureFence = await readInferenceAgentFailureFence(this.options.statePath);
|
|
40539
40566
|
if (failureFence?.retry_at === null) {
|
|
@@ -40589,6 +40616,7 @@ var init_runner = __esm({
|
|
|
40589
40616
|
}
|
|
40590
40617
|
}
|
|
40591
40618
|
if (!state) {
|
|
40619
|
+
if (this.options.quiesceSignal?.aborted) return this.now();
|
|
40592
40620
|
const assignment2 = await this.options.controlClient.nextAssignment({
|
|
40593
40621
|
operation_id: randomUUID7(),
|
|
40594
40622
|
host_id: this.options.hostId,
|
|
@@ -40691,6 +40719,7 @@ var init_runner = __esm({
|
|
|
40691
40719
|
await this.handleCancelledAssignment(state, signal);
|
|
40692
40720
|
return this.now() + (this.options.idlePollMs ?? 5e3);
|
|
40693
40721
|
}
|
|
40722
|
+
if (this.options.quiesceSignal?.aborted) return this.now();
|
|
40694
40723
|
assignment = {
|
|
40695
40724
|
...assignment,
|
|
40696
40725
|
lease_expires_at: preTurnHeartbeat.lease_expires_at
|
|
@@ -41086,9 +41115,14 @@ var init_runner = __esm({
|
|
|
41086
41115
|
}
|
|
41087
41116
|
async waitUntilWake(nextWakeAtMs, signal) {
|
|
41088
41117
|
const heartbeatIntervalMs = this.options.heartbeatIntervalMs ?? 3e3;
|
|
41089
|
-
while (!this.stopped && !signal?.aborted && this.now() < nextWakeAtMs) {
|
|
41090
|
-
|
|
41091
|
-
|
|
41118
|
+
while (!this.stopped && !signal?.aborted && !this.options.quiesceSignal?.aborted && this.now() < nextWakeAtMs) {
|
|
41119
|
+
const waitSignal = this.options.quiesceSignal ? AbortSignal.any([this.options.quiesceSignal, ...signal ? [signal] : []]) : signal;
|
|
41120
|
+
try {
|
|
41121
|
+
await this.sleep(Math.min(heartbeatIntervalMs, nextWakeAtMs - this.now()), waitSignal);
|
|
41122
|
+
} catch (error48) {
|
|
41123
|
+
if (!this.options.quiesceSignal?.aborted) throw error48;
|
|
41124
|
+
}
|
|
41125
|
+
if (this.stopped || signal?.aborted || this.options.quiesceSignal?.aborted) return "stopped";
|
|
41092
41126
|
if (this.now() >= nextWakeAtMs) return "ready";
|
|
41093
41127
|
const state = await readInferenceAgentRuntimeState(this.options.statePath);
|
|
41094
41128
|
if (state?.schema_version !== "vtx_inference_agent_runtime_v3" || state.adapter_id !== this.options.adapterId) return "cancelled";
|
|
@@ -41113,7 +41147,7 @@ var init_runner = __esm({
|
|
|
41113
41147
|
updated_at: requestedAt
|
|
41114
41148
|
});
|
|
41115
41149
|
}
|
|
41116
|
-
return this.stopped || signal?.aborted ? "stopped" : "ready";
|
|
41150
|
+
return this.stopped || signal?.aborted || this.options.quiesceSignal?.aborted ? "stopped" : "ready";
|
|
41117
41151
|
}
|
|
41118
41152
|
async releaseForHostStop(reasonCode = "host_stopped") {
|
|
41119
41153
|
const recovered = await readInferenceAgentRuntimeState(this.options.statePath);
|
|
@@ -41240,6 +41274,8 @@ var init_runtime_policy_generated = __esm({
|
|
|
41240
41274
|
},
|
|
41241
41275
|
external_inference: {
|
|
41242
41276
|
service: {
|
|
41277
|
+
update_check_interval_ms: 3e5,
|
|
41278
|
+
update_registry_timeout_ms: 15e3,
|
|
41243
41279
|
startup_max_attempts: 40,
|
|
41244
41280
|
startup_poll_interval_ms: 250,
|
|
41245
41281
|
restart_stable_uptime_ms: 6e4,
|
|
@@ -41280,13 +41316,14 @@ import { createWriteStream, readFileSync } from "node:fs";
|
|
|
41280
41316
|
import { access as access4, chmod as chmod3, mkdir as mkdir3, readFile as readFile9, rm as rm10, writeFile as writeFile4 } from "node:fs/promises";
|
|
41281
41317
|
import { homedir as homedir2 } from "node:os";
|
|
41282
41318
|
import { dirname as dirname12, join as join13, resolve as resolve10 } from "node:path";
|
|
41283
|
-
var SERVICE_NAME, SYSTEMD_UNIT, LAUNCHD_LABEL, SERVICE_COOPERATIVE_STOP_SECONDS, SERVICE_UPDATE_STARTUP_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, serviceBootstrapArguments, windowsOwnedCommandLine, vbScriptString, windowsServiceLauncher, windowsTaskXml, systemdUnit, launchAgentPlist, sameWorker, sameServiceDefinition, sameWorkerSet, InferenceHostServiceManager, appendServiceLog, spawnInferenceHostServiceChild, runInferenceHostServiceSupervisor;
|
|
41319
|
+
var SERVICE_NAME, SYSTEMD_UNIT, LAUNCHD_LABEL, SERVICE_COOPERATIVE_STOP_SECONDS, SERVICE_UPDATE_STARTUP_SECONDS, INFERENCE_HOST_SERVICE_DRAIN_COMMAND, INFERENCE_HOST_SERVICE_QUIESCE_COMMAND, InferenceHostBootstrapRestartRequiredError, 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, serviceBootstrapArguments, windowsOwnedCommandLine, vbScriptString, windowsServiceLauncher, windowsTaskXml, systemdUnit, launchAgentPlist, sameWorker, sameServiceDefinition, sameWorkerSet, InferenceHostServiceManager, appendServiceLog, spawnInferenceHostServiceChild, runInferenceHostServiceSupervisor;
|
|
41284
41320
|
var init_service = __esm({
|
|
41285
41321
|
"lib/inference-host/service.ts"() {
|
|
41286
41322
|
"use strict";
|
|
41287
41323
|
init_define_VTX_EXO_POLICY();
|
|
41288
41324
|
init_define_VTX_GROK_POLICY();
|
|
41289
41325
|
init_define_VTX_PI_MODEL_POLICY();
|
|
41326
|
+
init_agent_cli_release();
|
|
41290
41327
|
init_runtime_policy_generated();
|
|
41291
41328
|
init_durable_adapter();
|
|
41292
41329
|
init_config();
|
|
@@ -41296,6 +41333,12 @@ var init_service = __esm({
|
|
|
41296
41333
|
SERVICE_COOPERATIVE_STOP_SECONDS = 75;
|
|
41297
41334
|
SERVICE_UPDATE_STARTUP_SECONDS = 600;
|
|
41298
41335
|
INFERENCE_HOST_SERVICE_DRAIN_COMMAND = "vtx-inference-host-service-drain-v1";
|
|
41336
|
+
INFERENCE_HOST_SERVICE_QUIESCE_COMMAND = "vtx-inference-host-service-quiesce-v1";
|
|
41337
|
+
InferenceHostBootstrapRestartRequiredError = class extends Error {
|
|
41338
|
+
constructor() {
|
|
41339
|
+
super("The verified service bootstrap is ready for restart.");
|
|
41340
|
+
}
|
|
41341
|
+
};
|
|
41299
41342
|
inferenceHostServiceChildEnvironment = (runtimeEnvironment2, inheritedEnvironment = process.env) => {
|
|
41300
41343
|
const environment = { ...inheritedEnvironment };
|
|
41301
41344
|
for (const key of Object.keys(environment)) {
|
|
@@ -42415,7 +42458,7 @@ ${result2.stderr}`)) {
|
|
|
42415
42458
|
});
|
|
42416
42459
|
};
|
|
42417
42460
|
spawnInferenceHostServiceChild = async (manifest, worker, signal, onReady = () => {
|
|
42418
|
-
}) => {
|
|
42461
|
+
}, quiesceSignal) => {
|
|
42419
42462
|
const args = [
|
|
42420
42463
|
manifest.script,
|
|
42421
42464
|
"inference-host",
|
|
@@ -42477,6 +42520,12 @@ ${result2.stderr}`)) {
|
|
|
42477
42520
|
child.stderr.on("data", (chunk) => writeTaggedOutput("stderr", chunk.toString("utf8")));
|
|
42478
42521
|
child.stdin.on("error", () => {
|
|
42479
42522
|
});
|
|
42523
|
+
const onQuiesce = () => {
|
|
42524
|
+
child.stdin.write(`${INFERENCE_HOST_SERVICE_QUIESCE_COMMAND}
|
|
42525
|
+
`);
|
|
42526
|
+
};
|
|
42527
|
+
if (quiesceSignal?.aborted) onQuiesce();
|
|
42528
|
+
else quiesceSignal?.addEventListener("abort", onQuiesce, { once: true });
|
|
42480
42529
|
const onAbort = () => {
|
|
42481
42530
|
child.stdin.end(`${INFERENCE_HOST_SERVICE_DRAIN_COMMAND}
|
|
42482
42531
|
`);
|
|
@@ -42490,6 +42539,7 @@ ${result2.stderr}`)) {
|
|
|
42490
42539
|
else signal.addEventListener("abort", onAbort, { once: true });
|
|
42491
42540
|
child.once("error", (error48) => {
|
|
42492
42541
|
signal.removeEventListener("abort", onAbort);
|
|
42542
|
+
quiesceSignal?.removeEventListener("abort", onQuiesce);
|
|
42493
42543
|
if (cooperativeStopTimer) clearTimeout(cooperativeStopTimer);
|
|
42494
42544
|
writeTaggedOutput("stdout", "", true);
|
|
42495
42545
|
writeTaggedOutput("stderr", "", true);
|
|
@@ -42498,6 +42548,7 @@ ${result2.stderr}`)) {
|
|
|
42498
42548
|
});
|
|
42499
42549
|
child.once("exit", (code) => {
|
|
42500
42550
|
signal.removeEventListener("abort", onAbort);
|
|
42551
|
+
quiesceSignal?.removeEventListener("abort", onQuiesce);
|
|
42501
42552
|
if (cooperativeStopTimer) clearTimeout(cooperativeStopTimer);
|
|
42502
42553
|
writeTaggedOutput("stdout", "", true);
|
|
42503
42554
|
writeTaggedOutput("stderr", "", true);
|
|
@@ -42533,6 +42584,38 @@ ${result2.stderr}`)) {
|
|
|
42533
42584
|
const desiredPath = manifestPath.replace(/\.service\.json$/u, ".service-desired.json");
|
|
42534
42585
|
const runtimePath = manifestPath.replace(/\.service\.json$/u, ".service-runtime.json");
|
|
42535
42586
|
const signal = options.signal ?? new AbortController().signal;
|
|
42587
|
+
const migrationQuiesce = new AbortController();
|
|
42588
|
+
const quiesceSignal = options.quiesceSignal ? AbortSignal.any([options.quiesceSignal, migrationQuiesce.signal]) : migrationQuiesce.signal;
|
|
42589
|
+
let bootstrapRestartRequired = false;
|
|
42590
|
+
let bootstrapMigrationErrorReported = false;
|
|
42591
|
+
const migrateSelectedBootstrap = async () => {
|
|
42592
|
+
if (!serviceScript || !options.controlLockPath || bootstrapRestartRequired || (options.bootstrapVersion ?? process.env.VTX_INFERENCE_HOST_BOOTSTRAP_VERSION) === agent_cli_release_default.package_version || quiesceSignal.aborted || signal.aborted) return;
|
|
42593
|
+
let controlLock;
|
|
42594
|
+
try {
|
|
42595
|
+
controlLock = await acquireInferenceHostProcessLock(options.controlLockPath);
|
|
42596
|
+
} catch (error48) {
|
|
42597
|
+
if (/already owns/iu.test(error48 instanceof Error ? error48.message : "")) return;
|
|
42598
|
+
throw error48;
|
|
42599
|
+
}
|
|
42600
|
+
try {
|
|
42601
|
+
const current = await readManifestAcrossAtomicReplacement(manifestPath);
|
|
42602
|
+
if (!current || current.generation !== appliedManifest.generation || !await readDesiredAcrossAtomicReplacement(desiredPath) || signal.aborted) return;
|
|
42603
|
+
let selected;
|
|
42604
|
+
try {
|
|
42605
|
+
selected = JSON.parse(await readFile9(manifestPath.replace(/\.service\.json$/u, ".service-release.json"), "utf8"));
|
|
42606
|
+
} catch (error48) {
|
|
42607
|
+
if (error48.code === "ENOENT") return;
|
|
42608
|
+
throw error48;
|
|
42609
|
+
}
|
|
42610
|
+
if (selected.schema_version !== "vtx_inference_service_release_v1" || selected.package_name !== "@vtxmacro/cli" || selected.package_version !== agent_cli_release_default.package_version || typeof selected.script !== "string" || resolve10(selected.script) !== serviceScript) return;
|
|
42611
|
+
const bytes3 = await readFile9(join13(dirname12(serviceScript), "vtx-service-bootstrap.js"), "utf8");
|
|
42612
|
+
await writeAtomicInferencePrivateFile(manifestPath.replace(/\.service\.json$/u, ".service-bootstrap.js"), bytes3);
|
|
42613
|
+
bootstrapRestartRequired = true;
|
|
42614
|
+
migrationQuiesce.abort();
|
|
42615
|
+
} finally {
|
|
42616
|
+
await controlLock.release();
|
|
42617
|
+
}
|
|
42618
|
+
};
|
|
42536
42619
|
const sleep4 = options.sleep ?? (async (milliseconds) => {
|
|
42537
42620
|
await new Promise((resolvePromise) => setTimeout(resolvePromise, milliseconds));
|
|
42538
42621
|
});
|
|
@@ -42586,7 +42669,7 @@ ${result2.stderr}`)) {
|
|
|
42586
42669
|
};
|
|
42587
42670
|
const superviseWorker = async (serviceManifest, record4) => {
|
|
42588
42671
|
let failures = 0;
|
|
42589
|
-
while (!signal.aborted && !record4.controller.signal.aborted && await readDesiredAcrossAtomicReplacement(desiredPath)) {
|
|
42672
|
+
while (!signal.aborted && !quiesceSignal.aborted && !record4.controller.signal.aborted && await readDesiredAcrossAtomicReplacement(desiredPath)) {
|
|
42590
42673
|
try {
|
|
42591
42674
|
await updateRecord(record4, "starting");
|
|
42592
42675
|
const attemptController = new AbortController();
|
|
@@ -42611,7 +42694,8 @@ ${result2.stderr}`)) {
|
|
|
42611
42694
|
await updateRecord(record4, "running");
|
|
42612
42695
|
}
|
|
42613
42696
|
})();
|
|
42614
|
-
}
|
|
42697
|
+
},
|
|
42698
|
+
quiesceSignal
|
|
42615
42699
|
);
|
|
42616
42700
|
} finally {
|
|
42617
42701
|
launchSettled = true;
|
|
@@ -42627,7 +42711,7 @@ ${result2.stderr}`)) {
|
|
|
42627
42711
|
});
|
|
42628
42712
|
throw new Error("worker_cooperative_stop_timeout");
|
|
42629
42713
|
}
|
|
42630
|
-
if (signal.aborted || record4.controller.signal.aborted || !await readDesiredAcrossAtomicReplacement(desiredPath)) break;
|
|
42714
|
+
if (signal.aborted || quiesceSignal.aborted || record4.controller.signal.aborted || !await readDesiredAcrossAtomicReplacement(desiredPath)) break;
|
|
42631
42715
|
failures = result2.uptimeMs >= runtime_policy_generated_default.external_inference.service.restart_stable_uptime_ms ? 0 : failures + 1;
|
|
42632
42716
|
const retryAfterMs = Math.min(runtime_policy_generated_default.external_inference.service.restart_backoff_base_ms * 2 ** Math.min(failures, runtime_policy_generated_default.external_inference.service.restart_exponent_max), runtime_policy_generated_default.external_inference.service.restart_backoff_max_ms);
|
|
42633
42717
|
await updateRecord(record4, "failed", "worker_exited");
|
|
@@ -42641,7 +42725,7 @@ ${result2.stderr}`)) {
|
|
|
42641
42725
|
await waitRetry(retryAfterMs, record4.controller);
|
|
42642
42726
|
} catch (error48) {
|
|
42643
42727
|
if (error48 instanceof Error && error48.message === "worker_cooperative_stop_timeout") throw error48;
|
|
42644
|
-
if (signal.aborted || record4.controller.signal.aborted) break;
|
|
42728
|
+
if (signal.aborted || quiesceSignal.aborted || record4.controller.signal.aborted) break;
|
|
42645
42729
|
failures += 1;
|
|
42646
42730
|
const retryAfterMs = Math.min(runtime_policy_generated_default.external_inference.service.restart_backoff_base_ms * 2 ** Math.min(failures, runtime_policy_generated_default.external_inference.service.restart_exponent_max), runtime_policy_generated_default.external_inference.service.restart_backoff_max_ms);
|
|
42647
42731
|
await updateRecord(record4, "failed", "worker_launch_failed");
|
|
@@ -42724,14 +42808,41 @@ ${result2.stderr}`)) {
|
|
|
42724
42808
|
};
|
|
42725
42809
|
await reconcile(initialManifest);
|
|
42726
42810
|
try {
|
|
42727
|
-
while (!signal.aborted) {
|
|
42728
|
-
while (!signal.aborted && await readDesiredAcrossAtomicReplacement(desiredPath)) {
|
|
42811
|
+
while (!signal.aborted && !quiesceSignal.aborted) {
|
|
42812
|
+
while (!signal.aborted && !quiesceSignal.aborted && await readDesiredAcrossAtomicReplacement(desiredPath)) {
|
|
42813
|
+
try {
|
|
42814
|
+
await migrateSelectedBootstrap();
|
|
42815
|
+
} catch {
|
|
42816
|
+
if (!bootstrapMigrationErrorReported) {
|
|
42817
|
+
bootstrapMigrationErrorReported = true;
|
|
42818
|
+
await appendServiceLog(appliedManifest.log_path, "service_bootstrap_migration_deferred");
|
|
42819
|
+
}
|
|
42820
|
+
}
|
|
42821
|
+
if (quiesceSignal.aborted) break;
|
|
42729
42822
|
const storedNext = await readManifestAcrossAtomicReplacement(manifestPath);
|
|
42730
42823
|
if (!storedNext) throw new Error("Inference-host service manifest is missing.");
|
|
42731
42824
|
const next = withServiceScript(storedNext);
|
|
42732
42825
|
if (next.generation !== appliedManifest.generation && next.generation !== rejectedManifestGeneration) await reconcile(next);
|
|
42733
42826
|
await sleep4(250);
|
|
42734
42827
|
}
|
|
42828
|
+
if (quiesceSignal.aborted && !signal.aborted) {
|
|
42829
|
+
let finished = false;
|
|
42830
|
+
const completion = Promise.allSettled([...workers.values()].map((record4) => record4.promise)).then((results) => {
|
|
42831
|
+
finished = true;
|
|
42832
|
+
return results;
|
|
42833
|
+
});
|
|
42834
|
+
while (!finished && !signal.aborted && await readDesiredAcrossAtomicReplacement(desiredPath)) {
|
|
42835
|
+
await Promise.race([completion, sleep4(250)]);
|
|
42836
|
+
}
|
|
42837
|
+
if (!finished) {
|
|
42838
|
+
await drainWorkers();
|
|
42839
|
+
break;
|
|
42840
|
+
}
|
|
42841
|
+
const settled = await completion;
|
|
42842
|
+
const failure2 = settled.find((result2) => result2.status === "rejected");
|
|
42843
|
+
if (failure2) throw failure2.reason;
|
|
42844
|
+
break;
|
|
42845
|
+
}
|
|
42735
42846
|
await drainWorkers();
|
|
42736
42847
|
if (signal.aborted || !await readDesiredAcrossAtomicReplacement(desiredPath)) break;
|
|
42737
42848
|
const storedRestored = await readManifestAcrossAtomicReplacement(manifestPath);
|
|
@@ -42748,6 +42859,9 @@ ${result2.stderr}`)) {
|
|
|
42748
42859
|
await runtimeWriteChain;
|
|
42749
42860
|
await appendServiceLog(appliedManifest.log_path, "service_supervisor_stopped");
|
|
42750
42861
|
}
|
|
42862
|
+
if (bootstrapRestartRequired && !signal.aborted && await readDesiredAcrossAtomicReplacement(desiredPath)) {
|
|
42863
|
+
throw new InferenceHostBootstrapRestartRequiredError();
|
|
42864
|
+
}
|
|
42751
42865
|
};
|
|
42752
42866
|
}
|
|
42753
42867
|
});
|
|
@@ -43243,7 +43357,7 @@ Durable service:
|
|
|
43243
43357
|
});
|
|
43244
43358
|
child.unref();
|
|
43245
43359
|
};
|
|
43246
|
-
registerInferenceHostServiceControlInput = (input, abort) => {
|
|
43360
|
+
registerInferenceHostServiceControlInput = (input, abort, quiesce) => {
|
|
43247
43361
|
let pendingControlInput = "";
|
|
43248
43362
|
const onControlInput = (chunk) => {
|
|
43249
43363
|
pendingControlInput = `${pendingControlInput}${chunk.toString()}`.slice(-4096);
|
|
@@ -43251,6 +43365,8 @@ Durable service:
|
|
|
43251
43365
|
pendingControlInput = lines.pop() ?? "";
|
|
43252
43366
|
if (lines.some((line) => line === INFERENCE_HOST_SERVICE_DRAIN_COMMAND)) {
|
|
43253
43367
|
abort();
|
|
43368
|
+
} else if (lines.some((line) => line === INFERENCE_HOST_SERVICE_QUIESCE_COMMAND)) {
|
|
43369
|
+
quiesce?.();
|
|
43254
43370
|
}
|
|
43255
43371
|
};
|
|
43256
43372
|
input.on("data", onControlInput);
|
|
@@ -43260,13 +43376,13 @@ Durable service:
|
|
|
43260
43376
|
input.pause();
|
|
43261
43377
|
};
|
|
43262
43378
|
};
|
|
43263
|
-
defaultRegisterLifecycleSignalHandlers = (abort) => {
|
|
43379
|
+
defaultRegisterLifecycleSignalHandlers = (abort, quiesce) => {
|
|
43264
43380
|
const onSigint = () => abort("SIGINT");
|
|
43265
43381
|
const onSigterm = () => abort("SIGTERM");
|
|
43266
43382
|
process.on("SIGINT", onSigint);
|
|
43267
43383
|
process.on("SIGTERM", onSigterm);
|
|
43268
43384
|
const serviceChild = process.env.VTX_INFERENCE_HOST_SERVICE_CHILD === "1";
|
|
43269
|
-
const unregisterControlInput = serviceChild ? registerInferenceHostServiceControlInput(process.stdin, onSigterm) : () => {
|
|
43385
|
+
const unregisterControlInput = serviceChild ? registerInferenceHostServiceControlInput(process.stdin, onSigterm, quiesce) : () => {
|
|
43270
43386
|
};
|
|
43271
43387
|
return () => {
|
|
43272
43388
|
process.off("SIGINT", onSigint);
|
|
@@ -43276,12 +43392,14 @@ Durable service:
|
|
|
43276
43392
|
};
|
|
43277
43393
|
lifecycleCancellation = (dependencies) => {
|
|
43278
43394
|
const controller = new AbortController();
|
|
43395
|
+
const quiesceController = new AbortController();
|
|
43279
43396
|
let unregistered = false;
|
|
43280
43397
|
const unregisterSignalHandlers = (dependencies.registerLifecycleSignalHandlers ?? defaultRegisterLifecycleSignalHandlers)(() => {
|
|
43281
43398
|
if (!controller.signal.aborted) controller.abort();
|
|
43282
|
-
});
|
|
43399
|
+
}, () => quiesceController.abort());
|
|
43283
43400
|
return {
|
|
43284
43401
|
signal: controller.signal,
|
|
43402
|
+
quiesceSignal: quiesceController.signal,
|
|
43285
43403
|
unregister: () => {
|
|
43286
43404
|
if (unregistered) return;
|
|
43287
43405
|
unregistered = true;
|
|
@@ -43487,7 +43605,8 @@ Durable service:
|
|
|
43487
43605
|
adapter: agentAdapter,
|
|
43488
43606
|
dataRequestTimeoutMs: await loadInferenceAgentDataRequestTimeoutMs()
|
|
43489
43607
|
},
|
|
43490
|
-
signal: options.signal
|
|
43608
|
+
signal: options.signal,
|
|
43609
|
+
quiesceSignal: options.quiesceSignal
|
|
43491
43610
|
}).run();
|
|
43492
43611
|
};
|
|
43493
43612
|
preparePortableDurableAdapter = async (adapterId, config2, signal) => {
|
|
@@ -43558,7 +43677,8 @@ Durable service:
|
|
|
43558
43677
|
adapter: agentAdapter,
|
|
43559
43678
|
dataRequestTimeoutMs: await loadInferenceAgentDataRequestTimeoutMs()
|
|
43560
43679
|
},
|
|
43561
|
-
signal: options.signal
|
|
43680
|
+
signal: options.signal,
|
|
43681
|
+
quiesceSignal: options.quiesceSignal
|
|
43562
43682
|
}).run();
|
|
43563
43683
|
};
|
|
43564
43684
|
login = async (config2, parsed, env, dependencies, warnings) => {
|
|
@@ -44356,7 +44476,8 @@ Waiting for approval...
|
|
|
44356
44476
|
once: parsed.once,
|
|
44357
44477
|
processLock,
|
|
44358
44478
|
emitDiagnosticEvent,
|
|
44359
|
-
signal: cancellation.signal
|
|
44479
|
+
signal: cancellation.signal,
|
|
44480
|
+
quiesceSignal: cancellation.quiesceSignal
|
|
44360
44481
|
});
|
|
44361
44482
|
return {
|
|
44362
44483
|
exitCode: 0,
|
|
@@ -44396,7 +44517,8 @@ Waiting for approval...
|
|
|
44396
44517
|
env,
|
|
44397
44518
|
processLock,
|
|
44398
44519
|
emitDiagnosticEvent,
|
|
44399
|
-
signal: cancellation.signal
|
|
44520
|
+
signal: cancellation.signal,
|
|
44521
|
+
quiesceSignal: cancellation.quiesceSignal
|
|
44400
44522
|
});
|
|
44401
44523
|
return {
|
|
44402
44524
|
exitCode: 0,
|
|
@@ -45720,10 +45842,15 @@ Waiting for approval...
|
|
|
45720
45842
|
parsed.serviceManifestPath,
|
|
45721
45843
|
{
|
|
45722
45844
|
signal: cancellation.signal,
|
|
45723
|
-
|
|
45845
|
+
quiesceSignal: cancellation.quiesceSignal,
|
|
45846
|
+
serviceScript: resolve11(process.argv[1] ?? ""),
|
|
45847
|
+
controlLockPath: `${supervisorConfig.supervisorProcessLockPath}.service-control`
|
|
45724
45848
|
}
|
|
45725
45849
|
);
|
|
45726
45850
|
return { exitCode: 0, stdout: "", stderr: "" };
|
|
45851
|
+
} catch (error48) {
|
|
45852
|
+
if (error48 instanceof InferenceHostBootstrapRestartRequiredError) return { exitCode: 75, stdout: "", stderr: "" };
|
|
45853
|
+
throw error48;
|
|
45727
45854
|
} finally {
|
|
45728
45855
|
cancellation.unregister();
|
|
45729
45856
|
await serviceLock.release();
|
|
@@ -49776,6 +49903,8 @@ var init_runtime_policy_generated2 = __esm({
|
|
|
49776
49903
|
},
|
|
49777
49904
|
external_inference: {
|
|
49778
49905
|
service: {
|
|
49906
|
+
update_check_interval_ms: 3e5,
|
|
49907
|
+
update_registry_timeout_ms: 15e3,
|
|
49779
49908
|
startup_max_attempts: 40,
|
|
49780
49909
|
startup_poll_interval_ms: 250,
|
|
49781
49910
|
restart_stable_uptime_ms: 6e4,
|