@markbrutx/promptbook-core 0.1.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.
Files changed (144) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +53 -0
  3. package/dist/annotations.d.ts +56 -0
  4. package/dist/annotations.d.ts.map +1 -0
  5. package/dist/annotations.js +50 -0
  6. package/dist/annotations.js.map +1 -0
  7. package/dist/bundle.d.ts +44 -0
  8. package/dist/bundle.d.ts.map +1 -0
  9. package/dist/bundle.js +135 -0
  10. package/dist/bundle.js.map +1 -0
  11. package/dist/edge/index.js +192 -0
  12. package/dist/edge.d.ts +12 -0
  13. package/dist/edge.d.ts.map +1 -0
  14. package/dist/edge.js +11 -0
  15. package/dist/edge.js.map +1 -0
  16. package/dist/eval/assertions.d.ts +15 -0
  17. package/dist/eval/assertions.d.ts.map +1 -0
  18. package/dist/eval/assertions.js +131 -0
  19. package/dist/eval/assertions.js.map +1 -0
  20. package/dist/eval/evaluate.d.ts +15 -0
  21. package/dist/eval/evaluate.d.ts.map +1 -0
  22. package/dist/eval/evaluate.js +65 -0
  23. package/dist/eval/evaluate.js.map +1 -0
  24. package/dist/eval/load-fixtures.d.ts +12 -0
  25. package/dist/eval/load-fixtures.d.ts.map +1 -0
  26. package/dist/eval/load-fixtures.js +87 -0
  27. package/dist/eval/load-fixtures.js.map +1 -0
  28. package/dist/eval/types.d.ts +123 -0
  29. package/dist/eval/types.d.ts.map +1 -0
  30. package/dist/eval/types.js +2 -0
  31. package/dist/eval/types.js.map +1 -0
  32. package/dist/frontmatter.d.ts +12 -0
  33. package/dist/frontmatter.d.ts.map +1 -0
  34. package/dist/frontmatter.js +22 -0
  35. package/dist/frontmatter.js.map +1 -0
  36. package/dist/fs.d.ts +11 -0
  37. package/dist/fs.d.ts.map +1 -0
  38. package/dist/fs.js +20 -0
  39. package/dist/fs.js.map +1 -0
  40. package/dist/guards.d.ts +6 -0
  41. package/dist/guards.d.ts.map +1 -0
  42. package/dist/guards.js +9 -0
  43. package/dist/guards.js.map +1 -0
  44. package/dist/index.d.ts +22 -0
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +15 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/interpolate.d.ts +11 -0
  49. package/dist/interpolate.d.ts.map +1 -0
  50. package/dist/interpolate.js +25 -0
  51. package/dist/interpolate.js.map +1 -0
  52. package/dist/lint/lint.d.ts +11 -0
  53. package/dist/lint/lint.d.ts.map +1 -0
  54. package/dist/lint/lint.js +30 -0
  55. package/dist/lint/lint.js.map +1 -0
  56. package/dist/lint/references.d.ts +18 -0
  57. package/dist/lint/references.d.ts.map +1 -0
  58. package/dist/lint/references.js +39 -0
  59. package/dist/lint/references.js.map +1 -0
  60. package/dist/lint/rules/banned-tokens.d.ts +13 -0
  61. package/dist/lint/rules/banned-tokens.d.ts.map +1 -0
  62. package/dist/lint/rules/banned-tokens.js +38 -0
  63. package/dist/lint/rules/banned-tokens.js.map +1 -0
  64. package/dist/lint/rules/dangling-reference.d.ts +11 -0
  65. package/dist/lint/rules/dangling-reference.d.ts.map +1 -0
  66. package/dist/lint/rules/dangling-reference.js +37 -0
  67. package/dist/lint/rules/dangling-reference.js.map +1 -0
  68. package/dist/lint/rules/dead-rule.d.ts +21 -0
  69. package/dist/lint/rules/dead-rule.d.ts.map +1 -0
  70. package/dist/lint/rules/dead-rule.js +135 -0
  71. package/dist/lint/rules/dead-rule.js.map +1 -0
  72. package/dist/lint/rules/example-balance.d.ts +19 -0
  73. package/dist/lint/rules/example-balance.d.ts.map +1 -0
  74. package/dist/lint/rules/example-balance.js +57 -0
  75. package/dist/lint/rules/example-balance.js.map +1 -0
  76. package/dist/lint/rules/index.d.ts +28 -0
  77. package/dist/lint/rules/index.d.ts.map +1 -0
  78. package/dist/lint/rules/index.js +30 -0
  79. package/dist/lint/rules/index.js.map +1 -0
  80. package/dist/lint/rules/language-directive-position.d.ts +16 -0
  81. package/dist/lint/rules/language-directive-position.d.ts.map +1 -0
  82. package/dist/lint/rules/language-directive-position.js +42 -0
  83. package/dist/lint/rules/language-directive-position.js.map +1 -0
  84. package/dist/lint/rules/token-budget.d.ts +18 -0
  85. package/dist/lint/rules/token-budget.d.ts.map +1 -0
  86. package/dist/lint/rules/token-budget.js +39 -0
  87. package/dist/lint/rules/token-budget.js.map +1 -0
  88. package/dist/lint/rules/unused-fragment.d.ts +11 -0
  89. package/dist/lint/rules/unused-fragment.d.ts.map +1 -0
  90. package/dist/lint/rules/unused-fragment.js +33 -0
  91. package/dist/lint/rules/unused-fragment.js.map +1 -0
  92. package/dist/lint/types.d.ts +50 -0
  93. package/dist/lint/types.d.ts.map +1 -0
  94. package/dist/lint/types.js +2 -0
  95. package/dist/lint/types.js.map +1 -0
  96. package/dist/load.d.ts +12 -0
  97. package/dist/load.d.ts.map +1 -0
  98. package/dist/load.js +238 -0
  99. package/dist/load.js.map +1 -0
  100. package/dist/paths.d.ts +12 -0
  101. package/dist/paths.d.ts.map +1 -0
  102. package/dist/paths.js +25 -0
  103. package/dist/paths.js.map +1 -0
  104. package/dist/resolve-book.d.ts +15 -0
  105. package/dist/resolve-book.d.ts.map +1 -0
  106. package/dist/resolve-book.js +195 -0
  107. package/dist/resolve-book.js.map +1 -0
  108. package/dist/resolve.d.ts +13 -0
  109. package/dist/resolve.d.ts.map +1 -0
  110. package/dist/resolve.js +17 -0
  111. package/dist/resolve.js.map +1 -0
  112. package/dist/types.d.ts +173 -0
  113. package/dist/types.d.ts.map +1 -0
  114. package/dist/types.js +9 -0
  115. package/dist/types.js.map +1 -0
  116. package/package.json +48 -0
  117. package/src/annotations.ts +100 -0
  118. package/src/bundle.ts +163 -0
  119. package/src/edge.ts +11 -0
  120. package/src/eval/assertions.ts +174 -0
  121. package/src/eval/evaluate.ts +84 -0
  122. package/src/eval/load-fixtures.ts +91 -0
  123. package/src/eval/types.ts +134 -0
  124. package/src/frontmatter.ts +28 -0
  125. package/src/fs.ts +21 -0
  126. package/src/guards.ts +11 -0
  127. package/src/index.ts +84 -0
  128. package/src/interpolate.ts +27 -0
  129. package/src/lint/lint.ts +32 -0
  130. package/src/lint/references.ts +50 -0
  131. package/src/lint/rules/banned-tokens.ts +46 -0
  132. package/src/lint/rules/dangling-reference.ts +43 -0
  133. package/src/lint/rules/dead-rule.ts +147 -0
  134. package/src/lint/rules/example-balance.ts +68 -0
  135. package/src/lint/rules/index.ts +47 -0
  136. package/src/lint/rules/language-directive-position.ts +51 -0
  137. package/src/lint/rules/token-budget.ts +50 -0
  138. package/src/lint/rules/unused-fragment.ts +38 -0
  139. package/src/lint/types.ts +55 -0
  140. package/src/load.ts +282 -0
  141. package/src/paths.ts +27 -0
  142. package/src/resolve-book.ts +237 -0
  143. package/src/resolve.ts +18 -0
  144. package/src/types.ts +191 -0
