pi-mega-compact 0.20.76 → 0.20.78
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/config/vector-cortex-vc9b.js +4 -3
- package/dist/extensions/dashboard-server/api-contracts/endpoints/registry-ext.js +1 -1
- package/dist/extensions/dashboard-server/routes-rag-settings-vector-cortex.js +1 -1
- package/dist/extensions/dashboard-server/routes-setup-cortex-actions.js +6 -5
- package/dist/extensions/dashboard-server/setup-cortex-actions-vc2.js +334 -0
- package/dist/extensions/dashboard-server/setup-cortex-actions.js +18 -69
- package/dist/src/config/vector-cortex-vc9b.js +4 -3
- package/extensions/dashboard-client/dist/assets/{AdminTab-B8JqsA41.js → AdminTab-BsA8-_bX.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{AdminTab-B8JqsA41.js.map → AdminTab-BsA8-_bX.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{AreaChart-CeaexvWO.js → AreaChart-BRHEfWhc.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{AreaChart-CeaexvWO.js.map → AreaChart-BRHEfWhc.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{BarChart-Bhyviy7_.js → BarChart-C-M0LaFc.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{BarChart-Bhyviy7_.js.map → BarChart-C-M0LaFc.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{CacheTab-C6bFdEHq.js → CacheTab-Cj3n59U3.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{CacheTab-C6bFdEHq.js.map → CacheTab-Cj3n59U3.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{ConfigTab-CbsdI5yj.js → ConfigTab-C016XTNC.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{ConfigTab-CbsdI5yj.js.map → ConfigTab-C016XTNC.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{EventsTab-kvB5Znx2.js → EventsTab-DE29fuqe.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{EventsTab-kvB5Znx2.js.map → EventsTab-DE29fuqe.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{HealthTab-DqEUk5LW.js → HealthTab-D4eVI8ar.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{HealthTab-DqEUk5LW.js.map → HealthTab-D4eVI8ar.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MaintenanceTab-CS5HqDkY.js → MaintenanceTab-4fJ7M4S4.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MaintenanceTab-CS5HqDkY.js.map → MaintenanceTab-4fJ7M4S4.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MemoryMapTab-Oq-iqvUq.js → MemoryMapTab-CDbcK9e4.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MemoryMapTab-Oq-iqvUq.js.map → MemoryMapTab-CDbcK9e4.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MetricsCards-36RVmtPj.js → MetricsCards-VUEcgGzo.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MetricsCards-36RVmtPj.js.map → MetricsCards-VUEcgGzo.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/MetricsTab-CKqJ0Zl-.js +2 -0
- package/extensions/dashboard-client/dist/assets/{MetricsTab-Clkcniuo.js.map → MetricsTab-CKqJ0Zl-.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{OverviewTab-Cl2Zx7r1.js → OverviewTab-9Kxo79mi.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{OverviewTab-Cl2Zx7r1.js.map → OverviewTab-9Kxo79mi.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{ReposTab-DUoDgjk-.js → ReposTab-C4iveqrP.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{ReposTab-DUoDgjk-.js.map → ReposTab-C4iveqrP.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{SessionsTab-hEQ_OAfB.js → SessionsTab-DSEwkMQm.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{SessionsTab-hEQ_OAfB.js.map → SessionsTab-DSEwkMQm.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{SetupTab-Bqibg0cD.js → SetupTab-CCyWgy4O.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{SetupTab-Bqibg0cD.js.map → SetupTab-CCyWgy4O.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{TimeSavedCard-9QMQUc7L.js → TimeSavedCard-CyD8e_e_.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TimeSavedCard-9QMQUc7L.js.map → TimeSavedCard-CyD8e_e_.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{TurnMemoryView-DAfqhJqd.js → TurnMemoryView-5tLbWkRv.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TurnMemoryView-DAfqhJqd.js.map → TurnMemoryView-5tLbWkRv.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/TurnsTab-C7pm92Hg.js +2 -0
- package/extensions/dashboard-client/dist/assets/{TurnsTab-C-uZNH2F.js.map → TurnsTab-C7pm92Hg.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{VcStatusBadge-DyOagOVb.js → VcStatusBadge-ObhcIyfN.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{VcStatusBadge-DyOagOVb.js.map → VcStatusBadge-ObhcIyfN.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{VectorCortexTab-BxsbSUGv.js → VectorCortexTab-BtHZb7o7.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{VectorCortexTab-BxsbSUGv.js.map → VectorCortexTab-BtHZb7o7.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{WikiTab-CjefloQb.js → WikiTab-lQ4l3QIK.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{WikiTab-CjefloQb.js.map → WikiTab-lQ4l3QIK.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{button-D-9nb4Bw.js → button-DhQQAJGm.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{button-D-9nb4Bw.js.map → button-DhQQAJGm.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{card-Dvl16_R5.js → card-Cfhz9X31.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{card-Dvl16_R5.js.map → card-Cfhz9X31.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{client-extra-BShDrG99.js → client-extra-CKNOGEz_.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{client-extra-BShDrG99.js.map → client-extra-CKNOGEz_.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-Q_V4fqVi.js → generateCategoricalChart-JKjK9_cB.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-Q_V4fqVi.js.map → generateCategoricalChart-JKjK9_cB.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{index-CL6Af_JZ.js → index-iuxgtzEW.js} +4 -4
- package/extensions/dashboard-client/dist/assets/{index-CL6Af_JZ.js.map → index-iuxgtzEW.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{switch-0MNUTR9I.js → switch-7EHEQMSP.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{switch-0MNUTR9I.js.map → switch-7EHEQMSP.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{toggle-DHbWo-CW.js → toggle-z1lWY4UM.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{toggle-DHbWo-CW.js.map → toggle-z1lWY4UM.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{useSSE-DcBpzKtI.js → useSSE-sctOZuRM.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{useSSE-DcBpzKtI.js.map → useSSE-sctOZuRM.js.map} +1 -1
- package/extensions/dashboard-client/dist/index.html +1 -1
- package/extensions/dashboard-server/api-contracts/endpoints/registry-ext.ts +1 -1
- package/extensions/dashboard-server/routes-rag-settings-vector-cortex.ts +1 -1
- package/extensions/dashboard-server/routes-setup-cortex-actions.ts +6 -5
- package/extensions/dashboard-server/setup-cortex-actions-vc2.ts +400 -0
- package/extensions/dashboard-server/setup-cortex-actions.ts +18 -71
- package/package.json +1 -1
- package/src/config/vector-cortex-vc9b.ts +4 -3
- package/extensions/dashboard-client/dist/assets/MetricsTab-Clkcniuo.js +0 -2
- package/extensions/dashboard-client/dist/assets/TurnsTab-C-uZNH2F.js +0 -2
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dashboard-server/setup-cortex-actions-vc2.ts — VC2 model-prep action driver
|
|
3
|
+
* (fetch-model + bench), ported in-process.
|
|
4
|
+
*
|
|
5
|
+
* Sibling of setup-cortex-actions.ts (the vc9b actor surface). Implements the
|
|
6
|
+
* mechanics behind the VC9B `fetch-model` and `bench` actions, replacing the
|
|
7
|
+
* previous spawn-of-scripts approach: the npm package's `files` allowlist does
|
|
8
|
+
* NOT include scripts/, so scripts/vc2-model-prep/* is absent on installed
|
|
9
|
+
* devices and the spawn path 500s with "not found in this checkout".
|
|
10
|
+
*
|
|
11
|
+
* fetch-model: downloads the candidate encoder (model.onnx + tokenizer.json)
|
|
12
|
+
* from HuggingFace via node:https and verifies sha256 against pinned digests.
|
|
13
|
+
* PREVENT-PI-004 opt-in: user-triggered, confirm-gated download of ML model
|
|
14
|
+
* assets from HuggingFace (same exemption class as install-native-ort).
|
|
15
|
+
*
|
|
16
|
+
* bench: loads onnxruntime-node via createRequire, runs warm-up + timed
|
|
17
|
+
* inference iterations, computes p50/p95/p99 latency, samples RSS, and runs a
|
|
18
|
+
* determinism check (identical outputs within 1e-6 across repeats).
|
|
19
|
+
*
|
|
20
|
+
* Never throws: every failure is returned as { ok: false, ... } with a log.
|
|
21
|
+
* Guardrails: PREVENT-011 (no `any`); PREVENT-PI-004 (guardrails-allow below).
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
// guardrails-allow PREVENT-PI-004: opt-in, confirm-gated download of ML model
|
|
25
|
+
// assets from HuggingFace (user-triggered from dashboard)
|
|
26
|
+
import { get as httpsGet } from "node:https";
|
|
27
|
+
|
|
28
|
+
import { createHash } from "node:crypto";
|
|
29
|
+
import { createRequire } from "node:module";
|
|
30
|
+
import {
|
|
31
|
+
mkdirSync,
|
|
32
|
+
writeFileSync,
|
|
33
|
+
existsSync,
|
|
34
|
+
statSync,
|
|
35
|
+
rmSync,
|
|
36
|
+
} from "node:fs";
|
|
37
|
+
import { join, dirname } from "node:path";
|
|
38
|
+
import { fileURLToPath } from "node:url";
|
|
39
|
+
import type {
|
|
40
|
+
SetupCortexActionKind,
|
|
41
|
+
SetupCortexActionResult,
|
|
42
|
+
} from "./api-contracts/setup-cortex.js";
|
|
43
|
+
import { writeLogName, writeLog } from "./setup-cortex-actions.js";
|
|
44
|
+
|
|
45
|
+
// ─── fetch-model constants ─────────────────────────────────────────────────
|
|
46
|
+
|
|
47
|
+
const HF_BASE =
|
|
48
|
+
// guardrails-allow PREVENT-PI-004: opt-in, confirm-gated download of ML model
|
|
49
|
+
// assets from HuggingFace (user-triggered from dashboard)
|
|
50
|
+
"https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2/resolve/main";
|
|
51
|
+
const MODEL_URL = `${HF_BASE}/onnx/model_qint8_avx512_vnni.onnx`;
|
|
52
|
+
const TOKENIZER_URL = `${HF_BASE}/tokenizer.json`;
|
|
53
|
+
const MODEL_SHA256 =
|
|
54
|
+
"4278337fd0ff3c68bfb6291042cad8ab363e1d9fbc43dcb499fe91c871902474";
|
|
55
|
+
const TOKENIZER_SHA256 =
|
|
56
|
+
"be50c3628f2bf5bb5e3a7f17b1f74611b2561a3a27eeab05e5aa30f411572037";
|
|
57
|
+
|
|
58
|
+
// ─── bench constants ───────────────────────────────────────────────────────
|
|
59
|
+
|
|
60
|
+
const LATENCY_BUDGET_MS = 40;
|
|
61
|
+
const RSS_BUDGET_MIB = 150;
|
|
62
|
+
const DETERMINISM_EPSILON = 1e-6;
|
|
63
|
+
const BENCH_TOKENS = 512;
|
|
64
|
+
const BENCH_ITERS = 300;
|
|
65
|
+
const BENCH_THREADS = 4;
|
|
66
|
+
const BENCH_REPEATS = 200;
|
|
67
|
+
|
|
68
|
+
// ─── shared helpers ────────────────────────────────────────────────────────
|
|
69
|
+
|
|
70
|
+
function sha256Hex(buf: Buffer): string {
|
|
71
|
+
return createHash("sha256").update(buf).digest("hex");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function mib(bytes: number): number {
|
|
75
|
+
return +(bytes / 1048576).toFixed(1);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
function percentile(sorted: number[], p: number): number {
|
|
79
|
+
const i = Math.min(sorted.length - 1, Math.floor(sorted.length * p));
|
|
80
|
+
return +sorted[i].toFixed(2);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// ─── fetch helpers ─────────────────────────────────────────────────────────
|
|
84
|
+
|
|
85
|
+
/** Download a URL to a Buffer via node:https (follows one redirect). */
|
|
86
|
+
function download(url: string): Promise<Buffer> {
|
|
87
|
+
return new Promise((resolve, reject) => {
|
|
88
|
+
// guardrails-allow PREVENT-PI-004: opt-in, confirm-gated download of ML
|
|
89
|
+
// model assets from HuggingFace (user-triggered from dashboard)
|
|
90
|
+
httpsGet(url, (res) => {
|
|
91
|
+
if (
|
|
92
|
+
res.statusCode !== undefined &&
|
|
93
|
+
res.statusCode >= 300 &&
|
|
94
|
+
res.statusCode < 400 &&
|
|
95
|
+
res.headers.location
|
|
96
|
+
) {
|
|
97
|
+
res.resume();
|
|
98
|
+
// Follow a single redirect (HuggingFace CDN redirects). The Location
|
|
99
|
+
// header may be a RELATIVE path (e.g. /api/resolve-cache/...) — resolve
|
|
100
|
+
// it against the original URL so httpsGet never receives a bare path.
|
|
101
|
+
const redirected = new URL(res.headers.location, url).toString();
|
|
102
|
+
download(redirected).then(resolve, reject);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (res.statusCode !== 200) {
|
|
106
|
+
res.resume();
|
|
107
|
+
reject(new Error(`HTTP ${res.statusCode} for ${url}`));
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
const chunks: Buffer[] = [];
|
|
111
|
+
res.on("data", (chunk: Buffer) => chunks.push(chunk));
|
|
112
|
+
res.on("end", () => resolve(Buffer.concat(chunks)));
|
|
113
|
+
res.on("error", reject);
|
|
114
|
+
}).on("error", reject);
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** Fetch one asset: download, verify sha256, write to disk. */
|
|
119
|
+
async function fetchAsset(
|
|
120
|
+
url: string,
|
|
121
|
+
outPath: string,
|
|
122
|
+
wantSha: string,
|
|
123
|
+
logLines: string[],
|
|
124
|
+
): Promise<boolean> {
|
|
125
|
+
const label = outPath.split("/").pop() ?? outPath;
|
|
126
|
+
logLines.push(`fetching ${label}`);
|
|
127
|
+
let buf: Buffer;
|
|
128
|
+
try {
|
|
129
|
+
buf = await download(url);
|
|
130
|
+
} catch (err) {
|
|
131
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
132
|
+
logLines.push(`FAIL download ${label}: ${msg}`);
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
const got = sha256Hex(buf);
|
|
136
|
+
if (got !== wantSha) {
|
|
137
|
+
logLines.push(`DIGEST MISMATCH for ${label}`);
|
|
138
|
+
logLines.push(` expected: ${wantSha}`);
|
|
139
|
+
logLines.push(` actual: ${got}`);
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
// guardrails-allow PREVENT-PI-004: local state-dir filesystem write (loopback)
|
|
143
|
+
writeFileSync(outPath, buf);
|
|
144
|
+
logLines.push(` ok sha256=${got} bytes=${buf.length}`);
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// ─── fetch-model implementation ────────────────────────────────────────────
|
|
149
|
+
|
|
150
|
+
async function runFetchModel(
|
|
151
|
+
stateDir: string,
|
|
152
|
+
): Promise<SetupCortexActionResult> {
|
|
153
|
+
const action: SetupCortexActionKind = "fetch-model";
|
|
154
|
+
const { name, logPath } = writeLogName(action, stateDir);
|
|
155
|
+
const outdir = join(stateDir, "vc2-model-prep");
|
|
156
|
+
// guardrails-allow PREVENT-PI-004: local state-dir filesystem write (loopback)
|
|
157
|
+
mkdirSync(outdir, { recursive: true });
|
|
158
|
+
|
|
159
|
+
const logLines: string[] = [];
|
|
160
|
+
let ok = true;
|
|
161
|
+
|
|
162
|
+
// Model
|
|
163
|
+
const modelPath = join(outdir, "model.onnx");
|
|
164
|
+
if (!(await fetchAsset(MODEL_URL, modelPath, MODEL_SHA256, logLines))) {
|
|
165
|
+
ok = false;
|
|
166
|
+
// Clean up partial download
|
|
167
|
+
// guardrails-allow PREVENT-PI-004: removing file we just wrote (local FS)
|
|
168
|
+
rmSync(modelPath, { force: true });
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Tokenizer
|
|
172
|
+
const tokPath = join(outdir, "tokenizer.json");
|
|
173
|
+
if (!(await fetchAsset(TOKENIZER_URL, tokPath, TOKENIZER_SHA256, logLines))) {
|
|
174
|
+
ok = false;
|
|
175
|
+
// guardrails-allow PREVENT-PI-004: removing file we just wrote (local FS)
|
|
176
|
+
rmSync(tokPath, { force: true });
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
logLines.push("");
|
|
180
|
+
logLines.push(`Staged in ${outdir}.`);
|
|
181
|
+
logLines.push(
|
|
182
|
+
"NOTE: this export is opset 14, NOT the opset 17 required by MODEL_ASSET.md.",
|
|
183
|
+
);
|
|
184
|
+
logLines.push(
|
|
185
|
+
"See docs/vector-cortex/vc2-model-prep.md (Opset gap) before committing.",
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
writeLog(logPath, logLines.join("\n") + "\n");
|
|
189
|
+
return {
|
|
190
|
+
action,
|
|
191
|
+
ok,
|
|
192
|
+
exitCode: ok ? 0 : 1,
|
|
193
|
+
logPath,
|
|
194
|
+
logName: name,
|
|
195
|
+
spawned: false,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// ─── bench implementation ──────────────────────────────────────────────────
|
|
200
|
+
|
|
201
|
+
/** Locate model.onnx: stateDir first, then walk up from module for dev. */
|
|
202
|
+
function findModelPath(stateDir: string): string | null {
|
|
203
|
+
// Check stateDir first (installed-device path).
|
|
204
|
+
const fromState = join(stateDir, "vc2-model-prep", "model.onnx");
|
|
205
|
+
// guardrails-allow PREVENT-PI-004: local state-dir filesystem read (loopback)
|
|
206
|
+
if (existsSync(fromState)) return fromState;
|
|
207
|
+
|
|
208
|
+
// Walk up from module for repo-checkout dev mode.
|
|
209
|
+
let dir = dirname(fileURLToPath(import.meta.url));
|
|
210
|
+
const rel = join("scripts", "vc2-model-prep", "model.onnx");
|
|
211
|
+
for (let i = 0; i < 8; i++) {
|
|
212
|
+
const candidate = join(dir, rel);
|
|
213
|
+
// guardrails-allow PREVENT-PI-004: local repo filesystem read (loopback)
|
|
214
|
+
if (existsSync(candidate)) return candidate;
|
|
215
|
+
const next = dirname(dir);
|
|
216
|
+
if (next === dir) break;
|
|
217
|
+
dir = next;
|
|
218
|
+
}
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/** Run the ONNX bench: latency + RSS + determinism gates. */
|
|
223
|
+
async function runBench(
|
|
224
|
+
stateDir: string,
|
|
225
|
+
): Promise<SetupCortexActionResult> {
|
|
226
|
+
const action: SetupCortexActionKind = "bench";
|
|
227
|
+
const { name, logPath } = writeLogName(action, stateDir);
|
|
228
|
+
const logLines: string[] = [];
|
|
229
|
+
|
|
230
|
+
const modelPath = findModelPath(stateDir);
|
|
231
|
+
if (modelPath === null) {
|
|
232
|
+
logLines.push("bench: model.onnx not found (run fetch-model first)");
|
|
233
|
+
writeLog(logPath, logLines.join("\n") + "\n");
|
|
234
|
+
return { action, ok: false, exitCode: 2, logPath, logName: name, spawned: false };
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// Load onnxruntime-node via createRequire — the binding may be at the
|
|
238
|
+
// ENC-2a native-ort root or in the package's node_modules.
|
|
239
|
+
let ort;
|
|
240
|
+
try {
|
|
241
|
+
const req = createRequire(import.meta.url);
|
|
242
|
+
ort = req("onnxruntime-node");
|
|
243
|
+
} catch {
|
|
244
|
+
logLines.push(
|
|
245
|
+
"onnxruntime-node is not installed. See docs/vector-cortex/vc2-model-prep.md.",
|
|
246
|
+
);
|
|
247
|
+
writeLog(logPath, logLines.join("\n") + "\n");
|
|
248
|
+
return { action, ok: false, exitCode: 2, logPath, logName: name, spawned: false };
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const tokens = BENCH_TOKENS;
|
|
252
|
+
const iters = BENCH_ITERS;
|
|
253
|
+
const threads = BENCH_THREADS;
|
|
254
|
+
const repeats = BENCH_REPEATS;
|
|
255
|
+
|
|
256
|
+
const rssBefore = process.memoryUsage().rss;
|
|
257
|
+
const loadStart = Date.now();
|
|
258
|
+
const session = await ort.InferenceSession.create(modelPath, {
|
|
259
|
+
executionProviders: ["cpu"],
|
|
260
|
+
intraOpNumThreads: threads,
|
|
261
|
+
graphOptimizationLevel: "all",
|
|
262
|
+
});
|
|
263
|
+
const loadMs = Date.now() - loadStart;
|
|
264
|
+
|
|
265
|
+
const dims = [1, tokens];
|
|
266
|
+
const ids = BigInt64Array.from({ length: tokens }, (_: unknown, i: number) =>
|
|
267
|
+
BigInt(i === 0 ? 101 : i === tokens - 1 ? 102 : 2000 + (i % 500)),
|
|
268
|
+
);
|
|
269
|
+
const mask = BigInt64Array.from({ length: tokens }, () => 1n);
|
|
270
|
+
const types = new BigInt64Array(tokens);
|
|
271
|
+
|
|
272
|
+
interface Feeds { [key: string]: unknown }
|
|
273
|
+
const feeds = (): Feeds => {
|
|
274
|
+
const f: Feeds = {};
|
|
275
|
+
if (session.inputNames.includes("input_ids"))
|
|
276
|
+
f.input_ids = new ort.Tensor("int64", ids, dims);
|
|
277
|
+
if (session.inputNames.includes("attention_mask"))
|
|
278
|
+
f.attention_mask = new ort.Tensor("int64", mask, dims);
|
|
279
|
+
if (session.inputNames.includes("token_type_ids"))
|
|
280
|
+
f.token_type_ids = new ort.Tensor("int64", types, dims);
|
|
281
|
+
return f;
|
|
282
|
+
};
|
|
283
|
+
|
|
284
|
+
// Warm-up
|
|
285
|
+
for (let i = 0; i < 5; i++) await session.run(feeds());
|
|
286
|
+
|
|
287
|
+
// Latency measurement — do NOT retain outputs (measures working set, not GC).
|
|
288
|
+
const lat: number[] = [];
|
|
289
|
+
for (let i = 0; i < iters; i++) {
|
|
290
|
+
const t = process.hrtime.bigint();
|
|
291
|
+
await session.run(feeds());
|
|
292
|
+
lat.push(Number(process.hrtime.bigint() - t) / 1e6);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// GC + steady-state RSS
|
|
296
|
+
let gcRan = false;
|
|
297
|
+
if (typeof global.gc === "function") {
|
|
298
|
+
global.gc();
|
|
299
|
+
global.gc();
|
|
300
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
301
|
+
global.gc();
|
|
302
|
+
gcRan = true;
|
|
303
|
+
} else {
|
|
304
|
+
logLines.push(
|
|
305
|
+
"WARNING: global.gc not available (run under node --expose-gc);" +
|
|
306
|
+
" RSS figure is unreliable without it.",
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
const steadyRss = mib(process.memoryUsage().rss - rssBefore);
|
|
310
|
+
lat.sort((a, b) => a - b);
|
|
311
|
+
|
|
312
|
+
// Determinism: identical inputs must yield bit-stable outputs.
|
|
313
|
+
let ref: Float32Array | null = null;
|
|
314
|
+
let maxDelta = 0;
|
|
315
|
+
const digests = new Set<string>();
|
|
316
|
+
for (let i = 0; i < repeats; i++) {
|
|
317
|
+
const out = (await session.run(feeds())) as Record<string, { data: Float32Array }>;
|
|
318
|
+
const d = out[session.outputNames[0]].data;
|
|
319
|
+
digests.add(
|
|
320
|
+
createHash("sha256")
|
|
321
|
+
.update(Buffer.from(d.buffer, d.byteOffset, d.byteLength))
|
|
322
|
+
.digest("hex"),
|
|
323
|
+
);
|
|
324
|
+
if (!ref) ref = Float32Array.from(d);
|
|
325
|
+
else
|
|
326
|
+
for (let k = 0; k < d.length; k++) {
|
|
327
|
+
const delta = Math.abs(d[k] - ref[k]);
|
|
328
|
+
if (delta > maxDelta) maxDelta = delta;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const p95 = percentile(lat, 0.95);
|
|
333
|
+
const report = {
|
|
334
|
+
model: modelPath,
|
|
335
|
+
// guardrails-allow PREVENT-PI-004: local file stat (loopback)
|
|
336
|
+
modelBytes: statSync(modelPath).size,
|
|
337
|
+
backend: "onnxruntime-node",
|
|
338
|
+
ortVersion: (() => {
|
|
339
|
+
try {
|
|
340
|
+
return createRequire(import.meta.url)("onnxruntime-node/package.json").version as string;
|
|
341
|
+
} catch {
|
|
342
|
+
return "unknown";
|
|
343
|
+
}
|
|
344
|
+
})(),
|
|
345
|
+
platform: `${process.platform}-${process.arch}`,
|
|
346
|
+
threads,
|
|
347
|
+
tokens,
|
|
348
|
+
iters,
|
|
349
|
+
loadMs,
|
|
350
|
+
p50: percentile(lat, 0.5),
|
|
351
|
+
p95,
|
|
352
|
+
p99: percentile(lat, 0.99),
|
|
353
|
+
steadyRssMiB: steadyRss,
|
|
354
|
+
gcRan,
|
|
355
|
+
determinism: {
|
|
356
|
+
repeats,
|
|
357
|
+
distinctDigests: digests.size,
|
|
358
|
+
maxAbsDelta: maxDelta,
|
|
359
|
+
},
|
|
360
|
+
gates: {
|
|
361
|
+
latency: p95 <= LATENCY_BUDGET_MS,
|
|
362
|
+
rss: steadyRss <= RSS_BUDGET_MIB,
|
|
363
|
+
determinism: digests.size === 1 && maxDelta <= DETERMINISM_EPSILON,
|
|
364
|
+
},
|
|
365
|
+
};
|
|
366
|
+
const allPass =
|
|
367
|
+
report.gates.latency && report.gates.rss && report.gates.determinism;
|
|
368
|
+
|
|
369
|
+
logLines.push(JSON.stringify({ ...report, gates: { ...report.gates, all: allPass } }, null, 2));
|
|
370
|
+
writeLog(logPath, logLines.join("\n") + "\n");
|
|
371
|
+
return {
|
|
372
|
+
action,
|
|
373
|
+
ok: allPass,
|
|
374
|
+
exitCode: allPass ? 0 : 1,
|
|
375
|
+
logPath,
|
|
376
|
+
logName: name,
|
|
377
|
+
spawned: false,
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// ─── public entry point ────────────────────────────────────────────────────
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Run one VC2 model-prep action (fetch-model or bench) in-process.
|
|
385
|
+
* Never throws — every failure surfaces as { ok: false, ... } with a log.
|
|
386
|
+
*/
|
|
387
|
+
export async function runVc2Action(
|
|
388
|
+
action: Extract<SetupCortexActionKind, "fetch-model" | "bench">,
|
|
389
|
+
stateDir: string,
|
|
390
|
+
): Promise<SetupCortexActionResult> {
|
|
391
|
+
try {
|
|
392
|
+
if (action === "fetch-model") return await runFetchModel(stateDir);
|
|
393
|
+
return await runBench(stateDir);
|
|
394
|
+
} catch (err) {
|
|
395
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
396
|
+
const { name, logPath } = writeLogName(action, stateDir);
|
|
397
|
+
writeLog(logPath, `${action} failed: ${msg}\n`);
|
|
398
|
+
return { action, ok: false, exitCode: 1, logPath, logName: name, spawned: false };
|
|
399
|
+
}
|
|
400
|
+
}
|
|
@@ -2,24 +2,20 @@
|
|
|
2
2
|
* dashboard-server/setup-cortex-actions.ts — VC9B action driver (actor surface).
|
|
3
3
|
*
|
|
4
4
|
* Implements the actual mechanics behind POST /api/setup-cortex-action and
|
|
5
|
-
* GET /api/setup-cortex-action-log:
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* delegated
|
|
11
|
-
* npm-delegated local install + ENC-2b re-qualification).
|
|
5
|
+
* GET /api/setup-cortex-action-log: in-process HTTPS download for fetch-model
|
|
6
|
+
* and in-process ONNX bench (delegated to setup-cortex-actions-vc2.ts), re-running
|
|
7
|
+
* the committed encoder asset verification seam for verify-asset (NO subprocess),
|
|
8
|
+
* and serving a bounded + redacted log tail. ENC-2c adds the `install-native-ort`
|
|
9
|
+
* action, delegated to the sibling setup-cortex-actions-native-ort.ts (the
|
|
10
|
+
* confirm-gated, npm-delegated local install + ENC-2b re-qualification).
|
|
12
11
|
*
|
|
13
12
|
* This module is the ONLY place that touches the filesystem for VC9B actions.
|
|
14
13
|
* The route file (routes-setup-cortex-actions.ts) carries NO path/script/blocker
|
|
15
|
-
* string literals — it delegates here. Guardrails: the
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* prefixes + codes only, never payload bytes — EVAL-REDACT-002); PREVENT-011
|
|
19
|
-
* (no `any`).
|
|
14
|
+
* string literals — it delegates here. Guardrails: the log tail is bounded at
|
|
15
|
+
* 8 KiB and redacted (digest prefixes + codes only, never payload bytes —
|
|
16
|
+
* EVAL-REDACT-002); PREVENT-011 (no `any`).
|
|
20
17
|
*/
|
|
21
18
|
|
|
22
|
-
import { spawnSync } from "node:child_process"; // guardrails-allow PREVENT-PI-004: local subprocess spawn of committed repo script (loopback)
|
|
23
19
|
import {
|
|
24
20
|
mkdirSync,
|
|
25
21
|
readFileSync,
|
|
@@ -44,24 +40,11 @@ import {
|
|
|
44
40
|
encoderStateDir,
|
|
45
41
|
} from "./qualification-record.js";
|
|
46
42
|
import { runInstallNativeOrt } from "./setup-cortex-actions-native-ort.js";
|
|
43
|
+
import { runVc2Action } from "./setup-cortex-actions-vc2.js";
|
|
47
44
|
|
|
48
45
|
/** Cap applied to every log tail served by the action-log route. */
|
|
49
46
|
export const ACTION_LOG_TAIL_BYTES = 8192;
|
|
50
47
|
|
|
51
|
-
/** Locate the commit's vc2-model-prep directory by walking up to the repo root. */
|
|
52
|
-
function vc2ScriptDir(): string | null {
|
|
53
|
-
let dir = dirname(fileURLToPath(import.meta.url));
|
|
54
|
-
const rel = join("scripts", "vc2-model-prep");
|
|
55
|
-
for (let i = 0; i < 8; i++) {
|
|
56
|
-
const candidate = join(dir, rel);
|
|
57
|
-
if (existsSync(join(candidate, "fetch-model.sh"))) return candidate;
|
|
58
|
-
const next = dirname(dir);
|
|
59
|
-
if (next === dir) break;
|
|
60
|
-
dir = next;
|
|
61
|
-
}
|
|
62
|
-
return null;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
48
|
/** Absolute dir holding this repo's <stateDir>/logs/vc9b/ action logs. */
|
|
66
49
|
export function vc9bLogDir(stateDir: string): string {
|
|
67
50
|
return join(stateDir, "logs", "vc9b");
|
|
@@ -125,43 +108,6 @@ export function readActionLogTail(
|
|
|
125
108
|
};
|
|
126
109
|
}
|
|
127
110
|
|
|
128
|
-
/** Run a vc2-model-prep subprocess and capture its output to a vc9b log file. */
|
|
129
|
-
function runSpawnedAction(
|
|
130
|
-
action: Extract<SetupCortexActionKind, "fetch-model" | "bench">,
|
|
131
|
-
stateDir: string,
|
|
132
|
-
): SetupCortexActionResult {
|
|
133
|
-
const dir = vc2ScriptDir();
|
|
134
|
-
const { name, logPath } = writeLogName(action, stateDir);
|
|
135
|
-
if (dir === null) {
|
|
136
|
-
writeLog(logPath, "vc2-model-prep scripts not found in this checkout\n");
|
|
137
|
-
return { action, ok: false, exitCode: null, logPath, logName: name, spawned: true };
|
|
138
|
-
}
|
|
139
|
-
let result;
|
|
140
|
-
if (action === "fetch-model") {
|
|
141
|
-
// guardrails-allow PREVENT-PI-004: local subprocess spawn of committed repo script (loopback)
|
|
142
|
-
result = spawnSync("bash", [join(dir, "fetch-model.sh"), join(stateDir, "vc2-model-prep")], {
|
|
143
|
-
encoding: "utf8",
|
|
144
|
-
timeout: 60_000,
|
|
145
|
-
});
|
|
146
|
-
} else {
|
|
147
|
-
// guardrails-allow PREVENT-PI-004: local subprocess spawn of committed repo script (loopback)
|
|
148
|
-
result = spawnSync(process.execPath, [join(dir, "bench-onnx.mjs")], {
|
|
149
|
-
encoding: "utf8",
|
|
150
|
-
timeout: 60_000,
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
const out = `${result.stdout ?? ""}${result.stderr ?? ""}`;
|
|
154
|
-
writeLog(logPath, out || "(no output)\n");
|
|
155
|
-
return {
|
|
156
|
-
action,
|
|
157
|
-
ok: result.status === 0,
|
|
158
|
-
exitCode: result.status === null ? null : result.status,
|
|
159
|
-
logPath,
|
|
160
|
-
logName: name,
|
|
161
|
-
spawned: true,
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
|
|
165
111
|
/**
|
|
166
112
|
* Re-run the committed encoder asset verification seam (readEncoderManifest +
|
|
167
113
|
* verifyEncoderAsset + detectPlatform) WITHOUT any subprocess, and log a
|
|
@@ -236,7 +182,7 @@ interface LogFileRef {
|
|
|
236
182
|
}
|
|
237
183
|
|
|
238
184
|
/** Unique <action>-<ts>.log name + absolute path under the vc9b log dir. */
|
|
239
|
-
function writeLogName(action: SetupCortexActionKind, stateDir: string): LogFileRef {
|
|
185
|
+
export function writeLogName(action: SetupCortexActionKind, stateDir: string): LogFileRef {
|
|
240
186
|
let ts = Date.now();
|
|
241
187
|
const existing = new Set(readdirSync(ensureLogDir(stateDir)));
|
|
242
188
|
while (existing.has(`${action}-${ts}.log`)) ts++;
|
|
@@ -244,7 +190,8 @@ function writeLogName(action: SetupCortexActionKind, stateDir: string): LogFileR
|
|
|
244
190
|
return { name, logPath: join(vc9bLogDir(stateDir), name) };
|
|
245
191
|
}
|
|
246
192
|
|
|
247
|
-
|
|
193
|
+
/** Write a vc9b action log file. Exported for the VC2 sibling. */
|
|
194
|
+
export function writeLog(logPath: string, body: string): void {
|
|
248
195
|
// guardrails-allow PREVENT-PI-004: local state-dir filesystem write (loopback)
|
|
249
196
|
writeFileSync(logPath, body, "utf8");
|
|
250
197
|
}
|
|
@@ -252,10 +199,10 @@ function writeLog(logPath: string, body: string): void {
|
|
|
252
199
|
/**
|
|
253
200
|
* Run one Setup Cortex action against the given stateDir. Returns the action
|
|
254
201
|
* result on success; throws nothing — every failure is surfaced as a result with
|
|
255
|
-
* ok=false so the route can shape the HTTP response.
|
|
256
|
-
* the
|
|
257
|
-
*
|
|
258
|
-
*
|
|
202
|
+
* ok=false so the route can shape the HTTP response. fetch-model/bench run
|
|
203
|
+
* in-process via the VC2 sibling (HTTPS download + ONNX bench); install-native-ort
|
|
204
|
+
* (ENC-2c) runs the npm-delegated local install then re-qualifies via the ENC-2b
|
|
205
|
+
* retest path.
|
|
259
206
|
*/
|
|
260
207
|
export async function runSetupCortexAction(
|
|
261
208
|
action: SetupCortexActionKind,
|
|
@@ -263,5 +210,5 @@ export async function runSetupCortexAction(
|
|
|
263
210
|
): Promise<SetupCortexActionResult> {
|
|
264
211
|
if (action === "verify-asset") return runVerifyAsset(stateDir);
|
|
265
212
|
if (action === "install-native-ort") return runInstallNativeOrt(stateDir);
|
|
266
|
-
return
|
|
213
|
+
return runVc2Action(action, stateDir);
|
|
267
214
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-mega-compact",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.78",
|
|
4
4
|
"description": "Layered, local, vector-backed context compressor for pi — supersede/collapse/cluster compaction with deduped inline recall.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "BSD-3-Clause",
|
|
@@ -22,9 +22,10 @@ import { sprintFlag } from "./vector-cortex-flag.js";
|
|
|
22
22
|
* GET /api/setup-cortex-action-log). Default ON. `MEGACOMPACT_VC9B=0` disables
|
|
23
23
|
* and is byte-identical to the predecessor (VC9A-era): the action POST returns
|
|
24
24
|
* the disabled shape (404/disabled) and flag-off bytes are unchanged. The
|
|
25
|
-
* actions
|
|
26
|
-
*
|
|
27
|
-
* committed encoder assets
|
|
25
|
+
* actions run in-process: fetch-model downloads via HTTPS (opt-in, confirm-gated)
|
|
26
|
+
* and bench runs ONNX inference directly — no subprocess spawns. verify-asset
|
|
27
|
+
* re-reads the committed encoder assets; install-native-ort uses the npm-delegated
|
|
28
|
+
* install (PREVENT-PI-004 opt-in). Never payload bytes.
|
|
28
29
|
* This flag MUST also be a dashboard SETTINGS toggle (visible in config UI,
|
|
29
30
|
* never in EXCLUDED_SETTINGS), mirroring VC9A.
|
|
30
31
|
*/
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{j as r}from"./index-CL6Af_JZ.js";import{M as t}from"./MetricsCards-36RVmtPj.js";import"./card-Dvl16_R5.js";import"./generateCategoricalChart-Q_V4fqVi.js";import"./BarChart-Bhyviy7_.js";import"./AreaChart-CeaexvWO.js";function e(){return r.jsx(t,{})}export{e as default};
|
|
2
|
-
//# sourceMappingURL=MetricsTab-Clkcniuo.js.map
|