@rudderjs/ai 1.4.0 → 1.6.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.
- package/README.md +484 -7
- package/boost/guidelines.md +62 -2
- package/boost/skills/ai-tools/SKILL.md +14 -5
- package/dist/agent.d.ts +66 -15
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +529 -58
- package/dist/agent.js.map +1 -1
- package/dist/budget/pricing.d.ts +124 -0
- package/dist/budget/pricing.d.ts.map +1 -0
- package/dist/budget/pricing.js +175 -0
- package/dist/budget/pricing.js.map +1 -0
- package/dist/budget/storage.d.ts +104 -0
- package/dist/budget/storage.d.ts.map +1 -0
- package/dist/budget/storage.js +0 -0
- package/dist/budget/storage.js.map +1 -0
- package/dist/budget/with-budget.d.ts +119 -0
- package/dist/budget/with-budget.d.ts.map +1 -0
- package/dist/budget/with-budget.js +175 -0
- package/dist/budget/with-budget.js.map +1 -0
- package/dist/budget-orm/index.d.ts +96 -0
- package/dist/budget-orm/index.d.ts.map +1 -0
- package/dist/budget-orm/index.js +177 -0
- package/dist/budget-orm/index.js.map +1 -0
- package/dist/commands/ai-eval.d.ts +93 -0
- package/dist/commands/ai-eval.d.ts.map +1 -0
- package/dist/commands/ai-eval.js +378 -0
- package/dist/commands/ai-eval.js.map +1 -0
- package/dist/computer-use/actions.d.ts +214 -0
- package/dist/computer-use/actions.d.ts.map +1 -0
- package/dist/computer-use/actions.js +48 -0
- package/dist/computer-use/actions.js.map +1 -0
- package/dist/computer-use/errors.d.ts +57 -0
- package/dist/computer-use/errors.d.ts.map +1 -0
- package/dist/computer-use/errors.js +76 -0
- package/dist/computer-use/errors.js.map +1 -0
- package/dist/computer-use/index.d.ts +53 -0
- package/dist/computer-use/index.d.ts.map +1 -0
- package/dist/computer-use/index.js +51 -0
- package/dist/computer-use/index.js.map +1 -0
- package/dist/computer-use/playwright.d.ts +76 -0
- package/dist/computer-use/playwright.d.ts.map +1 -0
- package/dist/computer-use/playwright.js +270 -0
- package/dist/computer-use/playwright.js.map +1 -0
- package/dist/computer-use/tool.d.ts +154 -0
- package/dist/computer-use/tool.d.ts.map +1 -0
- package/dist/computer-use/tool.js +210 -0
- package/dist/computer-use/tool.js.map +1 -0
- package/dist/eval/fixtures.d.ts +65 -0
- package/dist/eval/fixtures.d.ts.map +1 -0
- package/dist/eval/fixtures.js +110 -0
- package/dist/eval/fixtures.js.map +1 -0
- package/dist/eval/html-reporter.d.ts +25 -0
- package/dist/eval/html-reporter.d.ts.map +1 -0
- package/dist/eval/html-reporter.js +209 -0
- package/dist/eval/html-reporter.js.map +1 -0
- package/dist/eval/index.d.ts +271 -0
- package/dist/eval/index.d.ts.map +1 -0
- package/dist/eval/index.js +510 -0
- package/dist/eval/index.js.map +1 -0
- package/dist/eval/json-reporter.d.ts +43 -0
- package/dist/eval/json-reporter.d.ts.map +1 -0
- package/dist/eval/json-reporter.js +40 -0
- package/dist/eval/json-reporter.js.map +1 -0
- package/dist/fake.d.ts +36 -1
- package/dist/fake.d.ts.map +1 -1
- package/dist/fake.js +49 -2
- package/dist/fake.js.map +1 -1
- package/dist/file-search.d.ts +168 -0
- package/dist/file-search.d.ts.map +1 -0
- package/dist/file-search.js +158 -0
- package/dist/file-search.js.map +1 -0
- package/dist/handoff.d.ts +95 -0
- package/dist/handoff.d.ts.map +1 -0
- package/dist/handoff.js +78 -0
- package/dist/handoff.js.map +1 -0
- package/dist/index.d.ts +29 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -2
- package/dist/index.js.map +1 -1
- package/dist/mcp/client-tools.d.ts +39 -0
- package/dist/mcp/client-tools.d.ts.map +1 -0
- package/dist/mcp/client-tools.js +147 -0
- package/dist/mcp/client-tools.js.map +1 -0
- package/dist/mcp/index.d.ts +16 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +15 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/server-from-agent.d.ts +24 -0
- package/dist/mcp/server-from-agent.d.ts.map +1 -0
- package/dist/mcp/server-from-agent.js +113 -0
- package/dist/mcp/server-from-agent.js.map +1 -0
- package/dist/mcp/types.d.ts +64 -0
- package/dist/mcp/types.d.ts.map +1 -0
- package/dist/mcp/types.js +6 -0
- package/dist/mcp/types.js.map +1 -0
- package/dist/memory-embedding/index.d.ts +121 -0
- package/dist/memory-embedding/index.d.ts.map +1 -0
- package/dist/memory-embedding/index.js +229 -0
- package/dist/memory-embedding/index.js.map +1 -0
- package/dist/memory-extract.d.ts +60 -0
- package/dist/memory-extract.d.ts.map +1 -0
- package/dist/memory-extract.js +163 -0
- package/dist/memory-extract.js.map +1 -0
- package/dist/memory-inject.d.ts +39 -0
- package/dist/memory-inject.d.ts.map +1 -0
- package/dist/memory-inject.js +135 -0
- package/dist/memory-inject.js.map +1 -0
- package/dist/memory-orm/index.d.ts +118 -0
- package/dist/memory-orm/index.d.ts.map +1 -0
- package/dist/memory-orm/index.js +187 -0
- package/dist/memory-orm/index.js.map +1 -0
- package/dist/memory.d.ts +55 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +132 -0
- package/dist/memory.js.map +1 -0
- package/dist/observers.d.ts +22 -0
- package/dist/observers.d.ts.map +1 -1
- package/dist/observers.js.map +1 -1
- package/dist/provider-tools.d.ts +15 -1
- package/dist/provider-tools.d.ts.map +1 -1
- package/dist/provider-tools.js +21 -1
- package/dist/provider-tools.js.map +1 -1
- package/dist/providers/anthropic.d.ts +9 -1
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +66 -11
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/bedrock.d.ts +60 -0
- package/dist/providers/bedrock.d.ts.map +1 -0
- package/dist/providers/bedrock.js +167 -0
- package/dist/providers/bedrock.js.map +1 -0
- package/dist/providers/elevenlabs.d.ts +98 -0
- package/dist/providers/elevenlabs.d.ts.map +1 -0
- package/dist/providers/elevenlabs.js +229 -0
- package/dist/providers/elevenlabs.js.map +1 -0
- package/dist/providers/google.d.ts +83 -1
- package/dist/providers/google.d.ts.map +1 -1
- package/dist/providers/google.js +491 -8
- package/dist/providers/google.js.map +1 -1
- package/dist/providers/openai.d.ts +8 -1
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +215 -5
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/openrouter.d.ts +43 -0
- package/dist/providers/openrouter.d.ts.map +1 -0
- package/dist/providers/openrouter.js +21 -0
- package/dist/providers/openrouter.js.map +1 -0
- package/dist/providers/voyage.d.ts +91 -0
- package/dist/providers/voyage.d.ts.map +1 -0
- package/dist/providers/voyage.js +166 -0
- package/dist/providers/voyage.js.map +1 -0
- package/dist/queue-job.d.ts +69 -4
- package/dist/queue-job.d.ts.map +1 -1
- package/dist/queue-job.js +114 -11
- package/dist/queue-job.js.map +1 -1
- package/dist/registry.d.ts +3 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +10 -0
- package/dist/registry.js.map +1 -1
- package/dist/server/provider.d.ts.map +1 -1
- package/dist/server/provider.js +38 -1
- package/dist/server/provider.js.map +1 -1
- package/dist/similarity-search.d.ts +163 -0
- package/dist/similarity-search.d.ts.map +1 -0
- package/dist/similarity-search.js +147 -0
- package/dist/similarity-search.js.map +1 -0
- package/dist/sub-agent-run-store.d.ts +40 -3
- package/dist/sub-agent-run-store.d.ts.map +1 -1
- package/dist/sub-agent-run-store.js.map +1 -1
- package/dist/tool.d.ts +59 -0
- package/dist/tool.d.ts.map +1 -1
- package/dist/tool.js +45 -4
- package/dist/tool.js.map +1 -1
- package/dist/types.d.ts +285 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/vector-stores/index.d.ts +96 -0
- package/dist/vector-stores/index.d.ts.map +1 -0
- package/dist/vector-stores/index.js +153 -0
- package/dist/vector-stores/index.js.map +1 -0
- package/package.json +43 -4
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fixture I/O for `pnpm rudder ai:eval --record` / `--replay` (#A5
|
|
3
|
+
* Phase 4). Each case writes one JSON file under
|
|
4
|
+
* `evals/__fixtures__/<suite>/<case>.json` carrying the assistant
|
|
5
|
+
* turns from a real provider run, normalized into the
|
|
6
|
+
* {@link AiFakeStep} shape so `--replay` can re-feed them via
|
|
7
|
+
* `AiFake.respondWithSequence` for zero-API regression tests.
|
|
8
|
+
*
|
|
9
|
+
* The fixture format is versioned. Bumping `version` forces a
|
|
10
|
+
* re-record on stale fixtures rather than silently mis-replaying.
|
|
11
|
+
*/
|
|
12
|
+
import type { AgentResponse } from '../types.js';
|
|
13
|
+
import type { AiFakeStep } from '../fake.js';
|
|
14
|
+
/** Fixture format. Bump `version` when the shape changes incompatibly. */
|
|
15
|
+
export interface EvalFixture {
|
|
16
|
+
version: 1;
|
|
17
|
+
suite: string;
|
|
18
|
+
case: string;
|
|
19
|
+
input: string;
|
|
20
|
+
recordedAt: string;
|
|
21
|
+
steps: AiFakeStep[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Convert an `AgentResponse` into the assistant-turn `AiFakeStep[]`
|
|
25
|
+
* sequence that `AiFake.respondWithSequence` expects.
|
|
26
|
+
*
|
|
27
|
+
* - Drops user/tool turns — those are framework-generated during a
|
|
28
|
+
* replayed run, not provider output.
|
|
29
|
+
* - Multi-modal assistant content collapses to its concatenated text
|
|
30
|
+
* parts (the fake's transport is text-only; image/document parts
|
|
31
|
+
* wouldn't replay meaningfully).
|
|
32
|
+
* - `toolCalls` carry through verbatim so multi-step tool loops
|
|
33
|
+
* replay deterministically.
|
|
34
|
+
*/
|
|
35
|
+
export declare function stepsFromResponse(response: AgentResponse): AiFakeStep[];
|
|
36
|
+
/**
|
|
37
|
+
* Default fixtures directory: `<cwd>/evals/__fixtures__`. Override
|
|
38
|
+
* via the CLI handler's options for tests / non-standard layouts.
|
|
39
|
+
*/
|
|
40
|
+
export declare function defaultFixturesDir(cwd: string): string;
|
|
41
|
+
/**
|
|
42
|
+
* Filesystem-safe slug for `<suite>/<case>` segments. Letters,
|
|
43
|
+
* digits, dot, dash, underscore pass through; everything else
|
|
44
|
+
* collapses to `-`. Multiple consecutive `-` collapse to one.
|
|
45
|
+
*
|
|
46
|
+
* Pure function; tested directly so suite/case rename diffs stay
|
|
47
|
+
* predictable across editors.
|
|
48
|
+
*/
|
|
49
|
+
export declare function slugify(s: string): string;
|
|
50
|
+
export declare function fixturePath(dir: string, suite: string, caseName: string): string;
|
|
51
|
+
/**
|
|
52
|
+
* Read a fixture file. Returns `null` when the fixture is missing
|
|
53
|
+
* (replay falls back to running normally with a clear stderr line).
|
|
54
|
+
*
|
|
55
|
+
* Throws on parse / version errors — corruption is not a passing
|
|
56
|
+
* case and silently ignoring it would mask real regressions.
|
|
57
|
+
*/
|
|
58
|
+
export declare function readFixture(dir: string, suite: string, caseName: string): Promise<EvalFixture | null>;
|
|
59
|
+
/**
|
|
60
|
+
* Write a fixture, creating intermediate directories as needed.
|
|
61
|
+
* Pretty-printed (2-space) so PR diffs remain readable when the
|
|
62
|
+
* model output evolves.
|
|
63
|
+
*/
|
|
64
|
+
export declare function writeFixture(dir: string, suite: string, caseName: string, payload: Omit<EvalFixture, 'version' | 'suite' | 'case' | 'recordedAt'>): Promise<string>;
|
|
65
|
+
//# sourceMappingURL=fixtures.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixtures.d.ts","sourceRoot":"","sources":["../../src/eval/fixtures.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAe,MAAM,aAAa,CAAA;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAE5C,0EAA0E;AAC1E,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAK,CAAC,CAAA;IACb,KAAK,EAAO,MAAM,CAAA;IAClB,IAAI,EAAQ,MAAM,CAAA;IAClB,KAAK,EAAO,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,KAAK,EAAO,UAAU,EAAE,CAAA;CACzB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,aAAa,GAAG,UAAU,EAAE,CAWvE;AASD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAEtD;AAED;;;;;;;GAOG;AACH,wBAAgB,OAAO,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAEzC;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEhF;AAID;;;;;;GAMG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAO,MAAM,EAChB,KAAK,EAAK,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAiB7B;AAED;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAO,MAAM,EAChB,KAAK,EAAK,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAG,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,YAAY,CAAC,GACvE,OAAO,CAAC,MAAM,CAAC,CAYjB"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fixture I/O for `pnpm rudder ai:eval --record` / `--replay` (#A5
|
|
3
|
+
* Phase 4). Each case writes one JSON file under
|
|
4
|
+
* `evals/__fixtures__/<suite>/<case>.json` carrying the assistant
|
|
5
|
+
* turns from a real provider run, normalized into the
|
|
6
|
+
* {@link AiFakeStep} shape so `--replay` can re-feed them via
|
|
7
|
+
* `AiFake.respondWithSequence` for zero-API regression tests.
|
|
8
|
+
*
|
|
9
|
+
* The fixture format is versioned. Bumping `version` forces a
|
|
10
|
+
* re-record on stale fixtures rather than silently mis-replaying.
|
|
11
|
+
*/
|
|
12
|
+
import { mkdir, readFile, writeFile } from 'node:fs/promises';
|
|
13
|
+
import path from 'node:path';
|
|
14
|
+
/**
|
|
15
|
+
* Convert an `AgentResponse` into the assistant-turn `AiFakeStep[]`
|
|
16
|
+
* sequence that `AiFake.respondWithSequence` expects.
|
|
17
|
+
*
|
|
18
|
+
* - Drops user/tool turns — those are framework-generated during a
|
|
19
|
+
* replayed run, not provider output.
|
|
20
|
+
* - Multi-modal assistant content collapses to its concatenated text
|
|
21
|
+
* parts (the fake's transport is text-only; image/document parts
|
|
22
|
+
* wouldn't replay meaningfully).
|
|
23
|
+
* - `toolCalls` carry through verbatim so multi-step tool loops
|
|
24
|
+
* replay deterministically.
|
|
25
|
+
*/
|
|
26
|
+
export function stepsFromResponse(response) {
|
|
27
|
+
return response.steps
|
|
28
|
+
.filter(step => step.message.role === 'assistant')
|
|
29
|
+
.map(step => {
|
|
30
|
+
const out = {
|
|
31
|
+
text: contentToText(step.message.content),
|
|
32
|
+
finishReason: step.finishReason,
|
|
33
|
+
};
|
|
34
|
+
if (step.toolCalls.length > 0)
|
|
35
|
+
out.toolCalls = step.toolCalls;
|
|
36
|
+
return out;
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
function contentToText(content) {
|
|
40
|
+
if (typeof content === 'string')
|
|
41
|
+
return content;
|
|
42
|
+
return content.filter(p => p.type === 'text').map(p => p.text).join('');
|
|
43
|
+
}
|
|
44
|
+
// ─── Fixture path conventions ─────────────────────────────
|
|
45
|
+
/**
|
|
46
|
+
* Default fixtures directory: `<cwd>/evals/__fixtures__`. Override
|
|
47
|
+
* via the CLI handler's options for tests / non-standard layouts.
|
|
48
|
+
*/
|
|
49
|
+
export function defaultFixturesDir(cwd) {
|
|
50
|
+
return path.join(cwd, 'evals', '__fixtures__');
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Filesystem-safe slug for `<suite>/<case>` segments. Letters,
|
|
54
|
+
* digits, dot, dash, underscore pass through; everything else
|
|
55
|
+
* collapses to `-`. Multiple consecutive `-` collapse to one.
|
|
56
|
+
*
|
|
57
|
+
* Pure function; tested directly so suite/case rename diffs stay
|
|
58
|
+
* predictable across editors.
|
|
59
|
+
*/
|
|
60
|
+
export function slugify(s) {
|
|
61
|
+
return s.replace(/[^A-Za-z0-9._-]+/g, '-').replace(/^-+|-+$/g, '') || '_';
|
|
62
|
+
}
|
|
63
|
+
export function fixturePath(dir, suite, caseName) {
|
|
64
|
+
return path.join(dir, slugify(suite), `${slugify(caseName)}.json`);
|
|
65
|
+
}
|
|
66
|
+
// ─── Read / write ─────────────────────────────────────────
|
|
67
|
+
/**
|
|
68
|
+
* Read a fixture file. Returns `null` when the fixture is missing
|
|
69
|
+
* (replay falls back to running normally with a clear stderr line).
|
|
70
|
+
*
|
|
71
|
+
* Throws on parse / version errors — corruption is not a passing
|
|
72
|
+
* case and silently ignoring it would mask real regressions.
|
|
73
|
+
*/
|
|
74
|
+
export async function readFixture(dir, suite, caseName) {
|
|
75
|
+
const file = fixturePath(dir, suite, caseName);
|
|
76
|
+
let raw;
|
|
77
|
+
try {
|
|
78
|
+
raw = await readFile(file, 'utf8');
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
if (err.code === 'ENOENT')
|
|
82
|
+
return null;
|
|
83
|
+
throw err;
|
|
84
|
+
}
|
|
85
|
+
const parsed = JSON.parse(raw);
|
|
86
|
+
if (parsed.version !== 1) {
|
|
87
|
+
throw new Error(`[RudderJS AI] Fixture ${file} is version ${String(parsed.version)}; expected 1. ` +
|
|
88
|
+
`Re-record with \`pnpm rudder ai:eval --record\`.`);
|
|
89
|
+
}
|
|
90
|
+
return parsed;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Write a fixture, creating intermediate directories as needed.
|
|
94
|
+
* Pretty-printed (2-space) so PR diffs remain readable when the
|
|
95
|
+
* model output evolves.
|
|
96
|
+
*/
|
|
97
|
+
export async function writeFixture(dir, suite, caseName, payload) {
|
|
98
|
+
const file = fixturePath(dir, suite, caseName);
|
|
99
|
+
await mkdir(path.dirname(file), { recursive: true });
|
|
100
|
+
const fixture = {
|
|
101
|
+
version: 1,
|
|
102
|
+
suite,
|
|
103
|
+
case: caseName,
|
|
104
|
+
recordedAt: new Date().toISOString(),
|
|
105
|
+
...payload,
|
|
106
|
+
};
|
|
107
|
+
await writeFile(file, `${JSON.stringify(fixture, null, 2)}\n`);
|
|
108
|
+
return file;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=fixtures.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fixtures.js","sourceRoot":"","sources":["../../src/eval/fixtures.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-contained HTML reporter for `pnpm rudder ai:eval --html`
|
|
3
|
+
* (#A5 Phase 5). Renders one or more {@link SuiteReport}s into a
|
|
4
|
+
* single HTML string with inline styles and minimal vanilla JS for
|
|
5
|
+
* row expand/collapse — no framework deps, no external assets, safe
|
|
6
|
+
* to paste into a PR comment or open offline.
|
|
7
|
+
*
|
|
8
|
+
* Defensive HTML-escape on every piece of user content (suite name,
|
|
9
|
+
* case name, input, response, metadata). Long responses get a
|
|
10
|
+
* `<pre>` block with `white-space: pre-wrap` so output stays
|
|
11
|
+
* scannable without a horizontal scroll.
|
|
12
|
+
*/
|
|
13
|
+
import type { SuiteReport } from './index.js';
|
|
14
|
+
export interface HtmlReportOptions {
|
|
15
|
+
/** Document `<title>`. Defaults to `"Eval Report"`. */
|
|
16
|
+
title?: string;
|
|
17
|
+
/** ISO timestamp shown in the header. Defaults to `new Date().toISOString()`. */
|
|
18
|
+
generatedAt?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Render an array of {@link SuiteReport}s as a single self-contained
|
|
22
|
+
* HTML document.
|
|
23
|
+
*/
|
|
24
|
+
export declare function reportHtml(reports: SuiteReport[], opts?: HtmlReportOptions): string;
|
|
25
|
+
//# sourceMappingURL=html-reporter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-reporter.d.ts","sourceRoot":"","sources":["../../src/eval/html-reporter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAgB,MAAM,YAAY,CAAA;AAE3D,MAAM,WAAW,iBAAiB;IAChC,uDAAuD;IACvD,KAAK,CAAC,EAAQ,MAAM,CAAA;IACpB,iFAAiF;IACjF,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,IAAI,GAAE,iBAAsB,GAAG,MAAM,CA6CvF"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-contained HTML reporter for `pnpm rudder ai:eval --html`
|
|
3
|
+
* (#A5 Phase 5). Renders one or more {@link SuiteReport}s into a
|
|
4
|
+
* single HTML string with inline styles and minimal vanilla JS for
|
|
5
|
+
* row expand/collapse — no framework deps, no external assets, safe
|
|
6
|
+
* to paste into a PR comment or open offline.
|
|
7
|
+
*
|
|
8
|
+
* Defensive HTML-escape on every piece of user content (suite name,
|
|
9
|
+
* case name, input, response, metadata). Long responses get a
|
|
10
|
+
* `<pre>` block with `white-space: pre-wrap` so output stays
|
|
11
|
+
* scannable without a horizontal scroll.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* Render an array of {@link SuiteReport}s as a single self-contained
|
|
15
|
+
* HTML document.
|
|
16
|
+
*/
|
|
17
|
+
export function reportHtml(reports, opts = {}) {
|
|
18
|
+
const title = opts.title ?? 'Eval Report';
|
|
19
|
+
const generatedAt = opts.generatedAt ?? new Date().toISOString();
|
|
20
|
+
const totals = reports.reduce((a, r) => ({
|
|
21
|
+
cases: a.cases + r.cases.length,
|
|
22
|
+
passed: a.passed + r.passed,
|
|
23
|
+
failed: a.failed + r.failed,
|
|
24
|
+
skipped: a.skipped + r.skipped,
|
|
25
|
+
cost: a.cost + r.cost,
|
|
26
|
+
tokens: a.tokens + r.tokens,
|
|
27
|
+
duration: a.duration + r.duration,
|
|
28
|
+
}), { cases: 0, passed: 0, failed: 0, skipped: 0, cost: 0, tokens: 0, duration: 0 });
|
|
29
|
+
const passRate = totals.cases > 0 ? Math.round((totals.passed / totals.cases) * 100) : 0;
|
|
30
|
+
return `<!DOCTYPE html>
|
|
31
|
+
<html lang="en">
|
|
32
|
+
<head>
|
|
33
|
+
<meta charset="UTF-8">
|
|
34
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
35
|
+
<title>${escapeHtml(title)}</title>
|
|
36
|
+
<style>${STYLE}</style>
|
|
37
|
+
</head>
|
|
38
|
+
<body>
|
|
39
|
+
<header class="page-header">
|
|
40
|
+
<h1>${escapeHtml(title)}</h1>
|
|
41
|
+
<div class="meta">
|
|
42
|
+
Generated ${escapeHtml(generatedAt)} ·
|
|
43
|
+
${reports.length} suite${plural(reports.length)} ·
|
|
44
|
+
${totals.cases} case${plural(totals.cases)} ·
|
|
45
|
+
<strong class="${passRate === 100 ? 'ok' : passRate >= 80 ? 'warn' : 'bad'}">${passRate}% pass</strong> ·
|
|
46
|
+
${formatCost(totals.cost)} ·
|
|
47
|
+
${totals.tokens.toLocaleString()} tokens ·
|
|
48
|
+
${formatMs(totals.duration)}
|
|
49
|
+
</div>
|
|
50
|
+
</header>
|
|
51
|
+
${reports.map(renderSuite).join('\n')}
|
|
52
|
+
<script>${SCRIPT}</script>
|
|
53
|
+
</body>
|
|
54
|
+
</html>
|
|
55
|
+
`;
|
|
56
|
+
}
|
|
57
|
+
function renderSuite(r) {
|
|
58
|
+
const passRate = r.cases.length > 0 ? Math.round((r.passed / r.cases.length) * 100) : 0;
|
|
59
|
+
return `<section class="suite">
|
|
60
|
+
<header class="suite-header">
|
|
61
|
+
<h2>${escapeHtml(r.suite)}</h2>
|
|
62
|
+
<div class="suite-stats">
|
|
63
|
+
<span class="${passRate === 100 ? 'ok' : passRate >= 80 ? 'warn' : 'bad'}">${r.passed}/${r.cases.length} passed</span>
|
|
64
|
+
${r.skipped > 0 ? `· <span class="muted">${r.skipped} skipped</span>` : ''}
|
|
65
|
+
· ${formatCost(r.cost)}
|
|
66
|
+
· ${r.tokens.toLocaleString()} tokens
|
|
67
|
+
· ${formatMs(r.duration)}
|
|
68
|
+
</div>
|
|
69
|
+
${renderMetadata(r.metadata)}
|
|
70
|
+
</header>
|
|
71
|
+
<table class="cases">
|
|
72
|
+
<thead>
|
|
73
|
+
<tr>
|
|
74
|
+
<th>Case</th>
|
|
75
|
+
<th>Status</th>
|
|
76
|
+
<th class="num">Tokens</th>
|
|
77
|
+
<th class="num">Cost</th>
|
|
78
|
+
<th class="num">Duration</th>
|
|
79
|
+
</tr>
|
|
80
|
+
</thead>
|
|
81
|
+
<tbody>
|
|
82
|
+
${r.cases.map(renderCase).join('\n')}
|
|
83
|
+
</tbody>
|
|
84
|
+
</table>
|
|
85
|
+
</section>`;
|
|
86
|
+
}
|
|
87
|
+
function renderCase(c) {
|
|
88
|
+
const glyph = c.status === 'passed' ? '✓' : c.status === 'failed' ? '✗' : '○';
|
|
89
|
+
const responseBlock = c.responseText !== undefined
|
|
90
|
+
? `<h4>Response</h4><pre>${escapeHtml(c.responseText)}</pre>`
|
|
91
|
+
: '<h4>Response</h4><pre class="muted"><no response — agent threw or skipped></pre>';
|
|
92
|
+
const reasonBlock = (c.metric?.reason ?? c.reason)
|
|
93
|
+
? `<h4>Reason</h4><pre>${escapeHtml(c.metric?.reason ?? c.reason)}</pre>`
|
|
94
|
+
: '';
|
|
95
|
+
const scoreBlock = c.metric?.score !== undefined
|
|
96
|
+
? `<h4>Score</h4><pre>${c.metric.score.toFixed(3)}</pre>`
|
|
97
|
+
: '';
|
|
98
|
+
return ` <tr class="case ${c.status}" tabindex="0" aria-expanded="false">
|
|
99
|
+
<td><span class="glyph">${glyph}</span> ${escapeHtml(c.name)}</td>
|
|
100
|
+
<td><span class="badge ${c.status}">${c.status}</span></td>
|
|
101
|
+
<td class="num">${c.tokens.toLocaleString()}</td>
|
|
102
|
+
<td class="num">${formatCost(c.cost)}</td>
|
|
103
|
+
<td class="num">${formatMs(c.duration)}</td>
|
|
104
|
+
</tr>
|
|
105
|
+
<tr class="case-detail" hidden>
|
|
106
|
+
<td colspan="5">
|
|
107
|
+
<h4>Input</h4>
|
|
108
|
+
<pre>${escapeHtml(c.input)}</pre>
|
|
109
|
+
${responseBlock}
|
|
110
|
+
${scoreBlock}
|
|
111
|
+
${reasonBlock}
|
|
112
|
+
</td>
|
|
113
|
+
</tr>`;
|
|
114
|
+
}
|
|
115
|
+
function renderMetadata(meta) {
|
|
116
|
+
if (!meta)
|
|
117
|
+
return '';
|
|
118
|
+
const rows = Object.entries(meta).filter(([, v]) => v !== undefined && v !== '');
|
|
119
|
+
if (rows.length === 0)
|
|
120
|
+
return '';
|
|
121
|
+
return `<dl class="metadata">${rows.map(([k, v]) => `<dt>${escapeHtml(formatLabel(k))}</dt><dd>${escapeHtml(v)}</dd>`).join('')}</dl>`;
|
|
122
|
+
}
|
|
123
|
+
function formatLabel(key) {
|
|
124
|
+
// camelCase → Title Case for the well-known keys; pass others through.
|
|
125
|
+
if (key === 'lastReviewed')
|
|
126
|
+
return 'Last reviewed';
|
|
127
|
+
return key.charAt(0).toUpperCase() + key.slice(1);
|
|
128
|
+
}
|
|
129
|
+
// ─── HTML escape (no external dep) ───────────────────────
|
|
130
|
+
const ESCAPE_MAP = {
|
|
131
|
+
'&': '&',
|
|
132
|
+
'<': '<',
|
|
133
|
+
'>': '>',
|
|
134
|
+
'"': '"',
|
|
135
|
+
"'": ''',
|
|
136
|
+
};
|
|
137
|
+
function escapeHtml(s) {
|
|
138
|
+
return s.replace(/[&<>"']/g, ch => ESCAPE_MAP[ch]);
|
|
139
|
+
}
|
|
140
|
+
function plural(n) {
|
|
141
|
+
return n === 1 ? '' : 's';
|
|
142
|
+
}
|
|
143
|
+
function formatMs(ms) {
|
|
144
|
+
if (ms < 1000)
|
|
145
|
+
return `${Math.round(ms)}ms`;
|
|
146
|
+
return `${(ms / 1000).toFixed(1)}s`;
|
|
147
|
+
}
|
|
148
|
+
function formatCost(usd) {
|
|
149
|
+
if (usd === 0)
|
|
150
|
+
return '$0.000';
|
|
151
|
+
if (usd < 0.001)
|
|
152
|
+
return '<$0.001';
|
|
153
|
+
return `$${usd.toFixed(3)}`;
|
|
154
|
+
}
|
|
155
|
+
// ─── Inline assets ────────────────────────────────────────
|
|
156
|
+
const STYLE = `
|
|
157
|
+
:root { color-scheme: light dark; --fg: #1a1a1a; --bg: #fff; --muted: #6a6a6a; --border: #e2e2e2; --row-hover: #f7f7f7; --ok: #1a7f37; --warn: #b08800; --bad: #b91c1c; --pre-bg: #f6f8fa; }
|
|
158
|
+
@media (prefers-color-scheme: dark) {
|
|
159
|
+
:root { --fg: #e6e6e6; --bg: #0d1117; --muted: #8a8a8a; --border: #30363d; --row-hover: #161b22; --ok: #3fb950; --warn: #d29922; --bad: #f85149; --pre-bg: #161b22; }
|
|
160
|
+
}
|
|
161
|
+
* { box-sizing: border-box }
|
|
162
|
+
body { font: 14px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif; color: var(--fg); background: var(--bg); margin: 0; padding: 24px; max-width: 1100px; margin-inline: auto }
|
|
163
|
+
h1 { margin: 0 0 4px; font-size: 24px }
|
|
164
|
+
h2 { margin: 0 0 4px; font-size: 18px }
|
|
165
|
+
h4 { margin: 12px 0 4px; font-size: 12px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted) }
|
|
166
|
+
pre { background: var(--pre-bg); border: 1px solid var(--border); border-radius: 6px; padding: 8px 12px; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word; font: 12px/1.45 ui-monospace,SFMono-Regular,Menlo,monospace; margin: 0 }
|
|
167
|
+
.page-header { border-bottom: 1px solid var(--border); padding-bottom: 12px; margin-bottom: 20px }
|
|
168
|
+
.page-header .meta { color: var(--muted); font-size: 13px }
|
|
169
|
+
.suite { margin-bottom: 28px }
|
|
170
|
+
.suite-header h2 { display: inline }
|
|
171
|
+
.suite-stats { color: var(--muted); font-size: 13px; margin-top: 4px }
|
|
172
|
+
.metadata { display: grid; grid-template-columns: max-content 1fr; gap: 4px 12px; margin: 8px 0 0; font-size: 13px }
|
|
173
|
+
.metadata dt { color: var(--muted); font-weight: normal }
|
|
174
|
+
.metadata dd { margin: 0 }
|
|
175
|
+
.cases { width: 100%; border-collapse: collapse; margin-top: 12px; border: 1px solid var(--border); border-radius: 6px; overflow: hidden }
|
|
176
|
+
.cases th, .cases td { padding: 8px 12px; text-align: left; border-bottom: 1px solid var(--border) }
|
|
177
|
+
.cases th { background: var(--pre-bg); font-weight: 600; font-size: 12px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted) }
|
|
178
|
+
.cases tr:last-child td { border-bottom: none }
|
|
179
|
+
.cases tr.case { cursor: pointer; user-select: none }
|
|
180
|
+
.cases tr.case:hover { background: var(--row-hover) }
|
|
181
|
+
.cases tr.case:focus { outline: 2px solid var(--warn); outline-offset: -2px }
|
|
182
|
+
.cases tr.case-detail td { background: var(--pre-bg) }
|
|
183
|
+
.cases td.num { text-align: right; font-variant-numeric: tabular-nums }
|
|
184
|
+
.glyph { display: inline-block; width: 14px; font-weight: bold }
|
|
185
|
+
.cases tr.case.passed .glyph { color: var(--ok) }
|
|
186
|
+
.cases tr.case.failed .glyph { color: var(--bad) }
|
|
187
|
+
.cases tr.case.skipped .glyph { color: var(--muted) }
|
|
188
|
+
.badge { display: inline-block; padding: 1px 8px; border-radius: 999px; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em }
|
|
189
|
+
.badge.passed { background: rgba(63,185,80,.15); color: var(--ok) }
|
|
190
|
+
.badge.failed { background: rgba(248,81,73,.15); color: var(--bad) }
|
|
191
|
+
.badge.skipped { background: rgba(138,138,138,.15); color: var(--muted) }
|
|
192
|
+
.ok { color: var(--ok) } .warn { color: var(--warn) } .bad { color: var(--bad) } .muted { color: var(--muted) }
|
|
193
|
+
`.trim();
|
|
194
|
+
const SCRIPT = `
|
|
195
|
+
document.querySelectorAll('tr.case').forEach(function(row) {
|
|
196
|
+
function toggle() {
|
|
197
|
+
var detail = row.nextElementSibling;
|
|
198
|
+
if (!detail || !detail.classList.contains('case-detail')) return;
|
|
199
|
+
var open = !detail.hidden;
|
|
200
|
+
detail.hidden = open;
|
|
201
|
+
row.setAttribute('aria-expanded', String(!open));
|
|
202
|
+
}
|
|
203
|
+
row.addEventListener('click', toggle);
|
|
204
|
+
row.addEventListener('keydown', function(e) {
|
|
205
|
+
if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); toggle(); }
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
`.trim();
|
|
209
|
+
//# sourceMappingURL=html-reporter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"html-reporter.js","sourceRoot":"","sources":["../../src/eval/html-reporter.ts"],"names":[],"mappings":"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"}
|