@@ -0,0 +1,131 @@
1
+ const EXCERPT_LIMIT = 160;
2
+ /** A short, single-line excerpt of the output for failure messages. */
3
+ function excerpt(text) {
4
+ const collapsed = text.replace(/\s+/g, " ").trim();
5
+ return collapsed.length > EXCERPT_LIMIT ? `${collapsed.slice(0, EXCERPT_LIMIT)}…` : collapsed;
6
+ }
7
+ function result(type, pass, message, output) {
8
+ return { type, pass, message, excerpt: excerpt(output) };
9
+ }
10
+ /** Require a spec field to be present, with a clear error when it is not. */
11
+ function need(value, type, field) {
12
+ if (value === undefined) {
13
+ throw new Error(`assertion "${type}" requires a "${field}" field.`);
14
+ }
15
+ return value;
16
+ }
17
+ function buildRegex(assertion) {
18
+ const pattern = need(assertion.pattern, assertion.type, "pattern");
19
+ try {
20
+ return new RegExp(pattern, assertion.flags);
21
+ }
22
+ catch (error) {
23
+ throw new Error(`assertion "${assertion.type}" has an invalid pattern: ${error.message}`);
24
+ }
25
+ }
26
+ const contains = (output, a) => {
27
+ const value = need(a.value, "contains", "value");
28
+ const pass = output.includes(value);
29
+ return result("contains", pass, pass ? `contains "${value}"` : `missing "${value}"`, output);
30
+ };
31
+ const notContains = (output, a) => {
32
+ const value = need(a.value, "not-contains", "value");
33
+ const pass = !output.includes(value);
34
+ return result("not-contains", pass, pass ? `does not contain "${value}"` : `unexpectedly contains "${value}"`, output);
35
+ };
36
+ const matches = (output, a) => {
37
+ const re = buildRegex({ ...a, type: "matches" });
38
+ const pass = re.test(output);
39
+ return result("matches", pass, pass ? `matches /${re.source}/` : `does not match /${re.source}/`, output);
40
+ };
41
+ const notMatches = (output, a) => {
42
+ const re = buildRegex({ ...a, type: "not-matches" });
43
+ const pass = !re.test(output);
44
+ return result("not-matches", pass, pass ? `does not match /${re.source}/` : `unexpectedly matches /${re.source}/`, output);
45
+ };
46
+ const equals = (output, a) => {
47
+ const value = need(a.value, "equals", "value");
48
+ const pass = output.trim() === value.trim();
49
+ return result("equals", pass, pass ? "equals expected text" : "does not equal expected text", output);
50
+ };
51
+ const jsonValid = (output) => {
52
+ try {
53
+ JSON.parse(output);
54
+ return result("json-valid", true, "output is valid JSON", output);
55
+ }
56
+ catch (error) {
57
+ return result("json-valid", false, `output is not valid JSON: ${error.message}`, output);
58
+ }
59
+ };
60
+ const maxLength = (output, a) => {
61
+ const max = need(a.max, "max-length", "max");
62
+ const pass = output.length <= max;
63
+ return result("max-length", pass, pass ? `length ${output.length} within ${max}` : `length ${output.length} exceeds ${max}`, output);
64
+ };
65
+ /** Map common language tags to the script the `language` heuristic checks. */
66
+ const SCRIPT_BY_LANGUAGE = {
67
+ ru: "cyrillic",
68
+ uk: "cyrillic",
69
+ be: "cyrillic",
70
+ bg: "cyrillic",
71
+ sr: "cyrillic",
72
+ mk: "cyrillic",
73
+ en: "latin",
74
+ fr: "latin",
75
+ es: "latin",
76
+ de: "latin",
77
+ it: "latin",
78
+ pt: "latin",
79
+ nl: "latin",
80
+ pl: "latin",
81
+ cs: "latin",
82
+ ro: "latin",
83
+ tr: "latin",
84
+ sv: "latin",
85
+ da: "latin",
86
+ no: "latin",
87
+ fi: "latin",
88
+ };
89
+ const CYRILLIC = /\p{Script=Cyrillic}/gu;
90
+ const LATIN = /\p{Script=Latin}/gu;
91
+ function count(text, re) {
92
+ return text.match(re)?.length ?? 0;
93
+ }
94
+ /**
95
+ * `language`: script-based heuristic. Resolves the spec `lang` to a script
96
+ * ("cyrillic"/"latin", either directly or via a language tag) and passes when
97
+ * that script has at least one letter and is at least as frequent as the
98
+ * other. Not an LLM judge — it detects script, not fluency.
99
+ */
100
+ const language = (output, a) => {
101
+ const lang = need(a.lang, "language", "lang").toLowerCase();
102
+ const script = SCRIPT_BY_LANGUAGE[lang] ?? lang;
103
+ if (script !== "cyrillic" && script !== "latin") {
104
+ return result("language", false, `unsupported language "${a.lang}" (no script heuristic)`, output);
105
+ }
106
+ const cyrillic = count(output, CYRILLIC);
107
+ const latin = count(output, LATIN);
108
+ const expected = script === "cyrillic" ? cyrillic : latin;
109
+ const other = script === "cyrillic" ? latin : cyrillic;
110
+ const pass = expected > 0 && expected >= other;
111
+ return result("language", pass, pass
112
+ ? `output is predominantly ${script}`
113
+ : `expected predominantly ${script} (cyrillic=${cyrillic}, latin=${latin})`, output);
114
+ };
115
+ /**
116
+ * The built-in assertion registry. Pass a merged/replaced object to
117
+ * {@link evaluate} to customize: `{ ...defaultAssertions(), myType: fn }`.
118
+ */
119
+ export function defaultAssertions() {
120
+ return {
121
+ contains,
122
+ "not-contains": notContains,
123
+ matches,
124
+ "not-matches": notMatches,
125
+ equals,
126
+ "json-valid": jsonValid,
127
+ "max-length": maxLength,
128
+ language,
129
+ };
130
+ }
131
+ //# sourceMappingURL=assertions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assertions.js","sourceRoot":"","sources":["../../src/eval/assertions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { EvalInput, EvalReport } from "./types.js";
2
+ /**
3
+ * Run fixtures through a model adapter and report pass-rate.
4
+ *
5
+ * For each fixture: assemble the system prompt once via {@link resolveBook}
6
+ * (deterministic — every sample of a fixture sees the same prompt), then take
7
+ * N samples through `adapter.complete` and run the assertions on each. A sample
8
+ * passes only when all its assertions pass; `passRate = passes / samples`. A
9
+ * fixture meets the gate when `passRate >= passThreshold` (default 1).
10
+ *
11
+ * The engine is pure given the adapter: its control flow is deterministic and
12
+ * the only stochasticity/IO is `adapter.complete`. It makes no network calls.
13
+ */
14
+ export declare function evaluate(input: EvalInput): Promise<EvalReport>;
15
+ //# sourceMappingURL=evaluate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluate.d.ts","sourceRoot":"","sources":["../../src/eval/evaluate.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAIV,SAAS,EACT,UAAU,EAGX,MAAM,YAAY,CAAC;AAapB;;;;;;;;;;;GAWG;AACH,wBAAsB,QAAQ,CAAC,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAiBpE"}
@@ -0,0 +1,65 @@
1
+ import { resolveBook } from "../resolve-book.js";
2
+ import { defaultAssertions } from "./assertions.js";
3
+ /** Run every assertion of a fixture against one model output. */
4
+ function runAssertions(output, asserts, registry) {
5
+ return asserts.map((assertion) => {
6
+ const fn = registry[assertion.type];
7
+ if (fn === undefined) {
8
+ return { type: assertion.type, pass: false, message: `unknown assertion type "${assertion.type}"` };
9
+ }
10
+ return fn(output, assertion);
11
+ });
12
+ }
13
+ /**
14
+ * Run fixtures through a model adapter and report pass-rate.
15
+ *
16
+ * For each fixture: assemble the system prompt once via {@link resolveBook}
17
+ * (deterministic — every sample of a fixture sees the same prompt), then take
18
+ * N samples through `adapter.complete` and run the assertions on each. A sample
19
+ * passes only when all its assertions pass; `passRate = passes / samples`. A
20
+ * fixture meets the gate when `passRate >= passThreshold` (default 1).
21
+ *
22
+ * The engine is pure given the adapter: its control flow is deterministic and
23
+ * the only stochasticity/IO is `adapter.complete`. It makes no network calls.
24
+ */
25
+ export async function evaluate(input) {
26
+ const registry = input.assertions ?? defaultAssertions();
27
+ const defaultSamples = input.samples ?? 1;
28
+ const threshold = input.passThreshold ?? 1;
29
+ const results = [];
30
+ for (const fixture of input.fixtures) {
31
+ results.push(await runFixture(fixture, input, registry, defaultSamples));
32
+ }
33
+ const passed = results.filter((r) => r.passRate >= threshold).length;
34
+ return {
35
+ results,
36
+ passed,
37
+ failed: results.length - passed,
38
+ passRate: results.length === 0 ? 1 : passed / results.length,
39
+ };
40
+ }
41
+ async function runFixture(fixture, input, registry, defaultSamples) {
42
+ const { text: system } = resolveBook(input.book, fixture.prompt, fixture.context ?? {});
43
+ const samples = fixture.samples ?? defaultSamples;
44
+ let passes = 0;
45
+ const failures = [];
46
+ for (let i = 0; i < samples; i += 1) {
47
+ const response = await input.adapter.complete({ system, input: fixture.input });
48
+ const sampleResults = runAssertions(response.text, fixture.assert, registry);
49
+ const failed = sampleResults.filter((r) => !r.pass);
50
+ if (failed.length === 0) {
51
+ passes += 1;
52
+ }
53
+ else {
54
+ failures.push(...failed);
55
+ }
56
+ }
57
+ return {
58
+ name: fixture.name,
59
+ samples,
60
+ passes,
61
+ passRate: samples === 0 ? 0 : passes / samples,
62
+ failures,
63
+ };
64
+ }
65
+ //# sourceMappingURL=evaluate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"evaluate.js","sourceRoot":"","sources":["../../src/eval/evaluate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import type { FsAdapter } from "../types.js";
2
+ import type { Fixture } from "./types.js";
3
+ /**
4
+ * Load eval fixtures from `<dir>/fixtures/*.json` into {@link Fixture}s.
5
+ *
6
+ * Mirrors {@link loadPrompts}: the same `dir` that holds `fragments/` and
7
+ * `rules/` also holds `fixtures/`. A missing `fixtures/` folder yields an empty
8
+ * list; a malformed fixture throws with its file path so the caller can report
9
+ * it. Files are read in sorted order for deterministic results.
10
+ */
11
+ export declare function loadFixtures(dir: string, fs?: FsAdapter): Promise<Fixture[]>;
12
+ //# sourceMappingURL=load-fixtures.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-fixtures.d.ts","sourceRoot":"","sources":["../../src/eval/load-fixtures.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAW,SAAS,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,KAAK,EAAa,OAAO,EAAE,MAAM,YAAY,CAAC;AA8DrD;;;;;;;GAOG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,GAAE,SAAoB,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAgB5F"}
@@ -0,0 +1,87 @@
1
+ import { nodeFs } from "../fs.js";
2
+ import { isContextValue, isMapping } from "../guards.js";
3
+ import { joinPath, listFiles, stripExt } from "../paths.js";
4
+ function parseContext(raw, file) {
5
+ if (raw === undefined) {
6
+ return undefined;
7
+ }
8
+ if (!isMapping(raw)) {
9
+ throw new Error(`Fixture "${file}" has a "context" that is not an object.`);
10
+ }
11
+ const context = {};
12
+ for (const [key, value] of Object.entries(raw)) {
13
+ if (!isContextValue(value)) {
14
+ throw new Error(`Fixture "${file}" context key "${key}" must be a string, number or boolean.`);
15
+ }
16
+ context[key] = value;
17
+ }
18
+ return context;
19
+ }
20
+ function parseAssertions(raw, file) {
21
+ if (!Array.isArray(raw) || raw.length === 0) {
22
+ throw new Error(`Fixture "${file}" must declare a non-empty "assert" array.`);
23
+ }
24
+ return raw.map((entry, index) => {
25
+ if (!isMapping(entry) || typeof entry.type !== "string" || entry.type === "") {
26
+ throw new Error(`Fixture "${file}" assertion #${index} must be an object with a string "type".`);
27
+ }
28
+ return entry;
29
+ });
30
+ }
31
+ function parseFixture(raw, file, fallbackName) {
32
+ if (!isMapping(raw)) {
33
+ throw new Error(`Fixture "${file}" is not a JSON object.`);
34
+ }
35
+ if (typeof raw.prompt !== "string" || raw.prompt === "") {
36
+ throw new Error(`Fixture "${file}" must declare a string "prompt".`);
37
+ }
38
+ if (typeof raw.input !== "string") {
39
+ throw new Error(`Fixture "${file}" must declare a string "input".`);
40
+ }
41
+ const name = typeof raw.name === "string" && raw.name !== "" ? raw.name : fallbackName;
42
+ const fixture = {
43
+ name,
44
+ prompt: raw.prompt,
45
+ input: raw.input,
46
+ assert: parseAssertions(raw.assert, file),
47
+ sourceFile: file,
48
+ };
49
+ const context = parseContext(raw.context, file);
50
+ if (context !== undefined) {
51
+ fixture.context = context;
52
+ }
53
+ if (raw.samples !== undefined) {
54
+ if (typeof raw.samples !== "number" || !Number.isInteger(raw.samples) || raw.samples <= 0) {
55
+ throw new Error(`Fixture "${file}" "samples" must be a positive integer.`);
56
+ }
57
+ fixture.samples = raw.samples;
58
+ }
59
+ return fixture;
60
+ }
61
+ /**
62
+ * Load eval fixtures from `<dir>/fixtures/*.json` into {@link Fixture}s.
63
+ *
64
+ * Mirrors {@link loadPrompts}: the same `dir` that holds `fragments/` and
65
+ * `rules/` also holds `fixtures/`. A missing `fixtures/` folder yields an empty
66
+ * list; a malformed fixture throws with its file path so the caller can report
67
+ * it. Files are read in sorted order for deterministic results.
68
+ */
69
+ export async function loadFixtures(dir, fs = nodeFs()) {
70
+ const fixturesDir = joinPath(dir, "fixtures");
71
+ const files = await listFiles(fs, fixturesDir, [".json"]);
72
+ const fixtures = [];
73
+ for (const file of files) {
74
+ const full = joinPath(fixturesDir, file);
75
+ const raw = await fs.readFile(full);
76
+ let doc;
77
+ try {
78
+ doc = JSON.parse(raw);
79
+ }
80
+ catch (error) {
81
+ throw new Error(`Fixture "${full}" is not valid JSON: ${error.message}`);
82
+ }
83
+ fixtures.push(parseFixture(doc, full, stripExt(file)));
84
+ }
85
+ return fixtures;
86
+ }
87
+ //# sourceMappingURL=load-fixtures.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load-fixtures.js","sourceRoot":"","sources":["../../src/eval/load-fixtures.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Public types for the eval engine.
3
+ *
4
+ * Eval is the one place stochasticity enters the system, and it is locked
5
+ * behind an injectable {@link ModelAdapter}. The engine's control flow is
6
+ * deterministic: given the same adapter outputs it returns the same report.
7
+ * The core ships no adapter and makes no network calls — a concrete adapter
8
+ * (e.g. `@markbrutx/promptbook-openrouter`) lives in its own package.
9
+ */
10
+ import type { Context, PromptBook } from "../types.js";
11
+ /** Token accounting, when an adapter reports it. Provider-agnostic shape. */
12
+ export interface ModelUsage {
13
+ promptTokens?: number;
14
+ completionTokens?: number;
15
+ totalTokens?: number;
16
+ }
17
+ /** One model call: the assembled system prompt plus the user input. */
18
+ export interface ModelRequest {
19
+ /** The assembled system prompt from {@link resolveBook}. */
20
+ system: string;
21
+ /** The user input that accompanies the system prompt. */
22
+ input: string;
23
+ /** Optional per-request model override; adapters define the default. */
24
+ model?: string;
25
+ }
26
+ /** A model's reply. `raw` carries the provider payload for debugging. */
27
+ export interface ModelResponse {
28
+ text: string;
29
+ usage?: ModelUsage;
30
+ raw?: unknown;
31
+ }
32
+ /**
33
+ * The seam stochasticity is locked behind. Implementations perform IO/network;
34
+ * the eval engine only ever calls `complete`, so it stays pure given a fake.
35
+ */
36
+ export interface ModelAdapter {
37
+ complete(request: ModelRequest): Promise<ModelResponse>;
38
+ }
39
+ /**
40
+ * A single assertion spec as authored in a fixture JSON. `type` selects the
41
+ * checker from the assertion registry; the remaining fields are its params.
42
+ */
43
+ export interface Assertion {
44
+ /** Registry key, e.g. "contains" or "language". */
45
+ type: string;
46
+ /** Substring (contains/not-contains) or exact text (equals). */
47
+ value?: string;
48
+ /** Regex source for matches/not-matches. */
49
+ pattern?: string;
50
+ /** Regex flags for matches/not-matches. */
51
+ flags?: string;
52
+ /** Character ceiling for max-length. */
53
+ max?: number;
54
+ /** Expected language tag or script for `language` (e.g. "ru", "latin"). */
55
+ lang?: string;
56
+ }
57
+ /** The outcome of running one assertion against one model output. */
58
+ export interface AssertionResult {
59
+ /** The assertion `type` that produced this result. */
60
+ type: string;
61
+ pass: boolean;
62
+ /** Human-readable, domain-agnostic explanation. */
63
+ message: string;
64
+ /** A short excerpt of the output relevant to the assertion. */
65
+ excerpt?: string;
66
+ }
67
+ /** A checker for one assertion type. Pure: same output + spec, same result. */
68
+ export type AssertionFn = (output: string, assertion: Assertion) => AssertionResult;
69
+ /** Map of assertion `type` to its checker. Callers may supply their own. */
70
+ export type AssertionRegistry = Record<string, AssertionFn>;
71
+ /** A single eval test case loaded from a `fixtures/*.json` file. */
72
+ export interface Fixture {
73
+ /** Lookup name; defaults to the file stem when omitted in JSON. */
74
+ name: string;
75
+ /** Composition name to assemble for this case. */
76
+ prompt: string;
77
+ /** Facts to resolve the composition under. */
78
+ context?: Context;
79
+ /** User input sent alongside the assembled system prompt. */
80
+ input: string;
81
+ /** Assertions every sample's output must satisfy. */
82
+ assert: Assertion[];
83
+ /** Per-fixture sample count; overrides the run-level default. */
84
+ samples?: number;
85
+ /** File the fixture was loaded from. */
86
+ sourceFile?: string;
87
+ }
88
+ /** Per-fixture aggregate over its samples. */
89
+ export interface FixtureResult {
90
+ name: string;
91
+ /** Number of samples taken. */
92
+ samples: number;
93
+ /** Samples where every assertion passed. */
94
+ passes: number;
95
+ /** `passes / samples` (0 when `samples` is 0). */
96
+ passRate: number;
97
+ /** Every failing assertion across all samples, with messages/excerpts. */
98
+ failures: AssertionResult[];
99
+ }
100
+ /** The aggregated outcome of an eval run. */
101
+ export interface EvalReport {
102
+ results: FixtureResult[];
103
+ /** Fraction of fixtures that met the threshold gate (`passed / total`). */
104
+ passRate: number;
105
+ /** Fixtures whose `passRate >= passThreshold`. */
106
+ passed: number;
107
+ /** Fixtures whose `passRate < passThreshold`. */
108
+ failed: number;
109
+ }
110
+ /** Input to {@link evaluate}. */
111
+ export interface EvalInput {
112
+ book: PromptBook;
113
+ fixtures: Fixture[];
114
+ /** The injected model seam; all stochasticity/IO lives here. */
115
+ adapter: ModelAdapter;
116
+ /** Assertion checkers; defaults to {@link defaultAssertions}. */
117
+ assertions?: AssertionRegistry;
118
+ /** Default sample count when a fixture sets none. Defaults to 1. */
119
+ samples?: number;
120
+ /** A fixture passes when `passRate >= passThreshold`. Defaults to 1. */
121
+ passThreshold?: number;
122
+ }
123
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/eval/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/eval/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ export interface ParsedFrontmatter {
2
+ data: Record<string, unknown>;
3
+ body: string;
4
+ }
5
+ /**
6
+ * Split a Markdown file into YAML frontmatter (parsed) and the body text.
7
+ *
8
+ * Intentionally dependency-light: a single YAML parser, no extra frontmatter
9
+ * library, so the core stays small and easy to run anywhere.
10
+ */
11
+ export declare function parseFrontmatter(raw: string): ParsedFrontmatter;
12
+ //# sourceMappingURL=frontmatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.d.ts","sourceRoot":"","sources":["../src/frontmatter.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,IAAI,EAAE,MAAM,CAAC;CACd;AAKD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAU/D"}
@@ -0,0 +1,22 @@
1
+ import { parse as parseYaml } from "yaml";
2
+ import { isMapping } from "./guards.js";
3
+ /** Matches a leading `---\n ... \n---` YAML frontmatter block. */
4
+ const FRONTMATTER_RE = /^---\r?\n([\s\S]*?)\r?\n---\r?\n?/;
5
+ /**
6
+ * Split a Markdown file into YAML frontmatter (parsed) and the body text.
7
+ *
8
+ * Intentionally dependency-light: a single YAML parser, no extra frontmatter
9
+ * library, so the core stays small and easy to run anywhere.
10
+ */
11
+ export function parseFrontmatter(raw) {
12
+ const match = raw.match(FRONTMATTER_RE);
13
+ if (!match) {
14
+ return { data: {}, body: raw };
15
+ }
16
+ const yamlText = match[1] ?? "";
17
+ const parsed = parseYaml(yamlText);
18
+ const data = isMapping(parsed) ? parsed : {};
19
+ const body = raw.slice(match[0].length);
20
+ return { data, body };
21
+ }
22
+ //# sourceMappingURL=frontmatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontmatter.js","sourceRoot":"","sources":["../src/frontmatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAOxC,kEAAkE;AAClE,MAAM,cAAc,GAAG,mCAAmC,CAAC;AAE3D;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IACxC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;IACjC,CAAC;IACD,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAY,CAAC;IAC9C,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7C,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACxC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AACxB,CAAC"}
package/dist/fs.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ import type { FsAdapter } from "./types.js";
2
+ /**
3
+ * Default filesystem adapter backed by `node:fs/promises`.
4
+ *
5
+ * The import is lazy so that simply importing the core does not pull in any
6
+ * Node-only module: callers in Deno/Bun (or tests) can inject their own
7
+ * {@link FsAdapter} and never touch this path. The module is resolved once
8
+ * per adapter (when `nodeFs()` is called), not on every read.
9
+ */
10
+ export declare function nodeFs(): FsAdapter;
11
+ //# sourceMappingURL=fs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs.d.ts","sourceRoot":"","sources":["../src/fs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C;;;;;;;GAOG;AACH,wBAAgB,MAAM,IAAI,SAAS,CAUlC"}
package/dist/fs.js ADDED
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Default filesystem adapter backed by `node:fs/promises`.
3
+ *
4
+ * The import is lazy so that simply importing the core does not pull in any
5
+ * Node-only module: callers in Deno/Bun (or tests) can inject their own
6
+ * {@link FsAdapter} and never touch this path. The module is resolved once
7
+ * per adapter (when `nodeFs()` is called), not on every read.
8
+ */
9
+ export function nodeFs() {
10
+ const fsModule = import("node:fs/promises");
11
+ return {
12
+ async readFile(path) {
13
+ return (await fsModule).readFile(path, "utf8");
14
+ },
15
+ async readDir(path) {
16
+ return (await fsModule).readdir(path);
17
+ },
18
+ };
19
+ }
20
+ //# sourceMappingURL=fs.js.map
package/dist/fs.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fs.js","sourceRoot":"","sources":["../src/fs.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,MAAM,UAAU,MAAM;IACpB,MAAM,QAAQ,GAAG,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAC5C,OAAO;QACL,KAAK,CAAC,QAAQ,CAAC,IAAY;YACzB,OAAO,CAAC,MAAM,QAAQ,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACjD,CAAC;QACD,KAAK,CAAC,OAAO,CAAC,IAAY;YACxB,OAAO,CAAC,MAAM,QAAQ,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACxC,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { ContextValue } from "./types.js";
2
+ /** True for a plain object (a YAML/JSON mapping); excludes arrays and null. */
3
+ export declare function isMapping(value: unknown): value is Record<string, unknown>;
4
+ /** True for a scalar that is a valid {@link ContextValue} (string/number/boolean). */
5
+ export declare function isContextValue(value: unknown): value is ContextValue;
6
+ //# sourceMappingURL=guards.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guards.d.ts","sourceRoot":"","sources":["../src/guards.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,+EAA+E;AAC/E,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAE1E;AAED,sFAAsF;AACtF,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAEpE"}
package/dist/guards.js ADDED
@@ -0,0 +1,9 @@
1
+ /** True for a plain object (a YAML/JSON mapping); excludes arrays and null. */
2
+ export function isMapping(value) {
3
+ return !!value && typeof value === "object" && !Array.isArray(value);
4
+ }
5
+ /** True for a scalar that is a valid {@link ContextValue} (string/number/boolean). */
6
+ export function isContextValue(value) {
7
+ return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
8
+ }
9
+ //# sourceMappingURL=guards.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guards.js","sourceRoot":"","sources":["../src/guards.ts"],"names":[],"mappings":"AAEA,+EAA+E;AAC/E,MAAM,UAAU,SAAS,CAAC,KAAc;IACtC,OAAO,CAAC,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AACvE,CAAC;AAED,sFAAsF;AACtF,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,CAAC;AAC9F,CAAC"}
@@ -0,0 +1,22 @@
1
+ export type { Annotation, AnnotationAnchor, AnnotationStatus, AnnotationTarget, } from "./annotations.js";
2
+ export { ANNOTATION_QUEUE_DIR, ANNOTATION_QUEUE_FILE, parseInbox, serializeAnnotationLine, serializeInbox, } from "./annotations.js";
3
+ export type { SerializeBookOptions } from "./bundle.js";
4
+ export { serializeBook, serializeBookExpression, serializeBookJson } from "./bundle.js";
5
+ export { defaultAssertions } from "./eval/assertions.js";
6
+ export { evaluate } from "./eval/evaluate.js";
7
+ export { loadFixtures } from "./eval/load-fixtures.js";
8
+ export type { Assertion, AssertionFn, AssertionRegistry, AssertionResult, EvalInput, EvalReport, Fixture, FixtureResult, ModelAdapter, ModelRequest, ModelResponse, ModelUsage, } from "./eval/types.js";
9
+ export { parseFrontmatter } from "./frontmatter.js";
10
+ export { nodeFs } from "./fs.js";
11
+ export { interpolate } from "./interpolate.js";
12
+ export { lint } from "./lint/lint.js";
13
+ export type { FragmentReference } from "./lint/references.js";
14
+ export { iterateReferences } from "./lint/references.js";
15
+ export type { BannedTokensOptions, DanglingReferenceOptions, DeadRuleOptions, ExampleBalanceOptions, LanguageDirectivePositionOptions, TokenBudgetOptions, UnusedFragmentOptions, } from "./lint/rules/index.js";
16
+ export { bannedTokens, type DefaultRulesOptions, danglingReference, deadRule, defaultRules, estimateTokensByChars, exampleBalance, languageDirectivePosition, tokenBudget, unusedFragment, } from "./lint/rules/index.js";
17
+ export type { LintFinding, LintInput, LintReport, LintRule, LintScope, Severity } from "./lint/types.js";
18
+ export { loadPrompts } from "./load.js";
19
+ export { resolve } from "./resolve.js";
20
+ export { resolveBook } from "./resolve-book.js";
21
+ export type { AddTrace, CodePrompt, CodePromptSample, Composition, Context, ContextValue, ForbidTrace, Fragment, FsAdapter, PromptBook, ReplaceTrace, ResolveInput, ResolveResult, Rule, RuleAction, RuleTrace, Trace, UnmatchedAxis, When, } from "./types.js";
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,UAAU,EACV,uBAAuB,EACvB,cAAc,GACf,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,YAAY,EACV,SAAS,EACT,WAAW,EACX,iBAAiB,EACjB,eAAe,EACf,SAAS,EACT,UAAU,EACV,OAAO,EACP,aAAa,EACb,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,UAAU,GACX,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,YAAY,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AACzD,YAAY,EACV,mBAAmB,EACnB,wBAAwB,EACxB,eAAe,EACf,qBAAqB,EACrB,gCAAgC,EAChC,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,YAAY,EACZ,KAAK,mBAAmB,EACxB,iBAAiB,EACjB,QAAQ,EACR,YAAY,EACZ,qBAAqB,EACrB,cAAc,EACd,yBAAyB,EACzB,WAAW,EACX,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACzG,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EACV,QAAQ,EACR,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,OAAO,EACP,YAAY,EACZ,WAAW,EACX,QAAQ,EACR,SAAS,EACT,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,IAAI,EACJ,UAAU,EACV,SAAS,EACT,KAAK,EACL,aAAa,EACb,IAAI,GACL,MAAM,YAAY,CAAC"}