evaliphy 1.0.1-beta.2 → 1.0.1-beta.4
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/dist/bin.mjs +139 -54
- package/dist/index.cjs +17 -3
- package/dist/index.mjs +17 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +17 -17
package/dist/bin.mjs
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
|
-
import fs, { existsSync
|
|
3
|
+
import fs, { existsSync } from "node:fs";
|
|
4
4
|
import path, { join } from "node:path";
|
|
5
5
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
6
6
|
import { pino } from "pino";
|
|
7
7
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
8
8
|
import { program } from "commander";
|
|
9
|
-
import fs$1 from "fs";
|
|
10
9
|
import path$1 from "path";
|
|
11
|
-
import {
|
|
10
|
+
import { fileURLToPath as fileURLToPath$1 } from "url";
|
|
12
11
|
import fg from "fast-glob";
|
|
12
|
+
import fs$1 from "fs";
|
|
13
13
|
import fs$2 from "node:fs/promises";
|
|
14
14
|
//#region \0rolldown/runtime.js
|
|
15
15
|
var __create = Object.create;
|
|
@@ -3744,7 +3744,14 @@ var ConfigLoader = class ConfigLoader {
|
|
|
3744
3744
|
const configPath = this.findConfigFile(cwd);
|
|
3745
3745
|
if (!configPath) {
|
|
3746
3746
|
this.configLogger.debug("No config file found, using defaults if applicable");
|
|
3747
|
-
throw new EvaliphyError(EvaliphyErrorCode.INVALID_CONFIG,
|
|
3747
|
+
throw new EvaliphyError(EvaliphyErrorCode.INVALID_CONFIG, `Could not load configuration. Please check the following:
|
|
3748
|
+
|
|
3749
|
+
- Does "evaliphy.config.ts" exist in your project root?
|
|
3750
|
+
- Is the path correct if you specified a custom config location?
|
|
3751
|
+
- Does the config file export a default defineConfig({}) call?
|
|
3752
|
+
|
|
3753
|
+
Expected location: ${process.cwd()}/evaliphy.config.ts
|
|
3754
|
+
Visit https://evaliphy.com/docs/configuration for more details.`);
|
|
3748
3755
|
}
|
|
3749
3756
|
if (!this.cachedConfig) {
|
|
3750
3757
|
this.configLogger.debug({ configPath }, "Loading base configuration from file");
|
|
@@ -3757,7 +3764,10 @@ var ConfigLoader = class ConfigLoader {
|
|
|
3757
3764
|
error: parsed.error,
|
|
3758
3765
|
configPath
|
|
3759
3766
|
}, "Configuration validation failed");
|
|
3760
|
-
throw new EvaliphyError(EvaliphyErrorCode.INVALID_CONFIG, `Invalid configuration in ${configPath}
|
|
3767
|
+
throw new EvaliphyError(EvaliphyErrorCode.INVALID_CONFIG, `Invalid configuration in ${configPath}
|
|
3768
|
+
|
|
3769
|
+
Please check your evaliphy.config.ts and fix the above fields.
|
|
3770
|
+
Docs: https://evaliphy.com/docs/configuration`);
|
|
3761
3771
|
}
|
|
3762
3772
|
this.cachedConfig = mergeConfigs(parsed.data, {}, this.cliOverrides);
|
|
3763
3773
|
this.cachedConfig.configFile = configPath;
|
|
@@ -3767,7 +3777,11 @@ var ConfigLoader = class ConfigLoader {
|
|
|
3767
3777
|
configPath
|
|
3768
3778
|
}, "Error loading configuration");
|
|
3769
3779
|
if (error instanceof EvaliphyError) throw error;
|
|
3770
|
-
throw new EvaliphyError(EvaliphyErrorCode.INVALID_CONFIG, `Failed to load config from ${configPath}: ${error.message}
|
|
3780
|
+
throw new EvaliphyError(EvaliphyErrorCode.INVALID_CONFIG, `Failed to load config from ${configPath}: ${error.message}
|
|
3781
|
+
|
|
3782
|
+
Please check your evaliphy.config.ts and fix the above fields.
|
|
3783
|
+
Docs: https://evaliphy.com/docs/configuration
|
|
3784
|
+
`);
|
|
3771
3785
|
}
|
|
3772
3786
|
}
|
|
3773
3787
|
const finalConfig = mergeConfigs(this.cachedConfig, transientOverrides, {});
|
|
@@ -4005,48 +4019,100 @@ function handleFatalError(err) {
|
|
|
4005
4019
|
}
|
|
4006
4020
|
//#endregion
|
|
4007
4021
|
//#region packages/cli/src/initProject/createFolderStructure.ts
|
|
4022
|
+
const require$1 = createRequire(import.meta.url);
|
|
4023
|
+
const green = (s) => `\x1b[32m${s}\x1b[0m`;
|
|
4024
|
+
const bold = (s) => `\x1b[1m${s}\x1b[0m`;
|
|
4025
|
+
const dim = (s) => `\x1b[2m${s}\x1b[0m`;
|
|
4026
|
+
const red = (s) => `\x1b[31m${s}\x1b[0m`;
|
|
4008
4027
|
function createProject(projectName) {
|
|
4009
|
-
const
|
|
4010
|
-
|
|
4011
|
-
|
|
4028
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
4029
|
+
const __dirname = path.dirname(__filename);
|
|
4030
|
+
const { version } = require$1(path.join(__dirname, "../package.json"));
|
|
4031
|
+
if (!/^[a-z0-9-_]+$/i.test(projectName)) {
|
|
4032
|
+
console.error(red(`\n ✗ Invalid project name "${projectName}".`));
|
|
4033
|
+
console.error(dim(" Use only letters, numbers, hyphens and underscores.\n"));
|
|
4034
|
+
process.exit(1);
|
|
4035
|
+
}
|
|
4036
|
+
const rootPath = path.join(process.cwd(), projectName);
|
|
4037
|
+
if (fs.existsSync(rootPath)) {
|
|
4038
|
+
console.error(red(`\n ✗ Directory "${projectName}" already exists.`));
|
|
4039
|
+
console.error(dim(` Choose a different name or remove the existing directory.\n`));
|
|
4012
4040
|
process.exit(1);
|
|
4013
4041
|
}
|
|
4014
|
-
|
|
4015
|
-
|
|
4016
|
-
evals: { "example.eval.ts": `
|
|
4017
|
-
|
|
4042
|
+
console.log(`\n Creating project ${bold(projectName)}...\n`);
|
|
4043
|
+
const structure = {
|
|
4044
|
+
evals: { "example.eval.ts": `import { evaluate, expect } from 'evaliphy';
|
|
4045
|
+
|
|
4046
|
+
/**
|
|
4047
|
+
* Example evaluation — replace this with your own RAG endpoint and samples.
|
|
4048
|
+
* Docs: https://evaliphy.com/docs/quick-start
|
|
4049
|
+
*/
|
|
4050
|
+
evaluate("context handling: multiple chunks", async ({ httpClient }) => {
|
|
4051
|
+
const query = "What are the support hours?";
|
|
4052
|
+
const context = [
|
|
4053
|
+
"Support is available 24/7 via email.",
|
|
4054
|
+
"Live chat support is open from 9 AM to 5 PM EST.",
|
|
4055
|
+
"Phone support is currently unavailable."
|
|
4056
|
+
];
|
|
4057
|
+
|
|
4058
|
+
const res = await httpClient.post("/api/generate", { prompt: query });
|
|
4059
|
+
const data = await res.json();
|
|
4018
4060
|
|
|
4019
|
-
|
|
4020
|
-
|
|
4061
|
+
await expect({
|
|
4062
|
+
query,
|
|
4063
|
+
response: data.content,
|
|
4064
|
+
context,
|
|
4065
|
+
}).toBeFaithful({ threshold: 0.7 });
|
|
4021
4066
|
});
|
|
4022
4067
|
` },
|
|
4023
|
-
|
|
4024
|
-
|
|
4025
|
-
|
|
4068
|
+
".env.example": `# Copy this file to .env and fill in your values
|
|
4069
|
+
OPENAI_API_KEY=your-api-key-here
|
|
4070
|
+
`,
|
|
4071
|
+
".gitignore": `.env
|
|
4072
|
+
node_modules
|
|
4073
|
+
dist
|
|
4074
|
+
results
|
|
4075
|
+
`,
|
|
4076
|
+
"evaliphy.config.ts": `import { defineConfig } from 'evaliphy';
|
|
4026
4077
|
|
|
4027
4078
|
export default defineConfig({
|
|
4028
|
-
|
|
4029
|
-
|
|
4079
|
+
http: {
|
|
4080
|
+
baseUrl: "http://localhost:8080",
|
|
4081
|
+
timeout: 10_000,
|
|
4082
|
+
},
|
|
4083
|
+
evalDir: './evals',
|
|
4030
4084
|
llmAsJudgeConfig: {
|
|
4031
4085
|
model: 'gpt-4o-mini',
|
|
4032
4086
|
provider: {
|
|
4033
|
-
type: '
|
|
4034
|
-
|
|
4035
|
-
apiKey: process.env.OPENROUTER_API_KEY,
|
|
4087
|
+
type: 'openai',
|
|
4088
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
4036
4089
|
},
|
|
4037
|
-
|
|
4038
|
-
temperature: 0
|
|
4090
|
+
temperature: 0,
|
|
4039
4091
|
},
|
|
4040
4092
|
});
|
|
4041
4093
|
`,
|
|
4042
|
-
"tsconfig.json": JSON.stringify({
|
|
4043
|
-
|
|
4044
|
-
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
|
|
4049
|
-
|
|
4094
|
+
"tsconfig.json": JSON.stringify({
|
|
4095
|
+
compilerOptions: {
|
|
4096
|
+
target: "ES2020",
|
|
4097
|
+
module: "ESNext",
|
|
4098
|
+
moduleResolution: "bundler",
|
|
4099
|
+
strict: true,
|
|
4100
|
+
esModuleInterop: true,
|
|
4101
|
+
skipLibCheck: true,
|
|
4102
|
+
outDir: "./dist"
|
|
4103
|
+
},
|
|
4104
|
+
include: ["**/*.ts"],
|
|
4105
|
+
exclude: ["node_modules", "dist"]
|
|
4106
|
+
}, null, 2)
|
|
4107
|
+
};
|
|
4108
|
+
try {
|
|
4109
|
+
fs.mkdirSync(rootPath, { recursive: true });
|
|
4110
|
+
createStructure(rootPath, structure);
|
|
4111
|
+
} catch (err) {
|
|
4112
|
+
console.error(red("\n ✗ Failed to create project files."));
|
|
4113
|
+
console.error(dim(` ${err.message}\n`));
|
|
4114
|
+
process.exit(1);
|
|
4115
|
+
}
|
|
4050
4116
|
const pkg = {
|
|
4051
4117
|
name: projectName,
|
|
4052
4118
|
version: "1.0.0",
|
|
@@ -4057,29 +4123,46 @@ export default defineConfig({
|
|
|
4057
4123
|
build: "tsc"
|
|
4058
4124
|
},
|
|
4059
4125
|
devDependencies: {
|
|
4060
|
-
"evaliphy":
|
|
4061
|
-
|
|
4126
|
+
"evaliphy": `^${version}`,
|
|
4127
|
+
typescript: "^5.0.0"
|
|
4062
4128
|
}
|
|
4063
4129
|
};
|
|
4064
|
-
fs$1.writeFileSync(path$1.join(rootPath, "package.json"), JSON.stringify(pkg, null, 2));
|
|
4065
4130
|
try {
|
|
4066
|
-
|
|
4067
|
-
execSync("npm install", {
|
|
4068
|
-
cwd: rootPath,
|
|
4069
|
-
stdio: "inherit"
|
|
4070
|
-
});
|
|
4131
|
+
fs.writeFileSync(path.join(rootPath, "package.json"), JSON.stringify(pkg, null, 2));
|
|
4071
4132
|
} catch (err) {
|
|
4072
|
-
console.error("Failed to
|
|
4133
|
+
console.error(red("\n ✗ Failed to write package.json."));
|
|
4134
|
+
console.error(dim(` ${err.message}\n`));
|
|
4135
|
+
process.exit(1);
|
|
4073
4136
|
}
|
|
4074
|
-
console.log(
|
|
4137
|
+
console.log(` ${green("✓")} evaliphy.config.ts`);
|
|
4138
|
+
console.log(` ${green("✓")} evals/example.eval.ts`);
|
|
4139
|
+
console.log(` ${green("✓")} .env.example`);
|
|
4140
|
+
console.log(` ${green("✓")} .gitignore`);
|
|
4141
|
+
console.log(` ${green("✓")} tsconfig.json`);
|
|
4142
|
+
console.log(` ${green("✓")} package.json`);
|
|
4143
|
+
console.log(`
|
|
4144
|
+
${green("✓")} ${bold(`Project "${projectName}" created successfully!`)}
|
|
4145
|
+
|
|
4146
|
+
${bold("Next steps:")}
|
|
4147
|
+
${dim("$")} Ensuer you have Node JS either v24.0.0 or higher.
|
|
4148
|
+
${dim("$")} cd ${projectName}
|
|
4149
|
+
${dim("$")} cp .env.example .env ${dim("← add your OPENAI_API_KEY")}
|
|
4150
|
+
${dim("$")} npm install
|
|
4151
|
+
${dim("$")} npm test
|
|
4152
|
+
|
|
4153
|
+
${dim(`Docs → https://evaliphy.com/docs`)}
|
|
4154
|
+
${dim(`Examples → https://evaliphy.com/docs/examples`)}
|
|
4155
|
+
`);
|
|
4075
4156
|
}
|
|
4076
4157
|
function createStructure(basePath, structure) {
|
|
4077
|
-
for (const name
|
|
4078
|
-
const fullPath = path
|
|
4079
|
-
if (typeof
|
|
4080
|
-
|
|
4081
|
-
fs
|
|
4082
|
-
|
|
4158
|
+
for (const [name, content] of Object.entries(structure)) {
|
|
4159
|
+
const fullPath = path.join(basePath, name);
|
|
4160
|
+
if (typeof content === "string") {
|
|
4161
|
+
fs.mkdirSync(path.dirname(fullPath), { recursive: true });
|
|
4162
|
+
fs.writeFileSync(fullPath, content, "utf8");
|
|
4163
|
+
} else {
|
|
4164
|
+
fs.mkdirSync(fullPath, { recursive: true });
|
|
4165
|
+
createStructure(fullPath, content);
|
|
4083
4166
|
}
|
|
4084
4167
|
}
|
|
4085
4168
|
}
|
|
@@ -31260,9 +31343,10 @@ var ConsoleReporter = class {
|
|
|
31260
31343
|
const duration = this.formatDuration(payload.duration);
|
|
31261
31344
|
console.log("\n" + this.getSeparator());
|
|
31262
31345
|
[
|
|
31263
|
-
import_picocolors.default.bold("Tests:
|
|
31264
|
-
import_picocolors.default.bold("Time:
|
|
31265
|
-
import_picocolors.default.bold("Run ID:
|
|
31346
|
+
import_picocolors.default.bold("Tests: ") + (payload.failed > 0 ? import_picocolors.default.red(`${payload.failed} failed`) + import_picocolors.default.dim(", ") : "") + import_picocolors.default.green(`${payload.passed} passed`) + import_picocolors.default.dim(`, ${total} total`),
|
|
31347
|
+
import_picocolors.default.bold("Time: ") + import_picocolors.default.white(duration),
|
|
31348
|
+
import_picocolors.default.bold("Run ID: ") + import_picocolors.default.dim(payload.runId),
|
|
31349
|
+
import_picocolors.default.bold("HTML Report: ") + import_picocolors.default.dim("report/report-" + payload.runId + ".html")
|
|
31266
31350
|
].forEach((line) => console.log(` ${line}`));
|
|
31267
31351
|
console.log(this.getSeparator() + "\n");
|
|
31268
31352
|
if (payload.failed > 0) console.log(` ${import_picocolors.default.red(import_picocolors.default.bold("FAIL"))} ${import_picocolors.default.red("Run failed")}\n`);
|
|
@@ -32131,8 +32215,9 @@ async function runRegistry(explicitFile) {
|
|
|
32131
32215
|
}
|
|
32132
32216
|
//#endregion
|
|
32133
32217
|
//#region packages/cli/src/bin.ts
|
|
32134
|
-
const
|
|
32135
|
-
const
|
|
32218
|
+
const __filename = fileURLToPath$1(import.meta.url);
|
|
32219
|
+
const __dirname = path$1.dirname(__filename);
|
|
32220
|
+
const { version } = __require(path$1.join(__dirname, "../package.json"));
|
|
32136
32221
|
program.name("evaliphy").version(version).description("Evaliphy — eval runner for LLM pipelines");
|
|
32137
32222
|
program.command("init <project-name>").description("Create project structure as recommended by Evaliphy.").action((projectName) => {
|
|
32138
32223
|
createProject(projectName);
|
package/dist/index.cjs
CHANGED
|
@@ -183,7 +183,14 @@ var ConfigLoader = class ConfigLoader {
|
|
|
183
183
|
const configPath = this.findConfigFile(cwd);
|
|
184
184
|
if (!configPath) {
|
|
185
185
|
this.configLogger.debug("No config file found, using defaults if applicable");
|
|
186
|
-
throw new EvaliphyError(EvaliphyErrorCode.INVALID_CONFIG,
|
|
186
|
+
throw new EvaliphyError(EvaliphyErrorCode.INVALID_CONFIG, `Could not load configuration. Please check the following:
|
|
187
|
+
|
|
188
|
+
- Does "evaliphy.config.ts" exist in your project root?
|
|
189
|
+
- Is the path correct if you specified a custom config location?
|
|
190
|
+
- Does the config file export a default defineConfig({}) call?
|
|
191
|
+
|
|
192
|
+
Expected location: ${process.cwd()}/evaliphy.config.ts
|
|
193
|
+
Visit https://evaliphy.com/docs/configuration for more details.`);
|
|
187
194
|
}
|
|
188
195
|
if (!this.cachedConfig) {
|
|
189
196
|
this.configLogger.debug({ configPath }, "Loading base configuration from file");
|
|
@@ -196,7 +203,10 @@ var ConfigLoader = class ConfigLoader {
|
|
|
196
203
|
error: parsed.error,
|
|
197
204
|
configPath
|
|
198
205
|
}, "Configuration validation failed");
|
|
199
|
-
throw new EvaliphyError(EvaliphyErrorCode.INVALID_CONFIG, `Invalid configuration in ${configPath}
|
|
206
|
+
throw new EvaliphyError(EvaliphyErrorCode.INVALID_CONFIG, `Invalid configuration in ${configPath}
|
|
207
|
+
|
|
208
|
+
Please check your evaliphy.config.ts and fix the above fields.
|
|
209
|
+
Docs: https://evaliphy.com/docs/configuration`);
|
|
200
210
|
}
|
|
201
211
|
this.cachedConfig = mergeConfigs(parsed.data, {}, this.cliOverrides);
|
|
202
212
|
this.cachedConfig.configFile = configPath;
|
|
@@ -206,7 +216,11 @@ var ConfigLoader = class ConfigLoader {
|
|
|
206
216
|
configPath
|
|
207
217
|
}, "Error loading configuration");
|
|
208
218
|
if (error instanceof EvaliphyError) throw error;
|
|
209
|
-
throw new EvaliphyError(EvaliphyErrorCode.INVALID_CONFIG, `Failed to load config from ${configPath}: ${error.message}
|
|
219
|
+
throw new EvaliphyError(EvaliphyErrorCode.INVALID_CONFIG, `Failed to load config from ${configPath}: ${error.message}
|
|
220
|
+
|
|
221
|
+
Please check your evaliphy.config.ts and fix the above fields.
|
|
222
|
+
Docs: https://evaliphy.com/docs/configuration
|
|
223
|
+
`);
|
|
210
224
|
}
|
|
211
225
|
}
|
|
212
226
|
const finalConfig = mergeConfigs(this.cachedConfig, transientOverrides, {});
|
package/dist/index.mjs
CHANGED
|
@@ -180,7 +180,14 @@ var ConfigLoader = class ConfigLoader {
|
|
|
180
180
|
const configPath = this.findConfigFile(cwd);
|
|
181
181
|
if (!configPath) {
|
|
182
182
|
this.configLogger.debug("No config file found, using defaults if applicable");
|
|
183
|
-
throw new EvaliphyError(EvaliphyErrorCode.INVALID_CONFIG,
|
|
183
|
+
throw new EvaliphyError(EvaliphyErrorCode.INVALID_CONFIG, `Could not load configuration. Please check the following:
|
|
184
|
+
|
|
185
|
+
- Does "evaliphy.config.ts" exist in your project root?
|
|
186
|
+
- Is the path correct if you specified a custom config location?
|
|
187
|
+
- Does the config file export a default defineConfig({}) call?
|
|
188
|
+
|
|
189
|
+
Expected location: ${process.cwd()}/evaliphy.config.ts
|
|
190
|
+
Visit https://evaliphy.com/docs/configuration for more details.`);
|
|
184
191
|
}
|
|
185
192
|
if (!this.cachedConfig) {
|
|
186
193
|
this.configLogger.debug({ configPath }, "Loading base configuration from file");
|
|
@@ -193,7 +200,10 @@ var ConfigLoader = class ConfigLoader {
|
|
|
193
200
|
error: parsed.error,
|
|
194
201
|
configPath
|
|
195
202
|
}, "Configuration validation failed");
|
|
196
|
-
throw new EvaliphyError(EvaliphyErrorCode.INVALID_CONFIG, `Invalid configuration in ${configPath}
|
|
203
|
+
throw new EvaliphyError(EvaliphyErrorCode.INVALID_CONFIG, `Invalid configuration in ${configPath}
|
|
204
|
+
|
|
205
|
+
Please check your evaliphy.config.ts and fix the above fields.
|
|
206
|
+
Docs: https://evaliphy.com/docs/configuration`);
|
|
197
207
|
}
|
|
198
208
|
this.cachedConfig = mergeConfigs(parsed.data, {}, this.cliOverrides);
|
|
199
209
|
this.cachedConfig.configFile = configPath;
|
|
@@ -203,7 +213,11 @@ var ConfigLoader = class ConfigLoader {
|
|
|
203
213
|
configPath
|
|
204
214
|
}, "Error loading configuration");
|
|
205
215
|
if (error instanceof EvaliphyError) throw error;
|
|
206
|
-
throw new EvaliphyError(EvaliphyErrorCode.INVALID_CONFIG, `Failed to load config from ${configPath}: ${error.message}
|
|
216
|
+
throw new EvaliphyError(EvaliphyErrorCode.INVALID_CONFIG, `Failed to load config from ${configPath}: ${error.message}
|
|
217
|
+
|
|
218
|
+
Please check your evaliphy.config.ts and fix the above fields.
|
|
219
|
+
Docs: https://evaliphy.com/docs/configuration
|
|
220
|
+
`);
|
|
207
221
|
}
|
|
208
222
|
}
|
|
209
223
|
const finalConfig = mergeConfigs(this.cachedConfig, transientOverrides, {});
|