@hasna/evals 0.1.7 → 0.1.8
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/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/index.js +112 -62
- package/dist/core/judge.d.ts.map +1 -1
- package/dist/index.js +27 -4
- package/dist/mcp/index.js +27 -4
- package/dist/server/index.js +27 -4
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"doctor.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAqCpC,wBAAgB,aAAa,IAAI,OAAO,CA4EvC"}
|
package/dist/cli/index.js
CHANGED
|
@@ -8413,17 +8413,17 @@ __export(exports_store, {
|
|
|
8413
8413
|
});
|
|
8414
8414
|
import { Database } from "bun:sqlite";
|
|
8415
8415
|
import { mkdirSync } from "fs";
|
|
8416
|
-
import { homedir } from "os";
|
|
8417
|
-
import { join } from "path";
|
|
8416
|
+
import { homedir as homedir2 } from "os";
|
|
8417
|
+
import { join as join2 } from "path";
|
|
8418
8418
|
function getDbPath() {
|
|
8419
|
-
return process.env["EVALS_DB_PATH"] ??
|
|
8419
|
+
return process.env["EVALS_DB_PATH"] ?? join2(homedir2(), ".hasna", "evals", "evals.db");
|
|
8420
8420
|
}
|
|
8421
8421
|
function getDatabase() {
|
|
8422
8422
|
if (_db)
|
|
8423
8423
|
return _db;
|
|
8424
8424
|
const path2 = getDbPath();
|
|
8425
8425
|
if (path2 !== ":memory:") {
|
|
8426
|
-
mkdirSync(
|
|
8426
|
+
mkdirSync(join2(path2, ".."), { recursive: true });
|
|
8427
8427
|
}
|
|
8428
8428
|
_db = new Database(path2);
|
|
8429
8429
|
_db.exec("PRAGMA journal_mode=WAL; PRAGMA foreign_keys=ON;");
|
|
@@ -8571,28 +8571,28 @@ __export(exports_dist, {
|
|
|
8571
8571
|
import { createRequire } from "module";
|
|
8572
8572
|
import { Database as Database2 } from "bun:sqlite";
|
|
8573
8573
|
import {
|
|
8574
|
-
existsSync as
|
|
8574
|
+
existsSync as existsSync4,
|
|
8575
8575
|
mkdirSync as mkdirSync2,
|
|
8576
8576
|
readdirSync,
|
|
8577
8577
|
copyFileSync
|
|
8578
8578
|
} from "fs";
|
|
8579
|
-
import { homedir as
|
|
8580
|
-
import { join as
|
|
8581
|
-
import { existsSync as existsSync22, mkdirSync as mkdirSync22, readFileSync as
|
|
8579
|
+
import { homedir as homedir5 } from "os";
|
|
8580
|
+
import { join as join5, relative } from "path";
|
|
8581
|
+
import { existsSync as existsSync22, mkdirSync as mkdirSync22, readFileSync as readFileSync4, writeFileSync as writeFileSync4 } from "fs";
|
|
8582
8582
|
import { homedir as homedir22 } from "os";
|
|
8583
8583
|
import { join as join22 } from "path";
|
|
8584
|
-
import { readdirSync as readdirSync2, existsSync as
|
|
8584
|
+
import { readdirSync as readdirSync2, existsSync as existsSync32 } from "fs";
|
|
8585
8585
|
import { join as join32 } from "path";
|
|
8586
8586
|
import { homedir as homedir32 } from "os";
|
|
8587
8587
|
import { hostname } from "os";
|
|
8588
|
-
import { existsSync as
|
|
8589
|
-
import { homedir as
|
|
8590
|
-
import { join as
|
|
8588
|
+
import { existsSync as existsSync42, readFileSync as readFileSync22 } from "fs";
|
|
8589
|
+
import { homedir as homedir42 } from "os";
|
|
8590
|
+
import { join as join42 } from "path";
|
|
8591
8591
|
import { existsSync as existsSync5, readdirSync as readdirSync3 } from "fs";
|
|
8592
|
-
import { join as
|
|
8592
|
+
import { join as join52 } from "path";
|
|
8593
8593
|
import { join as join6, dirname } from "path";
|
|
8594
8594
|
import { existsSync as existsSync6, writeFileSync as writeFileSync22, unlinkSync, mkdirSync as mkdirSync3 } from "fs";
|
|
8595
|
-
import { homedir as
|
|
8595
|
+
import { homedir as homedir52, platform } from "os";
|
|
8596
8596
|
function __accessProp2(key) {
|
|
8597
8597
|
return this[key];
|
|
8598
8598
|
}
|
|
@@ -9474,20 +9474,20 @@ function custom(check, _params = {}, fatal) {
|
|
|
9474
9474
|
return ZodAny.create();
|
|
9475
9475
|
}
|
|
9476
9476
|
function getDataDir(serviceName) {
|
|
9477
|
-
const dir =
|
|
9477
|
+
const dir = join5(HASNA_DIR, serviceName);
|
|
9478
9478
|
mkdirSync2(dir, { recursive: true });
|
|
9479
9479
|
return dir;
|
|
9480
9480
|
}
|
|
9481
9481
|
function getDbPath2(serviceName) {
|
|
9482
9482
|
const dir = getDataDir(serviceName);
|
|
9483
|
-
return
|
|
9483
|
+
return join5(dir, `${serviceName}.db`);
|
|
9484
9484
|
}
|
|
9485
9485
|
function migrateDotfile(serviceName) {
|
|
9486
|
-
const legacyDir =
|
|
9487
|
-
const newDir =
|
|
9488
|
-
if (!
|
|
9486
|
+
const legacyDir = join5(homedir5(), `.${serviceName}`);
|
|
9487
|
+
const newDir = join5(HASNA_DIR, serviceName);
|
|
9488
|
+
if (!existsSync4(legacyDir))
|
|
9489
9489
|
return [];
|
|
9490
|
-
if (
|
|
9490
|
+
if (existsSync4(newDir))
|
|
9491
9491
|
return [];
|
|
9492
9492
|
mkdirSync2(newDir, { recursive: true });
|
|
9493
9493
|
const migrated = [];
|
|
@@ -9497,8 +9497,8 @@ function migrateDotfile(serviceName) {
|
|
|
9497
9497
|
function copyDirRecursive(src, dest, root, migrated) {
|
|
9498
9498
|
const entries = readdirSync(src, { withFileTypes: true });
|
|
9499
9499
|
for (const entry of entries) {
|
|
9500
|
-
const srcPath =
|
|
9501
|
-
const destPath =
|
|
9500
|
+
const srcPath = join5(src, entry.name);
|
|
9501
|
+
const destPath = join5(dest, entry.name);
|
|
9502
9502
|
if (entry.isDirectory()) {
|
|
9503
9503
|
mkdirSync2(destPath, { recursive: true });
|
|
9504
9504
|
copyDirRecursive(srcPath, destPath, root, migrated);
|
|
@@ -9509,7 +9509,7 @@ function copyDirRecursive(src, dest, root, migrated) {
|
|
|
9509
9509
|
}
|
|
9510
9510
|
}
|
|
9511
9511
|
function hasLegacyDotfile(serviceName) {
|
|
9512
|
-
return
|
|
9512
|
+
return existsSync4(join5(homedir5(), `.${serviceName}`));
|
|
9513
9513
|
}
|
|
9514
9514
|
function getHasnaDir() {
|
|
9515
9515
|
mkdirSync2(HASNA_DIR, { recursive: true });
|
|
@@ -9526,7 +9526,7 @@ function getCloudConfig() {
|
|
|
9526
9526
|
return CloudConfigSchema.parse({});
|
|
9527
9527
|
}
|
|
9528
9528
|
try {
|
|
9529
|
-
const raw =
|
|
9529
|
+
const raw = readFileSync4(CONFIG_PATH, "utf-8");
|
|
9530
9530
|
return CloudConfigSchema.parse(JSON.parse(raw));
|
|
9531
9531
|
} catch {
|
|
9532
9532
|
return CloudConfigSchema.parse({});
|
|
@@ -9565,7 +9565,7 @@ function isSyncExcludedTable(table) {
|
|
|
9565
9565
|
}
|
|
9566
9566
|
function discoverServices() {
|
|
9567
9567
|
const dataDir = join32(homedir32(), ".hasna");
|
|
9568
|
-
if (!
|
|
9568
|
+
if (!existsSync32(dataDir))
|
|
9569
9569
|
return [];
|
|
9570
9570
|
try {
|
|
9571
9571
|
const entries = readdirSync2(dataDir, { withFileTypes: true });
|
|
@@ -9587,7 +9587,7 @@ function discoverSyncableServices() {
|
|
|
9587
9587
|
}
|
|
9588
9588
|
function getServiceDbPath(service) {
|
|
9589
9589
|
const dataDir = join32(homedir32(), ".hasna", service);
|
|
9590
|
-
if (!
|
|
9590
|
+
if (!existsSync32(dataDir))
|
|
9591
9591
|
return null;
|
|
9592
9592
|
const candidates = [
|
|
9593
9593
|
join32(dataDir, `${service}.db`),
|
|
@@ -9603,7 +9603,7 @@ function getServiceDbPath(service) {
|
|
|
9603
9603
|
}
|
|
9604
9604
|
} catch {}
|
|
9605
9605
|
for (const p of candidates) {
|
|
9606
|
-
if (
|
|
9606
|
+
if (existsSync32(p))
|
|
9607
9607
|
return p;
|
|
9608
9608
|
}
|
|
9609
9609
|
return null;
|
|
@@ -10524,7 +10524,7 @@ function resetAllSyncMeta(db) {
|
|
|
10524
10524
|
}
|
|
10525
10525
|
function getAutoSyncConfig() {
|
|
10526
10526
|
try {
|
|
10527
|
-
if (!
|
|
10527
|
+
if (!existsSync42(AUTO_SYNC_CONFIG_PATH)) {
|
|
10528
10528
|
return { ...DEFAULT_AUTO_SYNC_CONFIG };
|
|
10529
10529
|
}
|
|
10530
10530
|
const raw = JSON.parse(readFileSync22(AUTO_SYNC_CONFIG_PATH, "utf-8"));
|
|
@@ -10646,7 +10646,7 @@ function discoverSyncableServices2() {
|
|
|
10646
10646
|
for (const entry of entries) {
|
|
10647
10647
|
if (!entry.isDirectory())
|
|
10648
10648
|
continue;
|
|
10649
|
-
const dbPath =
|
|
10649
|
+
const dbPath = join52(hasnaDir, entry.name, `${entry.name}.db`);
|
|
10650
10650
|
if (existsSync5(dbPath)) {
|
|
10651
10651
|
services.push(entry.name);
|
|
10652
10652
|
}
|
|
@@ -10669,7 +10669,7 @@ async function runScheduledSync() {
|
|
|
10669
10669
|
errors: []
|
|
10670
10670
|
};
|
|
10671
10671
|
try {
|
|
10672
|
-
const dbPath =
|
|
10672
|
+
const dbPath = join52(getDataDir(service), `${service}.db`);
|
|
10673
10673
|
if (!existsSync5(dbPath)) {
|
|
10674
10674
|
continue;
|
|
10675
10675
|
}
|
|
@@ -10761,7 +10761,7 @@ function getWorkerPath() {
|
|
|
10761
10761
|
}
|
|
10762
10762
|
function getBunPath() {
|
|
10763
10763
|
const candidates = [
|
|
10764
|
-
join6(
|
|
10764
|
+
join6(homedir52(), ".bun", "bin", "bun"),
|
|
10765
10765
|
"/usr/local/bin/bun",
|
|
10766
10766
|
"/usr/bin/bun"
|
|
10767
10767
|
];
|
|
@@ -10772,7 +10772,7 @@ function getBunPath() {
|
|
|
10772
10772
|
return "bun";
|
|
10773
10773
|
}
|
|
10774
10774
|
function getLaunchdPlistPath() {
|
|
10775
|
-
return join6(
|
|
10775
|
+
return join6(homedir52(), "Library", "LaunchAgents", `com.hasna.cloud-sync.plist`);
|
|
10776
10776
|
}
|
|
10777
10777
|
function createLaunchdPlist(intervalMinutes) {
|
|
10778
10778
|
const workerPath = getWorkerPath();
|
|
@@ -10804,7 +10804,7 @@ function createLaunchdPlist(intervalMinutes) {
|
|
|
10804
10804
|
<key>PATH</key>
|
|
10805
10805
|
<string>${process.env.PATH || "/usr/local/bin:/usr/bin:/bin"}</string>
|
|
10806
10806
|
<key>HOME</key>
|
|
10807
|
-
<string>${
|
|
10807
|
+
<string>${homedir52()}</string>
|
|
10808
10808
|
</dict>
|
|
10809
10809
|
</dict>
|
|
10810
10810
|
</plist>`;
|
|
@@ -10829,7 +10829,7 @@ async function removeLaunchd() {
|
|
|
10829
10829
|
} catch {}
|
|
10830
10830
|
}
|
|
10831
10831
|
function getSystemdDir() {
|
|
10832
|
-
return join6(
|
|
10832
|
+
return join6(homedir52(), ".config", "systemd", "user");
|
|
10833
10833
|
}
|
|
10834
10834
|
function createSystemdService() {
|
|
10835
10835
|
const workerPath = getWorkerPath();
|
|
@@ -10841,7 +10841,7 @@ After=network.target
|
|
|
10841
10841
|
[Service]
|
|
10842
10842
|
Type=oneshot
|
|
10843
10843
|
ExecStart=${bunPath} run ${workerPath}
|
|
10844
|
-
Environment=HOME=${
|
|
10844
|
+
Environment=HOME=${homedir52()}
|
|
10845
10845
|
Environment=PATH=${process.env.PATH || "/usr/local/bin:/usr/bin:/bin"}
|
|
10846
10846
|
|
|
10847
10847
|
[Install]
|
|
@@ -19467,7 +19467,7 @@ See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode de
|
|
|
19467
19467
|
init_external();
|
|
19468
19468
|
});
|
|
19469
19469
|
init_dotfile = __esm2(() => {
|
|
19470
|
-
HASNA_DIR =
|
|
19470
|
+
HASNA_DIR = join5(homedir5(), ".hasna");
|
|
19471
19471
|
});
|
|
19472
19472
|
exports_config = {};
|
|
19473
19473
|
__export2(exports_config, {
|
|
@@ -19563,7 +19563,7 @@ See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode de
|
|
|
19563
19563
|
init_adapter();
|
|
19564
19564
|
init_config();
|
|
19565
19565
|
init_discover();
|
|
19566
|
-
AUTO_SYNC_CONFIG_PATH =
|
|
19566
|
+
AUTO_SYNC_CONFIG_PATH = join42(homedir42(), ".hasna", "cloud", "config.json");
|
|
19567
19567
|
DEFAULT_AUTO_SYNC_CONFIG = {
|
|
19568
19568
|
auto_sync_on_start: true,
|
|
19569
19569
|
auto_sync_on_stop: true
|
|
@@ -19573,7 +19573,7 @@ See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode de
|
|
|
19573
19573
|
init_adapter();
|
|
19574
19574
|
init_dotfile();
|
|
19575
19575
|
init_config();
|
|
19576
|
-
CONFIG_DIR2 = join6(
|
|
19576
|
+
CONFIG_DIR2 = join6(homedir52(), ".hasna", "cloud");
|
|
19577
19577
|
init_adapter();
|
|
19578
19578
|
init_config();
|
|
19579
19579
|
init_discover();
|
|
@@ -29440,6 +29440,29 @@ var _deployments_endpoints = new Set([
|
|
|
29440
29440
|
var openai_default = OpenAI;
|
|
29441
29441
|
|
|
29442
29442
|
// src/core/judge.ts
|
|
29443
|
+
import { existsSync, readFileSync } from "fs";
|
|
29444
|
+
import { homedir } from "os";
|
|
29445
|
+
import { join } from "path";
|
|
29446
|
+
function resolveKey(envVar, secretsRelPath, secretsKey) {
|
|
29447
|
+
if (process.env[envVar])
|
|
29448
|
+
return process.env[envVar];
|
|
29449
|
+
const p = join(homedir(), ".secrets", secretsRelPath);
|
|
29450
|
+
if (existsSync(p)) {
|
|
29451
|
+
for (const line of readFileSync(p, "utf8").split(`
|
|
29452
|
+
`)) {
|
|
29453
|
+
if (line.trim().startsWith(secretsKey + "=")) {
|
|
29454
|
+
const v = line.trim().slice(secretsKey.length + 1).replace(/^["']|["']$/g, "");
|
|
29455
|
+
if (v) {
|
|
29456
|
+
process.env[envVar] = v;
|
|
29457
|
+
return v;
|
|
29458
|
+
}
|
|
29459
|
+
}
|
|
29460
|
+
}
|
|
29461
|
+
}
|
|
29462
|
+
return;
|
|
29463
|
+
}
|
|
29464
|
+
resolveKey("ANTHROPIC_API_KEY", "hasnaxyz/anthropic/live.env", "HASNAXYZ_ANTHROPIC_LIVE_API_KEY");
|
|
29465
|
+
resolveKey("OPENAI_API_KEY", "hasnaxyz/openai/live.env", "HASNAXYZ_OPENAI_LIVE_API_KEY");
|
|
29443
29466
|
var DEFAULT_MODEL = "claude-sonnet-4-6";
|
|
29444
29467
|
var DEFAULT_PROVIDER = "anthropic";
|
|
29445
29468
|
var JUDGE_SYSTEM_PROMPT = `You are a precise AI output evaluator. Your job is to judge whether an AI response meets a given rubric.
|
|
@@ -30455,17 +30478,44 @@ function kappaLabel(k) {
|
|
|
30455
30478
|
}
|
|
30456
30479
|
|
|
30457
30480
|
// src/cli/commands/doctor.ts
|
|
30481
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
30482
|
+
import { homedir as homedir3 } from "os";
|
|
30483
|
+
import { join as join3 } from "path";
|
|
30484
|
+
function resolveApiKey(envVar, secretsPath, secretsKey) {
|
|
30485
|
+
if (process.env[envVar])
|
|
30486
|
+
return process.env[envVar];
|
|
30487
|
+
const fullPath = join3(homedir3(), ".secrets", secretsPath);
|
|
30488
|
+
if (existsSync2(fullPath)) {
|
|
30489
|
+
try {
|
|
30490
|
+
const content = readFileSync2(fullPath, "utf8");
|
|
30491
|
+
for (const line of content.split(`
|
|
30492
|
+
`)) {
|
|
30493
|
+
const trimmed = line.trim();
|
|
30494
|
+
if (trimmed.startsWith(secretsKey + "=")) {
|
|
30495
|
+
const value = trimmed.slice(secretsKey.length + 1).replace(/^["']|["']$/g, "");
|
|
30496
|
+
if (value) {
|
|
30497
|
+
process.env[envVar] = value;
|
|
30498
|
+
return value;
|
|
30499
|
+
}
|
|
30500
|
+
}
|
|
30501
|
+
}
|
|
30502
|
+
} catch {}
|
|
30503
|
+
}
|
|
30504
|
+
return;
|
|
30505
|
+
}
|
|
30458
30506
|
function doctorCommand() {
|
|
30459
30507
|
return new Command("doctor").description("Health check \u2014 verify API keys, DB, and config").action(async () => {
|
|
30460
30508
|
const checks = [];
|
|
30509
|
+
const anthropicKey = resolveApiKey("ANTHROPIC_API_KEY", "hasnaxyz/anthropic/live.env", "HASNAXYZ_ANTHROPIC_LIVE_API_KEY");
|
|
30461
30510
|
checks.push({
|
|
30462
30511
|
name: "ANTHROPIC_API_KEY",
|
|
30463
|
-
ok: !!
|
|
30464
|
-
hint: "export ANTHROPIC_API_KEY=<your-key>"
|
|
30512
|
+
ok: !!anthropicKey,
|
|
30513
|
+
hint: "export ANTHROPIC_API_KEY=<your-key> (or add to ~/.secrets/hasnaxyz/anthropic/live.env)"
|
|
30465
30514
|
});
|
|
30515
|
+
const openaiKey = resolveApiKey("OPENAI_API_KEY", "hasnaxyz/openai/live.env", "HASNAXYZ_OPENAI_LIVE_API_KEY");
|
|
30466
30516
|
checks.push({
|
|
30467
30517
|
name: "OPENAI_API_KEY (optional)",
|
|
30468
|
-
ok: !!
|
|
30518
|
+
ok: !!openaiKey,
|
|
30469
30519
|
hint: "export OPENAI_API_KEY=<your-key> (only needed for OpenAI adapter/judge)"
|
|
30470
30520
|
});
|
|
30471
30521
|
try {
|
|
@@ -30480,17 +30530,17 @@ function doctorCommand() {
|
|
|
30480
30530
|
}
|
|
30481
30531
|
try {
|
|
30482
30532
|
const { loadDataset: loadDataset2 } = await Promise.resolve().then(() => (init_loader(), exports_loader));
|
|
30483
|
-
const { existsSync } = await import("fs");
|
|
30484
|
-
const { join:
|
|
30485
|
-
const { homedir:
|
|
30533
|
+
const { existsSync: existsSync3 } = await import("fs");
|
|
30534
|
+
const { join: join4 } = await import("path");
|
|
30535
|
+
const { homedir: homedir4 } = await import("os");
|
|
30486
30536
|
const candidates = [
|
|
30487
30537
|
new URL("../../../datasets/examples/smoke.jsonl", import.meta.url).pathname,
|
|
30488
|
-
|
|
30489
|
-
|
|
30490
|
-
|
|
30491
|
-
|
|
30538
|
+
join4(import.meta.dir, "../../../datasets/examples/smoke.jsonl"),
|
|
30539
|
+
join4(import.meta.dir, "../../datasets/examples/smoke.jsonl"),
|
|
30540
|
+
join4(import.meta.dir, "../datasets/examples/smoke.jsonl"),
|
|
30541
|
+
join4(homedir4(), ".hasna", "evals", "examples", "smoke.jsonl")
|
|
30492
30542
|
];
|
|
30493
|
-
const found = candidates.find((p) =>
|
|
30543
|
+
const found = candidates.find((p) => existsSync3(p));
|
|
30494
30544
|
if (!found)
|
|
30495
30545
|
throw new Error("not found");
|
|
30496
30546
|
const { cases } = await loadDataset2(found);
|
|
@@ -30517,9 +30567,9 @@ function doctorCommand() {
|
|
|
30517
30567
|
}
|
|
30518
30568
|
|
|
30519
30569
|
// src/cli/commands/mcp.ts
|
|
30520
|
-
import { readFileSync, writeFileSync as writeFileSync2, existsSync } from "fs";
|
|
30521
|
-
import { homedir as
|
|
30522
|
-
import { join as
|
|
30570
|
+
import { readFileSync as readFileSync3, writeFileSync as writeFileSync2, existsSync as existsSync3 } from "fs";
|
|
30571
|
+
import { homedir as homedir4 } from "os";
|
|
30572
|
+
import { join as join4 } from "path";
|
|
30523
30573
|
function mcpCommand() {
|
|
30524
30574
|
const cmd = new Command("mcp").description("MCP server management");
|
|
30525
30575
|
cmd.addCommand(new Command("register").description("Register evals-mcp with an agent (Claude Code, Codex, Gemini)").option("--claude", "Register with Claude Code (~/.claude/mcp.json)").option("--codex", "Register with Codex (~/.codex/config.json)").option("--gemini", "Register with Gemini (~/.gemini/settings.json)").option("--all", "Register with all agents").action((opts) => {
|
|
@@ -30535,16 +30585,16 @@ function mcpCommand() {
|
|
|
30535
30585
|
}));
|
|
30536
30586
|
cmd.addCommand(new Command("start").description("Start MCP server (stdio)").action(() => {
|
|
30537
30587
|
const { spawnSync } = __require("child_process");
|
|
30538
|
-
spawnSync(process.execPath, [
|
|
30588
|
+
spawnSync(process.execPath, [join4(import.meta.dir, "../../mcp/index.js")], { stdio: "inherit" });
|
|
30539
30589
|
}));
|
|
30540
30590
|
return cmd;
|
|
30541
30591
|
}
|
|
30542
30592
|
var ENTRY = { command: "/home/hasna/.bun/bin/evals-mcp", args: [] };
|
|
30543
30593
|
function registerClaude() {
|
|
30544
|
-
const mcpPath =
|
|
30594
|
+
const mcpPath = join4(homedir4(), ".claude", "mcp.json");
|
|
30545
30595
|
let config = {};
|
|
30546
|
-
if (
|
|
30547
|
-
config = JSON.parse(
|
|
30596
|
+
if (existsSync3(mcpPath)) {
|
|
30597
|
+
config = JSON.parse(readFileSync3(mcpPath, "utf8"));
|
|
30548
30598
|
}
|
|
30549
30599
|
config.mcpServers = { ...config.mcpServers ?? {}, evals: ENTRY };
|
|
30550
30600
|
writeFileSync2(mcpPath, JSON.stringify(config, null, 2) + `
|
|
@@ -30553,10 +30603,10 @@ function registerClaude() {
|
|
|
30553
30603
|
console.log(" Restart Claude Code to load the new MCP server.");
|
|
30554
30604
|
}
|
|
30555
30605
|
function registerCodex() {
|
|
30556
|
-
const cfgPath =
|
|
30606
|
+
const cfgPath = join4(homedir4(), ".codex", "config.json");
|
|
30557
30607
|
let config = {};
|
|
30558
|
-
if (
|
|
30559
|
-
config = JSON.parse(
|
|
30608
|
+
if (existsSync3(cfgPath)) {
|
|
30609
|
+
config = JSON.parse(readFileSync3(cfgPath, "utf8"));
|
|
30560
30610
|
}
|
|
30561
30611
|
config.mcpServers = { ...config.mcpServers ?? {}, evals: { type: "stdio", ...ENTRY, env: {} } };
|
|
30562
30612
|
writeFileSync2(cfgPath, JSON.stringify(config, null, 2) + `
|
|
@@ -30564,10 +30614,10 @@ function registerCodex() {
|
|
|
30564
30614
|
console.log("\x1B[32m\u2713 Registered evals-mcp in ~/.codex/config.json\x1B[0m");
|
|
30565
30615
|
}
|
|
30566
30616
|
function registerGemini() {
|
|
30567
|
-
const cfgPath =
|
|
30617
|
+
const cfgPath = join4(homedir4(), ".gemini", "settings.json");
|
|
30568
30618
|
let config = {};
|
|
30569
|
-
if (
|
|
30570
|
-
config = JSON.parse(
|
|
30619
|
+
if (existsSync3(cfgPath)) {
|
|
30620
|
+
config = JSON.parse(readFileSync3(cfgPath, "utf8"));
|
|
30571
30621
|
}
|
|
30572
30622
|
config.mcpServers = { ...config.mcpServers ?? {}, evals: ENTRY };
|
|
30573
30623
|
writeFileSync2(cfgPath, JSON.stringify(config, null, 2) + `
|
package/dist/core/judge.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"judge.d.ts","sourceRoot":"","sources":["../../src/core/judge.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"judge.d.ts","sourceRoot":"","sources":["../../src/core/judge.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAW,MAAM,mBAAmB,CAAC;AA4E3E,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,WAAW,EACnB,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,WAAW,CAAC,CAmBtB;AA4ED,kEAAkE;AAClE,wBAAsB,SAAS,CAAC,MAAM,EAAE;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,WAAW,GAAG,QAAQ,CAAC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GAAG,OAAO,CAAC,WAAW,CAAC,CAOvB"}
|
package/dist/index.js
CHANGED
|
@@ -16810,6 +16810,29 @@ var _deployments_endpoints = new Set([
|
|
|
16810
16810
|
var openai_default = OpenAI;
|
|
16811
16811
|
|
|
16812
16812
|
// src/core/judge.ts
|
|
16813
|
+
import { existsSync, readFileSync } from "fs";
|
|
16814
|
+
import { homedir } from "os";
|
|
16815
|
+
import { join } from "path";
|
|
16816
|
+
function resolveKey(envVar, secretsRelPath, secretsKey) {
|
|
16817
|
+
if (process.env[envVar])
|
|
16818
|
+
return process.env[envVar];
|
|
16819
|
+
const p = join(homedir(), ".secrets", secretsRelPath);
|
|
16820
|
+
if (existsSync(p)) {
|
|
16821
|
+
for (const line of readFileSync(p, "utf8").split(`
|
|
16822
|
+
`)) {
|
|
16823
|
+
if (line.trim().startsWith(secretsKey + "=")) {
|
|
16824
|
+
const v = line.trim().slice(secretsKey.length + 1).replace(/^["']|["']$/g, "");
|
|
16825
|
+
if (v) {
|
|
16826
|
+
process.env[envVar] = v;
|
|
16827
|
+
return v;
|
|
16828
|
+
}
|
|
16829
|
+
}
|
|
16830
|
+
}
|
|
16831
|
+
}
|
|
16832
|
+
return;
|
|
16833
|
+
}
|
|
16834
|
+
resolveKey("ANTHROPIC_API_KEY", "hasnaxyz/anthropic/live.env", "HASNAXYZ_ANTHROPIC_LIVE_API_KEY");
|
|
16835
|
+
resolveKey("OPENAI_API_KEY", "hasnaxyz/openai/live.env", "HASNAXYZ_OPENAI_LIVE_API_KEY");
|
|
16813
16836
|
var DEFAULT_MODEL = "claude-sonnet-4-6";
|
|
16814
16837
|
var DEFAULT_PROVIDER = "anthropic";
|
|
16815
16838
|
var JUDGE_SYSTEM_PROMPT = `You are a precise AI output evaluator. Your job is to judge whether an AI response meets a given rubric.
|
|
@@ -23852,18 +23875,18 @@ async function* streamDataset(path2, opts = {}) {
|
|
|
23852
23875
|
// src/db/store.ts
|
|
23853
23876
|
import { Database } from "bun:sqlite";
|
|
23854
23877
|
import { mkdirSync } from "fs";
|
|
23855
|
-
import { homedir } from "os";
|
|
23856
|
-
import { join } from "path";
|
|
23878
|
+
import { homedir as homedir2 } from "os";
|
|
23879
|
+
import { join as join2 } from "path";
|
|
23857
23880
|
var _db = null;
|
|
23858
23881
|
function getDbPath() {
|
|
23859
|
-
return process.env["EVALS_DB_PATH"] ??
|
|
23882
|
+
return process.env["EVALS_DB_PATH"] ?? join2(homedir2(), ".hasna", "evals", "evals.db");
|
|
23860
23883
|
}
|
|
23861
23884
|
function getDatabase() {
|
|
23862
23885
|
if (_db)
|
|
23863
23886
|
return _db;
|
|
23864
23887
|
const path2 = getDbPath();
|
|
23865
23888
|
if (path2 !== ":memory:") {
|
|
23866
|
-
mkdirSync(
|
|
23889
|
+
mkdirSync(join2(path2, ".."), { recursive: true });
|
|
23867
23890
|
}
|
|
23868
23891
|
_db = new Database(path2);
|
|
23869
23892
|
_db.exec("PRAGMA journal_mode=WAL; PRAGMA foreign_keys=ON;");
|
package/dist/mcp/index.js
CHANGED
|
@@ -10501,17 +10501,17 @@ __export(exports_store, {
|
|
|
10501
10501
|
});
|
|
10502
10502
|
import { Database } from "bun:sqlite";
|
|
10503
10503
|
import { mkdirSync } from "fs";
|
|
10504
|
-
import { homedir } from "os";
|
|
10505
|
-
import { join } from "path";
|
|
10504
|
+
import { homedir as homedir2 } from "os";
|
|
10505
|
+
import { join as join2 } from "path";
|
|
10506
10506
|
function getDbPath() {
|
|
10507
|
-
return process.env["EVALS_DB_PATH"] ??
|
|
10507
|
+
return process.env["EVALS_DB_PATH"] ?? join2(homedir2(), ".hasna", "evals", "evals.db");
|
|
10508
10508
|
}
|
|
10509
10509
|
function getDatabase() {
|
|
10510
10510
|
if (_db)
|
|
10511
10511
|
return _db;
|
|
10512
10512
|
const path2 = getDbPath();
|
|
10513
10513
|
if (path2 !== ":memory:") {
|
|
10514
|
-
mkdirSync(
|
|
10514
|
+
mkdirSync(join2(path2, ".."), { recursive: true });
|
|
10515
10515
|
}
|
|
10516
10516
|
_db = new Database(path2);
|
|
10517
10517
|
_db.exec("PRAGMA journal_mode=WAL; PRAGMA foreign_keys=ON;");
|
|
@@ -20314,6 +20314,29 @@ var _deployments_endpoints = new Set([
|
|
|
20314
20314
|
var openai_default = OpenAI;
|
|
20315
20315
|
|
|
20316
20316
|
// src/core/judge.ts
|
|
20317
|
+
import { existsSync, readFileSync } from "fs";
|
|
20318
|
+
import { homedir } from "os";
|
|
20319
|
+
import { join } from "path";
|
|
20320
|
+
function resolveKey(envVar, secretsRelPath, secretsKey) {
|
|
20321
|
+
if (process.env[envVar])
|
|
20322
|
+
return process.env[envVar];
|
|
20323
|
+
const p = join(homedir(), ".secrets", secretsRelPath);
|
|
20324
|
+
if (existsSync(p)) {
|
|
20325
|
+
for (const line of readFileSync(p, "utf8").split(`
|
|
20326
|
+
`)) {
|
|
20327
|
+
if (line.trim().startsWith(secretsKey + "=")) {
|
|
20328
|
+
const v = line.trim().slice(secretsKey.length + 1).replace(/^["']|["']$/g, "");
|
|
20329
|
+
if (v) {
|
|
20330
|
+
process.env[envVar] = v;
|
|
20331
|
+
return v;
|
|
20332
|
+
}
|
|
20333
|
+
}
|
|
20334
|
+
}
|
|
20335
|
+
}
|
|
20336
|
+
return;
|
|
20337
|
+
}
|
|
20338
|
+
resolveKey("ANTHROPIC_API_KEY", "hasnaxyz/anthropic/live.env", "HASNAXYZ_ANTHROPIC_LIVE_API_KEY");
|
|
20339
|
+
resolveKey("OPENAI_API_KEY", "hasnaxyz/openai/live.env", "HASNAXYZ_OPENAI_LIVE_API_KEY");
|
|
20317
20340
|
var DEFAULT_MODEL = "claude-sonnet-4-6";
|
|
20318
20341
|
var DEFAULT_PROVIDER = "anthropic";
|
|
20319
20342
|
var JUDGE_SYSTEM_PROMPT = `You are a precise AI output evaluator. Your job is to judge whether an AI response meets a given rubric.
|
package/dist/server/index.js
CHANGED
|
@@ -16809,6 +16809,29 @@ var _deployments_endpoints = new Set([
|
|
|
16809
16809
|
var openai_default = OpenAI;
|
|
16810
16810
|
|
|
16811
16811
|
// src/core/judge.ts
|
|
16812
|
+
import { existsSync, readFileSync } from "fs";
|
|
16813
|
+
import { homedir } from "os";
|
|
16814
|
+
import { join } from "path";
|
|
16815
|
+
function resolveKey(envVar, secretsRelPath, secretsKey) {
|
|
16816
|
+
if (process.env[envVar])
|
|
16817
|
+
return process.env[envVar];
|
|
16818
|
+
const p = join(homedir(), ".secrets", secretsRelPath);
|
|
16819
|
+
if (existsSync(p)) {
|
|
16820
|
+
for (const line of readFileSync(p, "utf8").split(`
|
|
16821
|
+
`)) {
|
|
16822
|
+
if (line.trim().startsWith(secretsKey + "=")) {
|
|
16823
|
+
const v = line.trim().slice(secretsKey.length + 1).replace(/^["']|["']$/g, "");
|
|
16824
|
+
if (v) {
|
|
16825
|
+
process.env[envVar] = v;
|
|
16826
|
+
return v;
|
|
16827
|
+
}
|
|
16828
|
+
}
|
|
16829
|
+
}
|
|
16830
|
+
}
|
|
16831
|
+
return;
|
|
16832
|
+
}
|
|
16833
|
+
resolveKey("ANTHROPIC_API_KEY", "hasnaxyz/anthropic/live.env", "HASNAXYZ_ANTHROPIC_LIVE_API_KEY");
|
|
16834
|
+
resolveKey("OPENAI_API_KEY", "hasnaxyz/openai/live.env", "HASNAXYZ_OPENAI_LIVE_API_KEY");
|
|
16812
16835
|
var DEFAULT_MODEL = "claude-sonnet-4-6";
|
|
16813
16836
|
var DEFAULT_PROVIDER = "anthropic";
|
|
16814
16837
|
var JUDGE_SYSTEM_PROMPT = `You are a precise AI output evaluator. Your job is to judge whether an AI response meets a given rubric.
|
|
@@ -23744,18 +23767,18 @@ function toMarkdown(run) {
|
|
|
23744
23767
|
// src/db/store.ts
|
|
23745
23768
|
import { Database } from "bun:sqlite";
|
|
23746
23769
|
import { mkdirSync } from "fs";
|
|
23747
|
-
import { homedir } from "os";
|
|
23748
|
-
import { join } from "path";
|
|
23770
|
+
import { homedir as homedir2 } from "os";
|
|
23771
|
+
import { join as join2 } from "path";
|
|
23749
23772
|
var _db = null;
|
|
23750
23773
|
function getDbPath() {
|
|
23751
|
-
return process.env["EVALS_DB_PATH"] ??
|
|
23774
|
+
return process.env["EVALS_DB_PATH"] ?? join2(homedir2(), ".hasna", "evals", "evals.db");
|
|
23752
23775
|
}
|
|
23753
23776
|
function getDatabase() {
|
|
23754
23777
|
if (_db)
|
|
23755
23778
|
return _db;
|
|
23756
23779
|
const path2 = getDbPath();
|
|
23757
23780
|
if (path2 !== ":memory:") {
|
|
23758
|
-
mkdirSync(
|
|
23781
|
+
mkdirSync(join2(path2, ".."), { recursive: true });
|
|
23759
23782
|
}
|
|
23760
23783
|
_db = new Database(path2);
|
|
23761
23784
|
_db.exec("PRAGMA journal_mode=WAL; PRAGMA foreign_keys=ON;");
|
package/package.json
CHANGED