1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
- import invariant from 'tiny-invariant';
- import assertions from './assertions';
- import providers, { loadApiProvider } from './providers';
- import telemetry from './telemetry';
- import { disableCache } from './cache';
- import { evaluate as doEvaluate } from './evaluator';
- import { loadApiProviders } from './providers';
- import { readTests } from './testCases';
- import {
- readFilters,
- writeResultsToDatabase,
- writeMultipleOutputs,
- writeOutput,
- migrateResultsFromFileSystemToDatabase,
- } from './util';
- import type {
- EvaluateOptions,
- TestSuite,
- EvaluateTestSuite,
- ProviderOptions,
- PromptFunction,
- } from './types';
- import { readPrompts } from './prompts';
- export * from './types';
- export { generateTable } from './table';
- async function evaluate(testSuite: EvaluateTestSuite, options: EvaluateOptions = {}) {
- const constructedTestSuite: TestSuite = {
- ...testSuite,
- providers: await loadApiProviders(testSuite.providers, {
- env: testSuite.env,
- }),
- tests: await readTests(testSuite.tests),
- nunjucksFilters: await readFilters(testSuite.nunjucksFilters || {}),
- // Full prompts expected (not filepaths)
- prompts: (
- await Promise.all(
- testSuite.prompts.map(async (promptInput) => {
- if (typeof promptInput === 'function') {
- return {
- raw: promptInput.toString(),
- label: promptInput.toString(),
- function: promptInput as PromptFunction,
- };
- } else if (typeof promptInput === 'string') {
- const prompts = await readPrompts(promptInput);
- return prompts.map((p) => ({
- raw: p.raw,
- label: p.label,
- }));
- } else {
- return {
- raw: JSON.stringify(promptInput),
- label: JSON.stringify(promptInput),
- };
- }
- }),
- )
- ).flat(),
- };
- // Resolve nested providers
- for (const test of constructedTestSuite.tests || []) {
- if (test.options?.provider && typeof test.options.provider === 'function') {
- test.options.provider = await loadApiProvider(test.options.provider);
- }
- if (test.assert) {
- for (const assertion of test.assert) {
- if (assertion.type === 'assert-set' || typeof assertion.provider === 'function') {
- continue;
- }
- if (assertion.provider) {
- if (typeof assertion.provider === 'object') {
- const casted = assertion.provider as ProviderOptions;
- invariant(casted.id, 'Provider object must have an id');
- assertion.provider = await loadApiProvider(casted.id, { options: casted });
- } else if (typeof assertion.provider === 'string') {
- assertion.provider = await loadApiProvider(assertion.provider);
- } else {
- throw new Error('Invalid provider type');
- }
- }
- }
- }
- }
- // Other settings
- if (options.cache === false || (options.repeat && options.repeat > 1)) {
- disableCache();
- }
- telemetry.maybeShowNotice();
- // Run the eval!
- const ret = await doEvaluate(constructedTestSuite, {
- eventSource: 'library',
- ...options,
- });
- if (testSuite.outputPath) {
- if (typeof testSuite.outputPath === 'string') {
- await writeOutput(testSuite.outputPath, ret, testSuite, null);
- } else if (Array.isArray(testSuite.outputPath)) {
- await writeMultipleOutputs(testSuite.outputPath, ret, testSuite, null);
- }
- }
- if (testSuite.writeLatestResults) {
- await migrateResultsFromFileSystemToDatabase();
- await writeResultsToDatabase(ret, testSuite);
- }
- await telemetry.send();
- return ret;
- }
- export { evaluate, assertions, providers };
- export default {
- evaluate,
- assertions,
- providers,
- };
|