prefer-inference-core 0.0.0-g0be6ef9

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.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +166 -0
  3. package/dist/catalog.d.ts +27 -0
  4. package/dist/catalog.d.ts.map +1 -0
  5. package/dist/catalog.js +547 -0
  6. package/dist/catalog.js.map +1 -0
  7. package/dist/cli.d.ts +3 -0
  8. package/dist/cli.d.ts.map +1 -0
  9. package/dist/cli.js +412 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/huggingface.d.ts +18 -0
  12. package/dist/huggingface.d.ts.map +1 -0
  13. package/dist/huggingface.js +296 -0
  14. package/dist/huggingface.js.map +1 -0
  15. package/dist/index.d.ts +8 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +8 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/planning.d.ts +11 -0
  20. package/dist/planning.d.ts.map +1 -0
  21. package/dist/planning.js +610 -0
  22. package/dist/planning.js.map +1 -0
  23. package/dist/prefer.mjs +9493 -0
  24. package/dist/prefer.mjs.map +7 -0
  25. package/dist/releases.d.ts +33 -0
  26. package/dist/releases.d.ts.map +1 -0
  27. package/dist/releases.js +288 -0
  28. package/dist/releases.js.map +1 -0
  29. package/dist/resources.d.ts +10 -0
  30. package/dist/resources.d.ts.map +1 -0
  31. package/dist/resources.js +250 -0
  32. package/dist/resources.js.map +1 -0
  33. package/dist/types.d.ts +409 -0
  34. package/dist/types.d.ts.map +1 -0
  35. package/dist/types.js +2 -0
  36. package/dist/types.js.map +1 -0
  37. package/dist/utils.d.ts +20 -0
  38. package/dist/utils.d.ts.map +1 -0
  39. package/dist/utils.js +112 -0
  40. package/dist/utils.js.map +1 -0
  41. package/package.json +58 -0
  42. package/schemas/prefer-model-catalog-extension.schema.json +25 -0
  43. package/schemas/prefer-model-catalog.schema.json +54 -0
  44. package/schemas/prefer-model-plan.schema.json +115 -0
  45. package/schemas/prefer-resource-profile.schema.json +70 -0
