cb15c5e0d8
Release / Check for new version (push) Has been cancelled
Release / Build macOS ARM64 (push) Has been cancelled
Release / Build macOS x64 (push) Has been cancelled
Release / Build Linux ARM64 (push) Has been cancelled
Release / Build Linux musl ARM64 (push) Has been cancelled
Release / Build Linux musl x64 (push) Has been cancelled
Release / Build Linux x64 (push) Has been cancelled
Release / Build Windows x64 (push) Has been cancelled
Release / Publish to npm (push) Has been cancelled
Release / Publish sandbox package to npm (push) Has been cancelled
Release / Create GitHub Release (push) Has been cancelled
CI / Rust (windows-latest - x86_64-pc-windows-msvc) (push) Has been cancelled
CI / Native E2E Tests (push) Has been cancelled
CI / Windows Integration Test (push) Has been cancelled
CI / Global Install (macos-latest) (push) Has been cancelled
CI / Global Install (ubuntu-latest) (push) Has been cancelled
CI / Version Sync Check (push) Has been cancelled
CI / Rust (push) Has been cancelled
CI / Dashboard (push) Has been cancelled
CI / Sandbox Package (push) Has been cancelled
CI / Rust (macos-latest - aarch64-apple-darwin) (push) Has been cancelled
CI / Rust (macos-latest - x86_64-apple-darwin) (push) Has been cancelled
CI / Global Install (windows-latest) (push) Has been cancelled
152 lines
3.9 KiB
TypeScript
152 lines
3.9 KiB
TypeScript
import type {
|
|
EvalCase,
|
|
EvalResult,
|
|
Category,
|
|
ProviderName,
|
|
RunOptions,
|
|
} from "./lib/types.ts";
|
|
import { getProvider } from "./lib/providers.ts";
|
|
import { evaluate } from "./lib/judge.ts";
|
|
import {
|
|
printResult,
|
|
printCategoryHeader,
|
|
computeSummary,
|
|
printSummary,
|
|
printResultsJson,
|
|
} from "./lib/reporter.ts";
|
|
import { cases as skillLoadingCases } from "./cases/skill-loading.ts";
|
|
import { cases as skillSelectionCases } from "./cases/skill-selection.ts";
|
|
import { cases as commandUsageCases } from "./cases/command-usage.ts";
|
|
import { cases as contextFootprintCases } from "./cases/context-footprint.ts";
|
|
|
|
const ALL_CASES: EvalCase[] = [
|
|
...skillLoadingCases,
|
|
...skillSelectionCases,
|
|
...commandUsageCases,
|
|
...contextFootprintCases,
|
|
];
|
|
|
|
function parseArgs(args: string[]): RunOptions {
|
|
const options: RunOptions = {
|
|
provider: "claude",
|
|
model: "",
|
|
judge: false,
|
|
json: false,
|
|
concurrency: 1,
|
|
timeout: 60_000,
|
|
};
|
|
|
|
for (let i = 0; i < args.length; i++) {
|
|
const arg = args[i];
|
|
switch (arg) {
|
|
case "--provider":
|
|
options.provider = (args[++i] ?? "claude") as ProviderName;
|
|
break;
|
|
case "--model":
|
|
options.model = args[++i] ?? "";
|
|
break;
|
|
case "--category":
|
|
options.category = args[++i] as Category;
|
|
break;
|
|
case "--judge":
|
|
options.judge = true;
|
|
break;
|
|
case "--json":
|
|
options.json = true;
|
|
break;
|
|
case "--timeout":
|
|
options.timeout = parseInt(args[++i] ?? "60000", 10);
|
|
break;
|
|
case "--help":
|
|
case "-h":
|
|
printUsage();
|
|
process.exit(0);
|
|
}
|
|
}
|
|
|
|
return options;
|
|
}
|
|
|
|
function printUsage(): void {
|
|
console.log(
|
|
`
|
|
agent-browser skills evals
|
|
|
|
Usage: bun run evals/run.ts [options]
|
|
|
|
Options:
|
|
--provider <name> Provider to use: claude, codex (default: claude)
|
|
--model <name> Model override (default: provider's default model)
|
|
--category <cat> Filter by category: skill-loading, skill-selection, command-usage, context-footprint
|
|
--judge Enable LLM judge for quality scoring (costs extra API calls)
|
|
--json Output results as JSON
|
|
--timeout <ms> Timeout per eval case in milliseconds (default: 60000)
|
|
--help, -h Show this help
|
|
|
|
Providers:
|
|
claude Uses Claude CLI via Vercel AI Gateway (default model: anthropic/claude-sonnet-4.6)
|
|
codex Uses Codex CLI via Vercel AI Gateway (default model: openai/o3)
|
|
`.trim(),
|
|
);
|
|
}
|
|
|
|
async function main(): Promise<void> {
|
|
const options = parseArgs(process.argv.slice(2));
|
|
const provider = getProvider(options.provider);
|
|
const model = options.model || provider.defaultModel;
|
|
|
|
let cases = ALL_CASES;
|
|
if (options.category) {
|
|
cases = cases.filter((c) => c.category === options.category);
|
|
}
|
|
|
|
if (cases.length === 0) {
|
|
console.error("No eval cases match the given filters.");
|
|
process.exit(1);
|
|
}
|
|
|
|
if (!options.json) {
|
|
console.log(
|
|
`\nRunning ${cases.length} eval(s) with provider=${provider.name} model=${model}` +
|
|
(options.judge ? " + LLM judge" : ""),
|
|
);
|
|
}
|
|
|
|
const results: EvalResult[] = [];
|
|
const startTime = performance.now();
|
|
let currentCategory: string | null = null;
|
|
|
|
for (const evalCase of cases) {
|
|
if (!options.json && evalCase.category !== currentCategory) {
|
|
currentCategory = evalCase.category;
|
|
printCategoryHeader(currentCategory);
|
|
}
|
|
|
|
const result = await evaluate(evalCase, provider, {
|
|
model,
|
|
judge: options.judge,
|
|
timeout: options.timeout,
|
|
});
|
|
|
|
results.push(result);
|
|
|
|
if (!options.json) {
|
|
printResult(result);
|
|
}
|
|
}
|
|
|
|
const totalDurationMs = Math.round(performance.now() - startTime);
|
|
const summary = computeSummary(results, totalDurationMs);
|
|
|
|
if (options.json) {
|
|
printResultsJson(results, summary);
|
|
} else {
|
|
printSummary(summary);
|
|
}
|
|
|
|
const exitCode = summary.failed > 0 || summary.errors > 0 ? 1 : 0;
|
|
process.exit(exitCode);
|
|
}
|
|
|
|
main();
|