src/vs/platform/localTranscription/node/foundryLocalRuntime.ts

446 LOC · 359 covered · 87 uncovered · 71 ranges · 18 concepts · 18 introducers · 12 tests

File neighbourhood

The centred file is linked to every concept that introduces one of its ranges, every test that runs code from the file, and the gray connector concepts standing between those tests and the file's own introducer concepts. Undirected links join concepts to every file where they introduce source and concepts to the tests they introduce; arrows show specialization between the displayed concepts and bridge only concepts omitted from this view. Concept colors match the source ranges below; connector concepts have no source color and are shown in gray.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the file

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the related-file, concept, and source links on this page.

Focused file, its introducer and connector concepts, their introduced files, and tests that run code from the filefoundryLocalRuntime.ts ×3 · 8 introduced LOCfoundryLocalRuntime.ts ×…foundryLocalRuntime.ts ×1 · 2 introduced LOCfoundryLocalRuntime.ts ×…foundryLocalRuntime.ts ×6 · 17 introduced LOCfoundryLocalRuntime.ts ×…foundryLocalRuntime.ts ×2 · 6 introduced LOCfoundryLocalRuntime.ts ×…foundryLocalRuntime.ts ×14 · 89 introduced LOCfoundryLocalRuntime.ts ×…foundryLocalRuntime.ts ×1 · 1 introduced LOCfoundryLocalRuntime.ts ×…foundryLocalRuntime.ts ×1 · 6 introduced LOCfoundryLocalRuntime.ts ×…foundryLocalRuntime.ts ×6 · 16 introduced LOCfoundryLocalRuntime.ts ×…foundryLocalRuntime.ts ×2 · 6 introduced LOCfoundryLocalRuntime.ts ×…foundryLocalRuntime.ts ×1 · 3 introduced LOCfoundryLocalRuntime.ts ×…foundryLocalRuntime.ts ×1 · 3 introduced LOCfoundryLocalRuntime.ts ×…foundryLocalRuntime.ts ×1 · 1 introduced LOCfoundryLocalRuntime.ts ×…foundryLocalRuntime.ts ×1 · 3 introduced LOCfoundryLocalRuntime.ts ×…foundryLocalRuntime.ts ×1 · 8 introduced LOCfoundryLocalRuntime.ts ×…foundryLocalRuntime.ts ×3 · 5 introduced LOCfoundryLocalRuntime.ts ×…foundryLocalRuntime.ts ×4 · 11 introduced LOCfoundryLocalRuntime.ts ×…foundryLocalRuntime.ts ×2 · 5 introduced LOCfoundryLocalRuntime.ts ×…foundryLocalRuntime.ts ×21 · 169 introduced LOCfoundryLocalRuntime.ts ×…foundryLocalRuntime.test|title=FoundryLocalRuntime isRuntimeProvisioned: a different arch marker does not satisfy this arch|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/localTranscription/test/node/foundryLocalRuntime.test|title=FoundryLocalRuntime isRuntimeProvisioned: a different arch marker does not satisfy this arch|occurrence=1foundryLocalRuntime.test…foundryLocalRuntime.test|title=FoundryLocalRuntime isRuntimeProvisioned: false when marker present but payload missing (partial cache)|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/localTranscription/test/node/foundryLocalRuntime.test|title=FoundryLocalRuntime isRuntimeProvisioned: false when marker present but payload missing (partial cache)|occurrence=1foundryLocalRuntime.test…foundryLocalRuntime.test|title=FoundryLocalRuntime isRuntimeProvisioned: false when nothing is present|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/localTranscription/test/node/foundryLocalRuntime.test|title=FoundryLocalRuntime isRuntimeProvisioned: false when nothing is present|occurrence=1foundryLocalRuntime.test…foundryLocalRuntime.test|title=FoundryLocalRuntime isRuntimeProvisioned: false when one core library is missing (partial cache)|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/localTranscription/test/node/foundryLocalRuntime.test|title=FoundryLocalRuntime isRuntimeProvisioned: false when one core library is missing (partial cache)|occurrence=1foundryLocalRuntime.test…foundryLocalRuntime.test|title=FoundryLocalRuntime isRuntimeProvisioned: true only when marker AND payload are present (cache hit)|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/localTranscription/test/node/foundryLocalRuntime.test|title=FoundryLocalRuntime isRuntimeProvisioned: true only when marker AND payload are present (cache hit)|occurrence=1foundryLocalRuntime.test…foundryLocalRuntime.test|title=FoundryLocalRuntime platform key reflects the supported-platform set|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/localTranscription/test/node/foundryLocalRuntime.test|title=FoundryLocalRuntime platform key reflects the supported-platform set|occurrence=1foundryLocalRuntime.test…foundryLocalRuntime.test|title=FoundryLocalRuntime promoteDir: keeps the existing copy when a concurrent winner already promoted|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/localTranscription/test/node/foundryLocalRuntime.test|title=FoundryLocalRuntime promoteDir: keeps the existing copy when a concurrent winner already promoted|occurrence=1foundryLocalRuntime.test…foundryLocalRuntime.test|title=FoundryLocalRuntime promoteDir: moves a staged dir into place|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/localTranscription/test/node/foundryLocalRuntime.test|title=FoundryLocalRuntime promoteDir: moves a staged dir into place|occurrence=1foundryLocalRuntime.test…foundryLocalRuntime.test|title=FoundryLocalRuntime provisionRuntime: rejects an incomplete payload (missing core library) and writes no marker|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/localTranscription/test/node/foundryLocalRuntime.test|title=FoundryLocalRuntime provisionRuntime: rejects an incomplete payload (missing core library) and writes no marker|occurrence=1foundryLocalRuntime.test…foundryLocalRuntime.test|title=FoundryLocalRuntime provisionRuntime: rejects and writes no marker when the download 404s|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/localTranscription/test/node/foundryLocalRuntime.test|title=FoundryLocalRuntime provisionRuntime: rejects and writes no marker when the download 404s|occurrence=1foundryLocalRuntime.test…foundryLocalRuntime.test|title=FoundryLocalRuntime provisionRuntime: substitutes {target}, extracts the expected layout, writes the marker|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/localTranscription/test/node/foundryLocalRuntime.test|title=FoundryLocalRuntime provisionRuntime: substitutes {target}, extracts the expected layout, writes the marker|occurrence=1foundryLocalRuntime.test…foundryLocalRuntime.test|title=FoundryLocalRuntime resolveProxyUrl: honors scheme-specific vars, ALL_PROXY fallback, and NO_PROXY|occurrence=1 · introduced test · mocha:v1|namespace=vscode@05c208e9e28d8c1c723fa08f85e2b7a96092e8e5|file=vs/platform/localTranscription/test/node/foundryLocalRuntime.test|title=FoundryLocalRuntime resolveProxyUrl: honors scheme-specific vars, ALL_PROXY fallback, and NO_PROXY|occurrence=1foundryLocalRuntime.test…Focused file · src/vs/platform/localTranscription/node/foundryLocalRuntime.ts · 446 LOCnode/foundryLocalRuntime…

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the related-file, concept, and source links on this page while the interactive map is unavailable.

