@thyn-ai/sqai 0.1.2 → 0.1.3

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/dist/index.d.cts CHANGED
@@ -140,12 +140,29 @@ interface RuntimeStatus {
140
140
  platform: string;
141
141
  managed: boolean;
142
142
  }
143
+ /** A runtime bundle resolved for a specific module filter (build-on-provision). */
144
+ interface FilteredBundle {
145
+ url: string;
146
+ sha256: string;
147
+ version: string;
148
+ cacheKey: string;
149
+ }
143
150
  interface ProvisionerOptions {
144
151
  contract: CapabilityContract;
145
152
  autoInstall: boolean;
153
+ /**
154
+ * Build-on-provision: the developer's module filter. All 4,762 functions are
155
+ * available in the contract; only the selected modules are compiled + installed.
156
+ * Empty/undefined → the default pinned bundle (contract.runtime_bundle).
157
+ */
158
+ runtimeModules?: string[];
159
+ /** Build service that compiles a bundle for an exact filter (POST /v1/runtime/build). */
160
+ buildServiceUrl?: string;
146
161
  /** Injection points for tests. */
147
162
  runtimeFactory?: (config?: MojoRuntimeConfig) => MojoRuntime;
148
163
  downloadBundle?: (url: string, destination: string) => Promise<void>;
164
+ /** Resolve a filtered bundle (default: POST to buildServiceUrl). Test injection. */
165
+ resolveFilteredBundle?: (modules: string[], platformKey: string) => Promise<FilteredBundle>;
149
166
  /** Bundle cache directory (default: OS user cache — runtimeCacheDir()). */
150
167
  cacheDir?: string;
151
168
  /** Trust-root overrides (default: the embedded trust root). */
@@ -171,6 +188,27 @@ declare class RuntimeProvisioner {
171
188
  stop(): Promise<void>;
172
189
  private newRuntime;
173
190
  private cacheDir;
191
+ /** Normalized module filter (sorted, unique, non-empty) or null for the default bundle. */
192
+ private filterModules;
193
+ /** Ask the build service to compile + sign a bundle for exactly these modules. */
194
+ private resolveFilteredBundle;
195
+ /**
196
+ * The filter's cache key, computed IDENTICALLY to the build service
197
+ * (sha256("mods|platform|version")[:20], mods = sorted+unique, comma-joined).
198
+ * Lets the reuse fast-path find an already-running filtered daemon without a
199
+ * build-service round-trip. The build service's returned key is authoritative
200
+ * for install; this only has to match for the reuse optimization to hit.
201
+ */
202
+ private localCacheKey;
203
+ /**
204
+ * Deterministic per-filter daemon endpoint so a filtered runtime never collides
205
+ * with the default (or another filter's) daemon on the shared default socket.
206
+ */
207
+ private filterEndpoint;
208
+ private static readonly DAEMON_ENDPOINT_ENV;
209
+ /** Point the about-to-be-spawned daemon at a filter-specific socket/port/dir. */
210
+ private applyDaemonEndpointEnv;
211
+ private restoreEnv;
174
212
  private doEnsure;
175
213
  private provisionError;
176
214
  private wrapVerificationError;
@@ -179,7 +217,7 @@ declare class RuntimeProvisioner {
179
217
  private verifiedInstallOrNull;
180
218
  private acquireLock;
181
219
  private lockIsStale;
182
- /** Serialize installers on `<cacheDir>/<version>.lock`; returns the verified install. */
220
+ /** Serialize installers on `<cacheDir>/<installKey>.lock`; returns the verified install. */
183
221
  private ensureInstalled;
184
222
  /** Holder-of-the-lock path: download → verify → extract → atomic rename. */
185
223
  private downloadVerifyExtract;
@@ -384,6 +422,15 @@ interface SqaiConfig {
384
422
  timeout?: number;
385
423
  maxRetries?: number;
386
424
  resultStore?: ResultStoreConfig;
425
+ /**
426
+ * Build-on-provision module filter. All 4,762 functions are available in the
427
+ * contract; set this to install only the modules you use. The build service
428
+ * compiles + signs a bundle for exactly this set (cached by filter-hash).
429
+ * Omit for the default pinned bundle. Env: SQAI_RUNTIME_MODULES (comma-separated).
430
+ */
431
+ runtimeModules?: string[];
432
+ /** Build service endpoint for filtered bundles. Env: SQAI_BUILD_SERVICE_URL. */
433
+ buildServiceUrl?: string;
387
434
  /** BYO substrate (tests). */
388
435
  runtime?: Runtime;
389
436
  /** BYO computation dispatch target (tests / custom self-hosted engines). */
package/dist/index.d.ts CHANGED
@@ -140,12 +140,29 @@ interface RuntimeStatus {
140
140
  platform: string;
141
141
  managed: boolean;
142
142
  }
143
+ /** A runtime bundle resolved for a specific module filter (build-on-provision). */
144
+ interface FilteredBundle {
145
+ url: string;
146
+ sha256: string;
147
+ version: string;
148
+ cacheKey: string;
149
+ }
143
150
  interface ProvisionerOptions {
144
151
  contract: CapabilityContract;
145
152
  autoInstall: boolean;
153
+ /**
154
+ * Build-on-provision: the developer's module filter. All 4,762 functions are
155
+ * available in the contract; only the selected modules are compiled + installed.
156
+ * Empty/undefined → the default pinned bundle (contract.runtime_bundle).
157
+ */
158
+ runtimeModules?: string[];
159
+ /** Build service that compiles a bundle for an exact filter (POST /v1/runtime/build). */
160
+ buildServiceUrl?: string;
146
161
  /** Injection points for tests. */
147
162
  runtimeFactory?: (config?: MojoRuntimeConfig) => MojoRuntime;
148
163
  downloadBundle?: (url: string, destination: string) => Promise<void>;
164
+ /** Resolve a filtered bundle (default: POST to buildServiceUrl). Test injection. */
165
+ resolveFilteredBundle?: (modules: string[], platformKey: string) => Promise<FilteredBundle>;
149
166
  /** Bundle cache directory (default: OS user cache — runtimeCacheDir()). */
150
167
  cacheDir?: string;
151
168
  /** Trust-root overrides (default: the embedded trust root). */
@@ -171,6 +188,27 @@ declare class RuntimeProvisioner {
171
188
  stop(): Promise<void>;
172
189
  private newRuntime;
173
190
  private cacheDir;
191
+ /** Normalized module filter (sorted, unique, non-empty) or null for the default bundle. */
192
+ private filterModules;
193
+ /** Ask the build service to compile + sign a bundle for exactly these modules. */
194
+ private resolveFilteredBundle;
195
+ /**
196
+ * The filter's cache key, computed IDENTICALLY to the build service
197
+ * (sha256("mods|platform|version")[:20], mods = sorted+unique, comma-joined).
198
+ * Lets the reuse fast-path find an already-running filtered daemon without a
199
+ * build-service round-trip. The build service's returned key is authoritative
200
+ * for install; this only has to match for the reuse optimization to hit.
201
+ */
202
+ private localCacheKey;
203
+ /**
204
+ * Deterministic per-filter daemon endpoint so a filtered runtime never collides
205
+ * with the default (or another filter's) daemon on the shared default socket.
206
+ */
207
+ private filterEndpoint;
208
+ private static readonly DAEMON_ENDPOINT_ENV;
209
+ /** Point the about-to-be-spawned daemon at a filter-specific socket/port/dir. */
210
+ private applyDaemonEndpointEnv;
211
+ private restoreEnv;
174
212
  private doEnsure;
175
213
  private provisionError;
176
214
  private wrapVerificationError;
@@ -179,7 +217,7 @@ declare class RuntimeProvisioner {
179
217
  private verifiedInstallOrNull;
180
218
  private acquireLock;
181
219
  private lockIsStale;
182
- /** Serialize installers on `<cacheDir>/<version>.lock`; returns the verified install. */
220
+ /** Serialize installers on `<cacheDir>/<installKey>.lock`; returns the verified install. */
183
221
  private ensureInstalled;
184
222
  /** Holder-of-the-lock path: download → verify → extract → atomic rename. */
185
223
  private downloadVerifyExtract;
@@ -384,6 +422,15 @@ interface SqaiConfig {
384
422
  timeout?: number;
385
423
  maxRetries?: number;
386
424
  resultStore?: ResultStoreConfig;
425
+ /**
426
+ * Build-on-provision module filter. All 4,762 functions are available in the
427
+ * contract; set this to install only the modules you use. The build service
428
+ * compiles + signs a bundle for exactly this set (cached by filter-hash).
429
+ * Omit for the default pinned bundle. Env: SQAI_RUNTIME_MODULES (comma-separated).
430
+ */
431
+ runtimeModules?: string[];
432
+ /** Build service endpoint for filtered bundles. Env: SQAI_BUILD_SERVICE_URL. */
433
+ buildServiceUrl?: string;
387
434
  /** BYO substrate (tests). */
388
435
  runtime?: Runtime;
389
436
  /** BYO computation dispatch target (tests / custom self-hosted engines). */
package/dist/index.js CHANGED
@@ -134,11 +134,15 @@ function fromAlgentaError(error) {
134
134
  }
135
135
 
136
136
  // src/env.ts
137
+ var DEFAULT_BUILD_SERVICE_URL = "https://sqai-buildservice.fly.dev";
137
138
  function readEnv(env = process.env) {
138
139
  const apiKey = (env.SQAI_API_KEY ?? "").trim() || void 0;
139
140
  const engineUrl = (env.SQAI_ENGINE_URL ?? "").trim() || void 0;
140
141
  const autoInstall = (env.SQAI_RUNTIME_AUTO_INSTALL ?? "").trim() !== "0";
141
- return { apiKey, engineUrl, autoInstall };
142
+ const modulesRaw = (env.SQAI_RUNTIME_MODULES ?? "").split(",").map((m) => m.trim()).filter((m) => m.length > 0);
143
+ const runtimeModules = modulesRaw.length > 0 ? modulesRaw : void 0;
144
+ const buildServiceUrl = (env.SQAI_BUILD_SERVICE_URL ?? "").trim() || DEFAULT_BUILD_SERVICE_URL;
145
+ return { apiKey, engineUrl, autoInstall, runtimeModules, buildServiceUrl };
142
146
  }
143
147
  function inferMode(explicit, resolved) {
144
148
  if (explicit) {
@@ -314,7 +318,7 @@ var ResultStore = class {
314
318
  import { homedir, platform as osPlatform, arch as osArch } from "os";
315
319
  import { join as join2 } from "path";
316
320
  import { createWriteStream, promises as fs2 } from "fs";
317
- import { randomBytes as randomBytes2 } from "crypto";
321
+ import { createHash as createHash3, randomBytes as randomBytes2 } from "crypto";
318
322
  import { Readable } from "stream";
319
323
  import { pipeline } from "stream/promises";
320
324
  import { MojoRuntime } from "algenta-sdk";
@@ -990,7 +994,7 @@ async function removeQuietly(path) {
990
994
  } catch {
991
995
  }
992
996
  }
993
- var RuntimeProvisioner = class {
997
+ var RuntimeProvisioner = class _RuntimeProvisioner {
994
998
  options;
995
999
  trustRoot;
996
1000
  runtime = null;
@@ -1050,8 +1054,110 @@ var RuntimeProvisioner = class {
1050
1054
  cacheDir() {
1051
1055
  return this.options.cacheDir ?? runtimeCacheDir();
1052
1056
  }
1057
+ /** Normalized module filter (sorted, unique, non-empty) or null for the default bundle. */
1058
+ filterModules() {
1059
+ const mods = (this.options.runtimeModules ?? []).map((m) => m.trim()).filter((m) => m.length > 0);
1060
+ if (mods.length === 0) {
1061
+ return null;
1062
+ }
1063
+ return Array.from(new Set(mods)).sort();
1064
+ }
1065
+ /** Ask the build service to compile + sign a bundle for exactly these modules. */
1066
+ async resolveFilteredBundle(modules, platformKey) {
1067
+ if (this.options.resolveFilteredBundle) {
1068
+ return this.options.resolveFilteredBundle(modules, platformKey);
1069
+ }
1070
+ const base = this.options.buildServiceUrl;
1071
+ if (!base) {
1072
+ throw new SqaiError(
1073
+ "runtime_provision_failed",
1074
+ "runtimeModules was set but no build service is configured. Set SQAI_BUILD_SERVICE_URL to a build-on-provision endpoint, or omit runtimeModules to use the default bundle.",
1075
+ { details: { reason: "no_build_service", modules } }
1076
+ );
1077
+ }
1078
+ let response;
1079
+ try {
1080
+ response = await fetch(`${base.replace(/\/$/, "")}/v1/runtime/build`, {
1081
+ method: "POST",
1082
+ headers: { "content-type": "application/json" },
1083
+ body: JSON.stringify({ modules, platform: platformKey })
1084
+ });
1085
+ } catch (error) {
1086
+ const message = error instanceof Error ? error.message : String(error);
1087
+ throw new SqaiError(
1088
+ "runtime_provision_failed",
1089
+ `Build service request failed: ${message}`,
1090
+ { retryable: true, details: { reason: "build_service_unreachable", modules } }
1091
+ );
1092
+ }
1093
+ if (!response.ok) {
1094
+ throw new SqaiError(
1095
+ "runtime_provision_failed",
1096
+ `Build service returned HTTP ${response.status} for the requested filter.`,
1097
+ { retryable: response.status >= 500, details: { reason: "build_failed", modules } }
1098
+ );
1099
+ }
1100
+ const body = await response.json();
1101
+ return {
1102
+ url: body.url,
1103
+ sha256: body.sha256,
1104
+ version: body.version ?? this.options.contract.runtime_bundle.version,
1105
+ cacheKey: body.cache_key
1106
+ };
1107
+ }
1108
+ /**
1109
+ * The filter's cache key, computed IDENTICALLY to the build service
1110
+ * (sha256("mods|platform|version")[:20], mods = sorted+unique, comma-joined).
1111
+ * Lets the reuse fast-path find an already-running filtered daemon without a
1112
+ * build-service round-trip. The build service's returned key is authoritative
1113
+ * for install; this only has to match for the reuse optimization to hit.
1114
+ */
1115
+ localCacheKey(modules, platformKey) {
1116
+ const canonical = modules.join(",");
1117
+ const version = this.options.contract.runtime_bundle.version;
1118
+ return createHash3("sha256").update(`${canonical}|${platformKey}|${version}`).digest("hex").slice(0, 20);
1119
+ }
1120
+ /**
1121
+ * Deterministic per-filter daemon endpoint so a filtered runtime never collides
1122
+ * with the default (or another filter's) daemon on the shared default socket.
1123
+ */
1124
+ filterEndpoint(cacheKey) {
1125
+ const seed = parseInt(cacheKey.slice(0, 6), 16) || 0;
1126
+ const port = 50100 + seed % 800;
1127
+ return { sock: join2(this.cacheDir(), `${cacheKey}.sock`), tcp: `127.0.0.1:${port}` };
1128
+ }
1129
+ static DAEMON_ENDPOINT_ENV = [
1130
+ "ALGENTA_DAEMON_SOCK",
1131
+ "ALGENTA_DAEMON_TCP",
1132
+ "ALGENTA_MOJO_SOCK",
1133
+ "ALGENTA_RUNTIME_DIR"
1134
+ ];
1135
+ /** Point the about-to-be-spawned daemon at a filter-specific socket/port/dir. */
1136
+ applyDaemonEndpointEnv(endpoint, installDir) {
1137
+ const saved = {};
1138
+ for (const key of _RuntimeProvisioner.DAEMON_ENDPOINT_ENV) {
1139
+ saved[key] = process.env[key];
1140
+ }
1141
+ process.env.ALGENTA_DAEMON_SOCK = endpoint.sock;
1142
+ process.env.ALGENTA_DAEMON_TCP = endpoint.tcp;
1143
+ process.env.ALGENTA_MOJO_SOCK = `${endpoint.sock}.worker`;
1144
+ process.env.ALGENTA_RUNTIME_DIR = join2(installDir, ".runtime");
1145
+ return saved;
1146
+ }
1147
+ restoreEnv(saved) {
1148
+ for (const [key, value] of Object.entries(saved)) {
1149
+ if (value === void 0) {
1150
+ delete process.env[key];
1151
+ } else {
1152
+ process.env[key] = value;
1153
+ }
1154
+ }
1155
+ }
1053
1156
  async doEnsure() {
1054
- const runtime = this.newRuntime();
1157
+ const platformKey = currentPlatformKey();
1158
+ const filter = this.filterModules();
1159
+ const probeEndpoint = filter ? this.filterEndpoint(this.localCacheKey(filter, platformKey)) : void 0;
1160
+ const runtime = this.newRuntime(probeEndpoint ? { tcpAddress: probeEndpoint.tcp } : void 0);
1055
1161
  try {
1056
1162
  const health = await runtime.health();
1057
1163
  if (health.runtime_available) {
@@ -1060,40 +1166,54 @@ var RuntimeProvisioner = class {
1060
1166
  }
1061
1167
  } catch {
1062
1168
  }
1063
- const platformKey = currentPlatformKey();
1064
- const bundle = this.options.contract.runtime_bundle;
1065
- const platformBundle = bundle.platforms[platformKey];
1066
- if (!platformBundle) {
1067
- const supported = Object.keys(bundle.platforms);
1068
- throw new SqaiError(
1069
- "unsupported_platform",
1070
- supported.length === 0 ? "No managed runtime bundle is published yet for any platform. Start a local Algenta runtime daemon, or set SQAI_ENGINE_URL / SQAI_API_KEY to use a hosted engine." : `No managed runtime bundle is published for '${platformKey}'.`,
1071
- { details: { platform: platformKey, supported } }
1072
- );
1169
+ let version;
1170
+ let installKey;
1171
+ let platformBundle;
1172
+ let endpoint;
1173
+ if (filter) {
1174
+ const resolved = await this.resolveFilteredBundle(filter, platformKey);
1175
+ version = resolved.version;
1176
+ installKey = `filtered-${resolved.cacheKey}`;
1177
+ platformBundle = { url: resolved.url, sha256: resolved.sha256 };
1178
+ endpoint = this.filterEndpoint(resolved.cacheKey);
1179
+ } else {
1180
+ const bundle = this.options.contract.runtime_bundle;
1181
+ const pinned = bundle.platforms[platformKey];
1182
+ if (!pinned) {
1183
+ const supported = Object.keys(bundle.platforms);
1184
+ throw new SqaiError(
1185
+ "unsupported_platform",
1186
+ supported.length === 0 ? "No managed runtime bundle is published yet for any platform. Start a local Algenta runtime daemon, or set SQAI_ENGINE_URL / SQAI_API_KEY to use a hosted engine." : `No managed runtime bundle is published for '${platformKey}'.`,
1187
+ { details: { platform: platformKey, supported } }
1188
+ );
1189
+ }
1190
+ version = bundle.version;
1191
+ installKey = version;
1192
+ platformBundle = pinned;
1073
1193
  }
1074
1194
  if (!this.options.autoInstall) {
1075
1195
  throw new SqaiError(
1076
1196
  "runtime_provision_failed",
1077
1197
  "Automatic runtime installation is disabled (SQAI_RUNTIME_AUTO_INSTALL=0). Install manually with `sqai runtime install` or `sqai runtime install --from-file`.",
1078
- { details: { platform: platformKey, version: bundle.version } }
1198
+ { details: { platform: platformKey, version } }
1079
1199
  );
1080
1200
  }
1081
- if (compareRuntimeVersions(bundle.version, this.trustRoot.minAcceptedRuntimeVersion) < 0) {
1201
+ if (compareRuntimeVersions(version, this.trustRoot.minAcceptedRuntimeVersion) < 0) {
1082
1202
  throw new SqaiError(
1083
1203
  "runtime_provision_failed",
1084
- `Managed runtime ${bundle.version} is below the minimum accepted runtime version ${this.trustRoot.minAcceptedRuntimeVersion} (rollback protection).`,
1204
+ `Managed runtime ${version} is below the minimum accepted runtime version ${this.trustRoot.minAcceptedRuntimeVersion} (rollback protection).`,
1085
1205
  {
1086
1206
  details: {
1087
1207
  reason: "rollback_protected",
1088
1208
  platform: platformKey,
1089
- version: bundle.version,
1209
+ version,
1090
1210
  min_accepted_version: this.trustRoot.minAcceptedRuntimeVersion
1091
1211
  }
1092
1212
  }
1093
1213
  );
1094
1214
  }
1095
- const installed = await this.ensureInstalled(platformKey, bundle.version, platformBundle);
1096
- return this.spawnInstalled(platformKey, installed);
1215
+ const installed = await this.ensureInstalled(platformKey, version, platformBundle, installKey);
1216
+ return this.spawnInstalled(platformKey, installed, endpoint);
1097
1217
  }
1098
1218
  provisionError(reason, message, platformKey, version, extra = {}, retryable = false) {
1099
1219
  return new SqaiError("runtime_provision_failed", message, {
@@ -1135,8 +1255,8 @@ var RuntimeProvisioner = class {
1135
1255
  };
1136
1256
  }
1137
1257
  /** Verify an existing install if present; returns null when absent/invalid. */
1138
- async verifiedInstallOrNull(platformKey, version, removeOnFailure) {
1139
- const installDir = join2(this.cacheDir(), version);
1258
+ async verifiedInstallOrNull(platformKey, version, removeOnFailure, installKey = version) {
1259
+ const installDir = join2(this.cacheDir(), installKey);
1140
1260
  try {
1141
1261
  await fs2.access(join2(installDir, MANIFEST_NAME));
1142
1262
  } catch {
@@ -1187,15 +1307,15 @@ var RuntimeProvisioner = class {
1187
1307
  return true;
1188
1308
  }
1189
1309
  }
1190
- /** Serialize installers on `<cacheDir>/<version>.lock`; returns the verified install. */
1191
- async ensureInstalled(platformKey, version, platformBundle) {
1310
+ /** Serialize installers on `<cacheDir>/<installKey>.lock`; returns the verified install. */
1311
+ async ensureInstalled(platformKey, version, platformBundle, installKey = version) {
1192
1312
  const cacheDir = this.cacheDir();
1193
1313
  await fs2.mkdir(cacheDir, { recursive: true });
1194
- const existing = await this.verifiedInstallOrNull(platformKey, version, true);
1314
+ const existing = await this.verifiedInstallOrNull(platformKey, version, true, installKey);
1195
1315
  if (existing) {
1196
1316
  return existing;
1197
1317
  }
1198
- const lockPath = join2(cacheDir, `${version}.lock`);
1318
+ const lockPath = join2(cacheDir, `${installKey}.lock`);
1199
1319
  const waitTimeoutMs = this.options.lockWaitTimeoutMs ?? LOCK_WAIT_TIMEOUT_MS;
1200
1320
  const pollIntervalMs = this.options.lockPollIntervalMs ?? LOCK_POLL_INTERVAL_MS;
1201
1321
  const deadline = Date.now() + waitTimeoutMs;
@@ -1207,12 +1327,12 @@ var RuntimeProvisioner = class {
1207
1327
  await removeQuietly(lockPath);
1208
1328
  continue;
1209
1329
  }
1210
- const finished = await this.verifiedInstallOrNull(platformKey, version, false);
1330
+ const finished = await this.verifiedInstallOrNull(platformKey, version, false, installKey);
1211
1331
  if (finished) {
1212
1332
  return finished;
1213
1333
  }
1214
1334
  if (Date.now() >= deadline) {
1215
- const lastChance = await this.verifiedInstallOrNull(platformKey, version, false);
1335
+ const lastChance = await this.verifiedInstallOrNull(platformKey, version, false, installKey);
1216
1336
  if (lastChance) {
1217
1337
  return lastChance;
1218
1338
  }
@@ -1221,29 +1341,29 @@ var RuntimeProvisioner = class {
1221
1341
  `Another installer holds the runtime install lock for ${version} and did not finish within ${Math.round(waitTimeoutMs / 1e3)}s. Retry, or remove the stale lock from the runtime cache directory.`,
1222
1342
  platformKey,
1223
1343
  version,
1224
- { lock_file: `${version}.lock` },
1344
+ { lock_file: `${installKey}.lock` },
1225
1345
  true
1226
1346
  );
1227
1347
  }
1228
1348
  await sleep(pollIntervalMs);
1229
1349
  }
1230
1350
  try {
1231
- const raced = await this.verifiedInstallOrNull(platformKey, version, false);
1351
+ const raced = await this.verifiedInstallOrNull(platformKey, version, false, installKey);
1232
1352
  if (raced) {
1233
1353
  return raced;
1234
1354
  }
1235
- return await this.downloadVerifyExtract(platformKey, version, platformBundle);
1355
+ return await this.downloadVerifyExtract(platformKey, version, platformBundle, installKey);
1236
1356
  } finally {
1237
1357
  await removeQuietly(lockPath);
1238
1358
  }
1239
1359
  }
1240
1360
  /** Holder-of-the-lock path: download → verify → extract → atomic rename. */
1241
- async downloadVerifyExtract(platformKey, version, platformBundle) {
1361
+ async downloadVerifyExtract(platformKey, version, platformBundle, installKey = version) {
1242
1362
  const cacheDir = this.cacheDir();
1243
1363
  const token = randomBytes2(6).toString("hex");
1244
1364
  const tarballPath = join2(cacheDir, `tmp-${token}.tgz`);
1245
1365
  const extractDir = join2(cacheDir, `tmp-${token}`);
1246
- const installDir = join2(cacheDir, version);
1366
+ const installDir = join2(cacheDir, installKey);
1247
1367
  const url = resolveBundleUrl(platformBundle.url, version, platformKey);
1248
1368
  try {
1249
1369
  const download = this.options.downloadBundle ?? defaultDownloadBundle;
@@ -1290,7 +1410,7 @@ var RuntimeProvisioner = class {
1290
1410
  try {
1291
1411
  await fs2.rename(extractDir, installDir);
1292
1412
  } catch (error) {
1293
- const raced = await this.verifiedInstallOrNull(platformKey, version, false);
1413
+ const raced = await this.verifiedInstallOrNull(platformKey, version, false, installKey);
1294
1414
  if (raced) {
1295
1415
  return raced;
1296
1416
  }
@@ -1309,7 +1429,7 @@ var RuntimeProvisioner = class {
1309
1429
  }
1310
1430
  }
1311
1431
  /** Spawn the installed bundle's daemon through MojoRuntime autoStart. */
1312
- async spawnInstalled(platformKey, installed) {
1432
+ async spawnInstalled(platformKey, installed, endpoint) {
1313
1433
  const version = installed.manifest.runtime_bundle_version;
1314
1434
  let entryRelative;
1315
1435
  try {
@@ -1322,7 +1442,10 @@ var RuntimeProvisioner = class {
1322
1442
  "start",
1323
1443
  "--foreground"
1324
1444
  ];
1325
- const managed = this.newRuntime({ autoStart: true, daemonCommand });
1445
+ const managed = this.newRuntime(
1446
+ endpoint ? { autoStart: true, daemonCommand, tcpAddress: endpoint.tcp } : { autoStart: true, daemonCommand }
1447
+ );
1448
+ const savedEnv = endpoint ? this.applyDaemonEndpointEnv(endpoint, installed.installDir) : null;
1326
1449
  try {
1327
1450
  const health = await managed.health();
1328
1451
  if (!health.runtime_available) {
@@ -1346,6 +1469,10 @@ var RuntimeProvisioner = class {
1346
1469
  version,
1347
1470
  { daemon_entry: entryRelative }
1348
1471
  );
1472
+ } finally {
1473
+ if (savedEnv) {
1474
+ this.restoreEnv(savedEnv);
1475
+ }
1349
1476
  }
1350
1477
  try {
1351
1478
  await fs2.writeFile(
@@ -1612,7 +1739,9 @@ var SQAI = class {
1612
1739
  this.resultStore = new ResultStore(config.resultStore);
1613
1740
  this.provisioner = new RuntimeProvisioner({
1614
1741
  contract: this.contractIndex.contract,
1615
- autoInstall: env.autoInstall
1742
+ autoInstall: env.autoInstall,
1743
+ runtimeModules: config.runtimeModules ?? env.runtimeModules,
1744
+ buildServiceUrl: config.buildServiceUrl ?? env.buildServiceUrl
1616
1745
  });
1617
1746
  if (config.runtime) {
1618
1747
  this.rawRuntime = config.runtime;