Add a Benchmark
A benchmark owns the dataset contract, task preparation, evaluation logic, and aggregate metrics. It should not own model-provider calls, agent loops, sandbox lifecycle, or provider-specific image selection. Add a benchmark when you are introducing a new task family or a new scoring protocol. If the change only adapts an existing benchmark to a new sandbox image or workspace layout, add a recipe instead.Benchmark File
Create a module undersrc/agentcompass/benchmarks/. Most benchmarks define a RuntimeBenchmarkConfig subclass, an optional BenchmarkPlan, and a BaseBenchmark subclass.
Benchmark Responsibilities
Use
TaskSpec.metadata for source records, image names, docker metadata, expected files, and benchmark-specific IDs. Use PreparedTask.input and PreparedTask.output for the actual harness contract.
Register And Verify
Export the benchmark insrc/agentcompass/benchmarks/__init__.py so registry import side effects can discover it:
Add a Harness
A harness owns the agent or model execution loop. It consumesPreparedTask, RunRequest.model, and an EnvironmentSession, then returns a normalized RunResult. It should not load datasets, score benchmark correctness, or hard-code provider-specific sandbox images.
Add a harness when you are integrating a new agent framework, coding assistant, GUI agent, direct model-call path, or tool-use strategy.
Harness File
Create a module undersrc/agentcompass/harnesses/. A typical harness defines a user-facing config, a runtime plan, and a BaseHarness subclass.
Harness Responsibilities
Use
prepared.input.workspace, prepared.input.files, prepared.input.media, prepared.input.tools, and prepared.input.messages instead of reaching back into benchmark internals. A harness should be reusable across benchmarks that emit the same prepared-task contract.
Register And Verify
Export the harness insrc/agentcompass/harnesses/__init__.py:
Add an Environment
An environment provider owns execution primitives: commands, file transfer, text IO, directory sync, endpoint discovery, and teardown. It should not know benchmark scoring rules or agent behavior. Add an environment when AgentCompass needs to run the same benchmark/harness matrix on a new local process, container runtime, cloud sandbox, or remote execution provider.Environment File
Create a module undersrc/agentcompass/environments/. Each provider usually has a session class, config dataclass, and BaseEnvironment implementation.
Environment Responsibilities
Provider defaults belong in
config/defaults.yaml when they are useful for normal users. Benchmark-specific image, snapshot, workspace, or resource mapping belongs in recipes.
Register And Verify
Export the environment fromsrc/agentcompass/environments/__init__.py. Guard optional SDK imports if the dependency is not always installed:
Add a Recipe
A recipe is a compatibility layer between one benchmark family and one environment provider. It rewrites the per-taskExecutionPlan before the sandbox starts, usually to select images, workspaces, resource requests, snapshots, environment variables, or evaluation layout.
Add a recipe when task metadata already contains provider-relevant information and users should not have to pass it manually on the CLI.
Recipe File
Create a module undersrc/agentcompass/recipes/<benchmark_family>/. Keep one provider recipe per file when the provider behavior is meaningfully different.
Recipe Responsibilities
Recipes are applied automatically when
execution.enabled_recipes is empty. Users can restrict recipe selection with --enabled-recipes.
Register And Verify
Export the recipe from the package initializer:Recipe matched with the new recipe id:
Add an Analyzer
Analyzers run after a task produces aRunResult. They inspect trajectories, metrics, errors, latency, model output, or tool calls, then attach an AnalysisResult under analysis_result.<AnalyzerId> in each details JSON. Aggregate fields are rendered into analysis_summary.md and analysis_summary.json.
Add an analyzer when the logic is post-execution diagnosis or statistics. Do not put analyzer logic in a benchmark or harness if it can be rerun later with agentcompass analysis.
Analyzer File
Create a new file undersrc/agentcompass/analyzers/basic/, or create a dedicated sub-package for a larger analyzer family. Each analyzer must subclass BaseAnalyzer, register with @ANALYZERS.register(), and implement analysis().
Analyzer Attributes
AnalysisResult.is_badcase should be True for detected badcases, False for explicitly clean samples, and None for statistics-only analyzers that should not affect badcase ratios.
Aggregate Fields
Declare every cross-task summary field indistribution_fields:
Only keys returned inside
AnalysisResult.details can be aggregated.
Register And Verify
Export the analyzer from package initializers so registry import side effects can see it:Developer Notes
- Keep analyzer code read-only with respect to task execution. It should inspect persisted results, not mutate benchmark behavior.
- Use
datasetsfor benchmark-specific analyzers instead of branching on unrelated task metadata. - Use
base_analyzerandprioritywhen a benchmark-specific analyzer should override a generic analyzer. - Return a descriptive
errorinstead of raising when a sample cannot be analyzed because optional trajectory fields are missing.
