@happyvertical/smrt-education 0.60.17 → 0.61.0

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.
@@ -1,8 +1,21 @@
1
+ export interface IngestionMemoryLimitOptions {
2
+ /** Explicit opt-in for single-user desktop hosts (macOS, Windows) that have
3
+ * no cgroups. Ignored on Linux, where the cgroup-v2 check always applies.
4
+ * The resulting budget is advisory: no operating-system ceiling exists.
5
+ */
6
+ desktopBudget?: {
7
+ /** Defaults to min(maximumBytes, a quarter of total system memory). */
8
+ budgetBytes?: number;
9
+ };
10
+ }
11
+ export interface IngestionMemoryLimit {
12
+ memoryLimitBytes: number;
13
+ /** Present only for the desktop path; Linux results omit it. */
14
+ enforcement?: 'advisory-host-budget';
15
+ }
1
16
  /** Verify a real Linux cgroup-v2 native-memory ceiling before enabling decoders.
2
17
  * The worker and its children must remain in this cgroup; deployments must deny
3
18
  * cgroup writes/escape and run without privileged container capabilities.
4
19
  */
5
- export declare function requireIngestionMemoryLimit(maximumBytes: number): Promise<{
6
- memoryLimitBytes: number;
7
- }>;
20
+ export declare function requireIngestionMemoryLimit(maximumBytes: number, options?: IngestionMemoryLimitOptions): Promise<IngestionMemoryLimit>;
8
21
  //# sourceMappingURL=ingestion-isolation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ingestion-isolation.d.ts","sourceRoot":"","sources":["../src/ingestion-isolation.ts"],"names":[],"mappings":"AAGA;;;GAGG;AACH,wBAAsB,2BAA2B,CAC/C,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC;IAAE,gBAAgB,EAAE,MAAM,CAAA;CAAE,CAAC,CAmCvC"}
1
+ {"version":3,"file":"ingestion-isolation.d.ts","sourceRoot":"","sources":["../src/ingestion-isolation.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,2BAA2B;IAC1C;;;OAGG;IACH,aAAa,CAAC,EAAE;QACd,uEAAuE;QACvE,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;CACH;AAED,MAAM,WAAW,oBAAoB;IACnC,gBAAgB,EAAE,MAAM,CAAC;IACzB,gEAAgE;IAChE,WAAW,CAAC,EAAE,sBAAsB,CAAC;CACtC;AAED;;;GAGG;AACH,wBAAsB,2BAA2B,CAC/C,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,oBAAoB,CAAC,CAkD/B"}
package/dist/ingestion.js CHANGED
@@ -4,6 +4,7 @@ import { withPrivateAssetAccess } from "@happyvertical/smrt-assets";
4
4
  import { registerPermissionDefinitions } from "@happyvertical/smrt-users";
5
5
  import { GenerationSnapshotStaleError, ProposalsNotConfiguredError, extractAnalysis, normalizeObservedImageRegions } from "@happyvertical/smrt-ingestion/server";
6
6
  import { readFile } from "node:fs/promises";
7
+ import { totalmem } from "node:os";
7
8
  import { resolve } from "node:path";
8
9
  import { createHash } from "node:crypto";
9
10
  //#region src/intake-original-evidence.ts
@@ -31,9 +32,22 @@ function intakeOriginalEvidence(evidence) {
31
32
  }
32
33
  //#endregion
33
34
  //#region src/ingestion-isolation.ts
34
- async function requireIngestionMemoryLimit(maximumBytes) {
35
- if (process.platform !== "linux") throw new Error("Extraction requires a Linux cgroup-v2 memory-limited worker");
35
+ async function requireIngestionMemoryLimit(maximumBytes, options = {}) {
36
+ const desktop = options.desktopBudget;
37
+ const desktopHost = process.platform === "darwin" || process.platform === "win32";
38
+ if (process.platform !== "linux" && !(desktop && desktopHost)) throw new Error("Extraction requires a Linux cgroup-v2 memory-limited worker");
36
39
  if (!Number.isSafeInteger(maximumBytes) || maximumBytes < 1) throw new Error("Invalid worker memory ceiling");
40
+ if (process.platform !== "linux" && desktop) {
41
+ const system = totalmem();
42
+ if (!Number.isSafeInteger(system) || system < 1) throw new Error("Host memory size is unavailable");
43
+ const budget = desktop.budgetBytes ?? Math.min(maximumBytes, Math.floor(system / 4));
44
+ if (!Number.isSafeInteger(budget) || budget < 1) throw new Error("Invalid desktop memory budget");
45
+ if (budget > maximumBytes || budget > system) throw new Error("Desktop memory budget exceeds policy or host memory");
46
+ return {
47
+ memoryLimitBytes: budget,
48
+ enforcement: "advisory-host-budget"
49
+ };
50
+ }
37
51
  const entry = (await readFile("/proc/self/cgroup", "utf8")).split("\n").find((line) => line.startsWith("0::"));
38
52
  if (!entry) throw new Error("No cgroup-v2 membership");
39
53
  const relative = entry.slice(3);