@atomic-chat/core 0.17.0 → 0.18.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/app-daemon.js +9 -0
- package/dist/app-daemon.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/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 +7 -1
- 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/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/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 +78 -0
- package/dist/runtime/foundry-local/host-process.js +182 -0
- package/dist/runtime/foundry-local/host-process.js.map +1 -0
- package/dist/runtime/foundry-local/index.d.ts +11 -0
- package/dist/runtime/foundry-local/index.js +11 -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 +3 -1
- 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 +2 -0
- 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/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 +2 -1
- package/src/settings/schema/foundry-local.json +14 -0
|
@@ -14,8 +14,8 @@ export interface IdentityDeps {
|
|
|
14
14
|
platform?: NodeJS.Platform;
|
|
15
15
|
/** Read a procfs entry (Linux). */
|
|
16
16
|
readText?: (path: string) => Promise<string>;
|
|
17
|
-
/** Run a probe and return its stdout. */
|
|
18
|
-
run?: (file: string, args: string[]) => Promise<string>;
|
|
17
|
+
/** Run a probe and return its stdout; `env` is laid over this process's environment. */
|
|
18
|
+
run?: (file: string, args: string[], env?: Record<string, string>) => Promise<string>;
|
|
19
19
|
/** Signal-0 liveness probe. */
|
|
20
20
|
alive?: (pid: number) => boolean;
|
|
21
21
|
}
|
|
@@ -27,7 +27,7 @@ export interface IdentityDeps {
|
|
|
27
27
|
*/
|
|
28
28
|
export declare const IDENTITY_PROBE_TIMEOUT_MS = 15000;
|
|
29
29
|
export declare function isProcessAlive(pid: number): boolean;
|
|
30
|
-
export declare function runProbe(file: string, args: string[]): Promise<string>;
|
|
30
|
+
export declare function runProbe(file: string, args: string[], env?: Record<string, string>): Promise<string>;
|
|
31
31
|
/**
|
|
32
32
|
* An opaque, comparable token for "this incarnation of this PID", or `undefined` when the platform
|
|
33
33
|
* cannot tell us. Only ever compared for equality, never parsed.
|
|
@@ -44,5 +44,11 @@ export declare function processStartEpoch(pid: number, deps?: IdentityDeps): Pro
|
|
|
44
44
|
export declare function processName(pid: number, deps?: IdentityDeps): Promise<string | undefined>;
|
|
45
45
|
/** Compare a recorded identity with the live process. `unknown` means "cannot prove"; treat as live. */
|
|
46
46
|
export declare function verifyProcessIdentity(pid: number, expected: string | null | undefined, deps?: IdentityDeps): Promise<IdentityVerdict>;
|
|
47
|
+
/**
|
|
48
|
+
* Compare a recorded start time (`epoch:<seconds>`, `processStartEpoch`) with the live process. Seconds
|
|
49
|
+
* since the epoch read the same in every locale and zone, so a difference is proof of another process
|
|
50
|
+
* behind the PID; a second either way is the same start read at a different instant.
|
|
51
|
+
*/
|
|
52
|
+
export declare function verifyStartEpoch(pid: number, expected: string | null | undefined, deps?: IdentityDeps): Promise<IdentityVerdict>;
|
|
47
53
|
/** Only a proven-gone process releases what it held. */
|
|
48
54
|
export declare function identityPermitsTakeover(verdict: IdentityVerdict): boolean;
|
|
@@ -30,9 +30,13 @@ export function isProcessAlive(pid) {
|
|
|
30
30
|
return e.code === 'EPERM';
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
-
export function runProbe(file, args) {
|
|
33
|
+
export function runProbe(file, args, env) {
|
|
34
34
|
return new Promise((resolve, reject) => {
|
|
35
|
-
execFile(file, args, {
|
|
35
|
+
execFile(file, args, {
|
|
36
|
+
timeout: IDENTITY_PROBE_TIMEOUT_MS,
|
|
37
|
+
windowsHide: true,
|
|
38
|
+
...(env ? { env: { ...process.env, ...env } } : {}),
|
|
39
|
+
}, (err, stdout) => {
|
|
36
40
|
if (err)
|
|
37
41
|
reject(err);
|
|
38
42
|
else
|
|
@@ -40,6 +44,21 @@ export function runProbe(file, args) {
|
|
|
40
44
|
});
|
|
41
45
|
});
|
|
42
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* What `ps` prints depends on the locale and the time zone of whoever runs it; an identity compared
|
|
49
|
+
* later by another process (a core started from another terminal, a laptop in another zone) must not.
|
|
50
|
+
*/
|
|
51
|
+
const PINNED_PS_ENV = { LC_ALL: 'C', TZ: 'UTC' };
|
|
52
|
+
const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
53
|
+
/** `Mon Oct 19 10:33:52 2026` (C locale, UTC) → seconds since the epoch; `undefined` for anything else. */
|
|
54
|
+
function utcLstartSeconds(text) {
|
|
55
|
+
const m = /^[A-Z][a-z]{2} ([A-Z][a-z]{2}) +(\d{1,2}) (\d{2}):(\d{2}):(\d{2}) (\d{4})$/.exec(text);
|
|
56
|
+
const month = m ? MONTHS.indexOf(m[1]) : -1;
|
|
57
|
+
if (!m || month < 0)
|
|
58
|
+
return undefined;
|
|
59
|
+
const [day, h, min, sec, year] = m.slice(2).map(Number);
|
|
60
|
+
return Date.UTC(year, month, day, h, min, sec) / 1000;
|
|
61
|
+
}
|
|
43
62
|
/**
|
|
44
63
|
* An opaque, comparable token for "this incarnation of this PID", or `undefined` when the platform
|
|
45
64
|
* cannot tell us. Only ever compared for equality, never parsed.
|
|
@@ -65,19 +84,19 @@ export async function processStartId(pid, deps = {}) {
|
|
|
65
84
|
if (platform === 'darwin') {
|
|
66
85
|
// `lstart` has one-second resolution; a PID reused inside the same second is indistinguishable,
|
|
67
86
|
// which the takeover path treats as "unknown", never as a free lock.
|
|
68
|
-
const out = await run('/bin/ps', ['-o', 'lstart=', '-p', String(pid)]);
|
|
87
|
+
const out = await run('/bin/ps', ['-o', 'lstart=', '-p', String(pid)], PINNED_PS_ENV);
|
|
69
88
|
const value = out.trim().replace(/\s+/g, ' ');
|
|
70
|
-
return value ? `darwin:${value}` : undefined;
|
|
89
|
+
return value ? `darwin-utc:${value}` : undefined;
|
|
71
90
|
}
|
|
72
91
|
if (platform === 'win32') {
|
|
73
92
|
const out = await run('powershell.exe', [
|
|
74
93
|
'-NoProfile',
|
|
75
94
|
'-NonInteractive',
|
|
76
95
|
'-Command',
|
|
77
|
-
`(Get-Process -Id ${pid} -ErrorAction Stop).StartTime.Ticks`,
|
|
96
|
+
`(Get-Process -Id ${pid} -ErrorAction Stop).StartTime.ToUniversalTime().Ticks`,
|
|
78
97
|
]);
|
|
79
98
|
const value = out.trim();
|
|
80
|
-
return /^\d+$/.test(value) ? `win32:${value}` : undefined;
|
|
99
|
+
return /^\d+$/.test(value) ? `win32-utc:${value}` : undefined;
|
|
81
100
|
}
|
|
82
101
|
}
|
|
83
102
|
catch {
|
|
@@ -107,9 +126,9 @@ export async function processStartEpoch(pid, deps = {}) {
|
|
|
107
126
|
return `epoch:${Math.floor(boot + ticks / 100)}`;
|
|
108
127
|
}
|
|
109
128
|
if (platform === 'darwin') {
|
|
110
|
-
const out =
|
|
111
|
-
const epoch =
|
|
112
|
-
return
|
|
129
|
+
const out = await run('/bin/ps', ['-o', 'lstart=', '-p', String(pid)], PINNED_PS_ENV);
|
|
130
|
+
const epoch = utcLstartSeconds(out.trim().replace(/\s+/g, ' '));
|
|
131
|
+
return epoch === undefined ? undefined : `epoch:${epoch}`;
|
|
113
132
|
}
|
|
114
133
|
if (platform === 'win32') {
|
|
115
134
|
const out = await run('powershell.exe', [
|
|
@@ -168,11 +187,58 @@ export async function verifyProcessIdentity(pid, expected, deps = {}) {
|
|
|
168
187
|
return 'dead';
|
|
169
188
|
if (!expected)
|
|
170
189
|
return 'unknown';
|
|
190
|
+
// Written before identities were pinned: in the writer's locale and zone, which this reader cannot
|
|
191
|
+
// know. Equal still proves it; a difference proves nothing, so it never frees what the owner holds.
|
|
192
|
+
if (/^(darwin|win32):/.test(expected)) {
|
|
193
|
+
const legacy = await legacyStartId(pid, deps);
|
|
194
|
+
return legacy !== undefined && legacy === expected ? 'match' : 'unknown';
|
|
195
|
+
}
|
|
171
196
|
const actual = await processStartId(pid, deps);
|
|
172
197
|
if (!actual)
|
|
173
198
|
return 'unknown';
|
|
174
199
|
return actual === expected ? 'match' : 'mismatch';
|
|
175
200
|
}
|
|
201
|
+
/** The identity as cores before 0.18.3 wrote it: `ps` in the C locale and local zone, local ticks. */
|
|
202
|
+
async function legacyStartId(pid, deps) {
|
|
203
|
+
const platform = deps.platform ?? process.platform;
|
|
204
|
+
const run = deps.run ?? runProbe;
|
|
205
|
+
try {
|
|
206
|
+
if (platform === 'darwin') {
|
|
207
|
+
const out = await run('/bin/ps', ['-o', 'lstart=', '-p', String(pid)], { LC_ALL: 'C' });
|
|
208
|
+
const value = out.trim().replace(/\s+/g, ' ');
|
|
209
|
+
return value ? `darwin:${value}` : undefined;
|
|
210
|
+
}
|
|
211
|
+
if (platform === 'win32') {
|
|
212
|
+
const out = await run('powershell.exe', [
|
|
213
|
+
'-NoProfile',
|
|
214
|
+
'-NonInteractive',
|
|
215
|
+
'-Command',
|
|
216
|
+
`(Get-Process -Id ${pid} -ErrorAction Stop).StartTime.Ticks`,
|
|
217
|
+
]);
|
|
218
|
+
const value = out.trim();
|
|
219
|
+
return /^\d+$/.test(value) ? `win32:${value}` : undefined;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
return undefined;
|
|
224
|
+
}
|
|
225
|
+
return undefined;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Compare a recorded start time (`epoch:<seconds>`, `processStartEpoch`) with the live process. Seconds
|
|
229
|
+
* since the epoch read the same in every locale and zone, so a difference is proof of another process
|
|
230
|
+
* behind the PID; a second either way is the same start read at a different instant.
|
|
231
|
+
*/
|
|
232
|
+
export async function verifyStartEpoch(pid, expected, deps = {}) {
|
|
233
|
+
const alive = deps.alive ?? isProcessAlive;
|
|
234
|
+
if (!alive(pid))
|
|
235
|
+
return 'dead';
|
|
236
|
+
const want = Number(/^epoch:(\d+)$/.exec(expected ?? '')?.[1]);
|
|
237
|
+
const got = Number(/^epoch:(\d+)$/.exec((await processStartEpoch(pid, deps)) ?? '')?.[1]);
|
|
238
|
+
if (!Number.isFinite(want) || !Number.isFinite(got))
|
|
239
|
+
return 'unknown';
|
|
240
|
+
return Math.abs(want - got) <= 1 ? 'match' : 'mismatch';
|
|
241
|
+
}
|
|
176
242
|
/** Only a proven-gone process releases what it held. */
|
|
177
243
|
export function identityPermitsTakeover(verdict) {
|
|
178
244
|
return verdict === 'dead' || verdict === 'mismatch';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process-identity.js","sourceRoot":"","sources":["../../src/lock/process-identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAC7C,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAc3C;;;;;GAKG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,MAAM,CAAA;AAE/C,MAAM,QAAQ,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;AAEzD,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,KAAK,CAAA;IACpD,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;QACpB,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAQ,CAA2B,CAAC,IAAI,KAAK,OAAO,CAAA;IACtD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,IAAc;
|
|
1
|
+
{"version":3,"file":"process-identity.js","sourceRoot":"","sources":["../../src/lock/process-identity.ts"],"names":[],"mappings":"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"}
|
package/dist/router/resolve.d.ts
CHANGED
|
@@ -21,14 +21,14 @@ export interface RemoteProvider {
|
|
|
21
21
|
/** The image and video models enabled for this provider; never part of chat routing. */
|
|
22
22
|
media?: CloudProviderMedia;
|
|
23
23
|
}
|
|
24
|
-
export type LocalProvider = 'llamacpp' | 'llamacpp-upstream' | 'mlx' | 'tensorrt-llm' | 'atomic-prism' | 'vllm' | 'sglang';
|
|
24
|
+
export type LocalProvider = 'llamacpp' | 'llamacpp-upstream' | 'mlx' | 'tensorrt-llm' | 'atomic-prism' | 'vllm' | 'sglang' | 'foundry-local';
|
|
25
25
|
/**
|
|
26
26
|
* The order local providers are searched in when a request names only a model. The same model id
|
|
27
27
|
* loaded under two engines resolves to the first; changing the order would silently move traffic.
|
|
28
28
|
* `tensorrt-llm`, `atomic-prism`, `vllm` and `sglang` come last, in the order they were added, for
|
|
29
29
|
* exactly that reason: adding a provider moves nothing that already resolved (`vllm` after
|
|
30
30
|
* `atomic-prism`, which core 0.10.0 already shipped; change `add-vllm-runtime`, D11; `sglang` after
|
|
31
|
-
* `vllm`, change `add-sglang-runtime`, D8). A Prism-only file never loads
|
|
31
|
+
* `vllm`, change `add-sglang-runtime`, D8; `foundry-local` after `sglang`, change `add-foundry-local`, D5). A Prism-only file never loads
|
|
32
32
|
* under another engine (the compatibility gate), so its sessions are found here even near the end of
|
|
33
33
|
* the list; one store model is never loaded in two managed providers at once, so their order never
|
|
34
34
|
* decides between two live sessions of one id.
|
package/dist/router/resolve.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
* `tensorrt-llm`, `atomic-prism`, `vllm` and `sglang` come last, in the order they were added, for
|
|
12
12
|
* exactly that reason: adding a provider moves nothing that already resolved (`vllm` after
|
|
13
13
|
* `atomic-prism`, which core 0.10.0 already shipped; change `add-vllm-runtime`, D11; `sglang` after
|
|
14
|
-
* `vllm`, change `add-sglang-runtime`, D8). A Prism-only file never loads
|
|
14
|
+
* `vllm`, change `add-sglang-runtime`, D8; `foundry-local` after `sglang`, change `add-foundry-local`, D5). A Prism-only file never loads
|
|
15
15
|
* under another engine (the compatibility gate), so its sessions are found here even near the end of
|
|
16
16
|
* the list; one store model is never loaded in two managed providers at once, so their order never
|
|
17
17
|
* decides between two live sessions of one id.
|
|
@@ -24,6 +24,7 @@ export const LOCAL_SEARCH_ORDER = [
|
|
|
24
24
|
'atomic-prism',
|
|
25
25
|
'vllm',
|
|
26
26
|
'sglang',
|
|
27
|
+
'foundry-local',
|
|
27
28
|
];
|
|
28
29
|
/**
|
|
29
30
|
* The remote provider that owns `modelId`, if any. Remote wins over local — a model id the user
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/router/resolve.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/router/resolve.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA2BH;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAA6B;IAC1D,UAAU;IACV,mBAAmB;IACnB,KAAK;IACL,cAAc;IACd,cAAc;IACd,MAAM;IACN,QAAQ;IACR,eAAe;CAChB,CAAA;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,qBAAqB,CACnC,OAAe,EACf,SAA8C;IAE9C,KAAK,MAAM,MAAM,IAAI,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC;QACxC,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,OAAO,MAAM,CAAA;IACpD,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAClC,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QACf,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAA;QACvD,IAAI,QAAQ;YAAE,OAAO,QAAQ,CAAA;IAC/B,CAAC;IACD,OAAO,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;AAC/B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,CAAS,EAAE,CAAS;IAChD,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,KAAK,CAAA;IACvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;QACd,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;QACd,IAAI,CAAC,KAAK,CAAC;YAAE,SAAQ;QACrB,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,CAAC;YAAE,SAAQ;QAClE,OAAO,KAAK,CAAA;IACd,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAAe,EACf,IAAe,EACf,SAA8C;IAE9C,MAAM,KAAK,GAAG,CAAC,MAAsB,EAAE,EAAU,EAAW,EAAE,CAC5D,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,IAAI,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,IAAI,KAAK,CAAA;IACvF,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAClC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAA;QACpD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;QACrC,IAAI,KAAK,IAAI,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC;YAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,CAAA;IACnF,CAAC;IACD,KAAK,MAAM,MAAM,IAAI,SAAS,CAAC,MAAM,EAAE;QACrC,IAAI,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC;YAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,CAAA;IAClF,OAAO,SAAS,CAAA;AAClB,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Foundry Local's accelerators (openspec change `add-foundry-local`, task 6.4, design D3). The
|
|
3
|
+
* library finds and downloads them itself; core only decides when: a `probe` of the active build
|
|
4
|
+
* when a client first asks or the active build changed, and a `prepare` when a client orders it — one
|
|
5
|
+
* at a time, each step published as `foundry-local:accelerators`.
|
|
6
|
+
*
|
|
7
|
+
* What is prepared is core's own record, `<data>/foundry-local/runtime/accelerators.json`: the
|
|
8
|
+
* library's "registered" flag lives only as long as one process (spike finding 18).
|
|
9
|
+
*/
|
|
10
|
+
import type { CoreEvents, FoundryLocalAccelerators, FoundryLocalPrepareRequest, FoundryLocalPrepareResult } from '../../contracts/index.js';
|
|
11
|
+
import type { FoundryHostCommand } from './host-process.js';
|
|
12
|
+
export declare const ACCELERATORS_FILE = "accelerators.json";
|
|
13
|
+
export interface FoundryLocalAcceleratorDeps {
|
|
14
|
+
hostCommand: FoundryHostCommand;
|
|
15
|
+
/** The active build's directory, or nothing installed. */
|
|
16
|
+
resolveBuild: () => Promise<string | undefined>;
|
|
17
|
+
/** `<data>/foundry-local/runtime`: the library's data and core's `accelerators.json`. */
|
|
18
|
+
runtimeDir: string;
|
|
19
|
+
logsDir: string;
|
|
20
|
+
emit: (name: 'foundry-local:accelerators', payload: CoreEvents['foundry-local:accelerators']) => void;
|
|
21
|
+
env?: NodeJS.ProcessEnv;
|
|
22
|
+
now?: () => number;
|
|
23
|
+
}
|
|
24
|
+
export declare class FoundryLocalAcceleratorService {
|
|
25
|
+
private readonly deps;
|
|
26
|
+
private cache;
|
|
27
|
+
private preparing;
|
|
28
|
+
private readonly now;
|
|
29
|
+
constructor(deps: FoundryLocalAcceleratorDeps);
|
|
30
|
+
/** The names core recorded as prepared: what a load checks before it starts a host. */
|
|
31
|
+
prepared(): Promise<string[]>;
|
|
32
|
+
/** The last probe of the active build, with core's record of what is prepared; `force` probes again. */
|
|
33
|
+
list(options?: {
|
|
34
|
+
force?: boolean;
|
|
35
|
+
}): Promise<FoundryLocalAccelerators>;
|
|
36
|
+
/** Downloads and registers the accelerators named (none: all offered); one prepare at a time. */
|
|
37
|
+
prepare(request: FoundryLocalPrepareRequest): Promise<FoundryLocalPrepareResult>;
|
|
38
|
+
private withRecord;
|
|
39
|
+
private read;
|
|
40
|
+
/** Write-then-rename: a crash mid-write leaves the previous record, never half of one. */
|
|
41
|
+
private write;
|
|
42
|
+
}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Foundry Local's accelerators (openspec change `add-foundry-local`, task 6.4, design D3). The
|
|
3
|
+
* library finds and downloads them itself; core only decides when: a `probe` of the active build
|
|
4
|
+
* when a client first asks or the active build changed, and a `prepare` when a client orders it — one
|
|
5
|
+
* at a time, each step published as `foundry-local:accelerators`.
|
|
6
|
+
*
|
|
7
|
+
* What is prepared is core's own record, `<data>/foundry-local/runtime/accelerators.json`: the
|
|
8
|
+
* library's "registered" flag lives only as long as one process (spike finding 18).
|
|
9
|
+
*/
|
|
10
|
+
import { mkdir, readFile, rename, writeFile } from 'node:fs/promises';
|
|
11
|
+
import { basename, dirname, join } from 'node:path';
|
|
12
|
+
import { AtomicCoreError } from '../../contracts/index.js';
|
|
13
|
+
import { runFoundryHostPrepare, runFoundryHostProbe } from './host-process.js';
|
|
14
|
+
export const ACCELERATORS_FILE = 'accelerators.json';
|
|
15
|
+
const EMPTY = { prepared: [], failures: {}, updated_at: 0 };
|
|
16
|
+
export class FoundryLocalAcceleratorService {
|
|
17
|
+
deps;
|
|
18
|
+
cache = null;
|
|
19
|
+
preparing = false;
|
|
20
|
+
now;
|
|
21
|
+
constructor(deps) {
|
|
22
|
+
this.deps = deps;
|
|
23
|
+
this.now = deps.now ?? Date.now;
|
|
24
|
+
}
|
|
25
|
+
/** The names core recorded as prepared: what a load checks before it starts a host. */
|
|
26
|
+
async prepared() {
|
|
27
|
+
return [...(await this.read()).prepared];
|
|
28
|
+
}
|
|
29
|
+
/** The last probe of the active build, with core's record of what is prepared; `force` probes again. */
|
|
30
|
+
async list(options = {}) {
|
|
31
|
+
const build = await this.deps.resolveBuild();
|
|
32
|
+
if (!build)
|
|
33
|
+
return {
|
|
34
|
+
installed: false,
|
|
35
|
+
build: null,
|
|
36
|
+
version: null,
|
|
37
|
+
c_api_version: null,
|
|
38
|
+
probed_at: null,
|
|
39
|
+
accelerators: [],
|
|
40
|
+
error: null,
|
|
41
|
+
};
|
|
42
|
+
const record = await this.read();
|
|
43
|
+
if (!options.force && this.cache?.build === build)
|
|
44
|
+
return this.withRecord(this.cache.answer, record);
|
|
45
|
+
const name = `${basename(dirname(build))}/${basename(build)}`;
|
|
46
|
+
let answer;
|
|
47
|
+
try {
|
|
48
|
+
const probe = await runFoundryHostProbe(this.deps.hostCommand, {
|
|
49
|
+
libDir: build,
|
|
50
|
+
appDataDir: this.deps.runtimeDir,
|
|
51
|
+
logsDir: this.deps.logsDir,
|
|
52
|
+
prepared: record.prepared,
|
|
53
|
+
}, this.deps.env ? { env: this.deps.env } : {});
|
|
54
|
+
answer = {
|
|
55
|
+
installed: true,
|
|
56
|
+
build: name,
|
|
57
|
+
version: probe.version ?? null,
|
|
58
|
+
c_api_version: probe.c_api_version,
|
|
59
|
+
probed_at: this.now(),
|
|
60
|
+
accelerators: probe.accelerators.map((accelerator) => ({
|
|
61
|
+
name: accelerator.name,
|
|
62
|
+
execution_provider: (accelerator.execution_provider ??
|
|
63
|
+
null),
|
|
64
|
+
device: accelerator.device,
|
|
65
|
+
prepared: false,
|
|
66
|
+
})),
|
|
67
|
+
error: null,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
const details = error instanceof AtomicCoreError ? error.details : undefined;
|
|
72
|
+
answer = {
|
|
73
|
+
installed: true,
|
|
74
|
+
build: name,
|
|
75
|
+
version: null,
|
|
76
|
+
c_api_version: null,
|
|
77
|
+
probed_at: this.now(),
|
|
78
|
+
accelerators: [],
|
|
79
|
+
error: [error instanceof Error ? error.message : String(error), details].filter(Boolean).join(' '),
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
this.cache = { build, answer };
|
|
83
|
+
return this.withRecord(answer, record);
|
|
84
|
+
}
|
|
85
|
+
/** Downloads and registers the accelerators named (none: all offered); one prepare at a time. */
|
|
86
|
+
async prepare(request) {
|
|
87
|
+
if (this.preparing)
|
|
88
|
+
throw new AtomicCoreError('ENGINE_INSTALL_IN_PROGRESS', 'Foundry Local accelerators are already being prepared; wait for that to finish.');
|
|
89
|
+
this.preparing = true;
|
|
90
|
+
try {
|
|
91
|
+
const build = await this.deps.resolveBuild();
|
|
92
|
+
if (!build)
|
|
93
|
+
throw new AtomicCoreError('BINARY_NOT_FOUND', 'Foundry Local is not installed; install it before preparing accelerators.');
|
|
94
|
+
const summary = await runFoundryHostPrepare(this.deps.hostCommand, { libDir: build, appDataDir: this.deps.runtimeDir, logsDir: this.deps.logsDir }, request.accelerators ?? [], (step) => this.deps.emit('foundry-local:accelerators', step), this.deps.env ? { env: this.deps.env } : {});
|
|
95
|
+
const record = await this.read();
|
|
96
|
+
const prepared = new Set(record.prepared);
|
|
97
|
+
const failures = { ...record.failures };
|
|
98
|
+
for (const outcome of summary.accelerators) {
|
|
99
|
+
if (outcome.prepared) {
|
|
100
|
+
prepared.add(outcome.name);
|
|
101
|
+
delete failures[outcome.name];
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
prepared.delete(outcome.name);
|
|
105
|
+
failures[outcome.name] = outcome.reason ?? 'Foundry Local did not register it.';
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
await this.write({ prepared: [...prepared], failures, updated_at: this.now() });
|
|
109
|
+
// The library state changed: the next request probes again (spec: after install, update, prepare).
|
|
110
|
+
this.cache = null;
|
|
111
|
+
return { accelerators: summary.accelerators };
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
this.preparing = false;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
withRecord(answer, record) {
|
|
118
|
+
return {
|
|
119
|
+
...answer,
|
|
120
|
+
accelerators: answer.accelerators.map((accelerator) => {
|
|
121
|
+
const reason = record.failures[accelerator.name];
|
|
122
|
+
const prepared = record.prepared.includes(accelerator.name);
|
|
123
|
+
return { ...accelerator, prepared, ...(!prepared && reason !== undefined ? { reason } : {}) };
|
|
124
|
+
}),
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
async read() {
|
|
128
|
+
try {
|
|
129
|
+
const raw = JSON.parse(await readFile(join(this.deps.runtimeDir, ACCELERATORS_FILE), 'utf8'));
|
|
130
|
+
return {
|
|
131
|
+
prepared: Array.isArray(raw.prepared)
|
|
132
|
+
? raw.prepared.filter((name) => typeof name === 'string')
|
|
133
|
+
: [],
|
|
134
|
+
failures: raw.failures && typeof raw.failures === 'object' && !Array.isArray(raw.failures)
|
|
135
|
+
? Object.fromEntries(Object.entries(raw.failures).filter(([, v]) => typeof v === 'string'))
|
|
136
|
+
: {},
|
|
137
|
+
updated_at: typeof raw.updated_at === 'number' ? raw.updated_at : 0,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
return EMPTY;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/** Write-then-rename: a crash mid-write leaves the previous record, never half of one. */
|
|
145
|
+
async write(record) {
|
|
146
|
+
await mkdir(this.deps.runtimeDir, { recursive: true });
|
|
147
|
+
const path = join(this.deps.runtimeDir, ACCELERATORS_FILE);
|
|
148
|
+
const temporary = `${path}.tmp-${process.pid}`;
|
|
149
|
+
await writeFile(temporary, JSON.stringify(record, null, 2));
|
|
150
|
+
await rename(temporary, path);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=accelerators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"accelerators.js","sourceRoot":"","sources":["../../../src/runtime/foundry-local/accelerators.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
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 type { FoundryLocalAccelerator, FoundryLocalCheckRequest, FoundryLocalCheckResult } from '../../contracts/index.js';
|
|
7
|
+
export interface FoundryLocalCheckFacts {
|
|
8
|
+
platform: NodeJS.Platform;
|
|
9
|
+
arch: string;
|
|
10
|
+
/** A Foundry Local build is installed and active. */
|
|
11
|
+
installed: boolean;
|
|
12
|
+
/** The last probe's accelerators, with core's record of what is prepared. */
|
|
13
|
+
accelerators: readonly FoundryLocalAccelerator[];
|
|
14
|
+
/** An NPU on this machine (`probeNpu`); `null` when unknown — the probe's list decides then. */
|
|
15
|
+
npu: boolean | null;
|
|
16
|
+
}
|
|
17
|
+
export declare function foundryLocalVerdict(facts: FoundryLocalCheckFacts, request: FoundryLocalCheckRequest): FoundryLocalCheckResult;
|
|
18
|
+
/** The request body, strictly: the accelerator and the device as text, nothing else. */
|
|
19
|
+
export declare function parseFoundryLocalCheckRequest(body: unknown): FoundryLocalCheckRequest;
|
|
@@ -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,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 {};
|