1 > /*--------------------------------------------------------------------------------------------- foundryLocalRuntime.ts ×21
2 > * Copyright (c) Microsoft Corporation. All rights reserved.
3 > * Licensed under the MIT License. See License.txt in the project root for license information.
4 > *--------------------------------------------------------------------------------------------*/
5 >
6 > import * as fs from 'fs';
7 > import * as os from 'os';
8 > import { dirname, join } from '../../../base/common/path.js';
9 > import { format2 } from '../../../base/common/strings.js';
10 > import { CancellationToken } from '../../../base/common/cancellation.js';
11 > import { CancellationError } from '../../../base/common/errors.js';
12 >
13 > /**
14 > * On-demand provisioning of the Foundry Local native runtime used by on-device
15 > * dictation.
16 > *
17 > * `foundry-local-sdk` ships a prebuilt N-API addon (`foundry_local_napi.node`)
18 > * and native core libraries (Foundry Local Core + ONNX Runtime + ONNX Runtime
19 > * GenAI). The addon requires a newer glibc than VS Code's minimum supported
20 > * Linux distros, so we deliberately do NOT bundle any of this native payload
21 > * with the product (see `build/gulpfile.vscode.ts`). Instead we republish a
22 > * per-target tarball of the addon + core libraries to VS Code's CDN at build
23 > * time (see `build/dictation-runtime/`) and download it here, at runtime, only
24 > * on supported platforms, into a per-user writable cache — keeping the shipped
25 > * package's glibc floor intact and avoiding any runtime dependency on the npm
26 > * registry or NuGet.
27 > *
28 > * The SDK loader (`dist/detail/coreInterop.js`) is patched during
29 > * `postinstall` to honor `VSCODE_FOUNDRY_LOCAL_NATIVE_DIR`, pointing it at the
30 > * cache directory this module populates. The tarball's internal layout mirrors
31 > * the SDK's own package layout so the patched resolution is a trivial path join:
32 > *
33 > * <cacheRoot>/<version>/prebuilds/<target>/foundry_local_napi.node
34 > * <cacheRoot>/<version>/foundry-local-core/<target>/<core libraries>
35 > *
36 > * NOTE: the single CDN download leg honors the standard proxy environment
37 > * variables (`HTTPS_PROXY`/`HTTP_PROXY`/`ALL_PROXY`, with `NO_PROXY`). VS Code's
38 > * `http.proxy`/`http.noProxy` settings are applied as these same environment
39 > * variables before provisioning (see `LocalTranscriptionService.start`), so a
40 > * proxy configured only in VS Code is honored here and by the native model
41 > * download too; `http.proxyAuthorization` (Basic) is folded into the proxy URL
42 > * and `http.proxyStrictSSL === false` disables TLS verification for this leg.
43 > * TLS-intercepting proxies otherwise rely on the CA being in the OS trust store.
44 > */
45 >
46 > /**
47 > * Platforms (`<process.platform>-<process.arch>`) for which Foundry Local ships
48 > * a native addon + core libraries. Mirrors the SDK installer's RID map.
49 > */
50 > export const FOUNDRY_LOCAL_SUPPORTED_PLATFORMS: ReadonlySet<string> = new Set([
51 > 'darwin-arm64',
52 > 'linux-x64',
53 > 'linux-arm64',
54 > 'win32-x64',
55 > 'win32-arm64',
56 > ]);
57 >
58 > /** The current host platform key, or `undefined` if Foundry Local can't run here. */
59 > export function foundryLocalPlatformKey(): string | undefined {
60 > const key = `${process.platform}-${process.arch}`; foundryLocalRuntime.ts ×2
61 > return FOUNDRY_LOCAL_SUPPORTED_PLATFORMS.has(key) ? key : undefined;
62 > }
64 > /** Whether on-device dictation's native runtime can run on this host. */
65 > export function isFoundryLocalRuntimeSupported(): boolean {
66 > return foundryLocalPlatformKey() !== undefined; foundryLocalRuntime.ts ×2
67 > }
69 > /** Progress callback invoked while the native runtime is being fetched. */
70 > export type FoundryLocalRuntimeProgress = (message: string) => void;
71 >
72 > /** Where the native runtime tarball is published (from `product.dictationRuntime`). */
73 > export interface IFoundryLocalRuntimeDownload {
74 > /** CDN URL template with a `{target}` placeholder for the host platform key. */
75 > readonly urlTemplate: string;
76 > /** The published runtime version (the pinned `foundry-local-sdk` version). */
77 > readonly version: string;
78 > }
79 >
80 > /** De-dupes concurrent provisioning requests targeting the same cache dir. */
81 > const inFlight = new Map<string, Promise<string>>();
82 >
83 > /** Abort a download after this long without any connection/response progress. */
84 > const DOWNLOAD_INACTIVITY_TIMEOUT_MS = 60_000;
85 >
86 > /**
87 > * Ensure the Foundry Local native runtime (addon + core libraries) is present
88 > * in `<cacheRoot>`, downloading the per-target CDN tarball if necessary. Returns
89 > * the versioned override directory to set as `VSCODE_FOUNDRY_LOCAL_NATIVE_DIR`
90 > * before loading the SDK.
91 > *
92 > * Idempotent: once a version is fully provisioned a per-platform `.complete`
93 > * marker is written and subsequent calls return immediately (after verifying the
94 > * payload) without touching the network.
95 > */
96 export async function ensureFoundryLocalRuntime(cacheRoot: string, download: IFoundryLocalRuntimeDownload, token: CancellationToken, onProgress?: FoundryLocalRuntimeProgress): Promise<string> {
97 const platformKey = foundryLocalPlatformKey();
98 if (!platformKey) {
99 throw new Error(`Foundry Local native runtime is not available on ${process.platform}-${process.arch}.`);
100 }
101
102 const overrideDir = join(cacheRoot, download.version);
103
104 // A single in-flight provisioning per override dir; late joiners share it.
105 const existing = inFlight.get(overrideDir);
106 if (existing) {
107 return existing;
108 }
109 const promise = doEnsure(overrideDir, platformKey, download, token, onProgress)
110 .finally(() => inFlight.delete(overrideDir));
111 inFlight.set(overrideDir, promise);
112 return promise;
113 }
115 async function doEnsure(overrideDir: string, platformKey: string, download: IFoundryLocalRuntimeDownload, token: CancellationToken, onProgress?: FoundryLocalRuntimeProgress): Promise<string> {
116 // The completion marker is per-platform: the shared `<cacheRoot>/<version>`
117 // dir can hold payloads for multiple architectures (e.g. a win32-arm64
118 // machine running x64 VS Code under emulation, then arm64 VS Code). Verify
119 // the target-specific payload as well as the marker, so a different arch's
120 // marker never short-circuits this arch's provisioning and a stale/partially
121 // deleted cache is repaired rather than trusted.
122 if (isRuntimeProvisioned(overrideDir, platformKey)) {
123 return overrideDir;
124 }
125
126 // Fail fast (before any download) when the host can't actually load the
127 // addon — e.g. Linux with glibc older than the addon requires — so users see
128 // a clear "unsupported" error instead of a large download that crashes on
129 // native import.
130 assertRuntimeLoadable(platformKey);
131
132 onProgress?.('Downloading dictation runtime…');
133 await provisionRuntime(overrideDir, platformKey, download.urlTemplate, download.version, token);
134 return overrideDir;
135 }
137 > /**
138 > * Download the `{target}`-substituted CDN tarball for `platformKey` into
139 > * `overrideDir`, extract + verify + atomically promote its payload, and write the
140 > * per-platform completion marker. Host-independent (does NOT run the glibc
141 > * loadability gate); exported for tests. Callers that provision for the running
142 > * host should use `ensureFoundryLocalRuntime`, which gates and de-dupes.
143 > */
144 > export async function provisionRuntime(overrideDir: string, platformKey: string, urlTemplate: string, version: string, token: CancellationToken): Promise<void> { foundryLocalRuntime.ts ×14
145 > const addonPath = foundryAddonPath(overrideDir, platformKey);
146 > const coreDir = foundryCoreDir(overrideDir, platformKey);
147 >
148 > // The cache is shared by the utility processes of every open VS Code window,
149 > // so provision into a process-unique staging dir and atomically promote each
150 > // payload directory into place. Two concurrent first-use downloads therefore
151 > // never write to the same final path; whichever process wins the rename is
152 > // the published copy and the loser accepts it as success.
153 > const url = format2(urlTemplate, { target: platformKey });
154 > const staging = join(overrideDir, `.staging-${process.pid}-${randomSuffix()}`);
155 > const stagingAddon = join(staging, 'prebuilds', platformKey, 'foundry_local_napi.node');
156 > const stagingCore = join(staging, 'foundry-local-core', platformKey);
157 > try {
158 > await downloadAndExtractTarball(url, staging, token);
159 > throwIfCancelled(token); foundryLocalRuntime.ts ×6
160 >
161 > if (!fs.existsSync(stagingAddon) || !hasAllCoreLibraries(stagingCore)) { foundryLocalRuntime.ts ×14
162 > throw new Error(`Foundry Local native runtime download from ${url} completed but expected files are missing.`); foundryLocalRuntime.ts ×1
163 > }
165 > await promoteDir(dirname(stagingAddon), dirname(addonPath));
166 > await promoteDir(stagingCore, coreDir);
167 > } finally { foundryLocalRuntime.ts ×14
168 > await fs.promises.rm(staging, { recursive: true, force: true }).catch(() => { /* best effort */ });
169 > }
171 > // Verify the published payload — ours or a concurrent winner's — is complete.
172 > if (!fs.existsSync(addonPath) || !hasAllCoreLibraries(coreDir)) { foundryLocalRuntime.ts ×14
173 throw new Error('Foundry Local native runtime is incomplete after provisioning.');
174 }
176 > await fs.promises.writeFile(foundryMarkerPath(overrideDir, platformKey), `${version}\n`).catch(() => { /* best effort marker */ });
177 > }
179 > /** Path of the per-platform completion marker inside a versioned override dir. */
180 > function foundryMarkerPath(overrideDir: string, platformKey: string): string { foundryLocalRuntime.ts ×3
181 > return join(overrideDir, `.complete-${platformKey}`);
182 > }
184 > /** Path of the prebuilt N-API addon inside a versioned override dir. */
185 > function foundryAddonPath(overrideDir: string, platformKey: string): string { foundryLocalRuntime.ts ×1
186 > return join(overrideDir, 'prebuilds', platformKey, 'foundry_local_napi.node');
187 > }
189 > /** Directory of the native core libraries inside a versioned override dir. */
190 > function foundryCoreDir(overrideDir: string, platformKey: string): string { foundryLocalRuntime.ts ×1
191 > return join(overrideDir, 'foundry-local-core', platformKey);
192 > }
194 > /**
195 > * Whether `<overrideDir>` holds a complete, verified runtime for `platformKey`:
196 > * the per-platform marker AND the actual addon + all core libraries. A marker
197 > * alone is insufficient (it can belong to a different architecture, or the
198 > * payload can be partially deleted). Exported for tests.
199 > */
200 > export function isRuntimeProvisioned(overrideDir: string, platformKey: string): boolean {
201 > return fs.existsSync(foundryMarkerPath(overrideDir, platformKey)) foundryLocalRuntime.ts ×3
202 > && fs.existsSync(foundryAddonPath(overrideDir, platformKey)) foundryLocalRuntime.ts ×1
203 > && hasAllCoreLibraries(foundryCoreDir(overrideDir, platformKey)); foundryLocalRuntime.ts ×1
206 > /**
207 > * Atomically move the fully-staged directory `from` to `to`. If another process
208 > * already promoted the same payload (the destination exists), keep the existing
209 > * copy — the caller re-verifies completeness afterwards. Exported for tests.
210 > */
211 > export async function promoteDir(from: string, to: string): Promise<void> { foundryLocalRuntime.ts ×2
212 > await fs.promises.mkdir(dirname(to), { recursive: true });
213 > try {
214 > await fs.promises.rename(from, to);
215 > } catch (err) {
216 > // A concurrent winner already created `to` (EEXIST/ENOTEMPTY), or the foundryLocalRuntime.ts ×1
217 > // staging dir is on a different filesystem. If a copy is already present,
218 > // accept it; otherwise surface the failure.
219 > if (fs.existsSync(to)) {
220 > return;
221 > }
222 throw err;
223 }
226 > function randomSuffix(): string { foundryLocalRuntime.ts ×14
227 > return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
228 > }
230 > /** Minimum glibc version the Foundry Local addon requires on Linux. */
231 > const MIN_GLIBC: readonly [number, number] = [2, 34];
232 >
233 > /**
234 > * Throw a classified error if this host cannot load the downloaded addon. Only
235 > * Linux is gated (on glibc): the prebuilt addon needs GLIBC_2.34, newer than VS
236 > * Code's minimum supported distros, so downloading + loading it there would
237 > * crash. Non-glibc / undetectable systems are left to fail at load time.
238 > */
239 function assertRuntimeLoadable(platformKey: string): void {
240 if (!platformKey.startsWith('linux-')) {
241 return;
242 }
243 const glibc = detectGlibcVersion();
244 if (glibc && (glibc[0] < MIN_GLIBC[0] || (glibc[0] === MIN_GLIBC[0] && glibc[1] < MIN_GLIBC[1]))) {
245 const err = new Error(`On-device dictation requires glibc ${MIN_GLIBC[0]}.${MIN_GLIBC[1]} or newer, but this system has glibc ${glibc[0]}.${glibc[1]}.`);
246 (err as Error & { code?: string }).code = 'ERR_FOUNDRY_UNSUPPORTED_LIBC';
247 throw err;
248 }
249 }
251 > /** Best-effort runtime glibc version via Node's diagnostic report, if available. */
252 function detectGlibcVersion(): [number, number] | undefined {
253 try {
254 const report = (process as unknown as { report?: { getReport?(): { header?: { glibcVersionRuntime?: string } } } }).report;
255 const version = report?.getReport?.()?.header?.glibcVersionRuntime;
256 const match = typeof version === 'string' ? /^(\d+)\.(\d+)/.exec(version) : null;
257 if (match) {
258 return [Number(match[1]), Number(match[2])];
259 }
260 } catch {
261 // Diagnostic report unavailable (e.g. non-glibc build); can't gate.
262 }
263 return undefined;
264 }
266 > /**
267 > * Download the per-target runtime tarball from `url` and extract it into
268 > * `stagingDir`, which then contains `prebuilds/<target>/foundry_local_napi.node`
269 > * and `foundry-local-core/<target>/<core libraries>` (the tarball's layout
270 > * mirrors the cache layout). The tarball is published to VS Code's CDN by
271 > * `build/dictation-runtime/`.
272 > */
273 > async function downloadAndExtractTarball(url: string, stagingDir: string, token: CancellationToken): Promise<void> { foundryLocalRuntime.ts ×14
274 > await fs.promises.mkdir(stagingDir, { recursive: true });
275 > const tmpDir = await fs.promises.mkdtemp(join(os.tmpdir(), 'vscode-foundry-runtime-'));
276 > try {
277 > const tarballPath = join(tmpDir, 'runtime.tgz');
278 > await downloadFile(url, tarballPath, token);
279 > throwIfCancelled(token); foundryLocalRuntime.ts ×6
280 >
281 > // `tar` is a node_modules package, so it must be imported dynamically.
282 > const tar = await import('tar');
283 > await tar.x({ file: tarballPath, cwd: stagingDir });
284 > } finally { foundryLocalRuntime.ts ×14
285 > await fs.promises.rm(tmpDir, { recursive: true, force: true }).catch(() => { /* best effort */ });
286 > }
287 > }
289 > /** The core library filenames required for the current platform. Exported for tests. */
290 > export function requiredCoreLibraryNames(): string[] {
291 > const ext = process.platform === 'win32' ? '.dll' : process.platform === 'darwin' ? '.dylib' : '.so'; foundryLocalRuntime.ts ×1
292 > const prefix = process.platform === 'win32' ? '' : 'lib';
293 > return [
294 > `Microsoft.AI.Foundry.Local.Core${ext}`,
295 > `${prefix}onnxruntime${ext}`,
296 > `${prefix}onnxruntime-genai${ext}`,
297 > ];
298 > }
300 > /** Whether all required core libraries already exist in `coreDir`. */
301 > function hasAllCoreLibraries(coreDir: string): boolean { foundryLocalRuntime.ts ×1
302 > return requiredCoreLibraryNames().every(name => fs.existsSync(join(coreDir, name)));
303 > }
305 > /**
306 > * Resolve the proxy URL to use for `targetUrl` from the standard proxy
307 > * environment variables, or `undefined` when the request should go direct.
308 > *
309 > * Mirrors the env-var handling of the GitHub desktop app's Rust
310 > * `foundry-local-sdk` (reqwest/ureq): for an `https:` target it prefers
311 > * `HTTPS_PROXY`, for an `http:` target `HTTP_PROXY`, each falling back to
312 > * `ALL_PROXY` (all case-insensitive), and it skips the proxy when the host
313 > * matches `NO_PROXY`. `env` defaults to `process.env`; it is a parameter so the
314 > * resolution can be unit-tested without mutating global environment state.
315 > */
316 > export function resolveProxyUrl(targetUrl: string, env: NodeJS.ProcessEnv = process.env): string | undefined {
317 > let parsed: URL; foundryLocalRuntime.ts ×4
318 > try {
319 > parsed = new URL(targetUrl);
320 > } catch {
321 > return undefined; foundryLocalRuntime.ts ×6
322 > }
323 > const scheme = parsed.protocol === 'http:' foundryLocalRuntime.ts ×4
324 > ? (env.HTTP_PROXY ?? env.http_proxy)
325 > : (env.HTTPS_PROXY ?? env.https_proxy); foundryLocalRuntime.ts ×6
326 > const proxy = scheme ?? env.ALL_PROXY ?? env.all_proxy; foundryLocalRuntime.ts ×4
327 > if (!proxy) {
328 > return undefined;
329 > }
330 > const noProxy = env.NO_PROXY ?? env.no_proxy; foundryLocalRuntime.ts ×6
331 > if (noProxy && isNoProxyHost(noProxy, parsed.hostname)) { foundryLocalRuntime.ts ×4
332 > return undefined; foundryLocalRuntime.ts ×6
333 > }
334 > return proxy;
335 > }
337 > /** Whether `hostname` matches any entry in a `NO_PROXY` list. */
338 > function isNoProxyHost(noProxy: string, hostname: string): boolean { foundryLocalRuntime.ts ×6
339 > const host = hostname.toLowerCase();
340 > return noProxy.split(',').some(raw => {
341 > const entry = raw.trim().toLowerCase().replace(/^\./, '');
342 > if (!entry) {
343 return false;
344 }
345 > return entry === '*' || host === entry || host.endsWith(`.${entry}`); foundryLocalRuntime.ts ×6
346 > });
347 > }
349 > /**
350 > * A proxy `Agent` for `targetUrl` built from the environment, or `undefined`
351 > * when no proxy applies. `https-proxy-agent` is a `node_modules` package, so it
352 > * is imported dynamically like the other runtime-only dependencies here.
353 > */
354 > async function resolveProxyAgent(targetUrl: string): Promise<import('http').Agent | undefined> { foundryLocalRuntime.ts ×14
355 > const proxyUrl = resolveProxyUrl(targetUrl);
356 > if (!proxyUrl) {
357 > return undefined;
358 > }
359 const { HttpsProxyAgent } = await import('https-proxy-agent');
360 return new HttpsProxyAgent(proxyUrl);
361 }
363 > /** Download `url` to `dest`, following redirects, honoring cancellation. */
364 > async function downloadFile(url: string, dest: string, token: CancellationToken): Promise<void> { foundryLocalRuntime.ts ×14
365 > // `http`/`https` are slow-to-load builtins; import them lazily at runtime.
366 > // The CDN is always `https:`; `http:` support exists only so provisioning can
367 > // be exercised against a local test server.
368 > const [https, http] = await Promise.all([import('https'), import('http')]);
369 > const getFor = (u: string) => (new URL(u).protocol === 'http:' ? http.get : https.get);
370 > // A single proxy agent tunnels to whatever host each request (including any
371 > // redirect target) addresses, so resolving it once from the initial URL is
372 > // sufficient. `undefined` means "go direct".
373 > const agent = await resolveProxyAgent(url);
374 > return new Promise<void>((resolve, reject) => {
375 > let settled = false;
376 > let timer: ReturnType<typeof setTimeout> | undefined;
377 > let activeRequest: import('http').ClientRequest | undefined;
378 > const file = fs.createWriteStream(dest);
379 >
380 > const finish = (err?: Error) => {
381 > if (settled) {
382 return;
383 }
384 > settled = true; foundryLocalRuntime.ts ×14
385 > if (timer) {
386 > clearTimeout(timer);
387 > }
388 > activeRequest?.destroy();
389 > if (!err) {
390 > resolve(); foundryLocalRuntime.ts ×6
391 > return;
392 > }
393 > // Remove the partial file before surfacing the failure. foundryLocalRuntime.ts ×2
394 > file.close(() => fs.promises.rm(dest, { force: true }).catch(() => { /* best effort */ }).finally(() => reject(err)));
396 > // `https.get` has no default timeout, so a stalled connection/response
397 > // would hang forever (and, via `stop()` awaiting the open promise, hang
398 > // dictation shutdown). Bound it with an inactivity timeout that resets on
399 > // progress and tears the request/partial file down when it fires.
400 > const armTimeout = () => {
401 > if (timer) {
402 > clearTimeout(timer);
403 > }
404 > timer = setTimeout(() => finish(new Error(`Timed out downloading ${url}.`)), DOWNLOAD_INACTIVITY_TIMEOUT_MS);
405 > };
406 >
407 > const request = (currentUrl: string, redirectsLeft: number): void => {
408 > if (token.isCancellationRequested) {
409 finish(new CancellationError());
410 return;
411 }
412 > armTimeout(); foundryLocalRuntime.ts ×14
413 > activeRequest = getFor(currentUrl)(currentUrl, { agent }, response => {
414 > armTimeout();
415 > const status = response.statusCode ?? 0;
416 > if (status >= 300 && status < 400 && response.headers.location) {
417 response.resume();
418 if (redirectsLeft <= 0) {
419 finish(new Error(`Too many redirects downloading ${url}.`));
420 return;
421 }
422 request(new URL(response.headers.location, currentUrl).toString(), redirectsLeft - 1);
423 return;
424 }
425 > if (status !== 200) { foundryLocalRuntime.ts ×14
426 > response.resume(); foundryLocalRuntime.ts ×2
427 > finish(new Error(`Download failed with status ${status}: ${currentUrl}`));
428 > return;
429 > }
430 > response.on('data', armTimeout); foundryLocalRuntime.ts ×6
431 > response.on('error', err => finish(err));
432 > response.pipe(file);
433 > file.on('finish', () => file.close(err => err ? finish(err) : finish()));
435 > activeRequest.on('error', err => finish(err));
436 > };
437 > file.on('error', err => finish(err));
438 > request(url, 5);
439 > });
440 > }
442 > function throwIfCancelled(token: CancellationToken): void { foundryLocalRuntime.ts ×6
443 > if (token.isCancellationRequested) {
444 throw new CancellationError();
445 }