import fs from "node:fs/promises";
const base = process.env.CONTEXT_TEST_ORIGIN || "http://127.0.0.1:4191";
if (!/^http:\/\/(127\.0\.0\.1|localhost):4191$/.test(base))
throw new Error("Use the local Context server.");
const call = async (path, body) => {
const response = await fetch(
base + "/api/" + path,
body
? {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
signal: AbortSignal.timeout(60000),
}
: undefined,
);
const data = await response.json();
return { ok: response.ok, status: response.status, data };
};
const health = (await call("status")).data;
if (!health.modelConfigured)
throw new Error("Connect the model through the demo interface first.");
const cases = (await call("cases")).data;
const report = {
runAt: new Date().toISOString(),
model: health.model,
engine: health.engineVersion,
scope: "Live synthetic integration checks, not clinical validation",
cases: [],
};
for (const scenario of cases) {
const row = { id: scenario.id, passed: false };
const started = performance.now();
try {
const extraction = await call("extract", {
sources: scenario.sources,
syntheticOnly: true,
useModel: true,
freshModel: true,
});
if (!extraction.ok) throw new Error(extraction.data.error);
const draft = extraction.data;
row.mode = draft.mode;
row.strategy = draft.strategy;
row.providerCalls = draft.metrics?.providerCalls;
if (draft.mode === "local" && draft.metrics?.providerCalls !== 0)
throw new Error("Incorrect structured-reader telemetry");
row.extractionMs = draft.durationMs;
row.attempts = draft.attempts ?? 0;
row.factCount = draft.facts.length;
const review = Object.fromEntries(
draft.facts.map((f) => [f.id, "include"]),
);
const payload = {
sources: scenario.sources,
review,
fingerprint: draft.fingerprint,
acknowledgeUnparsed: Boolean(
draft.sourceReviewRequired || draft.unparsed.length,
),
syntheticOnly: true,
...(draft.id ? { draftId: draft.id } : {}),
};
if (scenario.id === "conflicting-records") {
const blocked = await call("assess", payload);
row.conflictBlocked =
!blocked.ok && /[Cc]onflict/.test(blocked.data.error);
if (!row.conflictBlocked)
throw new Error("Conflicting medication records were not blocked");
const rejected = draft.facts.find(
(f) => f.sourceId === "fatima-clinic" && f.kind === "medicine",
);
review[rejected.id] = "exclude";
}
const checked = await call("assess", payload);
if (!checked.ok) throw new Error(checked.data.error);
row.ruleIds = checked.data.contextual.findings.map((f) => f.ruleId);
row.addedRuleIds = checked.data.addedRuleIds;
const expected =
scenario.id === "allergy-context"
? "allergy-penicillin"
: "lab-metformin-egfr-45";
if (!row.addedRuleIds.includes(expected))
throw new Error("Expected contextual finding was absent");
row.passed = true;
} catch (error) {
row.error = error.message;
}
row.totalMs = Math.round(performance.now() - started);
report.cases.push(row);
console.log(JSON.stringify(row));
}
report.passed = report.cases.filter((r) => r.passed).length;
report.total = report.cases.length;
const target = process.argv[2] || "validation/live-latest.json";
await fs.writeFile(target, JSON.stringify(report, null, 2) + "\n");
console.log(`Saved ${target}: ${report.passed}/${report.total} passed`);
process.exitCode = report.passed === report.total ? 0 : 1;