Documentation
¶
Overview ¶
Package benchmark provides benchmarking infrastructure for testing LLM tool usage.
Index ¶
- Variables
- func FindBenchmarksFile(workspaceRoot string) string
- func FindHaystackFile(workspaceRoot string) string
- func FindThinkbenchSuite(root string) string
- func GetBenchmarksByCategory(benchmarks []BenchmarkDef) map[string][]BenchmarkDef
- func GetCSVPath(outputPath string) string
- func GroupBenchmarksByHaystack(benchmarks []BenchmarkDef) map[string][]BenchmarkDef
- func IsNeedleRetrieval(b BenchmarkDef) bool
- func ListBenchmarks(cfg *config.Config) error
- func ListCategories(benchmarks []BenchmarkDef) []string
- func LoadHaystackContent(benchmarksDir string, haystack HaystackDef) (string, error)
- func NewANSIStripWriter(w io.Writer) io.Writer
- func ResolveThinkbench(root, override, configDir string) (suiteDir, tbRoot string)
- func Run(ctx context.Context, flags CLIFlags, runner *agent.Runner, cfg *config.Config, ...) error
- func RunHaystack(ctx context.Context, flags HaystackCLIFlags, cfg *config.Config, ...) error
- func RunThinkbench(ctx context.Context, flags ThinkbenchCLIFlags, runner *agent.Runner, ...) error
- func WriteTBResultsJSON(path string, res *TBResults) error
- func WriteTBResultsMarkdown(path string, model string, res *TBResults, rawResults []TBRunResult, ...) error
- type AggregatedStats
- type BenchmarkConfig
- type BenchmarkDef
- type BenchmarksFile
- type CLIFlags
- type CSVWriter
- type ClassStats
- type Environment
- func (e *Environment) CleanupAll() error
- func (e *Environment) CleanupBenchmark(benchmark BenchmarkDef, runID int) error
- func (e *Environment) FileExistsInWorkspace(benchmarkID string, runID int, relativePath string) bool
- func (e *Environment) GetWorkspaceDir(benchmarkID string, runID int) string
- func (e *Environment) Initialize() error
- func (e *Environment) ListFilesInWorkspace(benchmarkID string, runID int) ([]string, error)
- func (e *Environment) LoadExpected(benchmarkID string) ([]byte, error)
- func (e *Environment) ReadFileFromWorkspace(benchmarkID string, runID int, relativePath string) ([]byte, error)
- func (e *Environment) SaveExpected(benchmarkID string, content []byte) error
- func (e *Environment) SetupBenchmark(benchmark BenchmarkDef, runID int) (string, error)
- type ExecuteResult
- type Executor
- type FailureDetail
- type HaystackBenchmarkDef
- type HaystackCLIFlags
- type HaystackDef
- type HaystackFile
- type Progress
- func (p *Progress) CompleteRun(duration time.Duration, result *RunResult)
- func (p *Progress) Display()
- func (p *Progress) Finish()
- func (p *Progress) PrintSummary(results []RunResult)
- func (p *Progress) SetResumePoint(completedRuns int, originalStartTime time.Time)
- func (p *Progress) StartRun(benchmarkID string, run int, prompt string)
- type Report
- type ReportGenerator
- type ResumeInfo
- type RunResult
- type Runner
- type Sandbox
- type SetupFile
- type TBCSVWriter
- type TBCheck
- type TBExecutor
- type TBManifestEntry
- type TBResults
- type TBRunResult
- type TBScorecard
- type TBTask
- type TBType
- type ThinkbenchCLIFlags
- type ToolCallLog
- type ValidationCheck
- type ValidationResult
- type Validator
Constants ¶
This section is empty.
Variables ¶
var CSVHeaders = []string{
"benchmark_id",
"run",
"success",
"llm_calls",
"tokens",
"prompt_tokens",
"generated_tokens",
"cached_tokens",
"context_used",
"cost",
"duration_ms",
"prompt_ms",
"generation_ms",
"tool_calls",
"errors",
"started_at",
"completed_at",
}
CSVHeaders are the column headers for the benchmark CSV.
var TBCSVHeaders = []string{
"slug", "type", "run", "observed",
"score", "passed", "total", "full_pass", "import_ok",
"llm_calls", "tokens", "prompt_tokens", "generated_tokens", "cached_tokens",
"context_used", "cost", "duration_ms", "errors", "workspace_dir", "failed_checks",
"timed_out",
}
TBCSVHeaders are the columns for the thinkbench results CSV (used for resume).
Functions ¶
func FindBenchmarksFile ¶
FindBenchmarksFile looks for benchmarks.yaml in standard locations.
func FindHaystackFile ¶
FindHaystackFile looks for haystack.yaml in standard locations.
func FindThinkbenchSuite ¶
FindThinkbenchSuite locates the in-repo thinkbench suite directory. It checks benchmarks/thinkbench/suite under the given root and a couple of parents, so it works whether kvit-coder is invoked from the repo root or the benchmarks directory. Returns "" if not found.
func GetBenchmarksByCategory ¶
func GetBenchmarksByCategory(benchmarks []BenchmarkDef) map[string][]BenchmarkDef
GetBenchmarksByCategory groups benchmarks by category.
func GetCSVPath ¶
GetCSVPath returns the CSV path for a given output path. If output is benchmark-results.md, returns benchmark-results.csv
func GroupBenchmarksByHaystack ¶
func GroupBenchmarksByHaystack(benchmarks []BenchmarkDef) map[string][]BenchmarkDef
GroupBenchmarksByHaystack groups needle_retrieval benchmarks by their haystack. Returns a map of haystack ID -> benchmarks, preserving order within each group.
func IsNeedleRetrieval ¶
func IsNeedleRetrieval(b BenchmarkDef) bool
IsNeedleRetrieval returns true if the benchmark is a needle retrieval type.
func ListBenchmarks ¶
ListBenchmarks prints available benchmarks.
func ListCategories ¶
func ListCategories(benchmarks []BenchmarkDef) []string
ListCategories returns unique categories from benchmarks.
func LoadHaystackContent ¶
func LoadHaystackContent(benchmarksDir string, haystack HaystackDef) (string, error)
LoadHaystackContent loads the content of a haystack file. If the file doesn't exist and generate script is specified, runs the script first.
func NewANSIStripWriter ¶
NewANSIStripWriter creates a new writer that strips ANSI escape codes.
func ResolveThinkbench ¶
ResolveThinkbench resolves the suite directory and the thinkbench root (the parent of the suite, under which the generated runs/.uv/results dirs live), anchored to the suite location rather than the current working directory. This lets the harness run identically from the repo root or from benchmarks/. Precedence for the suite: explicit override → config suite_dir → discovery. suiteDir is "" when the suite cannot be found; tbRoot then falls back to <root>/benchmarks/thinkbench.
func Run ¶
func Run(ctx context.Context, flags CLIFlags, runner *agent.Runner, cfg *config.Config, systemPrompt string, version string, originalWorkspaceRoot string) error
Run executes the benchmark CLI with the given configuration. originalWorkspaceRoot is the workspace before benchmark override (for finding benchmarks.yaml)
func RunHaystack ¶
func RunHaystack(ctx context.Context, flags HaystackCLIFlags, cfg *config.Config, version string, originalWorkspaceRoot string) error
RunHaystack executes haystack (needle retrieval) benchmarks. These benchmarks inject large context into the prompt and test retrieval without tools.
func RunThinkbench ¶
func RunThinkbench(ctx context.Context, flags ThinkbenchCLIFlags, runner *agent.Runner, cfg *config.Config, systemPrompt, version, originalWorkspaceRoot string) error
RunThinkbench runs the thinkbench benchmark family: it provisions the uv environment, sets up the OS sandbox, runs each (task × trial) through the agent loop in a hard workspace sandbox, grades with the held-out grader, and writes results.json + RESULTS.md. It mirrors RunHaystack's orchestration.
func WriteTBResultsJSON ¶
WriteTBResultsJSON writes results.json.
func WriteTBResultsMarkdown ¶
func WriteTBResultsMarkdown(path string, model string, res *TBResults, rawResults []TBRunResult, configYAML string) error
WriteTBResultsMarkdown writes the human-readable report: overall, by-type, per-task (with timing), every per-run result, a failures breakdown (which grader checks failed), the observed tasks, and the config it ran with.
Types ¶
type AggregatedStats ¶
type AggregatedStats struct {
BenchmarkID string `json:"benchmark_id"`
TotalRuns int `json:"total_runs"`
Successes int `json:"successes"`
Failures int `json:"failures"`
SuccessRate float64 `json:"success_rate"`
// LLM Calls
LLMCallsMin int `json:"llm_calls_min"`
LLMCallsMax int `json:"llm_calls_max"`
LLMCallsMean float64 `json:"llm_calls_mean"`
LLMCallsMedian float64 `json:"llm_calls_median"`
LLMCallsP5 float64 `json:"llm_calls_p5"`
LLMCallsP95 float64 `json:"llm_calls_p95"`
LLMCallsStdDev float64 `json:"llm_calls_stddev"`
// Tokens (total: prompt + completion)
TokensMin int `json:"tokens_min"`
TokensMax int `json:"tokens_max"`
TokensMean float64 `json:"tokens_mean"`
TokensMedian float64 `json:"tokens_median"`
TokensP5 float64 `json:"tokens_p5"`
TokensP95 float64 `json:"tokens_p95"`
TokensStdDev float64 `json:"tokens_stddev"`
// Generated Tokens (completion tokens only)
GeneratedTokensMin int `json:"generated_tokens_min"`
GeneratedTokensMax int `json:"generated_tokens_max"`
GeneratedTokensMean float64 `json:"generated_tokens_mean"`
GeneratedTokensMedian float64 `json:"generated_tokens_median"`
GeneratedTokensP5 float64 `json:"generated_tokens_p5"`
GeneratedTokensP95 float64 `json:"generated_tokens_p95"`
GeneratedTokensStdDev float64 `json:"generated_tokens_stddev"`
// Context Used (max context window used)
ContextUsedMin int `json:"context_used_min"`
ContextUsedMax int `json:"context_used_max"`
ContextUsedMean float64 `json:"context_used_mean"`
ContextUsedMedian float64 `json:"context_used_median"`
ContextUsedP5 float64 `json:"context_used_p5"`
ContextUsedP95 float64 `json:"context_used_p95"`
// Processed Tokens (prompt - cached)
ProcessedTokensMean float64 `json:"processed_tokens_mean"`
// Speed metrics (tokens/sec, weighted averages across all runs)
PromptSpeed float64 `json:"prompt_speed"` // processed tokens / prompt time
GenerationSpeed float64 `json:"generation_speed"` // generated tokens / generation time
// Cost
CostMin float64 `json:"cost_min"`
CostMax float64 `json:"cost_max"`
CostMean float64 `json:"cost_mean"`
CostTotal float64 `json:"cost_total"`
CostStdDev float64 `json:"cost_stddev"`
// Duration
DurationMinMS int64 `json:"duration_min_ms"`
DurationMaxMS int64 `json:"duration_max_ms"`
DurationMeanMS float64 `json:"duration_mean_ms"`
DurationMedianMS float64 `json:"duration_median_ms"`
DurationP5MS float64 `json:"duration_p5_ms"`
DurationP95MS float64 `json:"duration_p95_ms"`
DurationStdDevMS float64 `json:"duration_stddev_ms"`
// Tool usage
ToolCallCounts map[string]int `json:"tool_call_counts"`
// Errors
ErrorCounts map[string]int `json:"error_counts"`
}
AggregatedStats holds aggregated statistics for a benchmark across all runs.
type BenchmarkConfig ¶
type BenchmarkConfig struct {
Enabled bool `yaml:"enabled"`
OutputDir string `yaml:"output_dir"`
RunsPerTask int `yaml:"runs_per_task"`
TimeoutPerRun int `yaml:"timeout_per_run"` // seconds
ReportFormat string `yaml:"report_format"` // "markdown" or "json"
Categories []string `yaml:"categories"` // Which categories to run
BenchmarkIDs []string `yaml:"benchmark_ids"` // Specific benchmarks to run
WarmupTask string `yaml:"warmup_task"` // Warmup task (default: "Say hello")
NoResume bool `yaml:"no_resume"` // Force fresh start
}
BenchmarkConfig holds configuration for benchmark runs.
func DefaultBenchmarkConfig ¶
func DefaultBenchmarkConfig() *BenchmarkConfig
DefaultBenchmarkConfig returns default benchmark configuration.
type BenchmarkDef ¶
type BenchmarkDef struct {
ID string `yaml:"id"`
Name string `yaml:"name"`
Category string `yaml:"category"`
Goal string `yaml:"goal"`
Setup []SetupFile `yaml:"setup"`
Task string `yaml:"task"`
Validation []ValidationCheck `yaml:"validation"`
Tags []string `yaml:"tags"`
Haystack string `yaml:"haystack,omitempty"` // For needle_retrieval: haystack ID to use
}
BenchmarkDef defines a single benchmark test case.
func FilterBenchmarks ¶
func FilterBenchmarks(benchmarks []BenchmarkDef, categories []string, ids []string) []BenchmarkDef
FilterBenchmarks filters benchmarks by category and/or IDs.
func LoadBenchmarks ¶
func LoadBenchmarks(path string) ([]BenchmarkDef, error)
LoadBenchmarks loads benchmark definitions from a YAML file.
func LoadBenchmarksWithHaystacks ¶
func LoadBenchmarksWithHaystacks(path string) (map[string]HaystackDef, []BenchmarkDef, error)
LoadBenchmarksWithHaystacks loads benchmark definitions and haystack configs from a YAML file.
type BenchmarksFile ¶
type BenchmarksFile struct {
Haystacks map[string]HaystackDef `yaml:"haystacks"`
Benchmarks []BenchmarkDef `yaml:"benchmarks"`
}
BenchmarksFile represents the structure of benchmarks.yaml
type CLIFlags ¶
type CLIFlags struct {
Enabled bool
Runs int
Category string
BenchmarkID string
OutputFile string
NoResume bool
Suffix string
}
CLIFlags holds the command-line flags for benchmarks.
type CSVWriter ¶
type CSVWriter struct {
// contains filtered or unexported fields
}
CSVWriter handles writing benchmark results to CSV.
func NewCSVWriter ¶
NewCSVWriter creates a new CSV writer for benchmark results.
func (*CSVWriter) WriteResult ¶
WriteResult writes a single benchmark result to CSV.
type ClassStats ¶
type ClassStats struct {
Class string
TotalRuns int
Successes int
Failures int
SuccessRate float64
TotalDurationMS int64
TotalGeneratedTokens int64
}
ClassStats holds aggregated statistics for a benchmark class (e.g., C, E, R, S, W)
type Environment ¶
type Environment struct {
BaseDir string // .kvit-coder-benchmark
SetupDir string // .kvit-coder-benchmark/setup
WorkspaceDir string // .kvit-coder-benchmark/workspace
ExpectedDir string // .kvit-coder-benchmark/expected
ResultsDir string // .kvit-coder-benchmark/results
}
Environment manages the benchmark test environment.
func NewEnvironment ¶
func NewEnvironment(baseDir string) *Environment
NewEnvironment creates a new benchmark environment.
func (*Environment) CleanupAll ¶
func (e *Environment) CleanupAll() error
CleanupAll removes all benchmark workspaces.
func (*Environment) CleanupBenchmark ¶
func (e *Environment) CleanupBenchmark(benchmark BenchmarkDef, runID int) error
CleanupBenchmark cleans the workspace after a benchmark run.
func (*Environment) FileExistsInWorkspace ¶
func (e *Environment) FileExistsInWorkspace(benchmarkID string, runID int, relativePath string) bool
FileExistsInWorkspace checks if a file exists in the benchmark workspace.
func (*Environment) GetWorkspaceDir ¶
func (e *Environment) GetWorkspaceDir(benchmarkID string, runID int) string
GetWorkspaceDir returns the workspace directory for a specific run.
func (*Environment) Initialize ¶
func (e *Environment) Initialize() error
Initialize creates the benchmark directory structure.
func (*Environment) ListFilesInWorkspace ¶
func (e *Environment) ListFilesInWorkspace(benchmarkID string, runID int) ([]string, error)
ListFilesInWorkspace lists all files in the benchmark workspace.
func (*Environment) LoadExpected ¶
func (e *Environment) LoadExpected(benchmarkID string) ([]byte, error)
LoadExpected loads expected results for validation.
func (*Environment) ReadFileFromWorkspace ¶
func (e *Environment) ReadFileFromWorkspace(benchmarkID string, runID int, relativePath string) ([]byte, error)
ReadFileFromWorkspace reads a file from the benchmark workspace.
func (*Environment) SaveExpected ¶
func (e *Environment) SaveExpected(benchmarkID string, content []byte) error
SaveExpected saves expected results for validation.
func (*Environment) SetupBenchmark ¶
func (e *Environment) SetupBenchmark(benchmark BenchmarkDef, runID int) (string, error)
SetupBenchmark prepares the workspace for a specific benchmark run. All benchmarks share the same workspace directory, which is cleaned before each run.
type ExecuteResult ¶
type ExecuteResult struct {
RunResult *RunResult
FinalOutput string
ToolCalls []ToolCallLog
Messages []llm.Message
WorkspaceDir string
}
ExecuteResult contains the result of executing a benchmark.
type Executor ¶
type Executor struct {
// contains filtered or unexported fields
}
Executor handles running a single benchmark.
func NewExecutor ¶
func NewExecutor(runner *agent.Runner, cfg *config.Config, systemPrompt string, env *Environment, timeout time.Duration, stdoutWriter, stderrWriter io.Writer) *Executor
NewExecutor creates a new benchmark executor.
func (*Executor) Execute ¶
func (e *Executor) Execute(ctx context.Context, benchmark BenchmarkDef, runID int) (*ExecuteResult, error)
Execute runs a single benchmark and returns the result.
func (*Executor) IsExternalCommand ¶
IsExternalCommand returns true if the executor is configured to use an external command.
type FailureDetail ¶
type FailureDetail struct {
BenchmarkID string `json:"benchmark_id"`
Run int `json:"run"`
Errors []string `json:"errors"`
LastToolCall string `json:"last_tool_call,omitempty"`
}
FailureDetail captures information about a failed benchmark run.
type HaystackBenchmarkDef ¶
type HaystackBenchmarkDef struct {
ID string `yaml:"id"`
Name string `yaml:"name"`
Haystack string `yaml:"haystack"`
Task string `yaml:"task"`
Validation []ValidationCheck `yaml:"validation"`
Tags []string `yaml:"tags"`
}
HaystackBenchmarkDef defines a haystack benchmark (simpler than tool benchmarks)
type HaystackCLIFlags ¶
type HaystackCLIFlags struct {
Enabled bool
Runs int
BenchmarkID string
OutputFile string
NoResume bool
Suffix string
}
HaystackCLIFlags holds the command-line flags for haystack benchmarks.
type HaystackDef ¶
type HaystackDef struct {
File string `yaml:"file"` // Path to haystack file (relative to benchmarks dir)
Generate string `yaml:"generate"` // Optional script to generate the file
Source string `yaml:"source"` // Optional download URL
Description string `yaml:"description"` // Human-readable description
}
HaystackDef defines a large context file for needle retrieval benchmarks.
type HaystackFile ¶
type HaystackFile struct {
Haystacks map[string]HaystackDef `yaml:"haystacks"`
Benchmarks []HaystackBenchmarkDef `yaml:"benchmarks"`
}
HaystackFile represents the structure of haystack.yaml
func LoadHaystackBenchmarks ¶
func LoadHaystackBenchmarks(path string) (*HaystackFile, error)
LoadHaystackBenchmarks loads haystack benchmark definitions from haystack.yaml
type Progress ¶
type Progress struct {
// contains filtered or unexported fields
}
Progress tracks and displays benchmark progress.
func NewProgress ¶
NewProgress creates a new progress tracker.
func (*Progress) CompleteRun ¶
CompleteRun marks a run as complete and shows pass/fail status with statistics.
func (*Progress) PrintSummary ¶
PrintSummary prints a summary after all benchmarks complete.
func (*Progress) SetResumePoint ¶
SetResumePoint sets the starting point when resuming.
type Report ¶
type Report struct {
Version string `json:"version"`
Date time.Time `json:"date"`
Config string `json:"config"` // Full config.yaml contents
Summary []AggregatedStats `json:"summary"`
Failures []FailureDetail `json:"failures"`
RawResults []RunResult `json:"raw_results,omitempty"` // Optional detailed results
}
Report holds the complete benchmark report.
type ReportGenerator ¶
type ReportGenerator struct {
// contains filtered or unexported fields
}
ReportGenerator generates benchmark reports.
func NewReportGenerator ¶
func NewReportGenerator(results []RunResult, benchmarks []BenchmarkDef, version, configYAML string, numRuns int) *ReportGenerator
NewReportGenerator creates a new report generator.
func (*ReportGenerator) GenerateMarkdown ¶
func (g *ReportGenerator) GenerateMarkdown() string
GenerateMarkdown generates a markdown report.
func (*ReportGenerator) WriteMarkdown ¶
func (g *ReportGenerator) WriteMarkdown(path string) error
WriteMarkdown writes the markdown report to a file.
type ResumeInfo ¶
type ResumeInfo struct {
CompletedRuns map[string]map[int]bool // map[benchmarkID]map[runNumber]completed
FirstStarted time.Time // When benchmarking started
LastCompleted time.Time // Last completion time
}
ResumeInfo contains information about where to resume benchmark runs.
func GetResumeInfo ¶
func GetResumeInfo(results []RunResult) *ResumeInfo
GetResumeInfo analyzes existing results to determine resume point.
func (*ResumeInfo) CountCompleted ¶
func (r *ResumeInfo) CountCompleted() int
CountCompleted returns the total number of completed runs.
func (*ResumeInfo) IsCompleted ¶
func (r *ResumeInfo) IsCompleted(benchmarkID string, run int) bool
IsCompleted checks if a specific benchmark run is already completed.
type RunResult ¶
type RunResult struct {
BenchmarkID string `json:"benchmark_id" csv:"benchmark_id"`
Run int `json:"run" csv:"run"`
Success bool `json:"success" csv:"success"`
LLMCalls int `json:"llm_calls" csv:"llm_calls"`
Tokens int `json:"tokens" csv:"tokens"`
PromptTokens int `json:"prompt_tokens" csv:"prompt_tokens"`
GeneratedTokens int `json:"generated_tokens" csv:"generated_tokens"`
CachedTokens int `json:"cached_tokens" csv:"cached_tokens"`
ContextUsed int `json:"context_used" csv:"context_used"`
Cost float64 `json:"cost" csv:"cost"`
DurationMS int64 `json:"duration_ms" csv:"duration_ms"`
PromptMS float64 `json:"prompt_ms" csv:"prompt_ms"`
GenerationMS float64 `json:"generation_ms" csv:"generation_ms"`
ToolCalls []ToolCallLog `json:"tool_calls" csv:"-"`
Errors []string `json:"errors" csv:"-"`
StartedAt time.Time `json:"started_at" csv:"started_at"`
CompletedAt time.Time `json:"completed_at" csv:"completed_at"`
// For CSV serialization
ToolCallsJSON string `json:"-" csv:"tool_calls"`
ErrorsJSON string `json:"-" csv:"errors"`
}
RunResult captures metrics from a single benchmark run.
func LoadResults ¶
LoadResults loads all benchmark results from a CSV file.
type Runner ¶
type Runner struct {
// contains filtered or unexported fields
}
Runner orchestrates the execution of all benchmarks.
func NewRunner ¶
func NewRunner(executor *Executor, env *Environment, config *BenchmarkConfig, benchmarks []BenchmarkDef, writer io.Writer, csvPath string) *Runner
NewRunner creates a new benchmark runner.
type Sandbox ¶
type Sandbox struct {
Tool string // "bwrap", "firejail", or "none"
ExecPrefix []string // argv prepended before "sh -c <cmd>" ({workdir} substituted at run time)
}
Sandbox describes the resolved sandbox configuration for a thinkbench run.
type SetupFile ¶
type SetupFile struct {
File string `yaml:"file"`
Content string `yaml:"content"`
Binary []byte `yaml:"binary,omitempty"` // For binary file tests
Dir bool `yaml:"dir,omitempty"` // Create directory instead of file
}
SetupFile defines a file to create for benchmark setup.
type TBCSVWriter ¶
type TBCSVWriter struct {
// contains filtered or unexported fields
}
TBCSVWriter appends thinkbench run results to a CSV for resume.
func NewTBCSVWriter ¶
func NewTBCSVWriter(path string, resume bool) (*TBCSVWriter, error)
NewTBCSVWriter opens (or creates) the CSV. When resume is true it appends.
func (*TBCSVWriter) WriteResult ¶
func (w *TBCSVWriter) WriteResult(r *TBRunResult) error
WriteResult appends one result row.
type TBCheck ¶
type TBCheck struct {
ID string `json:"id"`
Desc string `json:"desc"`
Detail string `json:"detail"`
Passed bool `json:"passed"`
}
TBCheck is one behavioral check within a grader scorecard.
type TBExecutor ¶
type TBExecutor struct {
// contains filtered or unexported fields
}
TBExecutor runs a single thinkbench (task, trial) end-to-end: sandboxed setup → agent loop → grade (or persist, for observed tasks).
func NewTBExecutor ¶
func NewTBExecutor(runner *agent.Runner, cfg *config.Config, systemPrompt string, env *thinkbenchEnv, workspace, observedDir string, timeout time.Duration, stdout, stderr io.Writer) *TBExecutor
NewTBExecutor builds a thinkbench executor.
func (*TBExecutor) Execute ¶
func (e *TBExecutor) Execute(ctx context.Context, task TBTask, runID int) *TBRunResult
Execute runs one (task, trial) and returns its result.
type TBManifestEntry ¶
type TBManifestEntry struct {
Slug string `json:"slug"`
Type string `json:"type"`
Brief string `json:"brief"`
Observed bool `json:"observed"`
NumChecks int `json:"num_checks"`
HasSetup bool `json:"has_setup"`
}
TBManifestEntry mirrors one entry in the suite manifest.json.
type TBResults ¶
type TBResults struct {
RunIDs []int64 `json:"run_ids"`
Models []string `json:"models"`
Trials int `json:"trials"`
NumGradedTasks int `json:"num_graded_tasks"`
NumObservedTasks int `json:"num_observed_tasks"`
NumRuns int `json:"num_runs"`
EffortMode string `json:"effort_mode"`
Config map[string]any `json:"config"`
OverallGraded map[string]tbRollup `json:"overall_graded"`
ByType map[string]map[string]tbRollup `json:"by_type"`
ByTask map[string]tbByTaskEntry `json:"by_task"`
Observed map[string]map[string]tbRollup `json:"observed"`
}
TBResults is the top-level results.json document.
func BuildTBResults ¶
func BuildTBResults(model string, runID int64, trials int, tasks []TBTask, results []TBRunResult, config map[string]any) *TBResults
BuildTBResults assembles the results document from all run results.
type TBRunResult ¶
type TBRunResult struct {
Slug string
Type string
Run int
Observed bool
// Scoring (graded tasks only; observed tasks leave these zero).
Score float64 // 0..1 = passed/total
Passed int
Total int
FullPass bool // Score == 1.0 — the binary "solve" analogue
ImportOK bool
// Metrics (reused from agent stats, mirroring RunResult).
DurationMS int64
Tokens int
PromptTokens int
GeneratedTokens int
CachedTokens int
ContextUsed int
Cost float64
LLMCalls int
// TimedOut records that the run was stopped by thinkbench.timeout_per_run
// rather than finishing. Such a run is still graded on whatever it wrote,
// so a nonzero Score here does not mean the agent completed the task.
TimedOut bool
Errors []string
FailedChecks []string // "check_id: detail" for each grader check that did not pass
WorkspaceDir string // persisted path for observed tasks / grading failures
}
TBRunResult captures the outcome and metrics of one (task, trial) run.
func LoadTBResults ¶
func LoadTBResults(path string) ([]TBRunResult, error)
LoadTBResults loads previously recorded thinkbench results from CSV.
func (*TBRunResult) CachedFrac ¶
func (r *TBRunResult) CachedFrac() float64
CachedFrac returns the cached fraction of prompt tokens for this run.
type TBScorecard ¶
type TBScorecard struct {
Task string `json:"task"`
ImportOK bool `json:"import_ok"`
Passed int `json:"passed"`
Total int `json:"total"`
Score float64 `json:"score"`
Checks []TBCheck `json:"checks"`
}
TBScorecard is the JSON scorecard a grade.py prints to stdout.
type TBTask ¶
type TBTask struct {
Slug string
Type TBType
Brief string // brief.txt contents (the only prompt the agent sees)
Observed bool // ambiguous-spec → true (no grader, persist-only)
NumChecks int // from manifest (0 for observed)
HasSetup bool // has a setup/ starter tree
SetupDir string // abs path to suite/tasks/<slug>/setup (may not exist)
GraderPath string // abs path to suite/tasks/<slug>/grade.py (held out; "" for observed)
}
TBTask is a single thinkbench task loaded from the suite directory.
func FilterThinkbench ¶
FilterThinkbench narrows tasks by slug (ids) and/or type, and applies the observed-task policy. When ids is non-empty, only matching slugs are kept (and observed tasks named explicitly are included regardless of policy). When types is non-empty, only matching types are kept. includeObserved controls whether ungraded ambiguous-spec tasks are run when not named explicitly.
func LoadThinkbenchSuite ¶
LoadThinkbenchSuite reads the suite manifest and, per task, resolves the on-disk brief, setup tree, and held-out grader path. It prefers the on-disk brief.txt over the manifest copy to avoid drift.
type ThinkbenchCLIFlags ¶
type ThinkbenchCLIFlags struct {
Enabled bool
Runs int // trials per task (already resolved: -n / config.trials / default)
BenchmarkID string // comma-separated slugs
Types string // comma-separated type override
SuiteDir string // override suite directory
OutputFile string
NoResume bool // accepted for parity; thinkbench is fresh-by-default so this is a no-op
Resume bool // opt in to resuming the most recent interrupted run
Suffix string
}
ThinkbenchCLIFlags holds the command-line flags for thinkbench benchmarks.
type ToolCallLog ¶
type ToolCallLog struct {
Tool string `json:"tool"`
Args json.RawMessage `json:"args,omitempty"`
}
ToolCallLog captures a single tool call made during a benchmark run.
func ExtractToolCalls ¶
func ExtractToolCalls(messages []json.RawMessage) []ToolCallLog
ExtractToolCalls extracts tool call logs from agent messages.
type ValidationCheck ¶
type ValidationCheck struct {
Type string `yaml:"type"` // "file_contains", "file_equals", "file_exists", "file_not_exists", "file_line_count", "tool_called", "tool_called_with", "output_contains", "output_not_contains", "multi_tool_calls", "run_command"
Target string `yaml:"target"` // File path or "output"
Expected string `yaml:"expected"` // Expected value, pattern, or tool name
Args string `yaml:"args"` // Expected args pattern (for tool_called_with)
Command string `yaml:"command"` // Command to run (for run_command)
Count int `yaml:"count"` // Expected count (for file_line_count, multi_tool_calls)
Line int `yaml:"line"` // Specific line number (for file_line_equals)
Negate bool `yaml:"negate"` // Check for absence instead of presence
}
ValidationCheck defines a validation condition for benchmark success.
type ValidationResult ¶
type ValidationResult struct {
Check ValidationCheck
Passed bool
Message string
}
ValidationResult holds the result of a single validation check.
type Validator ¶
type Validator struct {
// contains filtered or unexported fields
}
Validator validates benchmark results against expected conditions.
func NewValidator ¶
func NewValidator(workspaceDir, output string, toolCalls []ToolCallLog) *Validator
NewValidator creates a new validator for a benchmark run.