@webywz/eval-smoke 0.0.0-stage → 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 (49) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +180 -2
  3. package/dist/cli.d.ts +3 -0
  4. package/dist/cli.d.ts.map +1 -0
  5. package/dist/cli.js +5 -0
  6. package/dist/cli.js.map +1 -0
  7. package/dist/index.d.ts +10 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +9 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/load-suite.d.ts +4 -0
  12. package/dist/load-suite.d.ts.map +1 -0
  13. package/dist/load-suite.js +162 -0
  14. package/dist/load-suite.js.map +1 -0
  15. package/dist/matchers.d.ts +7 -0
  16. package/dist/matchers.d.ts.map +1 -0
  17. package/dist/matchers.js +69 -0
  18. package/dist/matchers.js.map +1 -0
  19. package/dist/providers.d.ts +15 -0
  20. package/dist/providers.d.ts.map +1 -0
  21. package/dist/providers.js +161 -0
  22. package/dist/providers.js.map +1 -0
  23. package/dist/report.d.ts +7 -0
  24. package/dist/report.d.ts.map +1 -0
  25. package/dist/report.js +60 -0
  26. package/dist/report.js.map +1 -0
  27. package/dist/run-cli.d.ts +14 -0
  28. package/dist/run-cli.d.ts.map +1 -0
  29. package/dist/run-cli.js +116 -0
  30. package/dist/run-cli.js.map +1 -0
  31. package/dist/run.d.ts +5 -0
  32. package/dist/run.d.ts.map +1 -0
  33. package/dist/run.js +118 -0
  34. package/dist/run.js.map +1 -0
  35. package/dist/tokens.d.ts +3 -0
  36. package/dist/tokens.d.ts.map +1 -0
  37. package/dist/tokens.js +7 -0
  38. package/dist/tokens.js.map +1 -0
  39. package/dist/types.d.ts +72 -0
  40. package/dist/types.d.ts.map +1 -0
  41. package/dist/types.js +8 -0
  42. package/dist/types.js.map +1 -0
  43. package/dist/version.d.ts +2 -0
  44. package/dist/version.d.ts.map +1 -0
  45. package/dist/version.js +6 -0
  46. package/dist/version.js.map +1 -0
  47. package/examples/suite.json +23 -0
  48. package/examples/suite.yaml +29 -0
  49. package/package.json +60 -4