@@ -0,0 +1,33 @@
1
+ import type { PreferReleaseManifest, PreferReleaseRecord } from "./types.js";
2
+ export interface GitHubReleaseOptions {
3
+ token?: string | undefined;
4
+ fetch?: typeof fetch | undefined;
5
+ apiBaseUrl?: string | undefined;
6
+ timeoutMs?: number | undefined;
7
+ cacheDir?: string | undefined;
8
+ }
9
+ export interface ResolveReleaseOptions extends GitHubReleaseOptions {
10
+ repository: string;
11
+ channel?: "stable" | "preview" | undefined;
12
+ revision?: string | undefined;
13
+ }
14
+ export interface DownloadedPreferRelease {
15
+ release: PreferReleaseRecord;
16
+ manifest: PreferReleaseManifest;
17
+ }
18
+ export declare function listPreferReleases(repositoryInput: string, options?: GitHubReleaseOptions & {
19
+ channel?: "stable" | "preview";
20
+ limit?: number;
21
+ }): Promise<PreferReleaseRecord[]>;
22
+ export declare function resolvePreferRelease(options: ResolveReleaseOptions): Promise<DownloadedPreferRelease>;
23
+ export declare function downloadReleaseAsset(release: PreferReleaseRecord, name: string, options?: GitHubReleaseOptions & {
24
+ expectedSha256?: string | undefined;
25
+ maxBytes?: number | undefined;
26
+ }): Promise<Uint8Array>;
27
+ export declare function downloadPreferTooling(options: ResolveReleaseOptions & {
28
+ outputDir: string;
29
+ }): Promise<DownloadedPreferRelease & {
30
+ files: Record<string, string>;
31
+ }>;
32
+ export declare function validatePreferReleaseManifest(value: unknown, release?: PreferReleaseRecord, repositoryInput?: string): PreferReleaseManifest;
33
+ //# sourceMappingURL=releases.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"releases.d.ts","sourceRoot":"","sources":["../src/releases.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAsB,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAOjG,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,KAAK,CAAC,EAAE,OAAO,KAAK,GAAG,SAAS,CAAC;IACjC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/B;AAED,MAAM,WAAW,qBAAsB,SAAQ,oBAAoB;IACjE,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/B;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,mBAAmB,CAAC;IAC7B,QAAQ,EAAE,qBAAqB,CAAC;CACjC;AAED,wBAAsB,kBAAkB,CAAC,eAAe,EAAE,MAAM,EAAE,OAAO,GAAE,oBAAoB,GAAG;IAAE,OAAO,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAyCzL;AAED,wBAAsB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAuB3G;AAED,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,mBAAmB,EAC5B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,oBAAoB,GAAG;IAAE,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAO,GAC1G,OAAO,CAAC,UAAU,CAAC,CAsBrB;AAED,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,qBAAqB,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,GACrD,OAAO,CAAC,uBAAuB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC,CAgCtE;AAED,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,mBAAmB,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,qBAAqB,CAmB5I"}
@@ -0,0 +1,288 @@
1
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { dirname, resolve } from "node:path";
3
+ import { isObject, requireString, sha256, validateRepository } from "./utils.js";
4
+ const MAX_RELEASE_HISTORY_BYTES = 10 * 1024 * 1024;
5
+ const MAX_MANIFEST_BYTES = 2 * 1024 * 1024;
6
+ const MAX_TOOLING_ASSET_BYTES = 100 * 1024 * 1024;
7
+ export async function listPreferReleases(repositoryInput, options = {}) {
8
+ const repository = validateRepository(repositoryInput);
9
+ const limit = options.limit ?? 20;
10
+ if (!Number.isInteger(limit) || limit < 1 || limit > 30)
11
+ throw new Error("release limit must be between 1 and 30");
12
+ const base = (options.apiBaseUrl ?? "https://api.github.com").replace(/\/+$/u, "");
13
+ const response = await githubFetch(`${base}/repos/${repository}/releases?per_page=30`, options);
14
+ const raw = await responseJson(response, MAX_RELEASE_HISTORY_BYTES, "GitHub release history");
15
+ if (!Array.isArray(raw))
16
+ throw new Error("GitHub release history is not an array");
17
+ const releases = raw.flatMap((entry) => {
18
+ if (!isObject(entry) || entry.draft !== false || typeof entry.prerelease !== "boolean")
19
+ return [];
20
+ const id = typeof entry.tag_name === "string" ? entry.tag_name : "";
21
+ const revision = typeof entry.target_commitish === "string" ? entry.target_commitish.toLowerCase() : "";
22
+ if (!/^sha-[0-9a-f]{7}$/u.test(id) || !/^[0-9a-f]{40}$/u.test(revision) || id !== `sha-${revision.slice(0, 7)}`)
23
+ return [];
24
+ const channel = entry.prerelease ? "preview" : "stable";
25
+ if (options.channel && channel !== options.channel)
26
+ return [];
27
+ const published = typeof entry.published_at === "string" ? new Date(entry.published_at) : new Date(Number.NaN);
28
+ if (!Number.isFinite(published.getTime()))
29
+ return [];
30
+ const assets = {};
31
+ if (Array.isArray(entry.assets)) {
32
+ for (const rawAsset of entry.assets) {
33
+ if (!isObject(rawAsset) || (rawAsset.state !== undefined && rawAsset.state !== "uploaded"))
34
+ continue;
35
+ const name = typeof rawAsset.name === "string" ? rawAsset.name : "";
36
+ const url = typeof rawAsset.browser_download_url === "string" ? rawAsset.browser_download_url : "";
37
+ if (!/^[a-z0-9][a-z0-9._-]{0,199}$/iu.test(name) || !validAssetUrl(url, repository, id, name))
38
+ continue;
39
+ const size = typeof rawAsset.size === "number" && Number.isSafeInteger(rawAsset.size) && rawAsset.size >= 0 ? rawAsset.size : undefined;
40
+ const digest = typeof rawAsset.digest === "string" && /^sha256:[0-9a-f]{64}$/u.test(rawAsset.digest) ? rawAsset.digest : undefined;
41
+ assets[name] = { name, url, ...(size !== undefined ? { size } : {}), ...(digest ? { digest } : {}) };
42
+ }
43
+ }
44
+ if (!assets["prefer-release.json"])
45
+ return [];
46
+ return [{
47
+ id,
48
+ revision,
49
+ channel,
50
+ published_at: published.toISOString(),
51
+ title: typeof entry.name === "string" && entry.name ? entry.name.slice(0, 160) : id,
52
+ url: `https://github.com/${repository}/releases/tag/${id}`,
53
+ assets
54
+ }];
55
+ });
56
+ return releases.sort((left, right) => right.published_at.localeCompare(left.published_at)).slice(0, limit);
57
+ }
58
+ export async function resolvePreferRelease(options) {
59
+ const repository = validateRepository(options.repository);
60
+ let release;
61
+ if (options.revision) {
62
+ const revision = options.revision.trim().toLowerCase();
63
+ if (!/^[0-9a-f]{40}$/u.test(revision))
64
+ throw new Error("PreFer release revision must be a full commit SHA");
65
+ const tag = `sha-${revision.slice(0, 7)}`;
66
+ const base = (options.apiBaseUrl ?? "https://api.github.com").replace(/\/+$/u, "");
67
+ const response = await githubFetch(`${base}/repos/${repository}/releases/tags/${tag}`, options);
68
+ const entry = await responseJson(response, MAX_RELEASE_HISTORY_BYTES, `GitHub release ${tag}`);
69
+ release = parseSingleRelease(entry, repository);
70
+ if (release.revision !== revision)
71
+ throw new Error(`PreFer release ${tag} does not match the requested revision`);
72
+ }
73
+ else {
74
+ [release] = await listPreferReleases(repository, { ...options, channel: options.channel ?? "stable", limit: 1 });
75
+ }
76
+ if (!release)
77
+ throw new Error(`no completed ${options.channel ?? "stable"} PreFer release was found`);
78
+ const manifestAsset = release.assets["prefer-release.json"];
79
+ const manifestBytes = await downloadReleaseAsset(release, manifestAsset.name, { ...options, expectedSha256: digestHex(manifestAsset.digest), maxBytes: MAX_MANIFEST_BYTES });
80
+ let manifestValue;
81
+ try {
82
+ manifestValue = JSON.parse(new TextDecoder().decode(manifestBytes));
83
+ }
84
+ catch {
85
+ throw new Error("PreFer release manifest is not valid JSON");
86
+ }
87
+ const manifest = validatePreferReleaseManifest(manifestValue, release, repository);
88
+ return { release, manifest };
89
+ }
90
+ export async function downloadReleaseAsset(release, name, options = {}) {
91
+ requireAssetName(name);
92
+ const asset = release.assets[name];
93
+ if (!asset)
94
+ throw new Error(`PreFer release ${release.id} is missing ${name}`);
95
+ const expected = options.expectedSha256 ?? digestHex(asset.digest);
96
+ const cachePath = options.cacheDir ? resolve(options.cacheDir, release.revision, name) : undefined;
97
+ if (cachePath) {
98
+ try {
99
+ const cached = new Uint8Array(await readFile(cachePath));
100
+ if (!expected || sha256(cached) === expected)
101
+ return cached;
102
+ }
103
+ catch (error) {
104
+ if (!(error instanceof Error && "code" in error && error.code === "ENOENT"))
105
+ throw error;
106
+ }
107
+ }
108
+ const response = await githubFetch(asset.url, options, "application/octet-stream");
109
+ const bytes = await responseBytes(response, options.maxBytes ?? MAX_TOOLING_ASSET_BYTES, name);
110
+ if (expected && sha256(bytes) !== expected)
111
+ throw new Error(`${name} does not match its expected SHA-256`);
112
+ if (cachePath) {
113
+ await mkdir(dirname(cachePath), { recursive: true });
114
+ await writeFile(cachePath, bytes);
115
+ }
116
+ return bytes;
117
+ }
118
+ export async function downloadPreferTooling(options) {
119
+ const resolvedRelease = await resolvePreferRelease(options);
120
+ const tooling = objectValue(resolvedRelease.manifest.tooling, "PreFer release tooling");
121
+ if (tooling.schema_version !== "prefer.release-tooling.v1")
122
+ throw new Error("PreFer release tooling schema is incompatible");
123
+ const packageVersion = requireString(tooling.package_version, "PreFer release tooling package version");
124
+ if (packageVersion !== `0.0.0-g${resolvedRelease.release.revision.slice(0, 7)}`) {
125
+ throw new Error("PreFer release tooling package version does not match its release");
126
+ }
127
+ requireSha256(tooling.catalog_fingerprint, "PreFer release tooling catalog fingerprint");
128
+ requireSha256(tooling.source_fingerprint, "PreFer release tooling source fingerprint");
129
+ const files = {};
130
+ for (const key of [
131
+ "package",
132
+ "cli",
133
+ "model_catalog",
134
+ "model_catalog_schema",
135
+ "model_catalog_extension_schema",
136
+ "resource_profile_schema",
137
+ "model_plan_schema"
138
+ ]) {
139
+ const binding = objectValue(tooling[key], `PreFer release tooling ${key}`);
140
+ const asset = requireAssetName(requireString(binding.asset, `PreFer release tooling ${key} asset`));
141
+ const expectedBytes = requireNonnegativeInteger(binding.bytes, `PreFer release tooling ${key} bytes`);
142
+ const expectedSha256 = requireSha256(binding.sha256, `PreFer release tooling ${key} SHA-256`);
143
+ const bytes = await downloadReleaseAsset(resolvedRelease.release, asset, { ...options, expectedSha256 });
144
+ if (bytes.byteLength !== expectedBytes)
145
+ throw new Error(`${asset} does not match its expected size`);
146
+ const path = resolve(options.outputDir, asset);
147
+ await mkdir(dirname(path), { recursive: true });
148
+ await writeFile(path, bytes);
149
+ files[key] = path;
150
+ }
151
+ return { ...resolvedRelease, files };
152
+ }
153
+ export function validatePreferReleaseManifest(value, release, repositoryInput) {
154
+ const manifest = objectValue(value, "PreFer release manifest");
155
+ if (manifest.schema_version !== "prefer.release.v1")
156
+ throw new Error("PreFer release manifest schema is incompatible");
157
+ const revision = requireString(manifest.release?.source_revision, "PreFer release source revision").toLowerCase();
158
+ const id = requireString(manifest.release?.id, "PreFer release id");
159
+ if (!/^[0-9a-f]{40}$/u.test(revision) || id !== `sha-${revision.slice(0, 7)}`)
160
+ throw new Error("PreFer release manifest identity is invalid");
161
+ if (release && (release.id !== id || release.revision !== revision))
162
+ throw new Error("PreFer release manifest does not match its GitHub release");
163
+ if (repositoryInput) {
164
+ const repository = validateRepository(repositoryInput);
165
+ const source = manifest.release.source_repository.replace(/^https:\/\/github\.com\//u, "").replace(/\/$/u, "");
166
+ if (source.toLowerCase() !== repository.toLowerCase())
167
+ throw new Error("PreFer release source repository is invalid");
168
+ }
169
+ if (manifest.distribution?.model_weights_embedded !== false
170
+ || manifest.distribution.models_stage_at_runtime !== true
171
+ || manifest.distribution.all_engine_images_share_release_revision !== true) {
172
+ throw new Error("PreFer release distribution contract is incompatible");
173
+ }
174
+ objectValue(manifest.engines, "PreFer release engines");
175
+ return manifest;
176
+ }
177
+ async function githubFetch(url, options, accept = "application/vnd.github+json") {
178
+ const headers = { accept, "user-agent": "prefer-inference-core", "x-github-api-version": "2022-11-28" };
179
+ if (options.token?.trim())
180
+ headers.authorization = `Bearer ${options.token.trim()}`;
181
+ const response = await (options.fetch ?? fetch)(url, { headers, signal: AbortSignal.timeout(options.timeoutMs ?? 30_000) });
182
+ if (!response.ok) {
183
+ const reset = response.headers.get("x-ratelimit-reset");
184
+ const retry = response.headers.get("retry-after");
185
+ const rateLimit = response.status === 429 || (response.status === 403 && response.headers.get("x-ratelimit-remaining") === "0")
186
+ ? `; rate limited${retry ? `, retry after ${retry}s` : reset ? `, reset at ${new Date(Number(reset) * 1000).toISOString()}` : ""}`
187
+ : "";
188
+ throw new Error(`${url} returned HTTP ${response.status}${rateLimit}`);
189
+ }
190
+ return response;
191
+ }
192
+ async function responseJson(response, maxBytes, label) {
193
+ const bytes = await responseBytes(response, maxBytes, label);
194
+ try {
195
+ return JSON.parse(new TextDecoder().decode(bytes));
196
+ }
197
+ catch {
198
+ throw new Error(`${label} returned invalid JSON`);
199
+ }
200
+ }
201
+ async function responseBytes(response, maxBytes, label) {
202
+ const declared = Number(response.headers.get("content-length") ?? "0");
203
+ if (declared > maxBytes)
204
+ throw new Error(`${label} exceeds the response size limit`);
205
+ const bytes = new Uint8Array(await response.arrayBuffer());
206
+ if (bytes.byteLength > maxBytes)
207
+ throw new Error(`${label} exceeds the response size limit`);
208
+ return bytes;
209
+ }
210
+ function parseSingleRelease(value, repository) {
211
+ const entry = objectValue(value, "GitHub release");
212
+ const id = requireString(entry.tag_name, "GitHub release tag");
213
+ const revision = requireString(entry.target_commitish, "GitHub release target").toLowerCase();
214
+ if (entry.draft !== false || typeof entry.prerelease !== "boolean" || !/^sha-[0-9a-f]{7}$/u.test(id) || !/^[0-9a-f]{40}$/u.test(revision)) {
215
+ throw new Error("GitHub release is not a completed immutable PreFer release");
216
+ }
217
+ const published = new Date(requireString(entry.published_at, "GitHub release publication time"));
218
+ if (!Number.isFinite(published.getTime()))
219
+ throw new Error("GitHub release publication time is invalid");
220
+ const assets = {};
221
+ if (!Array.isArray(entry.assets))
222
+ throw new Error("GitHub release assets are invalid");
223
+ for (const rawAsset of entry.assets) {
224
+ if (!isObject(rawAsset))
225
+ continue;
226
+ const name = typeof rawAsset.name === "string" ? rawAsset.name : "";
227
+ const url = typeof rawAsset.browser_download_url === "string" ? rawAsset.browser_download_url : "";
228
+ if (!validAssetName(name) || !validAssetUrl(url, repository, id, name))
229
+ continue;
230
+ assets[name] = {
231
+ name,
232
+ url,
233
+ ...(typeof rawAsset.size === "number" ? { size: rawAsset.size } : {}),
234
+ ...(typeof rawAsset.digest === "string" ? { digest: rawAsset.digest } : {})
235
+ };
236
+ }
237
+ if (!assets["prefer-release.json"])
238
+ throw new Error("GitHub release is missing prefer-release.json");
239
+ return {
240
+ id,
241
+ revision,
242
+ channel: entry.prerelease ? "preview" : "stable",
243
+ published_at: published.toISOString(),
244
+ title: typeof entry.name === "string" && entry.name ? entry.name : id,
245
+ url: `https://github.com/${repository}/releases/tag/${id}`,
246
+ assets
247
+ };
248
+ }
249
+ function validAssetUrl(value, repository, tag, name) {
250
+ try {
251
+ const url = new URL(value);
252
+ return url.protocol === "https:"
253
+ && url.hostname.toLowerCase() === "github.com"
254
+ && !url.username && !url.password && !url.search && !url.hash
255
+ && decodeURIComponent(url.pathname).toLowerCase() === `/${repository}/releases/download/${tag}/${name}`.toLowerCase();
256
+ }
257
+ catch {
258
+ return false;
259
+ }
260
+ }
261
+ function digestHex(value) {
262
+ return value?.startsWith("sha256:") ? value.slice(7) : undefined;
263
+ }
264
+ function requireSha256(value, label) {
265
+ const result = requireString(value, label).toLowerCase();
266
+ if (!/^[0-9a-f]{64}$/u.test(result))
267
+ throw new Error(`${label} is invalid`);
268
+ return result;
269
+ }
270
+ function requireNonnegativeInteger(value, label) {
271
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0)
272
+ throw new Error(`${label} is invalid`);
273
+ return value;
274
+ }
275
+ function validAssetName(value) {
276
+ return /^[a-z0-9][a-z0-9._-]{0,199}$/iu.test(value);
277
+ }
278
+ function requireAssetName(value) {
279
+ if (!validAssetName(value))
280
+ throw new Error(`invalid PreFer release asset name ${value}`);
281
+ return value;
282
+ }
283
+ function objectValue(value, label) {
284
+ if (!isObject(value))
285
+ throw new Error(`${label} must be an object`);
286
+ return value;
287
+ }
288
+ //# sourceMappingURL=releases.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"releases.js","sourceRoot":"","sources":["../src/releases.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { AcceleratorResource, ResourceProfile, RuntimeResourceObservation } from "./types.js";
2
+ export interface DetectRuntimeResourcesOptions {
3
+ base?: ResourceProfile;
4
+ runNvidiaSmi?: (() => Promise<string>) | undefined;
5
+ }
6
+ export declare function normalizeDeploymentResources(value: unknown, observation?: RuntimeResourceObservation): ResourceProfile;
7
+ export declare function mergeRuntimeResources(base: ResourceProfile, observation: RuntimeResourceObservation): ResourceProfile;
8
+ export declare function detectRuntimeResources(options?: DetectRuntimeResourcesOptions): Promise<ResourceProfile>;
9
+ export declare function parseNvidiaSmi(output: string): AcceleratorResource[];
10
+ //# sourceMappingURL=resources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.d.ts","sourceRoot":"","sources":["../src/resources.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,mBAAmB,EAGnB,eAAe,EACf,0BAA0B,EAC3B,MAAM,YAAY,CAAC;AAWpB,MAAM,WAAW,6BAA6B;IAC5C,IAAI,CAAC,EAAE,eAAe,CAAC;IACvB,YAAY,CAAC,EAAE,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC;CACpD;AAED,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,OAAO,EACd,WAAW,CAAC,EAAE,0BAA0B,GACvC,eAAe,CAgDjB;AAED,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,eAAe,EACrB,WAAW,EAAE,0BAA0B,GACtC,eAAe,CA0CjB;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,GAAE,6BAAkC,GAC1C,OAAO,CAAC,eAAe,CAAC,CAiC1B;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,mBAAmB,EAAE,CAuBpE"}
@@ -0,0 +1,250 @@
1
+ import { arch, cpus, freemem, totalmem } from "node:os";
2
+ import { execFile } from "node:child_process";
3
+ import { promisify } from "node:util";
4
+ import { isObject } from "./utils.js";
5
+ const GIB = 1024 ** 3;
6
+ const MIB = 1024 ** 2;
7
+ const execFileAsync = promisify(execFile);
8
+ const DERIVED_RESOURCE_CAPABILITIES = new Set([
9
+ "gpu", "cpu", "multi-gpu", "unified-memory", "discrete-vram", "host-memory",
10
+ "cuda", "bf16", "fp8", "nvfp4"
11
+ ]);
12
+ export function normalizeDeploymentResources(value, observation) {
13
+ const deployment = isObject(value) ? value : {};
14
+ if (deployment.schema_version === "prefer.resources.v1") {
15
+ return observation
16
+ ? mergeRuntimeResources(deployment, observation)
17
+ : structuredClone(deployment);
18
+ }
19
+ const hardware = isObject(deployment.hardware) ? deployment.hardware : deployment;
20
+ const compatibility = isObject(deployment.compatibility) ? deployment.compatibility : {};
21
+ const provider = stringValue(deployment.provider) ?? stringValue(hardware.provider);
22
+ const providerSku = stringValue(hardware.provider_sku) ?? stringValue(hardware.host_shape);
23
+ const count = positiveInteger(hardware.gpu_count) ?? 0;
24
+ const totalEach = bytesFromGiB(hardware.vram_gb_each) ?? bytesFromGiB(hardware.vram_gb);
25
+ const topology = memoryTopology(hardware, count);
26
+ const acceleratorCapabilities = deriveAcceleratorCapabilities(hardware, compatibility);
27
+ const accelerators = Array.from({ length: count }, (_, index) => ({
28
+ ...(count > 1 ? { id: `deployment-gpu-${index}` } : {}),
29
+ ...(stringValue(hardware.gpu_slug) ? { slug: stringValue(hardware.gpu_slug) } : {}),
30
+ ...(stringValue(hardware.gpu_id) ? { canonical_id: stringValue(hardware.gpu_id) } : {}),
31
+ ...(stringValue(hardware.provider_gpu_type_id) ? { provider_id: stringValue(hardware.provider_gpu_type_id) } : {}),
32
+ ...(stringValue(hardware.gpu_name) ?? stringValue(hardware.gpu_type_id)
33
+ ? { name: (stringValue(hardware.gpu_name) ?? stringValue(hardware.gpu_type_id)) }
34
+ : {}),
35
+ ...(stringValue(hardware.architecture) ? { architecture: stringValue(hardware.architecture) } : {}),
36
+ ...(stringValue(hardware.compute_capability) ?? stringValue(compatibility.minimum_compute_capability)
37
+ ? { compute_capability: (stringValue(hardware.compute_capability) ?? stringValue(compatibility.minimum_compute_capability)) }
38
+ : {}),
39
+ ...(totalEach !== undefined ? { total_bytes: totalEach } : {}),
40
+ capabilities: [...acceleratorCapabilities]
41
+ }));
42
+ const unifiedTotal = bytesFromGiB(hardware.unified_memory_gb) ?? (topology === "unified" ? totalEach : undefined);
43
+ const hostTotal = bytesFromGiB(hardware.host_ram_gb) ?? bytesFromGiB(hardware.observed_host_ram_gb);
44
+ const storageTotal = bytesFromGiB(hardware.local_nvme_gb);
45
+ const logicalCores = positiveInteger(hardware.vcpu) ?? positiveInteger(hardware.observed_vcpu);
46
+ const profile = {
47
+ schema_version: "prefer.resources.v1",
48
+ source: "deployment",
49
+ ...(provider ? { provider } : {}),
50
+ ...(providerSku ? { provider_sku: providerSku } : {}),
51
+ memory_topology: topology,
52
+ accelerators,
53
+ ...(unifiedTotal !== undefined ? { unified_memory: { total_bytes: unifiedTotal } } : {}),
54
+ ...(hostTotal !== undefined ? { host_memory: { total_bytes: hostTotal } } : {}),
55
+ ...(logicalCores !== undefined ? { cpu: { logical_cores: logicalCores } } : {}),
56
+ ...(storageTotal !== undefined ? { storage: { total_bytes: storageTotal, kind: "local" } } : {}),
57
+ capabilities: deriveProfileCapabilities(topology, accelerators, hardware, compatibility)
58
+ };
59
+ return observation ? mergeRuntimeResources(profile, observation) : profile;
60
+ }
61
+ export function mergeRuntimeResources(base, observation) {
62
+ const acceleratorObservationSupplied = observation.accelerators !== undefined;
63
+ const observedAccelerators = observation.accelerators?.map(normalizeAccelerator);
64
+ const accelerators = acceleratorObservationSupplied
65
+ ? (observedAccelerators ?? []).map((observed, index) => mergeAccelerator(base.accelerators[index], observed))
66
+ : base.accelerators.map((entry) => structuredClone(entry));
67
+ const topology = observation.unified_memory
68
+ ? "unified"
69
+ : acceleratorObservationSupplied
70
+ ? accelerators.length
71
+ ? base.memory_topology === "unified" ? "unified" : "discrete"
72
+ : "host"
73
+ : base.memory_topology;
74
+ const unifiedMemory = mergeMemory(base.unified_memory, observation.unified_memory);
75
+ const hostMemory = mergeMemory(base.host_memory, observation.host_memory);
76
+ const baseCapabilities = acceleratorObservationSupplied
77
+ ? base.capabilities.filter((capability) => !DERIVED_RESOURCE_CAPABILITIES.has(capability))
78
+ : base.capabilities;
79
+ const structuralCapabilities = [
80
+ accelerators.length ? "gpu" : "cpu",
81
+ ...(accelerators.length > 1 ? ["multi-gpu"] : []),
82
+ topology === "unified" ? "unified-memory" : topology === "discrete" ? "discrete-vram" : "host-memory"
83
+ ];
84
+ const result = {
85
+ ...structuredClone(base),
86
+ source: "merged",
87
+ memory_topology: topology,
88
+ accelerators,
89
+ ...(unifiedMemory ? { unified_memory: unifiedMemory } : {}),
90
+ ...(hostMemory ? { host_memory: hostMemory } : {}),
91
+ ...(observation.cpu ? { cpu: { ...base.cpu, ...observation.cpu } } : {}),
92
+ ...(observation.storage ? { storage: { ...base.storage, ...observation.storage } } : {}),
93
+ capabilities: [...new Set([
94
+ ...baseCapabilities,
95
+ ...structuralCapabilities,
96
+ ...(observation.capabilities ?? []),
97
+ ...accelerators.flatMap((entry) => entry.capabilities)
98
+ ])].sort()
99
+ };
100
+ if (!unifiedMemory)
101
+ delete result.unified_memory;
102
+ if (!hostMemory)
103
+ delete result.host_memory;
104
+ return result;
105
+ }
106
+ export async function detectRuntimeResources(options = {}) {
107
+ const run = options.runNvidiaSmi ?? defaultNvidiaSmi;
108
+ let accelerators = [];
109
+ let acceleratorProbeSucceeded = false;
110
+ try {
111
+ accelerators = parseNvidiaSmi(await run());
112
+ acceleratorProbeSucceeded = true;
113
+ }
114
+ catch { /* CPU-only and restricted containers are valid resource probes. */ }
115
+ const observation = {
116
+ ...(acceleratorProbeSucceeded ? { accelerators } : {}),
117
+ host_memory: { total_bytes: totalmem(), available_bytes: freemem() },
118
+ cpu: {
119
+ architecture: arch(),
120
+ logical_cores: cpus().length,
121
+ ...(cpus()[0]?.model ? { model: cpus()[0].model } : {})
122
+ },
123
+ ...(acceleratorProbeSucceeded ? { capabilities: accelerators.length ? ["gpu"] : ["cpu"] } : {})
124
+ };
125
+ if (options.base)
126
+ return mergeRuntimeResources(options.base, observation);
127
+ return {
128
+ schema_version: "prefer.resources.v1",
129
+ source: "runtime",
130
+ memory_topology: accelerators.length ? "discrete" : "host",
131
+ accelerators,
132
+ host_memory: observation.host_memory,
133
+ cpu: observation.cpu,
134
+ capabilities: [...new Set([
135
+ accelerators.length ? "gpu" : "cpu",
136
+ ...(observation.capabilities ?? []),
137
+ ...accelerators.flatMap((entry) => entry.capabilities)
138
+ ])].sort()
139
+ };
140
+ }
141
+ export function parseNvidiaSmi(output) {
142
+ return output.split(/\r?\n/u).map((line) => line.trim()).filter(Boolean).map((line, index) => {
143
+ const fields = line.split(",").map((field) => field.trim());
144
+ if (fields.length < 4)
145
+ throw new Error(`invalid nvidia-smi row ${index + 1}`);
146
+ const [name, id, totalMiB, freeMiB, computeCapability] = fields;
147
+ const total = Number(totalMiB);
148
+ const available = Number(freeMiB);
149
+ if (!name || !Number.isFinite(total) || !Number.isFinite(available)) {
150
+ throw new Error(`invalid nvidia-smi memory row ${index + 1}`);
151
+ }
152
+ const hardware = {
153
+ gpu_name: name,
154
+ ...(computeCapability ? { compute_capability: `sm_${computeCapability.replace(".", "")}` } : {})
155
+ };
156
+ return {
157
+ ...(id ? { id } : {}),
158
+ name,
159
+ total_bytes: Math.round(total * MIB),
160
+ available_bytes: Math.round(available * MIB),
161
+ ...(computeCapability ? { compute_capability: `sm_${computeCapability.replace(".", "")}` } : {}),
162
+ capabilities: [...deriveAcceleratorCapabilities(hardware, {})]
163
+ };
164
+ });
165
+ }
166
+ function memoryTopology(hardware, count) {
167
+ const explicit = stringValue(hardware.memory_topology) ?? stringValue(hardware.memory_model);
168
+ if (explicit === "unified" || explicit === "discrete" || explicit === "host")
169
+ return explicit;
170
+ if (hardware.unified_memory === true || hardware.unified_memory_gb !== undefined)
171
+ return "unified";
172
+ return count > 0 ? "discrete" : "host";
173
+ }
174
+ function deriveProfileCapabilities(topology, accelerators, hardware, compatibility) {
175
+ return [...new Set([
176
+ ...(accelerators.length ? ["gpu"] : ["cpu"]),
177
+ ...(accelerators.length > 1 ? ["multi-gpu"] : []),
178
+ topology === "unified" ? "unified-memory" : topology === "discrete" ? "discrete-vram" : "host-memory",
179
+ ...stringArray(hardware.capabilities),
180
+ ...stringArray(compatibility.capabilities),
181
+ ...accelerators.flatMap((entry) => entry.capabilities)
182
+ ])].sort();
183
+ }
184
+ function deriveAcceleratorCapabilities(hardware, compatibility) {
185
+ const result = new Set([...stringArray(hardware.capabilities), ...stringArray(compatibility.capabilities)]);
186
+ const architecture = (stringValue(hardware.architecture) ?? stringValue(hardware.gpu_name) ?? "").toLowerCase();
187
+ const compute = stringValue(hardware.compute_capability) ?? stringValue(compatibility.minimum_compute_capability) ?? "";
188
+ const computeNumber = Number(compute.toLowerCase().replace(/^sm_/u, ""));
189
+ if (architecture.includes("blackwell") || computeNumber >= 100) {
190
+ result.add("bf16");
191
+ result.add("fp8");
192
+ result.add("nvfp4");
193
+ }
194
+ else if (architecture.includes("hopper") || (computeNumber >= 89 && computeNumber < 100)) {
195
+ result.add("bf16");
196
+ result.add("fp8");
197
+ }
198
+ else if (architecture.includes("ampere") || (computeNumber >= 80 && computeNumber < 89)) {
199
+ result.add("bf16");
200
+ }
201
+ if (compute || architecture)
202
+ result.add("cuda");
203
+ return result;
204
+ }
205
+ function mergeAccelerator(base, observed) {
206
+ const preserveBase = base !== undefined && acceleratorIdentityMatches(base, observed);
207
+ return {
208
+ ...(preserveBase ? base : {}),
209
+ ...observed,
210
+ capabilities: [...new Set([...(preserveBase ? base.capabilities : []), ...observed.capabilities])].sort()
211
+ };
212
+ }
213
+ function acceleratorIdentityMatches(base, observed) {
214
+ if (base.compute_capability && observed.compute_capability)
215
+ return base.compute_capability === observed.compute_capability;
216
+ if (base.name && observed.name) {
217
+ const left = base.name.toLowerCase().replaceAll(/[^a-z0-9]/gu, "");
218
+ const right = observed.name.toLowerCase().replaceAll(/[^a-z0-9]/gu, "");
219
+ return left.includes(right) || right.includes(left);
220
+ }
221
+ return true;
222
+ }
223
+ function normalizeAccelerator(value) {
224
+ return { ...structuredClone(value), capabilities: [...new Set(value.capabilities ?? [])].sort() };
225
+ }
226
+ function mergeMemory(base, observed) {
227
+ if (!base && !observed)
228
+ return undefined;
229
+ return { ...base, ...observed };
230
+ }
231
+ function stringValue(value) {
232
+ return typeof value === "string" && value.trim() ? value.trim() : undefined;
233
+ }
234
+ function positiveInteger(value) {
235
+ return typeof value === "number" && Number.isInteger(value) && value > 0 ? value : undefined;
236
+ }
237
+ function bytesFromGiB(value) {
238
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? Math.round(value * GIB) : undefined;
239
+ }
240
+ function stringArray(value) {
241
+ return Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : [];
242
+ }
243
+ async function defaultNvidiaSmi() {
244
+ const { stdout } = await execFileAsync("nvidia-smi", [
245
+ "--query-gpu=name,uuid,memory.total,memory.free,compute_cap",
246
+ "--format=csv,noheader,nounits"
247
+ ], { encoding: "utf8", timeout: 10_000 });
248
+ return stdout;
249
+ }
250
+ //# sourceMappingURL=resources.js.map