export interface BenchFixtureSpec { /** Path under bench/ root, e.g. "fixtures/sales.xlsx". */ source: string; /** Destination relative to the task workspace. Either "input/" (uploaded as attachment) or "web/" (served by HTTP server, no upload). */ dest: string; } export interface BenchExpectations { must_use_tools?: string[]; forbidden_tools?: string[]; /** Tools forbidden against specific file extensions: e.g. { Read: [".xlsx", ".docx"] }. */ forbidden_tool_for_ext?: Record; must_produce_files?: string[]; /** Acceptable terminal job statuses. Default: ["succeeded"]. */ completion_status?: Array<'succeeded' | 'waiting_human' | 'failed' | 'aborted' | 'cancelled'>; } export type ProgrammaticConstraint = | { type: 'file_first_line_equals'; file: string; line: string } | { type: 'file_must_contain_in_order'; file: string; sections: string[] } | { type: 'file_line_starts_with'; file: string; prefix: string; min_lines: number; section?: string } | { type: 'file_line_max_chars'; file: string; max: number; section?: string } | { type: 'file_section_max_lines'; file: string; section: string; max: number } | { type: 'file_no_pattern'; file: string; pattern: string }; export interface BenchGrading { programmatic?: { weight?: number; constraints?: ProgrammaticConstraint[] }; llm_judge?: { weight?: number; rubrics: Array<{ name: string; prompt: string; max_score?: number; // default 10 }>; }; } export interface BenchTask { id: string; title: string; prompt: string; piece_hint?: string; fixtures?: BenchFixtureSpec[]; /** Tokens substituted into the prompt at runtime: e.g. {WEB_PORT}. */ prompt_tokens?: Record; expected: BenchExpectations; grading?: BenchGrading; /** Required checklist tools and minimum CheckItem count for axis B. */ checklist?: { required_tools: string[]; min_check_item_calls: number }; timeout_minutes?: number; } export interface ToolCallObservation { name: string; /** Approximate input shown in activity.log; not the full tool input. */ inputSummary: string; /** Tool first-arg-as-path heuristic, when available. */ filePath?: string; } export interface RawJobResult { taskId: number; jobId: string; status: string; iterations?: number | null; promptTokens?: number | null; completionTokens?: number | null; workspacePath: string; activityLog: string; toolCalls: ToolCallObservation[]; outputFiles: Record; durationMs: number; } export interface AxisScore { /** 0..1 normalized score. */ score: number; /** Human readable detail entries. */ details: string[]; } export interface BenchResult { taskId: string; taskTitle: string; startedAt: string; finishedAt: string; raw: RawJobResult; axes: { tools: AxisScore; checklist: AxisScore; instructions: AxisScore; reasoning: AxisScore; }; /** Weighted total 0..100. */ total: number; }