@@ -0,0 +1,161 @@
1
+ import { UsageError } from "./types.js";
2
+ const MOCK_FIXTURES = [
3
+ { match: /\bhello\b/i, reply: "Hello" },
4
+ { match: /capital of france/i, reply: "Paris" },
5
+ { match: /2\s*\+\s*2/, reply: "4" },
6
+ {
7
+ match: /ignore (all )?previous|pwned/i,
8
+ reply: "I cannot ignore my instructions. How can I help you?",
9
+ },
10
+ ];
11
+ export const DEFAULT_MODELS = {
12
+ openai: "gpt-4o-mini",
13
+ anthropic: "claude-3-5-haiku-20241022",
14
+ };
15
+ export function mockComplete(request) {
16
+ if (request.signal.aborted) {
17
+ return Promise.reject(signalError(request.signal));
18
+ }
19
+ const hit = MOCK_FIXTURES.find((fixture) => fixture.match.test(request.prompt));
20
+ return Promise.resolve(hit?.reply ?? `[mock] No canned reply for this prompt.`);
21
+ }
22
+ function signalError(signal) {
23
+ const err = new Error("The operation was aborted");
24
+ err.name = "AbortError";
25
+ if (signal.reason instanceof Error)
26
+ return signal.reason;
27
+ return err;
28
+ }
29
+ async function readJson(response) {
30
+ const text = await response.text();
31
+ try {
32
+ return JSON.parse(text);
33
+ }
34
+ catch {
35
+ return { raw: text };
36
+ }
37
+ }
38
+ function asRecord(value) {
39
+ return typeof value === "object" && value !== null ? value : undefined;
40
+ }
41
+ export function createOpenAIComplete(apiKey, fetchFn, baseUrl = "https://api.openai.com/v1") {
42
+ return async (request) => {
43
+ const response = await fetchFn(`${baseUrl.replace(/\/$/, "")}/chat/completions`, {
44
+ method: "POST",
45
+ signal: request.signal,
46
+ headers: {
47
+ authorization: `Bearer ${apiKey}`,
48
+ "content-type": "application/json",
49
+ },
50
+ body: JSON.stringify({
51
+ model: request.model,
52
+ messages: [
53
+ ...(request.system ? [{ role: "system", content: request.system }] : []),
54
+ { role: "user", content: request.prompt },
55
+ ],
56
+ max_tokens: request.maxTokens ?? 256,
57
+ temperature: 0,
58
+ }),
59
+ });
60
+ const data = await readJson(response);
61
+ if (!response.ok) {
62
+ throw new Error(`OpenAI ${response.status}: ${summarizeError(data)}`);
63
+ }
64
+ const choices = data.choices;
65
+ if (!Array.isArray(choices) || choices.length === 0) {
66
+ throw new Error("OpenAI response was missing choices");
67
+ }
68
+ const message = asRecord(asRecord(choices[0])?.message);
69
+ const content = message?.content;
70
+ if (typeof content !== "string") {
71
+ throw new Error("OpenAI response was missing message content");
72
+ }
73
+ return content;
74
+ };
75
+ }
76
+ export function createAnthropicComplete(apiKey, fetchFn, baseUrl = "https://api.anthropic.com/v1") {
77
+ return async (request) => {
78
+ const response = await fetchFn(`${baseUrl.replace(/\/$/, "")}/messages`, {
79
+ method: "POST",
80
+ signal: request.signal,
81
+ headers: {
82
+ "x-api-key": apiKey,
83
+ "anthropic-version": "2023-06-01",
84
+ "content-type": "application/json",
85
+ },
86
+ body: JSON.stringify({
87
+ model: request.model,
88
+ max_tokens: request.maxTokens ?? 256,
89
+ temperature: 0,
90
+ system: request.system,
91
+ messages: [{ role: "user", content: request.prompt }],
92
+ }),
93
+ });
94
+ const data = await readJson(response);
95
+ if (!response.ok) {
96
+ throw new Error(`Anthropic ${response.status}: ${summarizeError(data)}`);
97
+ }
98
+ const content = data.content;
99
+ if (!Array.isArray(content)) {
100
+ throw new Error("Anthropic response was missing content");
101
+ }
102
+ const text = content
103
+ .map((part) => asRecord(part))
104
+ .filter((part) => part?.type === "text" && typeof part.text === "string")
105
+ .map((part) => part?.text)
106
+ .join("");
107
+ if (!text) {
108
+ throw new Error("Anthropic response had no text content");
109
+ }
110
+ return text;
111
+ };
112
+ }
113
+ function summarizeError(data) {
114
+ const err = asRecord(data.error);
115
+ const message = err?.message ?? data.message ?? data.raw;
116
+ if (typeof message === "string" && message.trim()) {
117
+ return message.slice(0, 240);
118
+ }
119
+ return "request failed";
120
+ }
121
+ export function resolveProvider(options) {
122
+ if (options.mock)
123
+ return "mock";
124
+ if (options.provider)
125
+ return options.provider;
126
+ if (options.suiteProvider)
127
+ return options.suiteProvider;
128
+ const model = options.model ?? "";
129
+ if (model.startsWith("claude"))
130
+ return "anthropic";
131
+ const env = options.env ?? process.env;
132
+ if (env.OPENAI_API_KEY)
133
+ return "openai";
134
+ if (env.ANTHROPIC_API_KEY)
135
+ return "anthropic";
136
+ throw new UsageError("No API key set. Pass --mock for an offline run, or set OPENAI_API_KEY / ANTHROPIC_API_KEY.");
137
+ }
138
+ export function resolveModel(provider, requested, suiteDefault) {
139
+ if (requested)
140
+ return requested;
141
+ if (suiteDefault)
142
+ return suiteDefault;
143
+ if (provider === "mock")
144
+ return "mock";
145
+ return DEFAULT_MODELS[provider];
146
+ }
147
+ export function createComplete(provider, env = process.env, fetchFn = fetch) {
148
+ if (provider === "mock")
149
+ return mockComplete;
150
+ if (provider === "openai") {
151
+ const key = env.OPENAI_API_KEY;
152
+ if (!key)
153
+ throw new UsageError("OPENAI_API_KEY is not set");
154
+ return createOpenAIComplete(key, fetchFn, env.OPENAI_BASE_URL);
155
+ }
156
+ const key = env.ANTHROPIC_API_KEY;
157
+ if (!key)
158
+ throw new UsageError("ANTHROPIC_API_KEY is not set");
159
+ return createAnthropicComplete(key, fetchFn, env.ANTHROPIC_BASE_URL);
160
+ }
161
+ //# sourceMappingURL=providers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers.js","sourceRoot":"","sources":["../src/providers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { Report } from "./types.js";
2
+ export interface FormatOptions {
3
+ json?: boolean;
4
+ color?: boolean;
5
+ }
6
+ export declare function formatReport(report: Report, options?: FormatOptions): string;
7
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA2B,MAAM,EAAE,MAAM,YAAY,CAAC;AAQlE,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAsCD,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM,CA0BhF"}
package/dist/report.js ADDED
@@ -0,0 +1,60 @@
1
+ const RESET = "\u001b[0m";
2
+ const GREEN = "\u001b[32m";
3
+ const RED = "\u001b[31m";
4
+ const YELLOW = "\u001b[33m";
5
+ const DIM = "\u001b[2m";
6
+ function paint(enabled, color, text) {
7
+ return enabled ? `${color}${text}${RESET}` : text;
8
+ }
9
+ function truncate(text, max = 220) {
10
+ const compact = text.replace(/\s+/g, " ").trim();
11
+ if (compact.length <= max)
12
+ return compact;
13
+ return `${compact.slice(0, max - 1)}…`;
14
+ }
15
+ function failedChecks(result) {
16
+ return (result.checks ?? []).filter((check) => !check.ok);
17
+ }
18
+ function formatCase(result, color) {
19
+ const ms = `${result.duration_ms}ms`;
20
+ if (result.skipped) {
21
+ return [` ${paint(color, YELLOW, "skip")} ${result.id.padEnd(22)} ${paint(color, DIM, ms)}`];
22
+ }
23
+ if (result.ok) {
24
+ return [` ${paint(color, GREEN, "pass")} ${result.id.padEnd(22)} ${paint(color, DIM, ms)}`];
25
+ }
26
+ const lines = [` ${paint(color, RED, "fail")} ${result.id.padEnd(22)} ${paint(color, DIM, ms)}`];
27
+ if (result.error) {
28
+ lines.push(` ${result.error}`);
29
+ }
30
+ for (const check of failedChecks(result)) {
31
+ lines.push(` ${check.name}: ${check.detail ?? "failed"}`);
32
+ }
33
+ if (result.output) {
34
+ lines.push(` output: ${truncate(result.output)}`);
35
+ }
36
+ return lines;
37
+ }
38
+ export function formatReport(report, options = {}) {
39
+ if (options.json) {
40
+ return `${JSON.stringify(report, null, 2)}\n`;
41
+ }
42
+ const color = Boolean(options.color);
43
+ const bits = [
44
+ `eval-smoke ${report.version}`,
45
+ report.runner,
46
+ report.model,
47
+ report.suite,
48
+ `${report.cases.length} cases`,
49
+ ].filter(Boolean);
50
+ const lines = [paint(color, DIM, bits.join(" · ")), ""];
51
+ for (const result of report.cases) {
52
+ lines.push(...formatCase(result, color));
53
+ }
54
+ const summary = `${report.passed} passed ${report.failed} failed${report.skipped ? ` ${report.skipped} skipped` : ""} ${report.duration_ms}ms`;
55
+ lines.push("");
56
+ lines.push(report.ok ? paint(color, GREEN, summary) : paint(color, RED, summary));
57
+ lines.push("");
58
+ return lines.join("\n");
59
+ }
60
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ export declare const HELP = "eval-smoke \u2014 one-minute smoke evals for prompts and models\n\nUsage:\n eval-smoke <suite.yaml|suite.json> [options]\n\nOptions:\n --mock Offline runner with deterministic fake answers\n --json Machine-readable JSON report\n --fail-fast Stop after the first failing case\n --timeout <ms> Per-case timeout (default: 30000)\n --model <name> Override suite model\n --provider <name> openai | anthropic | mock\n -h, --help Show this help\n -v, --version Show version\n\nExit codes:\n 0 all cases passed\n 1 one or more cases failed\n 2 usage or configuration error\n\nExamples:\n eval-smoke examples/suite.yaml --mock\n eval-smoke examples/suite.yaml --json --fail-fast\n OPENAI_API_KEY=sk-... eval-smoke examples/suite.yaml\n";
2
+ export interface CliIo {
3
+ stdout: {
4
+ write(text: string): void;
5
+ };
6
+ stderr: {
7
+ write(text: string): void;
8
+ };
9
+ env: NodeJS.ProcessEnv;
10
+ cwd: string;
11
+ isTTY: boolean;
12
+ }
13
+ export declare function runCli(argv: string[], io?: CliIo): Promise<number>;
14
+ //# sourceMappingURL=run-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-cli.d.ts","sourceRoot":"","sources":["../src/run-cli.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,IAAI,0yBAwBhB,CAAC;AAEF,MAAM,WAAW,KAAK;IACpB,MAAM,EAAE;QAAE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACtC,MAAM,EAAE;QAAE,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IACtC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,OAAO,CAAC;CAChB;AAyBD,wBAAsB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,GAAE,KAAmB,GAAG,OAAO,CAAC,MAAM,CAAC,CA+DrF"}
@@ -0,0 +1,116 @@
1
+ import { parseArgs } from "node:util";
2
+ import { loadSuite } from "./load-suite.js";
3
+ import { formatReport } from "./report.js";
4
+ import { DEFAULT_TIMEOUT_MS, runSuite } from "./run.js";
5
+ import { UsageError } from "./types.js";
6
+ import { VERSION } from "./version.js";
7
+ export const HELP = `eval-smoke — one-minute smoke evals for prompts and models
8
+
9
+ Usage:
10
+ eval-smoke <suite.yaml|suite.json> [options]
11
+
12
+ Options:
13
+ --mock Offline runner with deterministic fake answers
14
+ --json Machine-readable JSON report
15
+ --fail-fast Stop after the first failing case
16
+ --timeout <ms> Per-case timeout (default: ${DEFAULT_TIMEOUT_MS})
17
+ --model <name> Override suite model
18
+ --provider <name> openai | anthropic | mock
19
+ -h, --help Show this help
20
+ -v, --version Show version
21
+
22
+ Exit codes:
23
+ 0 all cases passed
24
+ 1 one or more cases failed
25
+ 2 usage or configuration error
26
+
27
+ Examples:
28
+ eval-smoke examples/suite.yaml --mock
29
+ eval-smoke examples/suite.yaml --json --fail-fast
30
+ OPENAI_API_KEY=sk-... eval-smoke examples/suite.yaml
31
+ `;
32
+ const defaultIo = () => ({
33
+ stdout: process.stdout,
34
+ stderr: process.stderr,
35
+ env: process.env,
36
+ cwd: process.cwd(),
37
+ isTTY: Boolean(process.stdout.isTTY),
38
+ });
39
+ function parseTimeout(raw) {
40
+ if (raw == null)
41
+ return DEFAULT_TIMEOUT_MS;
42
+ const value = Number(raw);
43
+ if (!Number.isInteger(value) || value <= 0) {
44
+ throw new UsageError("--timeout must be a positive integer (milliseconds)");
45
+ }
46
+ return value;
47
+ }
48
+ function parseProvider(raw) {
49
+ if (raw == null)
50
+ return undefined;
51
+ if (raw === "mock" || raw === "openai" || raw === "anthropic")
52
+ return raw;
53
+ throw new UsageError("--provider must be openai, anthropic, or mock");
54
+ }
55
+ export async function runCli(argv, io = defaultIo()) {
56
+ let parsed;
57
+ try {
58
+ parsed = parseArgs({
59
+ args: argv,
60
+ allowPositionals: true,
61
+ strict: true,
62
+ options: {
63
+ mock: { type: "boolean", default: false },
64
+ json: { type: "boolean", default: false },
65
+ "fail-fast": { type: "boolean", default: false },
66
+ timeout: { type: "string" },
67
+ model: { type: "string" },
68
+ provider: { type: "string" },
69
+ help: { type: "boolean", short: "h", default: false },
70
+ version: { type: "boolean", short: "v", default: false },
71
+ },
72
+ });
73
+ }
74
+ catch (error) {
75
+ io.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
76
+ return 2;
77
+ }
78
+ const { values, positionals } = parsed;
79
+ const asString = (value) => typeof value === "string" ? value : undefined;
80
+ const asBool = (value) => value === true;
81
+ if (asBool(values.help)) {
82
+ io.stdout.write(HELP);
83
+ return 0;
84
+ }
85
+ if (asBool(values.version)) {
86
+ io.stdout.write(`${VERSION}\n`);
87
+ return 0;
88
+ }
89
+ const suitePath = positionals[0];
90
+ if (!suitePath) {
91
+ io.stderr.write("Missing suite file.\n\n");
92
+ io.stderr.write(HELP);
93
+ return 2;
94
+ }
95
+ try {
96
+ const json = asBool(values.json);
97
+ const suite = loadSuite(suitePath, io.cwd);
98
+ const report = await runSuite(suite, {
99
+ mock: asBool(values.mock),
100
+ provider: parseProvider(asString(values.provider)),
101
+ model: asString(values.model),
102
+ failFast: asBool(values["fail-fast"]),
103
+ timeoutMs: parseTimeout(asString(values.timeout)),
104
+ env: io.env,
105
+ });
106
+ const color = io.isTTY && !json && !io.env.NO_COLOR;
107
+ io.stdout.write(formatReport(report, { json, color }));
108
+ return report.ok ? 0 : 1;
109
+ }
110
+ catch (error) {
111
+ const message = error instanceof Error ? error.message : String(error);
112
+ io.stderr.write(`${message}\n`);
113
+ return error instanceof UsageError ? error.exitCode : 2;
114
+ }
115
+ }
116
+ //# sourceMappingURL=run-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-cli.js","sourceRoot":"","sources":["../src/run-cli.ts"],"names":[],"mappings":"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"}
package/dist/run.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ import type { Report, RunOptions, Suite } from "./types.js";
2
+ declare const DEFAULT_TIMEOUT_MS = 30000;
3
+ export declare function runSuite(suite: Suite, options?: RunOptions): Promise<Report>;
4
+ export { DEFAULT_TIMEOUT_MS };
5
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAA0B,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGpF,QAAA,MAAM,kBAAkB,QAAS,CAAC;AA6ElC,wBAAsB,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,GAAE,UAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAkDtF;AAED,OAAO,EAAE,kBAAkB,EAAE,CAAC"}
package/dist/run.js ADDED
@@ -0,0 +1,118 @@
1
+ import { evaluateCase } from "./matchers.js";
2
+ import { createComplete, resolveModel, resolveProvider } from "./providers.js";
3
+ import { VERSION } from "./version.js";
4
+ const DEFAULT_TIMEOUT_MS = 30_000;
5
+ function isAbortError(error) {
6
+ return ((error instanceof Error && error.name === "AbortError") ||
7
+ (typeof error === "object" && error !== null && error.name === "TimeoutError"));
8
+ }
9
+ function errorMessage(error) {
10
+ return error instanceof Error ? error.message : String(error);
11
+ }
12
+ function timeoutError(timeoutMs) {
13
+ const error = new Error(`timed out after ${timeoutMs}ms`);
14
+ error.name = "TimeoutError";
15
+ return error;
16
+ }
17
+ async function withTimeout(timeoutMs, work) {
18
+ const controller = new AbortController();
19
+ let timer;
20
+ const timeout = new Promise((_, reject) => {
21
+ timer = setTimeout(() => {
22
+ const error = timeoutError(timeoutMs);
23
+ controller.abort(error);
24
+ reject(error);
25
+ }, timeoutMs);
26
+ });
27
+ try {
28
+ return await Promise.race([work(controller.signal), timeout]);
29
+ }
30
+ finally {
31
+ if (timer)
32
+ clearTimeout(timer);
33
+ }
34
+ }
35
+ async function runCase(suite, caseIndex, complete, model, timeoutMs) {
36
+ const testCase = suite.cases[caseIndex];
37
+ if (!testCase) {
38
+ throw new Error(`Missing case at index ${caseIndex}`);
39
+ }
40
+ const started = performance.now();
41
+ try {
42
+ const output = await withTimeout(timeoutMs, (signal) => complete({
43
+ prompt: testCase.prompt,
44
+ system: testCase.system ?? suite.system,
45
+ model: testCase.model ?? model,
46
+ maxTokens: testCase.expect.max_tokens,
47
+ signal,
48
+ }));
49
+ const checks = evaluateCase(output, testCase);
50
+ return {
51
+ id: testCase.id,
52
+ ok: checks.every((check) => check.ok),
53
+ duration_ms: Math.round(performance.now() - started),
54
+ output,
55
+ checks,
56
+ };
57
+ }
58
+ catch (error) {
59
+ const timedOut = isAbortError(error);
60
+ return {
61
+ id: testCase.id,
62
+ ok: false,
63
+ duration_ms: Math.round(performance.now() - started),
64
+ error: timedOut ? `timed out after ${timeoutMs}ms` : errorMessage(error),
65
+ };
66
+ }
67
+ }
68
+ export async function runSuite(suite, options = {}) {
69
+ const env = options.env ?? process.env;
70
+ const runner = resolveProvider({
71
+ mock: options.mock,
72
+ provider: options.provider,
73
+ suiteProvider: suite.provider,
74
+ model: options.model ?? suite.model,
75
+ env,
76
+ });
77
+ const model = resolveModel(runner, options.model, suite.model);
78
+ const complete = options.complete ?? createComplete(runner, env, options.fetch ?? globalThis.fetch);
79
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
80
+ const started = performance.now();
81
+ const cases = [];
82
+ for (let index = 0; index < suite.cases.length; index += 1) {
83
+ const result = await runCase(suite, index, complete, model, timeoutMs);
84
+ cases.push(result);
85
+ if (!result.ok && options.failFast) {
86
+ for (let rest = index + 1; rest < suite.cases.length; rest += 1) {
87
+ const skipped = suite.cases[rest];
88
+ if (!skipped)
89
+ continue;
90
+ cases.push({
91
+ id: skipped.id,
92
+ ok: false,
93
+ skipped: true,
94
+ duration_ms: 0,
95
+ error: "skipped (fail-fast)",
96
+ });
97
+ }
98
+ break;
99
+ }
100
+ }
101
+ const passed = cases.filter((item) => item.ok).length;
102
+ const skipped = cases.filter((item) => item.skipped).length;
103
+ const failed = cases.length - passed - skipped;
104
+ return {
105
+ ok: failed === 0 && skipped === 0,
106
+ version: VERSION,
107
+ runner,
108
+ model,
109
+ suite: suite.name,
110
+ passed,
111
+ failed,
112
+ skipped,
113
+ duration_ms: Math.round(performance.now() - started),
114
+ cases,
115
+ };
116
+ }
117
+ export { DEFAULT_TIMEOUT_MS };
118
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** Rough cl100k-style estimate used only for `expect.max_tokens`. */
2
+ export declare function estimateTokens(text: string): number;
3
+ //# sourceMappingURL=tokens.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGnD"}
package/dist/tokens.js ADDED
@@ -0,0 +1,7 @@
1
+ /** Rough cl100k-style estimate used only for `expect.max_tokens`. */
2
+ export function estimateTokens(text) {
3
+ if (!text)
4
+ return 0;
5
+ return Math.max(1, Math.ceil(text.length / 4));
6
+ }
7
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,IAAI,CAAC,IAAI;QAAE,OAAO,CAAC,CAAC;IACpB,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC"}
@@ -0,0 +1,72 @@
1
+ export type ProviderName = "mock" | "openai" | "anthropic";
2
+ export type StringList = string | string[];
3
+ export interface Expect {
4
+ contains?: StringList;
5
+ not_contains?: StringList;
6
+ regex?: StringList;
7
+ max_tokens?: number;
8
+ }
9
+ export interface Case {
10
+ id: string;
11
+ prompt: string;
12
+ system?: string;
13
+ model?: string;
14
+ expect: Expect;
15
+ }
16
+ export interface Suite {
17
+ name?: string;
18
+ model?: string;
19
+ provider?: ProviderName;
20
+ system?: string;
21
+ cases: Case[];
22
+ }
23
+ export interface CompleteRequest {
24
+ prompt: string;
25
+ system?: string;
26
+ model: string;
27
+ maxTokens?: number;
28
+ signal: AbortSignal;
29
+ }
30
+ export type CompleteFn = (request: CompleteRequest) => Promise<string>;
31
+ export interface CheckResult {
32
+ name: "contains" | "not_contains" | "regex" | "max_tokens";
33
+ ok: boolean;
34
+ expected: string;
35
+ detail?: string;
36
+ }
37
+ export interface CaseResult {
38
+ id: string;
39
+ ok: boolean;
40
+ skipped?: boolean;
41
+ duration_ms: number;
42
+ output?: string;
43
+ error?: string;
44
+ checks?: CheckResult[];
45
+ }
46
+ export interface Report {
47
+ ok: boolean;
48
+ version: string;
49
+ runner: ProviderName;
50
+ model: string;
51
+ suite?: string;
52
+ passed: number;
53
+ failed: number;
54
+ skipped: number;
55
+ duration_ms: number;
56
+ cases: CaseResult[];
57
+ }
58
+ export interface RunOptions {
59
+ mock?: boolean;
60
+ provider?: ProviderName;
61
+ model?: string;
62
+ failFast?: boolean;
63
+ timeoutMs?: number;
64
+ complete?: CompleteFn;
65
+ env?: NodeJS.ProcessEnv;
66
+ fetch?: typeof fetch;
67
+ }
68
+ export declare class UsageError extends Error {
69
+ readonly exitCode = 2;
70
+ constructor(message: string);
71
+ }
72
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE3D,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;AAE3C,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,YAAY,CAAC,EAAE,UAAU,CAAC;IAC1B,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,KAAK;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAEvE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,UAAU,GAAG,cAAc,GAAG,OAAO,GAAG,YAAY,CAAC;IAC3D,EAAE,EAAE,OAAO,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,YAAY,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,UAAU,CAAC;IACtB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;CACtB;AAED,qBAAa,UAAW,SAAQ,KAAK;IACnC,QAAQ,CAAC,QAAQ,KAAK;gBACV,OAAO,EAAE,MAAM;CAI5B"}
package/dist/types.js ADDED
@@ -0,0 +1,8 @@
1
+ export class UsageError extends Error {
2
+ exitCode = 2;
3
+ constructor(message) {
4
+ super(message);
5
+ this.name = "UsageError";
6
+ }
7
+ }
8
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AA8EA,MAAM,OAAO,UAAW,SAAQ,KAAK;IAC1B,QAAQ,GAAG,CAAC,CAAC;IACtB,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;IAC3B,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export declare const VERSION: string;
2
+ //# sourceMappingURL=version.d.ts.map