praxis-agent 0.46.5 → 0.47.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 +4 -0
- package/dist/cli-runtime.d.ts +2 -0
- package/dist/cli-runtime.js +29 -2
- package/dist/evals/eval-contract.d.ts +102 -0
- package/dist/evals/eval-contract.js +57 -0
- package/dist/evals/eval-graders.d.ts +6 -0
- package/dist/evals/eval-graders.js +94 -0
- package/dist/evals/project-eval-runner.d.ts +59 -0
- package/dist/evals/project-eval-runner.js +359 -0
- package/dist/evals/project-eval-schema.d.ts +35 -0
- package/dist/evals/project-eval-schema.js +395 -0
- package/dist/evals/project-eval-workspace.d.ts +30 -0
- package/dist/evals/project-eval-workspace.js +108 -0
- package/dist/evals/project-eval.d.ts +77 -0
- package/dist/evals/project-eval.js +214 -0
- package/dist/platform/bounded-process-runner.d.ts +2 -0
- package/dist/platform/bounded-process-runner.js +4 -2
- package/dist/plugins/claude-plugin-eval-graders.d.ts +2 -33
- package/dist/plugins/claude-plugin-eval-graders.js +7 -66
- package/dist/plugins/claude-plugin-eval-runner.d.ts +4 -29
- package/dist/plugins/claude-plugin-eval-runner.js +3 -58
- package/dist/plugins/claude-plugin-eval-schema.d.ts +9 -34
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -100,6 +100,10 @@ troubleshooting. Run `praxis --help` for the authoritative command surface.
|
|
|
100
100
|
|
|
101
101
|
## What Praxis provides
|
|
102
102
|
|
|
103
|
+
- **Outcome-driven evaluation** — `praxis eval <target>` runs contained cases
|
|
104
|
+
in isolated workspaces, requires explicit verifier authorization, and writes
|
|
105
|
+
versioned artifacts locally; usage and cost remain explicitly available or
|
|
106
|
+
unknown.
|
|
103
107
|
- **Local agent runtime** — C+ Quiet Operator responsive TUI with a linear
|
|
104
108
|
`❯` user / `⏺` assistant conversation, `✻` thinking activity, and `!` shell
|
|
105
109
|
composer grammar, compact stable tool rows, responsive density,
|
package/dist/cli-runtime.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ import { launchTmuxWorktree } from './platform/tmux-worktree.js';
|
|
|
22
22
|
import { type CliControls, type CliRuntimeInfo, type CliElicitationRequest, type CliElicitationResult } from './cli/protocol.js';
|
|
23
23
|
import { executeProviderAuthCommand } from './cli/provider-auth-command.js';
|
|
24
24
|
import { type PluginEvalDependencies } from './plugins/claude-plugin-eval.js';
|
|
25
|
+
import { type ProjectEvalDependencies } from './evals/project-eval.js';
|
|
25
26
|
import { type SelfUpdateResult } from './maintenance/self-update.js';
|
|
26
27
|
export { parseContextEnvironment, parseProviderEnvironment };
|
|
27
28
|
export interface CliIO {
|
|
@@ -153,6 +154,7 @@ export interface CliDependencies extends InteractiveServiceFactory {
|
|
|
153
154
|
statePath?: string;
|
|
154
155
|
}): Promise<ModelProvider>;
|
|
155
156
|
pluginEval?: PluginEvalDependencies;
|
|
157
|
+
projectEval?: ProjectEvalDependencies;
|
|
156
158
|
runInteractive?(options: {
|
|
157
159
|
agent?: string;
|
|
158
160
|
controls?: CliControls;
|
package/dist/cli-runtime.js
CHANGED
|
@@ -70,6 +70,7 @@ import { executeProviderAuthCommand } from './cli/provider-auth-command.js';
|
|
|
70
70
|
import { describeClaudePlugin, initClaudePlugin, installClaudePlugin, loadClaudePlugins, readPluginRegistry, setClaudePluginEnabled, uninstallClaudePlugin, updateClaudePlugin, validateClaudePlugin, } from './plugins/claude-plugin-runtime.js';
|
|
71
71
|
import { addClaudeMarketplace, disableAllNativePlugins, installClaudeMarketplacePlugin, listClaudeMarketplaceAvailablePlugins, listNativePluginRecords, readClaudeKnownMarketplaces, removeClaudeMarketplace, setNativePluginEnabled, saveClaudePluginConfig, uninstallNativePlugin, updateClaudeMarketplace, updateNativePlugin, validateClaudeMarketplace, } from './plugins/claude-plugin-marketplace.js';
|
|
72
72
|
import { executeClaudePluginEvalCommand, PLUGIN_EVAL_HELP, } from './plugins/claude-plugin-eval.js';
|
|
73
|
+
import { executeProjectEvalCommand, PROJECT_EVAL_HELP, } from './evals/project-eval.js';
|
|
73
74
|
import { CLAUDE_PLUGIN_PRUNE_HELP, CLAUDE_PLUGIN_TAG_HELP, executeClaudePluginPrune, planClaudePluginPrune, tagClaudePlugin, } from './plugins/claude-plugin-maintenance.js';
|
|
74
75
|
import { formatDoctorReport, runDoctor } from './maintenance/doctor.js';
|
|
75
76
|
import { runSelfUpdate, } from './maintenance/self-update.js';
|
|
@@ -123,6 +124,7 @@ Usage:
|
|
|
123
124
|
praxis mcp <list|get|add|add-json|remove|reset-project-choices|login|logout|serve> ...
|
|
124
125
|
praxis auto-mode <config|defaults|critique>
|
|
125
126
|
praxis plugin|plugins <details|list|install|uninstall|enable|disable|update|init|prune|tag|validate|marketplace> ...
|
|
127
|
+
praxis eval [options] <target>
|
|
126
128
|
praxis doctor [--json]
|
|
127
129
|
praxis auth <status|set-key|login|logout> ...
|
|
128
130
|
praxis import [options] [source]
|
|
@@ -2282,7 +2284,7 @@ const defaultPluginEvalRuntimeFactory = {
|
|
|
2282
2284
|
dataPlane: options.dataPlane,
|
|
2283
2285
|
sessionPersistence: false,
|
|
2284
2286
|
maxTurns: options.maxTurns,
|
|
2285
|
-
pluginDirectories: [...options.pluginDirectories],
|
|
2287
|
+
pluginDirectories: [...(options.pluginDirectories ?? [])],
|
|
2286
2288
|
addDirectories: [...options.addDirs],
|
|
2287
2289
|
allowedTools: [...options.allowedTools],
|
|
2288
2290
|
disallowedTools: [],
|
|
@@ -2305,6 +2307,7 @@ const defaultPluginEvalRuntimeFactory = {
|
|
|
2305
2307
|
...(result.costUsd === undefined
|
|
2306
2308
|
? {}
|
|
2307
2309
|
: { costUsd: result.costUsd }),
|
|
2310
|
+
usage: result.usage,
|
|
2308
2311
|
};
|
|
2309
2312
|
},
|
|
2310
2313
|
close: () => service.close?.() ?? Promise.resolve(),
|
|
@@ -2523,6 +2526,11 @@ export function createDefaultDependencies(entrypoint = fileURLToPath(import.meta
|
|
|
2523
2526
|
runtimeFactory: defaultPluginEvalRuntimeFactory,
|
|
2524
2527
|
judge: defaultPluginEvalJudge,
|
|
2525
2528
|
},
|
|
2529
|
+
projectEval: {
|
|
2530
|
+
runtimeFactory: defaultPluginEvalRuntimeFactory,
|
|
2531
|
+
version: VERSION,
|
|
2532
|
+
configRoot: resolveDataPlaneRoot(),
|
|
2533
|
+
},
|
|
2526
2534
|
cliPath: entrypoint,
|
|
2527
2535
|
runInteractive: async ({ agent, controls, initialPrompt, resume, signal, }) => {
|
|
2528
2536
|
const { runInteractive } = await import('./cli/interactive.js');
|
|
@@ -4899,6 +4907,7 @@ async function executeTeamCommand(args, io, dependencies, signal) {
|
|
|
4899
4907
|
}
|
|
4900
4908
|
function specialCommandIndex(argv) {
|
|
4901
4909
|
const commands = new Set([
|
|
4910
|
+
'eval',
|
|
4902
4911
|
'team',
|
|
4903
4912
|
'plugin',
|
|
4904
4913
|
'plugins',
|
|
@@ -4963,7 +4972,9 @@ async function execute(argv, io, dependencies, signal) {
|
|
|
4963
4972
|
return executeTeamCommand(argv.slice(commandIndex), io, dependencies, signal);
|
|
4964
4973
|
}
|
|
4965
4974
|
const specialPrefix = commandIndex > 0 &&
|
|
4966
|
-
(argv[commandIndex] === 'plugin' ||
|
|
4975
|
+
(argv[commandIndex] === 'plugin' ||
|
|
4976
|
+
argv[commandIndex] === 'plugins' ||
|
|
4977
|
+
argv[commandIndex] === 'eval')
|
|
4967
4978
|
? parseCliInvocation([...argv.slice(0, commandIndex), '__probe__'])
|
|
4968
4979
|
: undefined;
|
|
4969
4980
|
const special = commandIndex >= 0
|
|
@@ -4971,6 +4982,22 @@ async function execute(argv, io, dependencies, signal) {
|
|
|
4971
4982
|
args: argv.slice(commandIndex),
|
|
4972
4983
|
}
|
|
4973
4984
|
: { args: [...argv] };
|
|
4985
|
+
if (special.args[0] === 'eval') {
|
|
4986
|
+
if (special.args
|
|
4987
|
+
.slice(1)
|
|
4988
|
+
.some((value) => value === '-h' || value === '--help')) {
|
|
4989
|
+
io.stdout(PROJECT_EVAL_HELP);
|
|
4990
|
+
return 0;
|
|
4991
|
+
}
|
|
4992
|
+
if (!dependencies.projectEval)
|
|
4993
|
+
throw new Error('Project eval unavailable');
|
|
4994
|
+
return executeProjectEvalCommand([
|
|
4995
|
+
...(specialPrefix?.model === undefined
|
|
4996
|
+
? []
|
|
4997
|
+
: ['--model', specialPrefix.model]),
|
|
4998
|
+
...special.args.slice(1),
|
|
4999
|
+
], io, dependencies.projectEval, process.cwd(), signal);
|
|
5000
|
+
}
|
|
4974
5001
|
if ((special.args[0] === 'plugin' || special.args[0] === 'plugins') &&
|
|
4975
5002
|
special.args[1] === 'eval') {
|
|
4976
5003
|
if (!dependencies.pluginEval)
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import type { ModelUsage, RuntimeEvent } from '../core/runtime.js';
|
|
2
|
+
import type { DataPlane } from '../persistence/data-plane.js';
|
|
3
|
+
export interface EvalRuntime {
|
|
4
|
+
run(prompt: string, signal: AbortSignal): Promise<{
|
|
5
|
+
text: string;
|
|
6
|
+
turns: number;
|
|
7
|
+
costUsd?: number;
|
|
8
|
+
usage?: ModelUsage;
|
|
9
|
+
}>;
|
|
10
|
+
close?(): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
export interface EvalRuntimeFactoryOptions {
|
|
13
|
+
dataPlane: DataPlane;
|
|
14
|
+
cwd: string;
|
|
15
|
+
configRoot: string;
|
|
16
|
+
home: string;
|
|
17
|
+
model?: string;
|
|
18
|
+
maxTurns: number;
|
|
19
|
+
pluginDirectories?: readonly string[];
|
|
20
|
+
allowedTools: readonly string[];
|
|
21
|
+
appendSystemPrompt?: string;
|
|
22
|
+
historyFile?: string;
|
|
23
|
+
addDirs: readonly string[];
|
|
24
|
+
env: Readonly<Record<string, string>>;
|
|
25
|
+
eventSink(event: RuntimeEvent): void;
|
|
26
|
+
}
|
|
27
|
+
export interface EvalRuntimeFactory {
|
|
28
|
+
create(options: EvalRuntimeFactoryOptions): Promise<EvalRuntime>;
|
|
29
|
+
}
|
|
30
|
+
export interface EvalTraceEvent {
|
|
31
|
+
type: string;
|
|
32
|
+
tool?: string;
|
|
33
|
+
input?: Record<string, unknown>;
|
|
34
|
+
[key: string]: unknown;
|
|
35
|
+
}
|
|
36
|
+
export type EvalFocus = 'last_message' | 'trace' | 'files' | {
|
|
37
|
+
source: 'file';
|
|
38
|
+
path: string;
|
|
39
|
+
};
|
|
40
|
+
export type EvalArm = 'with-only' | 'both';
|
|
41
|
+
export type EvalToolMatch = string | {
|
|
42
|
+
tool: string;
|
|
43
|
+
input_match?: Record<string, unknown>;
|
|
44
|
+
};
|
|
45
|
+
export interface EvalGrader {
|
|
46
|
+
name: string;
|
|
47
|
+
weight: number;
|
|
48
|
+
arm?: EvalArm;
|
|
49
|
+
}
|
|
50
|
+
export type EvalGraderBase = EvalGrader;
|
|
51
|
+
export type EvalDeterministicGrader = (EvalGrader & {
|
|
52
|
+
type: 'regex';
|
|
53
|
+
target: EvalFocus;
|
|
54
|
+
pattern: string;
|
|
55
|
+
flags: string;
|
|
56
|
+
match: 'contains' | 'not_contains' | `count:${number}`;
|
|
57
|
+
}) | (EvalGrader & {
|
|
58
|
+
type: 'tool_order';
|
|
59
|
+
before: EvalToolMatch;
|
|
60
|
+
after: EvalToolMatch;
|
|
61
|
+
}) | (EvalGrader & {
|
|
62
|
+
type: 'tool_used';
|
|
63
|
+
tool: string;
|
|
64
|
+
input_match?: Record<string, unknown>;
|
|
65
|
+
min: number;
|
|
66
|
+
max: number;
|
|
67
|
+
}) | (EvalGrader & {
|
|
68
|
+
type: 'file_exists';
|
|
69
|
+
path: string;
|
|
70
|
+
exists: boolean;
|
|
71
|
+
});
|
|
72
|
+
export interface EvalRunArtifacts {
|
|
73
|
+
lastMessage: string;
|
|
74
|
+
trace: readonly EvalTraceEvent[];
|
|
75
|
+
cwd: string;
|
|
76
|
+
}
|
|
77
|
+
export interface EvalGraderResult {
|
|
78
|
+
name: string;
|
|
79
|
+
passed: boolean;
|
|
80
|
+
weight: number;
|
|
81
|
+
explanation: string;
|
|
82
|
+
judge_votes?: readonly boolean[];
|
|
83
|
+
evidence?: string;
|
|
84
|
+
with_only?: boolean;
|
|
85
|
+
}
|
|
86
|
+
export interface EvalJudge {
|
|
87
|
+
vote(request: {
|
|
88
|
+
criteria: string;
|
|
89
|
+
focus: string;
|
|
90
|
+
baseline?: string;
|
|
91
|
+
model: string;
|
|
92
|
+
signal?: AbortSignal;
|
|
93
|
+
}): Promise<{
|
|
94
|
+
passed: boolean;
|
|
95
|
+
explanation?: string;
|
|
96
|
+
costUsd: number;
|
|
97
|
+
}>;
|
|
98
|
+
}
|
|
99
|
+
export declare const DEFAULT_EVAL_ALLOWED_TOOLS: readonly ["Read", "Glob", "Grep", "Skill"];
|
|
100
|
+
export declare function resolveEvalAllowedTools(requested: readonly string[], operatorGrants: readonly string[]): string[];
|
|
101
|
+
export declare function normalizeEvalTraceEvent(event: RuntimeEvent): EvalTraceEvent;
|
|
102
|
+
//# sourceMappingURL=eval-contract.d.ts.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export const DEFAULT_EVAL_ALLOWED_TOOLS = [
|
|
2
|
+
'Read',
|
|
3
|
+
'Glob',
|
|
4
|
+
'Grep',
|
|
5
|
+
'Skill',
|
|
6
|
+
];
|
|
7
|
+
function toolName(rule) {
|
|
8
|
+
const i = rule.indexOf('(');
|
|
9
|
+
return i < 0 ? rule : rule.slice(0, i);
|
|
10
|
+
}
|
|
11
|
+
function gatedTool(rule) {
|
|
12
|
+
const name = toolName(rule);
|
|
13
|
+
return (['Bash', 'Write', 'Edit', 'NotebookEdit', 'WebFetch', 'WebSearch'].includes(name) || name.startsWith('mcp__'));
|
|
14
|
+
}
|
|
15
|
+
function grants(requested, allowed) {
|
|
16
|
+
const name = toolName(requested);
|
|
17
|
+
const wildcard = (pattern) => {
|
|
18
|
+
const parts = pattern.split('*');
|
|
19
|
+
if (parts.length === 1 || !requested.startsWith(parts[0] ?? ''))
|
|
20
|
+
return false;
|
|
21
|
+
let cursor = parts[0]?.length ?? 0;
|
|
22
|
+
for (const part of parts.slice(1, -1)) {
|
|
23
|
+
const index = requested.indexOf(part, cursor);
|
|
24
|
+
if (index < 0)
|
|
25
|
+
return false;
|
|
26
|
+
cursor = index + part.length;
|
|
27
|
+
}
|
|
28
|
+
const last = parts.at(-1) ?? '';
|
|
29
|
+
return last.length === 0 || requested.slice(cursor).endsWith(last);
|
|
30
|
+
};
|
|
31
|
+
return allowed.some((grant) => grant === requested || grant === name || wildcard(grant));
|
|
32
|
+
}
|
|
33
|
+
export function resolveEvalAllowedTools(requested, operatorGrants) {
|
|
34
|
+
const selected = requested.length ? requested : DEFAULT_EVAL_ALLOWED_TOOLS;
|
|
35
|
+
for (const rule of selected)
|
|
36
|
+
if (gatedTool(rule) && !grants(rule, operatorGrants))
|
|
37
|
+
throw new Error(`Eval case requests gated tool ${rule}; grant it with --allow-tools`);
|
|
38
|
+
return [...new Set(selected)];
|
|
39
|
+
}
|
|
40
|
+
export function normalizeEvalTraceEvent(event) {
|
|
41
|
+
if (event.type === 'tool-call')
|
|
42
|
+
return {
|
|
43
|
+
type: 'tool-call',
|
|
44
|
+
tool: event.call.name,
|
|
45
|
+
input: event.call.input,
|
|
46
|
+
id: event.call.id,
|
|
47
|
+
};
|
|
48
|
+
if (event.type === 'tool-result')
|
|
49
|
+
return {
|
|
50
|
+
type: 'tool-result',
|
|
51
|
+
callId: event.callId,
|
|
52
|
+
content: event.content,
|
|
53
|
+
isError: event.isError,
|
|
54
|
+
};
|
|
55
|
+
return event;
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=eval-contract.js.map
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type EvalDeterministicGrader, type EvalGraderResult, type EvalRunArtifacts } from './eval-contract.js';
|
|
2
|
+
export declare function gradeDeterministicEvalRun(options: {
|
|
3
|
+
graders: readonly EvalDeterministicGrader[];
|
|
4
|
+
artifacts: EvalRunArtifacts;
|
|
5
|
+
}): Promise<EvalGraderResult[]>;
|
|
6
|
+
//# sourceMappingURL=eval-graders.d.ts.map
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { glob, readFile, realpath } from 'node:fs/promises';
|
|
2
|
+
import { resolve, sep } from 'node:path';
|
|
3
|
+
import { minimatch } from 'minimatch';
|
|
4
|
+
function subset(actual, expected) {
|
|
5
|
+
if (expected && typeof expected === 'object' && !Array.isArray(expected)) {
|
|
6
|
+
if (!actual || typeof actual !== 'object' || Array.isArray(actual))
|
|
7
|
+
return false;
|
|
8
|
+
return Object.entries(expected).every(([key, value]) => subset(actual[key], value));
|
|
9
|
+
}
|
|
10
|
+
return Object.is(actual, expected);
|
|
11
|
+
}
|
|
12
|
+
function matches(event, match) {
|
|
13
|
+
const selected = typeof match === 'string' ? { tool: match } : match;
|
|
14
|
+
return (event.type === 'tool-call' &&
|
|
15
|
+
event.tool === selected.tool &&
|
|
16
|
+
(!selected.input_match || subset(event.input, selected.input_match)));
|
|
17
|
+
}
|
|
18
|
+
async function containedPath(root, candidate) {
|
|
19
|
+
const rootPath = await realpath(resolve(root));
|
|
20
|
+
const path = await realpath(resolve(rootPath, candidate));
|
|
21
|
+
if (path !== rootPath && !path.startsWith(`${rootPath}${sep}`))
|
|
22
|
+
throw new Error(`Grader path escapes workspace: ${candidate}`);
|
|
23
|
+
return path;
|
|
24
|
+
}
|
|
25
|
+
async function focusText(focus, artifacts) {
|
|
26
|
+
if (focus === 'last_message')
|
|
27
|
+
return artifacts.lastMessage;
|
|
28
|
+
if (focus === 'trace')
|
|
29
|
+
return artifacts.trace.map((item) => JSON.stringify(item)).join('\n');
|
|
30
|
+
if (focus === 'files') {
|
|
31
|
+
const names = [];
|
|
32
|
+
for await (const path of glob('**/*', {
|
|
33
|
+
cwd: artifacts.cwd,
|
|
34
|
+
exclude: ['node_modules/**', '.git/**'],
|
|
35
|
+
}))
|
|
36
|
+
names.push(path);
|
|
37
|
+
return names.sort().join('\n');
|
|
38
|
+
}
|
|
39
|
+
return readFile(await containedPath(artifacts.cwd, focus.path), 'utf8');
|
|
40
|
+
}
|
|
41
|
+
export async function gradeDeterministicEvalRun(options) {
|
|
42
|
+
const results = [];
|
|
43
|
+
for (const grader of options.graders) {
|
|
44
|
+
let passed = false;
|
|
45
|
+
let evidence = '';
|
|
46
|
+
if (grader.type === 'regex') {
|
|
47
|
+
const target = await focusText(grader.target, options.artifacts);
|
|
48
|
+
const expression = new RegExp(grader.pattern, grader.flags.includes('g') ? grader.flags : `${grader.flags}g`);
|
|
49
|
+
const count = [...target.matchAll(expression)].length;
|
|
50
|
+
passed =
|
|
51
|
+
grader.match === 'contains'
|
|
52
|
+
? count > 0
|
|
53
|
+
: grader.match === 'not_contains'
|
|
54
|
+
? count === 0
|
|
55
|
+
: count === Number(grader.match.slice(6));
|
|
56
|
+
evidence = `matches=${count}`;
|
|
57
|
+
}
|
|
58
|
+
else if (grader.type === 'tool_used') {
|
|
59
|
+
const count = options.artifacts.trace.filter((event) => matches(event, {
|
|
60
|
+
tool: grader.tool,
|
|
61
|
+
...(grader.input_match ? { input_match: grader.input_match } : {}),
|
|
62
|
+
})).length;
|
|
63
|
+
passed = count >= grader.min && count <= grader.max;
|
|
64
|
+
evidence = `uses=${count}`;
|
|
65
|
+
}
|
|
66
|
+
else if (grader.type === 'tool_order') {
|
|
67
|
+
const before = options.artifacts.trace.findIndex((event) => matches(event, grader.before));
|
|
68
|
+
const after = options.artifacts.trace.findIndex((event, index) => index > before && matches(event, grader.after));
|
|
69
|
+
passed = before >= 0 && after > before;
|
|
70
|
+
evidence = `before=${before},after=${after}`;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
let count = 0;
|
|
74
|
+
for await (const path of glob('**/*', { cwd: options.artifacts.cwd })) {
|
|
75
|
+
if (!minimatch(path, grader.path))
|
|
76
|
+
continue;
|
|
77
|
+
await containedPath(options.artifacts.cwd, path);
|
|
78
|
+
count += 1;
|
|
79
|
+
}
|
|
80
|
+
passed = grader.exists ? count > 0 : count === 0;
|
|
81
|
+
evidence = `files=${count}`;
|
|
82
|
+
}
|
|
83
|
+
results.push({
|
|
84
|
+
name: grader.name,
|
|
85
|
+
passed,
|
|
86
|
+
weight: grader.weight,
|
|
87
|
+
explanation: passed ? 'passed' : 'failed',
|
|
88
|
+
evidence,
|
|
89
|
+
...(grader.arm === 'with-only' ? { with_only: true } : {}),
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
return results;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=eval-graders.js.map
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { ModelUsage } from '../core/runtime.js';
|
|
2
|
+
import { type EvalGraderResult, type EvalRuntimeFactory } from './eval-contract.js';
|
|
3
|
+
import type { ProjectEvalCase } from './project-eval-schema.js';
|
|
4
|
+
export type ProjectEvalTermination = 'timeout' | 'interrupted' | null;
|
|
5
|
+
export interface ProjectEvalVerificationResult {
|
|
6
|
+
schema_version: '1.0';
|
|
7
|
+
name: string;
|
|
8
|
+
command: string;
|
|
9
|
+
argv: readonly string[];
|
|
10
|
+
exit_code: number | null;
|
|
11
|
+
timed_out: boolean;
|
|
12
|
+
stdout: string;
|
|
13
|
+
stderr: string;
|
|
14
|
+
truncated: boolean;
|
|
15
|
+
duration_ms: number;
|
|
16
|
+
passed: boolean;
|
|
17
|
+
error: string | null;
|
|
18
|
+
}
|
|
19
|
+
export interface ProjectEvalRunResult {
|
|
20
|
+
schema_version: '1.0';
|
|
21
|
+
case: string;
|
|
22
|
+
run: number;
|
|
23
|
+
version: string;
|
|
24
|
+
model: string | null;
|
|
25
|
+
passed: boolean;
|
|
26
|
+
score: 0 | 1;
|
|
27
|
+
turns: number;
|
|
28
|
+
usage: ModelUsage | null;
|
|
29
|
+
cost_usd: number | null;
|
|
30
|
+
cost_known: boolean;
|
|
31
|
+
duration_ms: number;
|
|
32
|
+
termination: ProjectEvalTermination;
|
|
33
|
+
graders: readonly EvalGraderResult[];
|
|
34
|
+
checks: readonly EvalGraderResult[];
|
|
35
|
+
artifacts: {
|
|
36
|
+
trace: 'trace.jsonl';
|
|
37
|
+
workspace_diff: 'workspace-diff.json';
|
|
38
|
+
verification: 'verification.json';
|
|
39
|
+
result: 'result.json';
|
|
40
|
+
};
|
|
41
|
+
error: string | null;
|
|
42
|
+
cleanup_errors: readonly string[];
|
|
43
|
+
temp_root: string | null;
|
|
44
|
+
}
|
|
45
|
+
interface ProjectEvalRunOptions {
|
|
46
|
+
case: ProjectEvalCase;
|
|
47
|
+
factory: EvalRuntimeFactory;
|
|
48
|
+
run: number;
|
|
49
|
+
allowTools?: readonly string[];
|
|
50
|
+
model?: string;
|
|
51
|
+
keepTemp?: boolean;
|
|
52
|
+
runVerification?: boolean;
|
|
53
|
+
outputDir: string;
|
|
54
|
+
version: string;
|
|
55
|
+
signal?: AbortSignal;
|
|
56
|
+
}
|
|
57
|
+
export declare function runProjectEvalCase(options: ProjectEvalRunOptions): Promise<ProjectEvalRunResult>;
|
|
58
|
+
export {};
|
|
59
|
+
//# sourceMappingURL=project-eval-runner.d.ts.map
|