93 lines
3.9 KiB
TypeScript
93 lines
3.9 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import test from "node:test";
|
|
import {
|
|
PACK_CHARACTER_LIMIT,
|
|
allInterpretationPacks,
|
|
cachedInterpretationPreamble,
|
|
interpretationPackForTheme,
|
|
} from "../src/lib/report-interpretation-packs/index.ts";
|
|
import { REPORT_THEME_IDS } from "../src/lib/report-theme-evidence-plan.ts";
|
|
import { buildWriterSystemContents } from "../src/mastra/personal-report.ts";
|
|
|
|
test("every report theme resolves an interpretation pack", () => {
|
|
for (const theme of REPORT_THEME_IDS) {
|
|
const pack = interpretationPackForTheme(theme);
|
|
assert.ok(pack && pack.length > 200, `theme ${theme} has no usable pack`);
|
|
}
|
|
assert.equal(interpretationPackForTheme("not_a_theme"), null);
|
|
assert.equal(interpretationPackForTheme(null), null);
|
|
assert.ok(cachedInterpretationPreamble().length > 500);
|
|
});
|
|
|
|
test("packs stay inside the character budget", () => {
|
|
for (const pack of allInterpretationPacks()) {
|
|
assert.ok(
|
|
pack.text.length <= PACK_CHARACTER_LIMIT,
|
|
`${pack.id} is ${pack.text.length} characters, over the ${PACK_CHARACTER_LIMIT} budget`,
|
|
);
|
|
}
|
|
});
|
|
|
|
// The packs travel into a model prompt, so they must not leak repository
|
|
// structure, internal module names, vendor names or artefact names.
|
|
const FORBIDDEN_PACK_SUBSTRINGS = [
|
|
"references/", "scripts/", "frontend/", "src/", "node_modules",
|
|
"SKILL.md", ".md", ".ts", ".py", ".json",
|
|
"vedastro", "swisseph", "swiss ephemeris", "jyotish_engine", "mastra",
|
|
"anthropic", "openai", "claude", "gpt-",
|
|
"prompt", "system message", "schema", "bundle", "claimcard", "evidenceref",
|
|
"mevg", "workflow", "endpoint", "http://", "https://", "sha256",
|
|
];
|
|
|
|
test("packs contain no paths, module names, vendor names or artefact names", () => {
|
|
for (const pack of allInterpretationPacks()) {
|
|
const lowered = pack.text.toLowerCase();
|
|
for (const token of FORBIDDEN_PACK_SUBSTRINGS) {
|
|
assert.ok(!lowered.includes(token), `${pack.id} leaks "${token}"`);
|
|
}
|
|
}
|
|
});
|
|
|
|
test("packs restate the hard truth boundaries instead of relaxing them", () => {
|
|
const general = cachedInterpretationPreamble();
|
|
for (const banned of ["必定", "一定", "保证", "百分之百"]) {
|
|
assert.ok(general.includes(banned), `general pack must name "${banned}" as forbidden phrasing`);
|
|
}
|
|
assert.ok(general.includes("不做医疗诊断"));
|
|
const health = interpretationPackForTheme("health_pressure")!;
|
|
assert.ok(health.startsWith("非医疗边界:"));
|
|
assert.ok(health.includes("不做任何诊断"));
|
|
const wealth = interpretationPackForTheme("wealth")!;
|
|
assert.ok(wealth.includes("不推荐任何具体投资标的"));
|
|
const timing = interpretationPackForTheme("timing")!;
|
|
assert.ok(timing.includes("不写年份、月份与日期"));
|
|
});
|
|
|
|
test("writer system content caches the general pack and appends only the chapter pack", () => {
|
|
const summaryContents = buildWriterSystemContents(null);
|
|
assert.equal(summaryContents.length, 1, "summary calls carry the general pack only");
|
|
assert.ok(summaryContents[0].includes(cachedInterpretationPreamble()));
|
|
assert.ok(summaryContents[0].includes("【上下文缓存边界】"));
|
|
|
|
const previousCached = summaryContents[0];
|
|
for (const theme of REPORT_THEME_IDS) {
|
|
const contents = buildWriterSystemContents(theme);
|
|
assert.equal(contents.length, 2, `${theme} must add its own pack`);
|
|
assert.equal(
|
|
contents[0],
|
|
previousCached,
|
|
"the cached prefix must stay byte-identical across sections or the cache never hits",
|
|
);
|
|
assert.equal(contents[1], interpretationPackForTheme(theme));
|
|
}
|
|
});
|
|
|
|
test("writer system content never carries chart, subject or evidence data", () => {
|
|
for (const theme of [null, ...REPORT_THEME_IDS]) {
|
|
for (const content of buildWriterSystemContents(theme)) {
|
|
assert.ok(!/ev-[a-z0-9_-]+/.test(content), "no evidence ids in the static packs");
|
|
assert.ok(!/\d{4}-\d{2}-\d{2}/.test(content), "no dates in the static packs");
|
|
}
|
|
}
|
|
});
|