@atomic-chat/core 0.17.0 → 0.18.4
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/app-daemon.js +7 -0
- package/dist/app-daemon.js.map +1 -1
- package/dist/backend/advisor/advisor.d.ts +6 -1
- package/dist/backend/advisor/advisor.js +69 -7
- package/dist/backend/advisor/advisor.js.map +1 -1
- package/dist/backend/catalog/prism-manifest.d.ts +2 -0
- package/dist/backend/catalog/prism-manifest.js +3 -2
- package/dist/backend/catalog/prism-manifest.js.map +1 -1
- package/dist/cli/main.d.ts +1 -1
- package/dist/cli/main.js +5 -0
- package/dist/cli/main.js.map +1 -1
- package/dist/client/control-client.d.ts +10 -1
- package/dist/client/control-client.js +15 -0
- package/dist/client/control-client.js.map +1 -1
- package/dist/cloud/registry.js +1 -0
- package/dist/cloud/registry.js.map +1 -1
- package/dist/config/paths.d.ts +4 -0
- package/dist/config/paths.js +11 -0
- package/dist/config/paths.js.map +1 -1
- package/dist/contracts/backend-advisor.d.ts +12 -0
- package/dist/contracts/engine-builds.d.ts +1 -1
- package/dist/contracts/engine-builds.js +1 -1
- package/dist/contracts/engine-builds.js.map +1 -1
- package/dist/contracts/engines.d.ts +1 -1
- package/dist/contracts/engines.js +2 -0
- package/dist/contracts/engines.js.map +1 -1
- package/dist/contracts/errors.d.ts +13 -2
- package/dist/contracts/errors.js.map +1 -1
- package/dist/contracts/events.d.ts +7 -0
- package/dist/contracts/foundry-local.d.ts +77 -0
- package/dist/contracts/foundry-local.js +17 -0
- package/dist/contracts/foundry-local.js.map +1 -0
- package/dist/contracts/index.d.ts +1 -0
- package/dist/contracts/index.js +1 -0
- package/dist/contracts/index.js.map +1 -1
- package/dist/contracts/model-yml.d.ts +28 -0
- package/dist/contracts/model-yml.js +11 -0
- package/dist/contracts/model-yml.js.map +1 -1
- package/dist/contracts/session.d.ts +5 -1
- package/dist/contracts/session.js.map +1 -1
- package/dist/contracts/settings.d.ts +5 -1
- package/dist/contracts/settings.js.map +1 -1
- package/dist/core/atomic-core.d.ts +1 -1
- package/dist/core/create.js +106 -5
- package/dist/core/create.js.map +1 -1
- package/dist/core/types.d.ts +9 -0
- package/dist/core/types.js.map +1 -1
- package/dist/diffusion/install.d.ts +0 -4
- package/dist/diffusion/install.js +5 -2
- package/dist/diffusion/install.js.map +1 -1
- package/dist/diffusion/server-process.d.ts +5 -2
- package/dist/diffusion/server-process.js +10 -2
- package/dist/diffusion/server-process.js.map +1 -1
- package/dist/downloads/archive.d.ts +1 -1
- package/dist/downloads/archive.js +2 -2
- package/dist/downloads/archive.js.map +1 -1
- package/dist/engine-builds/engines.d.ts +83 -0
- package/dist/engine-builds/engines.js +144 -0
- package/dist/engine-builds/engines.js.map +1 -0
- package/dist/engine-builds/foundry-local.d.ts +22 -0
- package/dist/engine-builds/foundry-local.js +100 -0
- package/dist/engine-builds/foundry-local.js.map +1 -0
- package/dist/engine-builds/manifest.d.ts +57 -6
- package/dist/engine-builds/manifest.js +109 -4
- package/dist/engine-builds/manifest.js.map +1 -1
- package/dist/engine-builds/order.d.ts +2 -1
- package/dist/engine-builds/order.js +11 -4
- package/dist/engine-builds/order.js.map +1 -1
- package/dist/engine-builds/select.d.ts +27 -0
- package/dist/engine-builds/select.js +45 -0
- package/dist/engine-builds/select.js.map +1 -1
- package/dist/engine-builds/service.d.ts +14 -15
- package/dist/engine-builds/service.js +68 -126
- package/dist/engine-builds/service.js.map +1 -1
- package/dist/engines/service.d.ts +6 -3
- package/dist/engines/service.js +6 -3
- package/dist/engines/service.js.map +1 -1
- package/dist/hardware/index.d.ts +1 -0
- package/dist/hardware/index.js +1 -0
- package/dist/hardware/index.js.map +1 -1
- package/dist/hardware/npu.d.ts +14 -0
- package/dist/hardware/npu.js +29 -0
- package/dist/hardware/npu.js.map +1 -0
- package/dist/host/recipes/executor-io-windows.d.ts +11 -0
- package/dist/host/recipes/executor-io-windows.js +23 -5
- package/dist/host/recipes/executor-io-windows.js.map +1 -1
- package/dist/integrations/detect.d.ts +2 -0
- package/dist/integrations/detect.js +4 -3
- package/dist/integrations/detect.js.map +1 -1
- package/dist/lock/instance-lock.js +5 -2
- package/dist/lock/instance-lock.js.map +1 -1
- package/dist/lock/process-identity.d.ts +9 -3
- package/dist/lock/process-identity.js +75 -9
- package/dist/lock/process-identity.js.map +1 -1
- package/dist/router/resolve.d.ts +2 -2
- package/dist/router/resolve.js +2 -1
- package/dist/router/resolve.js.map +1 -1
- package/dist/runtime/foundry-local/accelerators.d.ts +42 -0
- package/dist/runtime/foundry-local/accelerators.js +153 -0
- package/dist/runtime/foundry-local/accelerators.js.map +1 -0
- package/dist/runtime/foundry-local/check.d.ts +19 -0
- package/dist/runtime/foundry-local/check.js +69 -0
- package/dist/runtime/foundry-local/check.js.map +1 -0
- package/dist/runtime/foundry-local/foundry-host.d.ts +18 -0
- package/dist/runtime/foundry-local/foundry-host.js +23 -0
- package/dist/runtime/foundry-local/foundry-host.js.map +1 -0
- package/dist/runtime/foundry-local/host/args.d.ts +44 -0
- package/dist/runtime/foundry-local/host/args.js +109 -0
- package/dist/runtime/foundry-local/host/args.js.map +1 -0
- package/dist/runtime/foundry-local/host/execution-providers.d.ts +27 -0
- package/dist/runtime/foundry-local/host/execution-providers.js +43 -0
- package/dist/runtime/foundry-local/host/execution-providers.js.map +1 -0
- package/dist/runtime/foundry-local/host/ffi-bun.d.ts +17 -0
- package/dist/runtime/foundry-local/host/ffi-bun.js +256 -0
- package/dist/runtime/foundry-local/host/ffi-bun.js.map +1 -0
- package/dist/runtime/foundry-local/host/library.d.ts +61 -0
- package/dist/runtime/foundry-local/host/library.js +17 -0
- package/dist/runtime/foundry-local/host/library.js.map +1 -0
- package/dist/runtime/foundry-local/host/run.d.ts +54 -0
- package/dist/runtime/foundry-local/host/run.js +316 -0
- package/dist/runtime/foundry-local/host/run.js.map +1 -0
- package/dist/runtime/foundry-local/host-process.d.ts +81 -0
- package/dist/runtime/foundry-local/host-process.js +185 -0
- package/dist/runtime/foundry-local/host-process.js.map +1 -0
- package/dist/runtime/foundry-local/index.d.ts +10 -0
- package/dist/runtime/foundry-local/index.js +10 -0
- package/dist/runtime/foundry-local/index.js.map +1 -0
- package/dist/runtime/foundry-local/model-yml.d.ts +8 -0
- package/dist/runtime/foundry-local/model-yml.js +63 -0
- package/dist/runtime/foundry-local/model-yml.js.map +1 -0
- package/dist/runtime/foundry-local/runtime.d.ts +88 -0
- package/dist/runtime/foundry-local/runtime.js +321 -0
- package/dist/runtime/foundry-local/runtime.js.map +1 -0
- package/dist/runtime/llamacpp/args.d.ts +5 -0
- package/dist/runtime/llamacpp/args.js +7 -1
- package/dist/runtime/llamacpp/args.js.map +1 -1
- package/dist/runtime/llamacpp/errors.d.ts +1 -0
- package/dist/runtime/llamacpp/errors.js +10 -0
- package/dist/runtime/llamacpp/errors.js.map +1 -1
- package/dist/runtime/llamacpp/load-plan.d.ts +5 -0
- package/dist/runtime/llamacpp/load-plan.js +8 -0
- package/dist/runtime/llamacpp/load-plan.js.map +1 -1
- package/dist/runtime/llamacpp/runtime-device.d.ts +8 -0
- package/dist/runtime/llamacpp/runtime-device.js +9 -3
- package/dist/runtime/llamacpp/runtime-device.js.map +1 -1
- package/dist/runtime/llamacpp/runtime.d.ts +6 -1
- package/dist/runtime/llamacpp/runtime.js +19 -3
- package/dist/runtime/llamacpp/runtime.js.map +1 -1
- package/dist/runtime/managed-text/gateway.d.ts +2 -0
- package/dist/runtime/managed-text/gateway.js +1 -1
- package/dist/runtime/managed-text/gateway.js.map +1 -1
- package/dist/runtime/shared/external-sessions.js +1 -0
- package/dist/runtime/shared/external-sessions.js.map +1 -1
- package/dist/runtime/shared/process.d.ts +13 -1
- package/dist/runtime/shared/process.js +21 -12
- package/dist/runtime/shared/process.js.map +1 -1
- package/dist/server/control/router.js +2 -0
- package/dist/server/control/router.js.map +1 -1
- package/dist/server/control/routes/foundry-local.d.ts +10 -0
- package/dist/server/control/routes/foundry-local.js +42 -0
- package/dist/server/control/routes/foundry-local.js.map +1 -0
- package/dist/server/control/routes/models.js +6 -3
- package/dist/server/control/routes/models.js.map +1 -1
- package/dist/server/control/types.d.ts +17 -1
- package/dist/server/control/types.js.map +1 -1
- package/dist/server/http.js +45 -7
- package/dist/server/http.js.map +1 -1
- package/dist/server/public/errors.d.ts +1 -0
- package/dist/server/public/errors.js +18 -0
- package/dist/server/public/errors.js.map +1 -1
- package/dist/server/public/listing.js +1 -0
- package/dist/server/public/listing.js.map +1 -1
- package/dist/settings/public.d.ts +7 -0
- package/dist/settings/public.js +8 -0
- package/dist/settings/public.js.map +1 -0
- package/dist/settings/schema/foundry-local.json +14 -0
- package/dist/settings/schema.js +8 -0
- package/dist/settings/schema.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +11 -3
- package/src/settings/schema/atomic-prism.json +0 -433
- package/src/settings/schema/foundation-models.json +0 -1
- package/src/settings/schema/llamacpp-upstream.json +0 -498
- package/src/settings/schema/llamacpp.json +0 -475
- package/src/settings/schema/mlx.json +0 -136
- package/src/settings/schema/sglang.json +0 -251
- package/src/settings/schema/tensorrt-llm.json +0 -253
- package/src/settings/schema/vllm.json +0 -273
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `POST /models/foundry-local/check` (openspec change `add-foundry-local`, task 6.5): whether a variant
|
|
3
|
+
* would run here, from what core already knows — the platform, the installed build, the last
|
|
4
|
+
* accelerators probe and whether the machine has an NPU. Never the network.
|
|
5
|
+
*/
|
|
6
|
+
import { AtomicCoreError, FOUNDRY_LOCAL_EXECUTION_PROVIDERS } from '../../contracts/index.js';
|
|
7
|
+
import { executionProvider } from './host/execution-providers.js';
|
|
8
|
+
import { variantRunsOn } from './runtime.js';
|
|
9
|
+
export function foundryLocalVerdict(facts, request) {
|
|
10
|
+
const known = FOUNDRY_LOCAL_EXECUTION_PROVIDERS.some((ep) => ep === request.execution_provider);
|
|
11
|
+
if (!known)
|
|
12
|
+
return {
|
|
13
|
+
verdict: 'platform-unsupported',
|
|
14
|
+
reason: `This core runs no Foundry Local variant on the "${request.execution_provider}" accelerator.`,
|
|
15
|
+
accelerator: null,
|
|
16
|
+
};
|
|
17
|
+
const short = request.execution_provider;
|
|
18
|
+
const ep = executionProvider(short);
|
|
19
|
+
const accelerator = ep.register;
|
|
20
|
+
if (!variantRunsOn(facts.platform, facts.arch, short))
|
|
21
|
+
return {
|
|
22
|
+
verdict: 'platform-unsupported',
|
|
23
|
+
reason: `${short.toUpperCase()} variants do not run on ${facts.platform} ${facts.arch}.`,
|
|
24
|
+
accelerator,
|
|
25
|
+
};
|
|
26
|
+
if (!facts.installed)
|
|
27
|
+
return {
|
|
28
|
+
verdict: 'engine-not-installed',
|
|
29
|
+
reason: 'Foundry Local is not installed on this computer.',
|
|
30
|
+
accelerator,
|
|
31
|
+
};
|
|
32
|
+
if (accelerator === null)
|
|
33
|
+
return { verdict: 'ok', reason: null, accelerator: null };
|
|
34
|
+
if (request.device === 'npu' && facts.npu === false)
|
|
35
|
+
return { verdict: 'accelerator-unavailable', reason: 'This computer has no NPU.', accelerator };
|
|
36
|
+
const found = facts.accelerators.find((candidate) => candidate.name === accelerator);
|
|
37
|
+
if (!found)
|
|
38
|
+
return {
|
|
39
|
+
verdict: 'accelerator-unavailable',
|
|
40
|
+
reason: `Foundry Local does not offer ${accelerator} on this computer.`,
|
|
41
|
+
accelerator,
|
|
42
|
+
};
|
|
43
|
+
if (!found.prepared)
|
|
44
|
+
return {
|
|
45
|
+
verdict: 'accelerator-not-prepared',
|
|
46
|
+
reason: `${accelerator} is not prepared yet; prepare it on the Foundry Local page.`,
|
|
47
|
+
accelerator,
|
|
48
|
+
};
|
|
49
|
+
return { verdict: 'ok', reason: null, accelerator };
|
|
50
|
+
}
|
|
51
|
+
/** The request body, strictly: the accelerator and the device as text, nothing else. */
|
|
52
|
+
export function parseFoundryLocalCheckRequest(body) {
|
|
53
|
+
const invalid = (why) => {
|
|
54
|
+
throw new AtomicCoreError('INVALID_ARGUMENT', why);
|
|
55
|
+
};
|
|
56
|
+
if (typeof body !== 'object' || body === null || Array.isArray(body))
|
|
57
|
+
return invalid('The request body must be a JSON object.');
|
|
58
|
+
const record = body;
|
|
59
|
+
const extra = Object.keys(record).filter((key) => key !== 'execution_provider' && key !== 'device');
|
|
60
|
+
if (extra.length > 0)
|
|
61
|
+
invalid(`The request has fields this core does not know: ${extra.sort().join(', ')}.`);
|
|
62
|
+
const { execution_provider: executionProvider, device } = record;
|
|
63
|
+
if (typeof executionProvider !== 'string' || executionProvider === '')
|
|
64
|
+
invalid('execution_provider is required.');
|
|
65
|
+
if (typeof device !== 'string' || device === '')
|
|
66
|
+
invalid('device is required.');
|
|
67
|
+
return { execution_provider: executionProvider, device: device };
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../../src/runtime/foundry-local/check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@atomic-chat/core/foundry-host`: the one entry of the hidden `foundry-host` mode (change
|
|
3
|
+
* close-cli-core-gaps, design D1). The core binaries and any program that embeds the core as a library
|
|
4
|
+
* (`atc`) hand it the arguments after `foundry-host` before they parse their own commands, because
|
|
5
|
+
* `foundryHostCommand` starts the host as `<this program> foundry-host …`.
|
|
6
|
+
*
|
|
7
|
+
* Importing this file loads no `bun:*`: the FFI bindings load dynamically, inside the mode alone.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Runs `foundry-host <argv…>` and returns its exit code (0 done, 2 usage, 3 the library does not
|
|
11
|
+
* load, 4 a library call failed). Lines go to this process's stdout and stderr, through writers that
|
|
12
|
+
* go quiet instead of crashing the host when the core closed its end of a pipe (EPIPE); `io` exists
|
|
13
|
+
* for the core's own CLI, which takes its streams injected.
|
|
14
|
+
*/
|
|
15
|
+
export declare function runFoundryHostMain(argv: readonly string[], io?: {
|
|
16
|
+
stdout: (text: string) => void;
|
|
17
|
+
stderr: (text: string) => void;
|
|
18
|
+
}): Promise<number>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@atomic-chat/core/foundry-host`: the one entry of the hidden `foundry-host` mode (change
|
|
3
|
+
* close-cli-core-gaps, design D1). The core binaries and any program that embeds the core as a library
|
|
4
|
+
* (`atc`) hand it the arguments after `foundry-host` before they parse their own commands, because
|
|
5
|
+
* `foundryHostCommand` starts the host as `<this program> foundry-host …`.
|
|
6
|
+
*
|
|
7
|
+
* Importing this file loads no `bun:*`: the FFI bindings load dynamically, inside the mode alone.
|
|
8
|
+
*/
|
|
9
|
+
import { detachableWriter } from '../../cli/io.js';
|
|
10
|
+
import { lineIo, loadLibraryWithBun, runFoundryHost } from './host/run.js';
|
|
11
|
+
/**
|
|
12
|
+
* Runs `foundry-host <argv…>` and returns its exit code (0 done, 2 usage, 3 the library does not
|
|
13
|
+
* load, 4 a library call failed). Lines go to this process's stdout and stderr, through writers that
|
|
14
|
+
* go quiet instead of crashing the host when the core closed its end of a pipe (EPIPE); `io` exists
|
|
15
|
+
* for the core's own CLI, which takes its streams injected.
|
|
16
|
+
*/
|
|
17
|
+
export async function runFoundryHostMain(argv, io = {
|
|
18
|
+
stdout: detachableWriter(process.stdout),
|
|
19
|
+
stderr: detachableWriter(process.stderr),
|
|
20
|
+
}) {
|
|
21
|
+
return runFoundryHost(argv, { ...lineIo(io), loadLibrary: loadLibraryWithBun });
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=foundry-host.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"foundry-host.js","sourceRoot":"","sources":["../../../src/runtime/foundry-local/foundry-host.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAE1E;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAuB,EACvB,KAAyE;IACvE,MAAM,EAAE,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC;IACxC,MAAM,EAAE,gBAAgB,CAAC,OAAO,CAAC,MAAM,CAAC;CACzC;IAED,OAAO,cAAc,CAAC,IAAI,EAAE,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,kBAAkB,EAAE,CAAC,CAAA;AACjF,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The arguments of the hidden `foundry-host` mode (openspec change `add-foundry-local`, task 5.1).
|
|
3
|
+
* Core is the only caller, so the parse is strict: anything unknown is a bug on core's side.
|
|
4
|
+
*
|
|
5
|
+
* foundry-host probe --lib <build> --app-data <dir> --logs <dir> [--prepared <ep>]…
|
|
6
|
+
* foundry-host prepare --lib <build> --app-data <dir> --logs <dir> [<ep>…]
|
|
7
|
+
* foundry-host serve --lib <build> --app-data <dir> --logs <dir> --model <dir> --ep <ep>
|
|
8
|
+
* --port <p> --cache <dir> --id <name>:<version> [--tools]
|
|
9
|
+
* [--reasoning-start <s> --reasoning-end <s>] [--context-length <n>]
|
|
10
|
+
*/
|
|
11
|
+
import type { FoundryLocalExecutionProvider } from '../../../contracts/index.js';
|
|
12
|
+
interface CommonArgs {
|
|
13
|
+
/** The build directory (`<root>/<tag>/<platform>`), holding `lib/`. */
|
|
14
|
+
lib: string;
|
|
15
|
+
/** The library's own data (`app_data_dir`): accelerators, shared by every build. */
|
|
16
|
+
appData: string;
|
|
17
|
+
logs: string;
|
|
18
|
+
}
|
|
19
|
+
export type FoundryHostArgs = (CommonArgs & {
|
|
20
|
+
mode: 'probe';
|
|
21
|
+
/** Accelerators core recorded as prepared; the library cannot tell (spike finding 18). */
|
|
22
|
+
prepared: string[];
|
|
23
|
+
}) | (CommonArgs & {
|
|
24
|
+
mode: 'prepare';
|
|
25
|
+
accelerators: string[];
|
|
26
|
+
}) | (CommonArgs & {
|
|
27
|
+
mode: 'serve';
|
|
28
|
+
model: string;
|
|
29
|
+
ep: FoundryLocalExecutionProvider;
|
|
30
|
+
port: number;
|
|
31
|
+
/** The host's own catalog index, deleted at exit. */
|
|
32
|
+
cache: string;
|
|
33
|
+
/** `<name>:<version>`, never one of Microsoft's catalog ids (spike finding 7). */
|
|
34
|
+
id: string;
|
|
35
|
+
tools: boolean;
|
|
36
|
+
reasoningStart?: string;
|
|
37
|
+
reasoningEnd?: string;
|
|
38
|
+
contextLength?: number;
|
|
39
|
+
});
|
|
40
|
+
export declare class FoundryHostUsageError extends Error {
|
|
41
|
+
constructor(message: string);
|
|
42
|
+
}
|
|
43
|
+
export declare function parseFoundryHostArgs(argv: readonly string[]): FoundryHostArgs;
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The arguments of the hidden `foundry-host` mode (openspec change `add-foundry-local`, task 5.1).
|
|
3
|
+
* Core is the only caller, so the parse is strict: anything unknown is a bug on core's side.
|
|
4
|
+
*
|
|
5
|
+
* foundry-host probe --lib <build> --app-data <dir> --logs <dir> [--prepared <ep>]…
|
|
6
|
+
* foundry-host prepare --lib <build> --app-data <dir> --logs <dir> [<ep>…]
|
|
7
|
+
* foundry-host serve --lib <build> --app-data <dir> --logs <dir> --model <dir> --ep <ep>
|
|
8
|
+
* --port <p> --cache <dir> --id <name>:<version> [--tools]
|
|
9
|
+
* [--reasoning-start <s> --reasoning-end <s>] [--context-length <n>]
|
|
10
|
+
*/
|
|
11
|
+
import { parseArgs } from 'node:util';
|
|
12
|
+
import { FOUNDRY_LOCAL_EXECUTION_PROVIDERS } from '../../../contracts/index.js';
|
|
13
|
+
export class FoundryHostUsageError extends Error {
|
|
14
|
+
constructor(message) {
|
|
15
|
+
super(message);
|
|
16
|
+
this.name = 'FoundryHostUsageError';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const COMMON_OPTIONS = {
|
|
20
|
+
'lib': { type: 'string' },
|
|
21
|
+
'app-data': { type: 'string' },
|
|
22
|
+
'logs': { type: 'string' },
|
|
23
|
+
};
|
|
24
|
+
const required = (values, key) => {
|
|
25
|
+
const value = values[key];
|
|
26
|
+
if (typeof value !== 'string' || value === '')
|
|
27
|
+
throw new FoundryHostUsageError(`--${key} is required`);
|
|
28
|
+
return value;
|
|
29
|
+
};
|
|
30
|
+
function common(values) {
|
|
31
|
+
return {
|
|
32
|
+
lib: required(values, 'lib'),
|
|
33
|
+
appData: required(values, 'app-data'),
|
|
34
|
+
logs: required(values, 'logs'),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export function parseFoundryHostArgs(argv) {
|
|
38
|
+
const [mode, ...rest] = argv;
|
|
39
|
+
try {
|
|
40
|
+
if (mode === 'probe') {
|
|
41
|
+
const { values } = parseArgs({
|
|
42
|
+
args: rest,
|
|
43
|
+
options: { ...COMMON_OPTIONS, prepared: { type: 'string', multiple: true } },
|
|
44
|
+
strict: true,
|
|
45
|
+
});
|
|
46
|
+
return { mode, ...common(values), prepared: values.prepared ?? [] };
|
|
47
|
+
}
|
|
48
|
+
if (mode === 'prepare') {
|
|
49
|
+
const { values, positionals } = parseArgs({
|
|
50
|
+
args: rest,
|
|
51
|
+
options: COMMON_OPTIONS,
|
|
52
|
+
strict: true,
|
|
53
|
+
allowPositionals: true,
|
|
54
|
+
});
|
|
55
|
+
return { mode, ...common(values), accelerators: positionals };
|
|
56
|
+
}
|
|
57
|
+
if (mode === 'serve') {
|
|
58
|
+
const { values } = parseArgs({
|
|
59
|
+
args: rest,
|
|
60
|
+
options: {
|
|
61
|
+
...COMMON_OPTIONS,
|
|
62
|
+
'model': { type: 'string' },
|
|
63
|
+
'ep': { type: 'string' },
|
|
64
|
+
'port': { type: 'string' },
|
|
65
|
+
'cache': { type: 'string' },
|
|
66
|
+
'id': { type: 'string' },
|
|
67
|
+
'tools': { type: 'boolean' },
|
|
68
|
+
'reasoning-start': { type: 'string' },
|
|
69
|
+
'reasoning-end': { type: 'string' },
|
|
70
|
+
'context-length': { type: 'string' },
|
|
71
|
+
},
|
|
72
|
+
strict: true,
|
|
73
|
+
});
|
|
74
|
+
const ep = required(values, 'ep');
|
|
75
|
+
if (!FOUNDRY_LOCAL_EXECUTION_PROVIDERS.some((known) => known === ep))
|
|
76
|
+
throw new FoundryHostUsageError(`--ep ${ep} is not an accelerator this host runs`);
|
|
77
|
+
const port = Number(required(values, 'port'));
|
|
78
|
+
if (!Number.isInteger(port) || port < 1 || port > 65535)
|
|
79
|
+
throw new FoundryHostUsageError(`--port ${values.port} is not a port`);
|
|
80
|
+
const id = required(values, 'id');
|
|
81
|
+
if (!/^[^:\s]+:\d+$/.test(id))
|
|
82
|
+
throw new FoundryHostUsageError(`--id ${id} is not <name>:<version>`);
|
|
83
|
+
const context = values['context-length'];
|
|
84
|
+
const contextLength = context === undefined ? undefined : Number(context);
|
|
85
|
+
if (contextLength !== undefined && (!Number.isSafeInteger(contextLength) || contextLength < 1))
|
|
86
|
+
throw new FoundryHostUsageError(`--context-length ${context} is not a positive whole number`);
|
|
87
|
+
return {
|
|
88
|
+
mode,
|
|
89
|
+
...common(values),
|
|
90
|
+
model: required(values, 'model'),
|
|
91
|
+
ep: ep,
|
|
92
|
+
port,
|
|
93
|
+
cache: required(values, 'cache'),
|
|
94
|
+
id,
|
|
95
|
+
tools: values.tools === true,
|
|
96
|
+
...(values['reasoning-start'] !== undefined ? { reasoningStart: values['reasoning-start'] } : {}),
|
|
97
|
+
...(values['reasoning-end'] !== undefined ? { reasoningEnd: values['reasoning-end'] } : {}),
|
|
98
|
+
...(contextLength !== undefined ? { contextLength } : {}),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
if (error instanceof FoundryHostUsageError)
|
|
104
|
+
throw error;
|
|
105
|
+
throw new FoundryHostUsageError(error instanceof Error ? error.message : String(error));
|
|
106
|
+
}
|
|
107
|
+
throw new FoundryHostUsageError(`foundry-host: unknown mode ${JSON.stringify(mode ?? '')} (probe, prepare, serve)`);
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=args.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"args.js","sourceRoot":"","sources":["../../../../src/runtime/foundry-local/host/args.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AACrC,OAAO,EAAE,iCAAiC,EAAE,MAAM,6BAA6B,CAAA;AAiC/E,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAC9C,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAA;IACrC,CAAC;CACF;AAED,MAAM,cAAc,GAAG;IACrB,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IACzB,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IAC9B,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;CAClB,CAAA;AAEV,MAAM,QAAQ,GAAG,CAAC,MAA+B,EAAE,GAAW,EAAU,EAAE;IACxE,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAA;IACzB,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,EAAE;QAAE,MAAM,IAAI,qBAAqB,CAAC,KAAK,GAAG,cAAc,CAAC,CAAA;IACtG,OAAO,KAAK,CAAA;AACd,CAAC,CAAA;AAED,SAAS,MAAM,CAAC,MAA+B;IAC7C,OAAO;QACL,GAAG,EAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC;QAC5B,OAAO,EAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;QACrC,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;KAC/B,CAAA;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,IAAuB;IAC1D,MAAM,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,CAAA;IAC5B,IAAI,CAAC;QACH,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YACrB,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;gBAC3B,IAAI,EAAE,IAAI;gBACV,OAAO,EAAE,EAAE,GAAG,cAAc,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,EAAE;gBAC5E,MAAM,EAAE,IAAI;aACb,CAAC,CAAA;YACF,OAAO,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAA;QACrE,CAAC;QACD,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,GAAG,SAAS,CAAC;gBACxC,IAAI,EAAE,IAAI;gBACV,OAAO,EAAE,cAAc;gBACvB,MAAM,EAAE,IAAI;gBACZ,gBAAgB,EAAE,IAAI;aACvB,CAAC,CAAA;YACF,OAAO,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,WAAW,EAAE,CAAA;QAC/D,CAAC;QACD,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;YACrB,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;gBAC3B,IAAI,EAAE,IAAI;gBACV,OAAO,EAAE;oBACP,GAAG,cAAc;oBACjB,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBAC3B,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACxB,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBAC1B,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBAC3B,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACxB,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;oBAC5B,iBAAiB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACrC,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;oBACnC,gBAAgB,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;iBACrC;gBACD,MAAM,EAAE,IAAI;aACb,CAAC,CAAA;YACF,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;YACjC,IAAI,CAAC,iCAAiC,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC;gBAClE,MAAM,IAAI,qBAAqB,CAAC,QAAQ,EAAE,uCAAuC,CAAC,CAAA;YACpF,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;YAC7C,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,GAAG,CAAC,IAAI,IAAI,GAAG,KAAK;gBACrD,MAAM,IAAI,qBAAqB,CAAC,UAAU,MAAM,CAAC,IAAI,gBAAgB,CAAC,CAAA;YACxE,MAAM,EAAE,GAAG,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;YACjC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;gBAAE,MAAM,IAAI,qBAAqB,CAAC,QAAQ,EAAE,0BAA0B,CAAC,CAAA;YACpG,MAAM,OAAO,GAAG,MAAM,CAAC,gBAAgB,CAAC,CAAA;YACxC,MAAM,aAAa,GAAG,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAA;YACzE,IAAI,aAAa,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,aAAa,CAAC,IAAI,aAAa,GAAG,CAAC,CAAC;gBAC5F,MAAM,IAAI,qBAAqB,CAAC,oBAAoB,OAAO,iCAAiC,CAAC,CAAA;YAC/F,OAAO;gBACL,IAAI;gBACJ,GAAG,MAAM,CAAC,MAAM,CAAC;gBACjB,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;gBAChC,EAAE,EAAE,EAAmC;gBACvC,IAAI;gBACJ,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;gBAChC,EAAE;gBACF,KAAK,EAAE,MAAM,CAAC,KAAK,KAAK,IAAI;gBAC5B,GAAG,CAAC,MAAM,CAAC,iBAAiB,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,MAAM,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjG,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC3F,GAAG,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC1D,CAAA;QACH,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,qBAAqB;YAAE,MAAM,KAAK,CAAA;QACvD,MAAM,IAAI,qBAAqB,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;IACzF,CAAC;IACD,MAAM,IAAI,qBAAqB,CAC7B,8BAA8B,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,EAAE,CAAC,0BAA0B,CACnF,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The three spellings of each accelerator (spike findings 6 and 14): conf and `model.yml` say `webgpu`,
|
|
3
|
+
* the library's EP registration and `Manager_GetDiscoverableEps` say `WebGpuExecutionProvider` (ONNX
|
|
4
|
+
* Runtime's name), and `RegisterModel` metadata wants `WebGPUExecutionProvider` (the catalog's name) —
|
|
5
|
+
* `Load` refuses the ORT spelling with "unknown execution provider for local model".
|
|
6
|
+
*/
|
|
7
|
+
import type { FoundryLocalExecutionProvider } from '../../../contracts/index.js';
|
|
8
|
+
interface ExecutionProviderNames {
|
|
9
|
+
short: FoundryLocalExecutionProvider;
|
|
10
|
+
/** What the variant runs on; OpenVINO serves Intel GPUs and NPUs alike (finding: offered without an NPU). */
|
|
11
|
+
device: 'cpu' | 'gpu' | 'npu' | 'gpu/npu';
|
|
12
|
+
/** `Manager_DownloadAndRegisterEps` / discoverable name; `null` for the CPU, which is always there. */
|
|
13
|
+
register: string | null;
|
|
14
|
+
/** `execution_provider` in `RegisterModel` metadata. */
|
|
15
|
+
metadata: string;
|
|
16
|
+
}
|
|
17
|
+
export declare const EXECUTION_PROVIDERS: readonly ExecutionProviderNames[];
|
|
18
|
+
export declare function executionProvider(short: FoundryLocalExecutionProvider): ExecutionProviderNames;
|
|
19
|
+
/**
|
|
20
|
+
* What the probe says about one discoverable accelerator. One this core does not run variants on
|
|
21
|
+
* (`NvTensorRTRTXExecutionProvider`, design non-goal) keeps its name with `execution_provider: null`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function describeDiscoverable(name: string): {
|
|
24
|
+
execution_provider: FoundryLocalExecutionProvider | null;
|
|
25
|
+
device: string;
|
|
26
|
+
};
|
|
27
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The three spellings of each accelerator (spike findings 6 and 14): conf and `model.yml` say `webgpu`,
|
|
3
|
+
* the library's EP registration and `Manager_GetDiscoverableEps` say `WebGpuExecutionProvider` (ONNX
|
|
4
|
+
* Runtime's name), and `RegisterModel` metadata wants `WebGPUExecutionProvider` (the catalog's name) —
|
|
5
|
+
* `Load` refuses the ORT spelling with "unknown execution provider for local model".
|
|
6
|
+
*/
|
|
7
|
+
export const EXECUTION_PROVIDERS = [
|
|
8
|
+
{ short: 'cpu', device: 'cpu', register: null, metadata: 'CPUExecutionProvider' },
|
|
9
|
+
{ short: 'cuda', device: 'gpu', register: 'CUDAExecutionProvider', metadata: 'CUDAExecutionProvider' },
|
|
10
|
+
{
|
|
11
|
+
short: 'webgpu',
|
|
12
|
+
device: 'gpu',
|
|
13
|
+
register: 'WebGpuExecutionProvider',
|
|
14
|
+
metadata: 'WebGPUExecutionProvider',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
short: 'openvino',
|
|
18
|
+
device: 'gpu/npu',
|
|
19
|
+
register: 'OpenVINOExecutionProvider',
|
|
20
|
+
metadata: 'OpenVINOExecutionProvider',
|
|
21
|
+
},
|
|
22
|
+
{ short: 'qnn', device: 'npu', register: 'QNNExecutionProvider', metadata: 'QNNExecutionProvider' },
|
|
23
|
+
{
|
|
24
|
+
short: 'vitisai',
|
|
25
|
+
device: 'npu',
|
|
26
|
+
register: 'VitisAIExecutionProvider',
|
|
27
|
+
metadata: 'VitisAIExecutionProvider',
|
|
28
|
+
},
|
|
29
|
+
];
|
|
30
|
+
export function executionProvider(short) {
|
|
31
|
+
return EXECUTION_PROVIDERS.find((ep) => ep.short === short);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* What the probe says about one discoverable accelerator. One this core does not run variants on
|
|
35
|
+
* (`NvTensorRTRTXExecutionProvider`, design non-goal) keeps its name with `execution_provider: null`.
|
|
36
|
+
*/
|
|
37
|
+
export function describeDiscoverable(name) {
|
|
38
|
+
const known = EXECUTION_PROVIDERS.find((ep) => ep.register === name);
|
|
39
|
+
if (known)
|
|
40
|
+
return { execution_provider: known.short, device: known.device };
|
|
41
|
+
return { execution_provider: null, device: /TensorRT|Cuda|Gpu|DML/i.test(name) ? 'gpu' : 'unknown' };
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=execution-providers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"execution-providers.js","sourceRoot":"","sources":["../../../../src/runtime/foundry-local/host/execution-providers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAcH,MAAM,CAAC,MAAM,mBAAmB,GAAsC;IACpE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,sBAAsB,EAAE;IACjF,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,uBAAuB,EAAE,QAAQ,EAAE,uBAAuB,EAAE;IACtG;QACE,KAAK,EAAE,QAAQ;QACf,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,yBAAyB;QACnC,QAAQ,EAAE,yBAAyB;KACpC;IACD;QACE,KAAK,EAAE,UAAU;QACjB,MAAM,EAAE,SAAS;QACjB,QAAQ,EAAE,2BAA2B;QACrC,QAAQ,EAAE,2BAA2B;KACtC;IACD,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,sBAAsB,EAAE,QAAQ,EAAE,sBAAsB,EAAE;IACnG;QACE,KAAK,EAAE,SAAS;QAChB,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,0BAA0B;QACpC,QAAQ,EAAE,0BAA0B;KACrC;CACF,CAAA;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAoC;IACpE,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,KAAK,KAAK,CAA2B,CAAA;AACvF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAI/C,MAAM,KAAK,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAA;IACpE,IAAI,KAAK;QAAE,OAAO,EAAE,kBAAkB,EAAE,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAA;IAC3E,OAAO,EAAE,kBAAkB,EAAE,IAAI,EAAE,MAAM,EAAE,wBAAwB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,EAAE,CAAA;AACtG,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `FoundryLibrary` over `bun:ffi` — the only file in `src/` that may import `bun:*` (operator decision
|
|
3
|
+
* Q2 of change `add-foundry-local`; allow-listed in `scripts/check-runtime-agnostic.mjs`). It is
|
|
4
|
+
* imported dynamically by the `foundry-host` mode alone, so the npm package still loads under Node.
|
|
5
|
+
*
|
|
6
|
+
* The library exports three symbols; everything else is a table of function pointers (`flApi` and its
|
|
7
|
+
* sub-APIs), read here by index. Indices follow `foundry_local_c.h` of C API version 2: tables only
|
|
8
|
+
* ever grow at the end, so a library that grants version 2 keeps these positions.
|
|
9
|
+
*
|
|
10
|
+
* Proven by the spike (rulings S1, S2): progress callbacks must not be `threadsafe` — the native caller
|
|
11
|
+
* would wait on a JS thread it itself blocks and read a non-zero return as "cancel"; on Windows the
|
|
12
|
+
* library's DLL dependencies are found only after `SetDllDirectoryW(<lib>)`.
|
|
13
|
+
*/
|
|
14
|
+
import type { LoadFoundryLibrary } from './library.js';
|
|
15
|
+
/** The `FOUNDRY_LOCAL_API_VERSION` these bindings are written against. */
|
|
16
|
+
export declare const BOUND_C_API_VERSION = 2;
|
|
17
|
+
export declare const loadBunFoundryLibrary: LoadFoundryLibrary;
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `FoundryLibrary` over `bun:ffi` — the only file in `src/` that may import `bun:*` (operator decision
|
|
3
|
+
* Q2 of change `add-foundry-local`; allow-listed in `scripts/check-runtime-agnostic.mjs`). It is
|
|
4
|
+
* imported dynamically by the `foundry-host` mode alone, so the npm package still loads under Node.
|
|
5
|
+
*
|
|
6
|
+
* The library exports three symbols; everything else is a table of function pointers (`flApi` and its
|
|
7
|
+
* sub-APIs), read here by index. Indices follow `foundry_local_c.h` of C API version 2: tables only
|
|
8
|
+
* ever grow at the end, so a library that grants version 2 keeps these positions.
|
|
9
|
+
*
|
|
10
|
+
* Proven by the spike (rulings S1, S2): progress callbacks must not be `threadsafe` — the native caller
|
|
11
|
+
* would wait on a JS thread it itself blocks and read a non-zero return as "cancel"; on Windows the
|
|
12
|
+
* library's DLL dependencies are found only after `SetDllDirectoryW(<lib>)`.
|
|
13
|
+
*/
|
|
14
|
+
import { CFunction, CString, dlopen, FFIType, JSCallback, ptr, read } from 'bun:ffi';
|
|
15
|
+
import { existsSync } from 'node:fs';
|
|
16
|
+
import { join } from 'node:path';
|
|
17
|
+
import { FoundryLibraryError } from './library.js';
|
|
18
|
+
/** The `FOUNDRY_LOCAL_API_VERSION` these bindings are written against. */
|
|
19
|
+
export const BOUND_C_API_VERSION = 2;
|
|
20
|
+
const POINTER = 8;
|
|
21
|
+
const CATALOG_LOCAL = 1;
|
|
22
|
+
/** `flEpInfo`: u32 version, padding, `const char* name` at 8, `bool is_registered` at 16. */
|
|
23
|
+
const EP_INFO_SIZE = 24;
|
|
24
|
+
const LIBRARY_FILE = {
|
|
25
|
+
win32: 'foundry_local.dll',
|
|
26
|
+
darwin: 'libfoundry_local.dylib',
|
|
27
|
+
linux: 'libfoundry_local.so',
|
|
28
|
+
};
|
|
29
|
+
/** Root table (`flApi`) indices. */
|
|
30
|
+
const API = {
|
|
31
|
+
statusGetErrorCode: 2,
|
|
32
|
+
statusGetErrorMessage: 3,
|
|
33
|
+
statusRelease: 1,
|
|
34
|
+
managerCreate: 4,
|
|
35
|
+
managerRelease: 5,
|
|
36
|
+
webServiceStart: 7,
|
|
37
|
+
webServiceUrls: 8,
|
|
38
|
+
getCatalogApi: 10,
|
|
39
|
+
getConfigurationApi: 11,
|
|
40
|
+
getModelApi: 14,
|
|
41
|
+
createKeyValuePairs: 15,
|
|
42
|
+
addKeyValuePair: 16,
|
|
43
|
+
keyValuePairsRelease: 20,
|
|
44
|
+
getDiscoverableEps: 24,
|
|
45
|
+
downloadAndRegisterEps: 25,
|
|
46
|
+
managerShutdown: 27,
|
|
47
|
+
getCatalogByType: 29,
|
|
48
|
+
};
|
|
49
|
+
const CONFIG = {
|
|
50
|
+
create: 0,
|
|
51
|
+
release: 1,
|
|
52
|
+
setAppDataDir: 3,
|
|
53
|
+
setLogsDir: 4,
|
|
54
|
+
setModelCacheDir: 5,
|
|
55
|
+
addWebServiceEndpoint: 8,
|
|
56
|
+
setAdditionalOptions: 10,
|
|
57
|
+
};
|
|
58
|
+
const CATALOG = { registerModel: 8 };
|
|
59
|
+
const MODEL = {
|
|
60
|
+
getInfo: 0,
|
|
61
|
+
load: 6,
|
|
62
|
+
unload: 7,
|
|
63
|
+
infoGetExecutionProvider: 17,
|
|
64
|
+
createModelInfo: 23,
|
|
65
|
+
releaseModelInfo: 24,
|
|
66
|
+
infoSetStringProperty: 25,
|
|
67
|
+
infoSetIntProperty: 26,
|
|
68
|
+
};
|
|
69
|
+
const T = FFIType;
|
|
70
|
+
const cstr = (value) => Buffer.from(`${value}\0`, 'utf8');
|
|
71
|
+
const outPointer = () => new BigUint64Array(1);
|
|
72
|
+
const deref = (out) => Number(out[0]);
|
|
73
|
+
export const loadBunFoundryLibrary = async (libDir) => {
|
|
74
|
+
const file = LIBRARY_FILE[process.platform];
|
|
75
|
+
if (!file)
|
|
76
|
+
throw new FoundryLibraryError('load', 0, `Foundry Local has no library for ${process.platform}`);
|
|
77
|
+
const path = join(libDir, file);
|
|
78
|
+
if (!existsSync(path))
|
|
79
|
+
throw new FoundryLibraryError('load', 0, `${path} not found: no ${file} in this build`);
|
|
80
|
+
if (process.platform === 'win32') {
|
|
81
|
+
// The loader does not search the DLL's own folder for onnxruntime.dll and its siblings (error 126).
|
|
82
|
+
const kernel32 = dlopen('kernel32.dll', { SetDllDirectoryW: { args: [T.ptr], returns: T.i32 } });
|
|
83
|
+
kernel32.symbols.SetDllDirectoryW(ptr(Buffer.from(`${libDir}\0`, 'utf16le')));
|
|
84
|
+
}
|
|
85
|
+
const library = dlopen(path, {
|
|
86
|
+
FoundryLocalGetApi: { args: [T.u32], returns: T.ptr },
|
|
87
|
+
FoundryLocalGetVersionString: { args: [], returns: T.cstring },
|
|
88
|
+
});
|
|
89
|
+
const version = String(library.symbols.FoundryLocalGetVersionString());
|
|
90
|
+
const api = library.symbols.FoundryLocalGetApi(BOUND_C_API_VERSION);
|
|
91
|
+
if (!api)
|
|
92
|
+
throw new FoundryLibraryError('FoundryLocalGetApi', 0, `Foundry Local ${version} does not provide C API version ${BOUND_C_API_VERSION}`);
|
|
93
|
+
return bindLibrary(api, version);
|
|
94
|
+
};
|
|
95
|
+
function bindLibrary(api, version) {
|
|
96
|
+
const fn = (table, index, args, returns) => CFunction({ ptr: read.ptr(table, index * POINTER), args, returns });
|
|
97
|
+
const statusCode = fn(api, API.statusGetErrorCode, [T.ptr], T.i32);
|
|
98
|
+
const statusMessage = fn(api, API.statusGetErrorMessage, [T.ptr], T.cstring);
|
|
99
|
+
const statusRelease = fn(api, API.statusRelease, [T.ptr], T.void);
|
|
100
|
+
/** A non-null `flStatus*` is an error: read it, free it, throw it. */
|
|
101
|
+
const check = (status, operation) => {
|
|
102
|
+
if (!status)
|
|
103
|
+
return;
|
|
104
|
+
const code = Number(statusCode(status));
|
|
105
|
+
const message = String(statusMessage(status));
|
|
106
|
+
statusRelease(status);
|
|
107
|
+
throw new FoundryLibraryError(operation, code, message);
|
|
108
|
+
};
|
|
109
|
+
const call = (f, operation, ...args) => check(f(...args), operation);
|
|
110
|
+
const configApi = fn(api, API.getConfigurationApi, [], T.ptr)();
|
|
111
|
+
const catalogApi = fn(api, API.getCatalogApi, [], T.ptr)();
|
|
112
|
+
const modelApi = fn(api, API.getModelApi, [], T.ptr)();
|
|
113
|
+
const f = {
|
|
114
|
+
configCreate: fn(configApi, CONFIG.create, [T.ptr, T.ptr], T.ptr),
|
|
115
|
+
configRelease: fn(configApi, CONFIG.release, [T.ptr], T.void),
|
|
116
|
+
setAppDataDir: fn(configApi, CONFIG.setAppDataDir, [T.ptr, T.ptr], T.ptr),
|
|
117
|
+
setLogsDir: fn(configApi, CONFIG.setLogsDir, [T.ptr, T.ptr], T.ptr),
|
|
118
|
+
setModelCacheDir: fn(configApi, CONFIG.setModelCacheDir, [T.ptr, T.ptr], T.ptr),
|
|
119
|
+
addWebServiceEndpoint: fn(configApi, CONFIG.addWebServiceEndpoint, [T.ptr, T.ptr], T.ptr),
|
|
120
|
+
setAdditionalOptions: fn(configApi, CONFIG.setAdditionalOptions, [T.ptr, T.ptr], T.ptr),
|
|
121
|
+
kvCreate: fn(api, API.createKeyValuePairs, [T.ptr], T.void),
|
|
122
|
+
kvAdd: fn(api, API.addKeyValuePair, [T.ptr, T.ptr, T.ptr], T.void),
|
|
123
|
+
kvRelease: fn(api, API.keyValuePairsRelease, [T.ptr], T.void),
|
|
124
|
+
managerCreate: fn(api, API.managerCreate, [T.ptr, T.ptr], T.ptr),
|
|
125
|
+
managerRelease: fn(api, API.managerRelease, [T.ptr], T.void),
|
|
126
|
+
managerShutdown: fn(api, API.managerShutdown, [T.ptr], T.ptr),
|
|
127
|
+
getDiscoverableEps: fn(api, API.getDiscoverableEps, [T.ptr, T.ptr, T.ptr], T.ptr),
|
|
128
|
+
downloadAndRegisterEps: fn(api, API.downloadAndRegisterEps, [T.ptr, T.ptr, T.u64, T.ptr, T.ptr], T.ptr),
|
|
129
|
+
getCatalogByType: fn(api, API.getCatalogByType, [T.ptr, T.i32, T.ptr], T.ptr),
|
|
130
|
+
webServiceStart: fn(api, API.webServiceStart, [T.ptr], T.ptr),
|
|
131
|
+
webServiceUrls: fn(api, API.webServiceUrls, [T.ptr, T.ptr, T.ptr], T.ptr),
|
|
132
|
+
registerModel: fn(catalogApi, CATALOG.registerModel, [T.ptr, T.ptr, T.ptr, T.ptr, T.ptr], T.ptr),
|
|
133
|
+
modelGetInfo: fn(modelApi, MODEL.getInfo, [T.ptr, T.ptr], T.ptr),
|
|
134
|
+
modelLoad: fn(modelApi, MODEL.load, [T.ptr], T.ptr),
|
|
135
|
+
modelUnload: fn(modelApi, MODEL.unload, [T.ptr], T.ptr),
|
|
136
|
+
infoGetExecutionProvider: fn(modelApi, MODEL.infoGetExecutionProvider, [T.ptr], T.cstring),
|
|
137
|
+
createModelInfo: fn(modelApi, MODEL.createModelInfo, [T.ptr], T.ptr),
|
|
138
|
+
releaseModelInfo: fn(modelApi, MODEL.releaseModelInfo, [T.ptr], T.void),
|
|
139
|
+
infoSetString: fn(modelApi, MODEL.infoSetStringProperty, [T.ptr, T.ptr, T.ptr], T.ptr),
|
|
140
|
+
infoSetInt: fn(modelApi, MODEL.infoSetIntProperty, [T.ptr, T.ptr, T.i64], T.ptr),
|
|
141
|
+
};
|
|
142
|
+
function createManager(config) {
|
|
143
|
+
const configOut = outPointer();
|
|
144
|
+
call(f.configCreate, 'Configuration_Create', ptr(cstr(config.appName)), ptr(configOut));
|
|
145
|
+
const cfg = deref(configOut);
|
|
146
|
+
let manager;
|
|
147
|
+
try {
|
|
148
|
+
call(f.setAppDataDir, 'SetAppDataDir', cfg, ptr(cstr(config.appDataDir)));
|
|
149
|
+
call(f.setLogsDir, 'SetLogsDir', cfg, ptr(cstr(config.logsDir)));
|
|
150
|
+
call(f.setModelCacheDir, 'SetModelCacheDir', cfg, ptr(cstr(config.modelCacheDir)));
|
|
151
|
+
for (const endpoint of config.webServiceEndpoints)
|
|
152
|
+
call(f.addWebServiceEndpoint, 'AddWebServiceEndpoint', cfg, ptr(cstr(endpoint)));
|
|
153
|
+
const kvOut = outPointer();
|
|
154
|
+
f.kvCreate(ptr(kvOut));
|
|
155
|
+
const kv = deref(kvOut);
|
|
156
|
+
for (const [key, value] of Object.entries(config.additionalOptions))
|
|
157
|
+
f.kvAdd(kv, ptr(cstr(key)), ptr(cstr(value)));
|
|
158
|
+
try {
|
|
159
|
+
call(f.setAdditionalOptions, 'SetAdditionalOptions', cfg, kv);
|
|
160
|
+
}
|
|
161
|
+
finally {
|
|
162
|
+
f.kvRelease(kv);
|
|
163
|
+
}
|
|
164
|
+
const managerOut = outPointer();
|
|
165
|
+
call(f.managerCreate, 'Manager_Create', cfg, ptr(managerOut));
|
|
166
|
+
manager = deref(managerOut);
|
|
167
|
+
}
|
|
168
|
+
finally {
|
|
169
|
+
f.configRelease(cfg);
|
|
170
|
+
}
|
|
171
|
+
return bindManager(manager);
|
|
172
|
+
}
|
|
173
|
+
function bindManager(manager) {
|
|
174
|
+
return {
|
|
175
|
+
discoverableEps() {
|
|
176
|
+
const epsOut = outPointer();
|
|
177
|
+
const countOut = outPointer();
|
|
178
|
+
call(f.getDiscoverableEps, 'Manager_GetDiscoverableEps', manager, ptr(epsOut), ptr(countOut));
|
|
179
|
+
const base = deref(epsOut);
|
|
180
|
+
const eps = [];
|
|
181
|
+
for (let i = 0; i < Number(countOut[0]); i++) {
|
|
182
|
+
const at = i * EP_INFO_SIZE;
|
|
183
|
+
eps.push({
|
|
184
|
+
name: new CString(read.ptr(base, at + 8)).toString(),
|
|
185
|
+
registered: read.u8(base, at + 16) !== 0,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
return eps;
|
|
189
|
+
},
|
|
190
|
+
downloadAndRegisterEps(names, onProgress) {
|
|
191
|
+
const strings = names.map(cstr);
|
|
192
|
+
const array = new BigUint64Array(strings.map((s) => BigInt(ptr(s))));
|
|
193
|
+
// Not threadsafe: the library calls back on the calling thread, synchronously (spike S1, S2).
|
|
194
|
+
const callback = onProgress
|
|
195
|
+
? new JSCallback((name, percent) => {
|
|
196
|
+
onProgress(new CString(name).toString(), percent);
|
|
197
|
+
return 0;
|
|
198
|
+
}, { args: [T.ptr, T.f32, T.ptr], returns: T.i32 })
|
|
199
|
+
: null;
|
|
200
|
+
try {
|
|
201
|
+
call(f.downloadAndRegisterEps, 'Manager_DownloadAndRegisterEps', manager, names.length > 0 ? ptr(array) : null, names.length, callback ? callback.ptr : null, null);
|
|
202
|
+
}
|
|
203
|
+
finally {
|
|
204
|
+
callback?.close();
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
registerLocalModel(path, id, metadata) {
|
|
208
|
+
const catalogOut = outPointer();
|
|
209
|
+
call(f.getCatalogByType, 'Manager_GetCatalogByType', manager, CATALOG_LOCAL, ptr(catalogOut));
|
|
210
|
+
const infoOut = outPointer();
|
|
211
|
+
call(f.createModelInfo, 'CreateModelInfo', ptr(infoOut));
|
|
212
|
+
const info = deref(infoOut);
|
|
213
|
+
const modelOut = outPointer();
|
|
214
|
+
try {
|
|
215
|
+
for (const [key, value] of Object.entries(metadata.strings))
|
|
216
|
+
call(f.infoSetString, `Info_SetStringProperty(${key})`, info, ptr(cstr(key)), ptr(cstr(value)));
|
|
217
|
+
for (const [key, value] of Object.entries(metadata.ints))
|
|
218
|
+
call(f.infoSetInt, `Info_SetIntProperty(${key})`, info, ptr(cstr(key)), BigInt(value));
|
|
219
|
+
call(f.registerModel, 'RegisterModel', deref(catalogOut), ptr(cstr(path)), ptr(cstr(id)), info, ptr(modelOut));
|
|
220
|
+
}
|
|
221
|
+
finally {
|
|
222
|
+
f.releaseModelInfo(info);
|
|
223
|
+
}
|
|
224
|
+
return bindModel(deref(modelOut));
|
|
225
|
+
},
|
|
226
|
+
webServiceStart() {
|
|
227
|
+
call(f.webServiceStart, 'Manager_WebServiceStart', manager);
|
|
228
|
+
const urlsOut = outPointer();
|
|
229
|
+
const countOut = outPointer();
|
|
230
|
+
call(f.webServiceUrls, 'Manager_WebServiceUrls', manager, ptr(urlsOut), ptr(countOut));
|
|
231
|
+
const urls = [];
|
|
232
|
+
for (let i = 0; i < Number(countOut[0]); i++)
|
|
233
|
+
urls.push(new CString(read.ptr(deref(urlsOut), i * POINTER)).toString());
|
|
234
|
+
return urls;
|
|
235
|
+
},
|
|
236
|
+
shutdown: () => call(f.managerShutdown, 'Manager_Shutdown', manager),
|
|
237
|
+
release: () => {
|
|
238
|
+
f.managerRelease(manager);
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
function bindModel(model) {
|
|
243
|
+
return {
|
|
244
|
+
load: () => call(f.modelLoad, 'Model_Load', model),
|
|
245
|
+
unload: () => call(f.modelUnload, 'Model_Unload', model),
|
|
246
|
+
executionProvider() {
|
|
247
|
+
const infoOut = outPointer();
|
|
248
|
+
call(f.modelGetInfo, 'Model_GetInfo', model, ptr(infoOut));
|
|
249
|
+
const ep = f.infoGetExecutionProvider(deref(infoOut));
|
|
250
|
+
return ep ? String(ep) : null;
|
|
251
|
+
},
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
return { version, cApiVersion: BOUND_C_API_VERSION, createManager };
|
|
255
|
+
}
|
|
256
|
+
//# sourceMappingURL=ffi-bun.js.map
|