Skip to main content
AgentCompass is organized around a direct evaluation runtime, but the more important design choice is that evaluation pieces are intentionally decoupled. A run is the composition of four independent axes:
Benchmark x Harness x Model x Environment
The benchmark owns task loading, task preparation, and scoring. The harness owns the agent loop or external agent framework. The model spec owns endpoint, protocol, credentials, and generation parameters. The environment owns command execution, files, workspaces, and optional remote sandbox lifecycle. The runtime connects these pieces through one shared RunRequest and a small set of contracts such as PreparedTask, EnvironmentSession, ExecutionPlan, and RunResult. That is why the same benchmark can be evaluated with different harnesses, the same harness can move from local execution to Modal or Daytona, and a model endpoint can be swapped without changing benchmark code.
AgentCompass aims for free composition, with explicit compatibility checks where reality requires them. A harness can reject unsupported environment/model combinations through supports(...), and recipes can adapt images, workspaces, and resources before sandbox startup.

Module Map

Runtime

Builds RunRequest, loads components, applies concurrency limits, emits progress, and persists artifacts.

Configuration

Explains default files, override precedence, scoped params, and how to keep secrets out of shared config.

Benchmarks

Load tasks, prepare benchmark material, score harness output, and aggregate metrics.

Harnesses

Adapt models, CLIs, and external agent frameworks to the shared PreparedTask contract.

Environments

Provide command execution and file primitives across local, container, remote, and cluster providers.

Recipes

Rewrite execution plans before sandbox startup, especially for images, workspaces, and provider resources.

Models

Carry run-local endpoint, protocol, API key, and sampling configuration.

Results

Store per-task details, summaries, progress events, logs, and analysis artifacts.

Analyzers

Re-run post-analysis over trajectories and aggregate latency, behavior, and qualitative reports.

One Run Lifecycle

CLI / Python API
  -> RunRequest
  -> benchmark.load_tasks()
  -> benchmark.select_tasks()
  -> planner builds ExecutionPlan
  -> recipes may rewrite plan
  -> environment.open()
  -> benchmark.prepare_task()
  -> harness.run_task()
  -> benchmark.evaluate()
  -> details + summary + progress + logs
  -> optional analyzers

Design Principles

PrincipleMeaning
Independent selection axesbenchmark, harness, model, and environment are separate specs in RunRequest, not hard-coded into one runner.
Narrow runtime contractsModules communicate through PreparedTask, EnvironmentSession, ExecutionPlan, and RunResult, not through private implementation fields.
Benchmark-owned truthBenchmarks own datasets, task material, evaluation, and aggregation. Harnesses do not score themselves.
Provider-neutral executionBenchmarks and harnesses use environment primitives instead of calling Modal, Daytona, Docker, or cluster SDKs directly.
Recipes adapt, not coupleRecipes resolve provider-specific images, workspaces, snapshots, and resources before startup without moving that logic into benchmarks.
Durable artifactsdetails/*.json, summaries, logs, progress events, and analyzer output preserve enough state to debug or re-analyze a run later.

What This Enables

ChangeWhat stays stable
Swap glm-5.2 for another OpenAI-compatible endpointBenchmark tasks, harness logic, environment setup, and scoring.
Run mini_swe_agent on Modal instead of DaytonaHarness behavior and SWE-bench scoring, while recipes adapt image and workspace details.
Compare multiple harnesses on SWE-bench VerifiedDataset loading, task metadata, and pass/fail evaluation.
Move a terminal benchmark from local execution to a remote sandboxBenchmark selection and harness contract, while environment provider changes the execution surface.
Add a new analyzer after results already existOriginal execution artifacts remain reusable; analysis is a post-processing layer.

Read By Goal

GoalStart here
Run an existing benchmarkRuntime, Configuration, Models, Results
Choose an execution backendEnvironments, Recipes
Add a new benchmarkBenchmarks, Data Protocol
Add a new agent adapterHarnesses, Runtime Extensions
Debug failures after a runResults, Analyzers

Composition Examples

These are examples of how the same runtime shape spans different evaluation styles. Copyable commands live in Setup and the cookbooks; this section focuses on the module boundaries.

GUI grounding, local execution

screenspot + qwen3vl_gui + host_process: the benchmark owns images and scoring, the harness adapts a VLM-style interaction loop, and the environment only needs local command/file primitives.

Agentic coding, remote sandbox

swebench_verified + mini_swe_agent + modal or daytona: the benchmark provides repository tasks and pass/fail evaluation, while recipes derive image and workspace settings before sandbox startup.

Terminal tasks, isolated shell

terminal_bench_2 + terminus2 + daytona or modal: the harness drives terminal behavior, and the environment provider supplies an isolated filesystem and shell for each task.

Research and tool use, API-first

browsecomp + researchharness + host_process: the benchmark supplies questions and judge logic, while the harness handles research workflow and model calls without a benchmark-specific sandbox provider.
Use the pages in this section to understand which module owns each responsibility, where defaults come from, and where to add a new implementation.