Skip to content

Architecture

Mickl edited this page Jul 10, 2026 · 2 revisions

AgentBench — System Architecture

1. Architecture Overview

┌─────────────────────────────────────────────────────────────────────┐
│                        AgentBench System                             │
├─────────────────────────────────────────────────────────────────────┤
│                                                                      │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐                 │
│  │   CLI Tool  │  │  Web Dashboard│ │   SDKs      │                 │
│  │ (Commander) │  │  (Next.js)   │  │ (@agentbench│                 │
│  │             │  │              │  │  /openai,   │                 │
│  │             │  │              │  │  /anthropic,│                 │
│  │             │  │              │  │  /mcp...)   │                 │
│  └──────┬──────┘  └──────┬───────┘  └──────┬──────┘                 │
│         │                │                 │                         │
│         └────────────────┼─────────────────┘                         │
│                          │                                           │
│                          ▼                                           │
│  ┌──────────────────────────────────────────────┐                   │
│  │              API Layer (REST + WS)            │                   │
│  │  ┌──────────┐ ┌──────────┐ ┌──────────────┐ │                   │
│  │  │ REST API │ │Server    │ │ WebSocket    │ │                   │
│  │  │(Next.js) │ │Actions   │ │ (Realtime)   │ │                   │
│  │  └──────────┘ └──────────┘ └──────────────┘ │                   │
│  └──────────────────────┬───────────────────────┘                   │
│                         │                                            │
│                         ▼                                            │
│  ┌──────────────────────────────────────────────┐                   │
│  │            @agentbench/core                   │                   │
│  │                                               │                   │
│  │  ┌─────────┐ ┌─────────┐ ┌────────────────┐ │                   │
│  │  │ Runner  │ │ Tracer  │ │  Storage       │ │                   │
│  │  │ Engine  │ │ Engine  │ │  Layer         │ │                   │
│  │  └────┬────┘ └────┬────┘ └───────┬────────┘ │                   │
│  │       │           │              │           │                   │
│  │  ┌────┴────┐ ┌────┴────┐ ┌──────┴────────┐ │                   │
│  │  │Replay   │ │Evaluator│ │  Snapshot     │ │                   │
│  │  │Engine   │ │Engine   │ │  Manager      │ │                   │
│  │  └─────────┘ └─────────┘ └───────────────┘ │                   │
│  │                                               │                   │
│  │  ┌─────────┐ ┌─────────┐ ┌────────────────┐ │                   │
│  │  │Diff     │ │Coverage │ │  Reporter      │ │                   │
│  │  │Engine   │ │Engine   │ │  Engine        │ │                   │
│  │  └─────────┘ └─────────┘ └────────────────┘ │                   │
│  └──────────────────────┬───────────────────────┘                   │
│                         │                                            │
│                         ▼                                            │
│  ┌──────────────────────────────────────────────┐                   │
│  │              Data & Infra Layer               │                   │
│  │                                               │                   │
│  │  ┌──────────┐ ┌──────────┐ ┌──────────────┐ │                   │
│  │  │PostgreSQL│ │  Redis   │ │ File Storage │ │                   │
│  │  │(Primary) │ │(Cache/Q) │ │ (S3/Local)   │ │                   │
│  │  └──────────┘ └──────────┘ └──────────────┘ │                   │
│  │                                               │                   │
│  │  ┌──────────┐ ┌──────────┐                   │                   │
│  │  │ BullMQ   │ │ External │                   │                   │
│  │  │(Workers) │ │ LLM APIs │                   │                   │
│  │  └──────────┘ └──────────┘                   │                   │
│  └──────────────────────────────────────────────┘                   │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘

2. Monorepo Package Architecture

2.1 Dependency Graph (v0.3.0 — 15 Packages)

                         ┌─────────────┐
                         │  @agentbench│
                         │  /core      │
                         └──────┬──────┘
                                │
       ┌────────────────────────┼────────────────────────────┐
       │                        │                            │
       ▼                        ▼                            ▼
┌────────────┐          ┌────────────┐              ┌────────────┐
│@agentbench │          │@agentbench │              │@agentbench │
│/openai     │          │/anthropic  │              │/mcp        │
└────────────┘          └────────────┘              └────────────┘

       ▼                        ▼                            ▼
┌────────────┐ [NEW]   ┌────────────┐ [NEW]    ┌────────────┐ [NEW]
│@agentbench │          │@agentbench │          │@agentbench │
│/gemini     │          │/deepseek   │          │/azure-openai│
└────────────┘          └────────────┘          └────────────┘

       ▼                        ▼                            ▼
┌────────────┐ [NEW]   ┌────────────┐ [NEW]    ┌────────────┐ [NEW]
│@agentbench │          │@agentbench │          │@agentbench │
│/openrouter │          │/groq       │          │/ollama     │
└────────────┘          └────────────┘          └────────────┘

                                │
                                ▼
                  ┌────────────────────┐ [NEW]
                  │ @agentbench        │
                  │ /provider-utils    │
                  └─────────┬──────────┘
                            │
          ┌─────────────────┼─────────────────┐
          │                 │                 │
          ▼                 ▼                 ▼
   ┌────────────┐   ┌────────────┐   ┌────────────┐
   │ agentbench │   │ agentbench │   │ agentbench │
   │ CLI        │   │ web        │   │ vscode [NEW]│
   └────────────┘   └────────────┘   └────────────┘

2.2 Package Responsibilities (v0.3.0 — 15 Packages)

Package Responsibility Dependencies Status
@agentbench/core Core engine: Runner, Tracer, Evaluator, Assertion, Snapshot, Diff, Coverage, Reporter, Storage abstraction, Dataset engine, Config system None (except DB driver) Updated
@agentbench/openai OpenAI SDK interception/wrapping @agentbench/core Stable
@agentbench/anthropic Anthropic SDK interception/wrapping @agentbench/core Stable
@agentbench/mcp MCP client wrapping and tracing @agentbench/core Stable
@agentbench/gemini Google Gemini SDK wrapping @agentbench/core, @agentbench/provider-utils [NEW]
@agentbench/deepseek DeepSeek API SDK wrapping @agentbench/core, @agentbench/provider-utils [NEW]
@agentbench/azure-openai Azure OpenAI Service SDK wrapping @agentbench/core, @agentbench/provider-utils [NEW]
@agentbench/openrouter OpenRouter multi-provider gateway wrapping @agentbench/core, @agentbench/provider-utils [NEW]
@agentbench/groq Groq fast inference SDK wrapping @agentbench/core, @agentbench/provider-utils [NEW]
@agentbench/ollama Ollama local model wrapping @agentbench/core, @agentbench/provider-utils [NEW]
@agentbench/provider-utils Shared base classes and utilities for building providers (AgentBenchProvider interface, OpenAICompatibleProvider base class) @agentbench/core [NEW]
agentbench-cli CLI tool (commander.js + ink) — 13 commands including dataset, benchmark @agentbench/core, all providers Updated
agentbench-web Next.js Dashboard @agentbench/core Updated
agentbench-vscode VS Code Extension — inline test results, trace viewer, run launcher @agentbench/core [NEW]
agentbench-github GitHub Integration — Actions, status checks, PR comments, CI badges @agentbench/core [NEW]

3. @agentbench/core — Detailed Design

3.1 Module Architecture

@agentbench/core/src/
├── index.ts                    # Public API surface
├── types/                      # Core type definitions
│   ├── index.ts
│   ├── trace.ts                # ExecutionTrace, TraceStep
│   ├── run.ts                  # Run, RunConfig, RunResult
│   ├── evaluator.ts            # Evaluator, Score, JudgeConfig
│   ├── assertion.ts            # Assertion, AssertionResult
│   ├── snapshot.ts             # Snapshot
│   ├── test.ts                 # TestCase, TestSuite
│   ├── experiment.ts           # Experiment, Variant
│   ├── coverage.ts             # CoverageReport
│   ├── dataset.ts              # Dataset, DatasetItem
│   └── provider.ts             # Provider, Model configs
│
├── runner/                     # Agent Runner Engine
│   ├── index.ts
│   ├── runner.ts               # Main runner class
│   ├── context.ts              # Execution context builder
│   ├── sandbox.ts              # Execution sandbox
│   ├── timeout.ts              # Timeout management
│   └── concurrency.ts          # Concurrent execution
│
├── tracer/                     # Execution Tracer
│   ├── index.ts
│   ├── tracer.ts               # Main tracer class
│   ├── interceptors/           # LLM SDK interceptors
│   │   ├── base.ts
│   │   ├── openai.ts
│   │   ├── anthropic.ts
│   │   └── generic.ts
│   ├── stream-capture.ts       # Streaming response capture
│   └── tool-capture.ts         # Tool call capture
│
├── evaluator/                  # Evaluation Engine
│   ├── index.ts
│   ├── rule-evaluator.ts       # Rule-based evaluation
│   ├── llm-judge.ts            # LLM-as-Judge
│   ├── hybrid-judge.ts         # Hybrid evaluation
│   ├── judge-pool.ts           # Judge model pool
│   └── scoring/                # Scoring functions
│       ├── correctness.ts
│       ├── faithfulness.ts
│       ├── safety.ts
│       ├── relevance.ts
│       ├── completeness.ts
│       └── reasoning.ts
│
├── assertion/                  # Assertion Engine
│   ├── index.ts
│   ├── assert.ts               # Main assertion builder
│   ├── matchers/               # Matcher library
│   │   ├── tool-matchers.ts
│   │   ├── token-matchers.ts
│   │   ├── latency-matchers.ts
│   │   ├── output-matchers.ts
│   │   └── score-matchers.ts
│   └── result.ts               # Assertion result types
│
├── snapshot/                   # Snapshot Manager
│   ├── index.ts
│   ├── create.ts               # Snapshot creation
│   ├── restore.ts              # Snapshot restoration
│   ├── compare.ts              # Snapshot comparison
│   └── store.ts                # Snapshot storage
│
├── diff/                       # Diff Engine
│   ├── index.ts
│   ├── text-diff.ts            # Text/prompt diff
│   ├── trace-diff.ts           # Execution trace diff
│   ├── metric-diff.ts          # Numeric metric diff
│   └── renderer.ts             # Diff visualization data
│
├── replay/                     # Replay Engine
│   ├── index.ts
│   ├── replay.ts               # Main replay class
│   ├── deterministic.ts        # Deterministic replay
│   └── cross-model.ts          # Cross-model replay
│
├── coverage/                   # Coverage Engine
│   ├── index.ts
│   ├── prompt-coverage.ts      # Variable combination coverage
│   ├── workflow-coverage.ts    # Execution path coverage
│   ├── tool-coverage.ts        # Tool call coverage
│   └── calculator.ts           # Coverage percentage calculation
│
├── experiment/                 # Experiment Engine
│   ├── index.ts
│   ├── experiment.ts           # Experiment runner
│   ├── variant.ts              # Variant management
│   └── statistics.ts           # Statistical tests
│
├── reporter/                   # Report Generation
│   ├── index.ts
│   ├── json-reporter.ts
│   ├── html-reporter.ts
│   ├── markdown-reporter.ts
│   └── junit-reporter.ts
│
├── storage/                    # Storage Abstraction Layer
│   ├── index.ts
│   ├── adapter.ts              # Storage adapter interface
│   ├── postgres-adapter.ts     # PostgreSQL adapter
│   ├── sqlite-adapter.ts       # SQLite adapter (local dev)
│   ├── memory-adapter.ts       # In-memory (ephemeral)
│   └── file-adapter.ts         # File-based (CLI local mode)
│
├── config/                     # Configuration
│   ├── index.ts
│   ├── loader.ts               # Config file loader
│   └── schema.ts               # Zod schema for config
│
└── utils/                      # Utilities
    ├── token-counter.ts        # Token counting (tiktoken)
    ├── cost-calculator.ts      # Cost calculation
    ├── latency.ts              # Timing utilities
    ├── id-generator.ts         # Run ID generation
    └── logger.ts               # Structured logging

3.2 Key Interfaces

// @agentbench/core/src/types/trace.ts

interface ExecutionTrace {
  id: string
  runId: string
  steps: TraceStep[]
  metadata: TraceMetadata
  createdAt: Date
}

interface TraceStep {
  id: string
  sequence: number
  type: 'llm_call' | 'tool_call' | 'response' | 'error'
  
  // Timing
  startedAt: Date
  endedAt: Date
  duration: number  // ms
  
  // LLM Call specific
  llmRequest?: {
    provider: string
    model: string
    messages: Message[]
    tools?: ToolDefinition[]
    temperature: number
    maxTokens: number
  }
  llmResponse?: {
    content: string
    toolCalls?: ToolCall[]
    finishReason: string
    usage: TokenUsage
  }
  
  // Tool Call specific
  toolRequest?: {
    name: string
    arguments: Record<string, unknown>
  }
  toolResponse?: {
    result: unknown
    error?: string
  }
  
  // Cost
  cost: number
  
  // Status
  status: 'success' | 'error' | 'timeout'
  error?: Error
}

interface TokenUsage {
  promptTokens: number
  completionTokens: number
  totalTokens: number
}
// @agentbench/core/src/types/run.ts

interface RunConfig {
  name: string
  description?: string
  projectId: string
  testCaseId?: string
  
  // Agent configuration
  agent: {
    provider: 'openai' | 'anthropic' | 'gemini' | 'custom'
    model: string
    temperature: number
    maxTokens: number
    systemPrompt: string
    tools: ToolDefinition[]
  }
  
  // Input
  input: {
    messages: Message[]
    variables?: Record<string, string>
    context?: Record<string, unknown>
  }
  
  // Execution options
  options: {
    timeout: number        // ms
    maxSteps: number
    retries: number
    concurrency: number
    seed?: number          // For deterministic replay
  }
  
  // Tags
  tags: string[]
  metadata: Record<string, unknown>
}

interface RunResult {
  id: string
  config: RunConfig
  status: 'passed' | 'failed' | 'error' | 'timeout'
  
  // Trace
  trace: ExecutionTrace
  
  // Metrics
  metrics: RunMetrics
  
  // Evaluations
  scores: Score[]
  assertionResults: AssertionResult[]
  
  // Timing
  startedAt: Date
  endedAt: Date
  duration: number
  
  // Summary
  summary: string
}

interface RunMetrics {
  totalTokens: number
  promptTokens: number
  completionTokens: number
  totalCost: number
  totalLatency: number
  firstTokenLatency: number
  toolCallCount: number
  toolSuccessCount: number
  toolFailureCount: number
  stepCount: number
  llmCallCount: number
}

4. API Design

4.1 REST API Endpoints

# Projects
GET    /api/v1/projects
POST   /api/v1/projects
GET    /api/v1/projects/:id
PATCH  /api/v1/projects/:id
DELETE /api/v1/projects/:id

# Test Suites
GET    /api/v1/projects/:projectId/suites
POST   /api/v1/projects/:projectId/suites
GET    /api/v1/suites/:id
PATCH  /api/v1/suites/:id
DELETE /api/v1/suites/:id

# Test Cases
GET    /api/v1/suites/:suiteId/cases
POST   /api/v1/suites/:suiteId/cases
GET    /api/v1/cases/:id
PATCH  /api/v1/cases/:id
DELETE /api/v1/cases/:id

# Runs
POST   /api/v1/runs                    # Execute a run
GET    /api/v1/runs                    # List runs (with filters)
GET    /api/v1/runs/:id                # Run detail
GET    /api/v1/runs/:id/trace          # Execution trace
GET    /api/v1/runs/:id/scores         # Evaluation scores
POST   /api/v1/runs/:id/replay        # Replay this run
POST   /api/v1/runs/:id/evaluate      # Re-evaluate
GET    /api/v1/runs/:id/artifacts     # Run artifacts (streaming)

# Compare / Diff
POST   /api/v1/compare                 # Compare two runs
GET    /api/v1/compare/:id             # Comparison result

# Snapshots
GET    /api/v1/projects/:projectId/snapshots
POST   /api/v1/snapshots
GET    /api/v1/snapshots/:id
POST   /api/v1/snapshots/:id/restore
DELETE /api/v1/snapshots/:id

# Experiments
GET    /api/v1/projects/:projectId/experiments
POST   /api/v1/experiments
GET    /api/v1/experiments/:id
POST   /api/v1/experiments/:id/run
GET    /api/v1/experiments/:id/results

# Coverage
GET    /api/v1/projects/:projectId/coverage
GET    /api/v1/projects/:projectId/coverage/trend

# Datasets
GET    /api/v1/projects/:projectId/datasets
POST   /api/v1/datasets
GET    /api/v1/datasets/:id
POST   /api/v1/datasets/:id/import
GET    /api/v1/datasets/:id/export
DELETE /api/v1/datasets/:id

# API Keys
GET    /api/v1/api-keys
POST   /api/v1/api-keys
DELETE /api/v1/api-keys/:id

# Dashboard
GET    /api/v1/dashboard/stats         # Aggregated statistics
GET    /api/v1/dashboard/trends        # Time-series data
GET    /api/v1/dashboard/models        # Per-model stats

# Auth
POST   /api/v1/auth/sign-up
POST   /api/v1/auth/sign-in
POST   /api/v1/auth/sign-out
POST   /api/v1/auth/refresh

# Webhook
POST   /api/v1/webhooks/github
POST   /api/v1/webhooks/gitlab
POST   /api/v1/webhooks/ci

4.2 WebSocket Events

# Real-time Run Updates
ws://localhost:3000/ws/runs/:runId

Events:
  - run.started        { runId, timestamp }
  - run.step           { runId, step: TraceStep }
  - run.completed      { runId, result: RunResult }
  - run.error          { runId, error }
  
# Dashboard Live Updates
ws://localhost:3000/ws/dashboard

Events:
  - stats.updated      { stats: DashboardStats }
  - run.created        { run: RunSummary }
  - run.completed      { run: RunSummary }

5. Route Design (Next.js App Router)

app/
├── (auth)/
│   ├── sign-in/page.tsx
│   ├── sign-up/page.tsx
│   ├── forgot-password/page.tsx
│   └── layout.tsx                    # Auth layout (centered card)
│
├── (dashboard)/
│   ├── layout.tsx                    # Dashboard layout (sidebar + header)
│   │
│   ├── dashboard/
│   │   └── page.tsx                  # Main dashboard
│   │
│   ├── projects/
│   │   ├── page.tsx                  # Project list
│   │   └── [projectId]/
│   │       ├── page.tsx              # Project overview
│   │       ├── tests/
│   │       │   ├── page.tsx          # Test suites & cases
│   │       │   └── [testId]/
│   │       │       └── page.tsx      # Test case detail
│   │       ├── runs/
│   │       │   ├── page.tsx          # Run history
│   │       │   └── [runId]/
│   │       │       ├── page.tsx      # Run detail (timeline)
│   │       │       └── trace/
│   │       │           └── page.tsx  # Full trace view
│   │       ├── experiments/
│   │       │   ├── page.tsx          # Experiment list
│   │       │   └── [experimentId]/
│   │       │       └── page.tsx      # Experiment detail
│   │       ├── coverage/
│   │       │   └── page.tsx          # Coverage dashboard
│   │       ├── datasets/
│   │       │   ├── page.tsx          # Dataset list
│   │       │   └── [datasetId]/
│   │       │       └── page.tsx      # Dataset detail
│   │       └── settings/
│   │           └── page.tsx          # Project settings
│   │
│   ├── snapshots/
│   │   ├── page.tsx                  # Snapshot list
│   │   └── [snapshotId]/
│   │       └── page.tsx              # Snapshot detail
│   │
│   ├── compare/
│   │   └── page.tsx                  # Compare runs
│   │
│   ├── settings/
│   │   ├── page.tsx                  # Account settings
│   │   ├── api-keys/
│   │   │   └── page.tsx              # API keys management
│   │   ├── team/
│   │   │   └── page.tsx              # Team management (Pro)
│   │   └── billing/
│   │       └── page.tsx              # Billing (Pro)
│   │
│   └── docs/
│       └── page.tsx                  # In-app documentation
│
├── api/
│   └── v1/
│       ├── projects/...
│       ├── runs/...
│       ├── snapshots/...
│       ├── experiments/...
│       ├── datasets/...
│       ├── compare/...
│       └── ...
│
├── layout.tsx                        # Root layout
├── page.tsx                          # Landing page
├── error.tsx                         # Global error boundary
├── not-found.tsx                     # 404 page
└── loading.tsx                       # Global loading

6. CLI Architecture

agentbench-cli/src/
├── index.ts                    # Entry point
├── cli.ts                      # CLI bootstrap
│
├── commands/
│   ├── init.ts                 # agentbench init
│   ├── run.ts                  # agentbench run
│   ├── test.ts                 # agentbench test
│   ├── replay.ts               # agentbench replay
│   ├── compare.ts              # agentbench compare
│   ├── snapshot.ts             # agentbench snapshot
│   ├── experiment.ts           # agentbench experiment
│   ├── report.ts               # agentbench report
│   ├── config.ts               # agentbench config
│   └── serve.ts                # agentbench serve (launch dashboard)
│
├── ui/                         # CLI UI (Ink/React)
│   ├── run-progress.tsx        # Live run progress
│   ├── results-table.tsx       # Results table
│   ├── trace-view.tsx          # Trace viewer
│   └── report-view.tsx         # Report viewer
│
├── config/
│   ├── loader.ts               # agentbench.config.ts loader
│   └── default-config.ts       # Default configuration
│
└── utils/
    ├── output.ts               # Formatted output
    ├── spinner.ts              # Loading spinner
    └── errors.ts               # Error formatting

7. Database Schema (Logical)

┌─────────────────────────────────────────────────────────────┐
│                      Database ER Diagram                     │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  ┌──────────┐       ┌──────────────┐       ┌──────────┐    │
│  │   User   │1────N│  Project     │1────N│ TestSuite│    │
│  └──────────┘       └──────┬───────┘       └────┬─────┘    │
│                            │                     │           │
│                            │                    1│           │
│                            │                     │           │
│              ┌─────────────┼─────────┐          N│           │
│              │             │         │          │           │
│              ▼             ▼         ▼          ▼           │
│        ┌─────────┐  ┌──────────┐ ┌──────────┐ ┌──────────┐│
│        │ Dataset │  │Experiment│ │  Run     │ │TestCase  ││
│        └────┬────┘  └────┬─────┘ └────┬─────┘ └────┬─────┘│
│             │            │            │              │       │
│            1│           1│           1│             1│       │
│             │            │            │              │       │
│            N│           N│           N│             N│       │
│        ┌────┴────┐ ┌────┴─────┐      │       ┌──────┴─────┐│
│        │Dataset  │ │Variant   │      │       │ Assertion  ││
│        │Item     │ └──────────┘      │       │ Evaluator  ││
│        └─────────┘                   │       └────────────┘│
│                                      │                      │
│              ┌───────────────────────┼───────────────┐      │
│              │                       │               │      │
│              ▼                       ▼               ▼      │
│        ┌──────────┐          ┌──────────┐    ┌──────────┐  │
│        │TraceStep │          │  Score   │    │Assertion │  │
│        │          │          │          │    │Result    │  │
│        └──────────┘          └──────────┘    └──────────┘  │
│                                                              │
│        ┌──────────┐          ┌──────────┐    ┌──────────┐  │
│        │ Snapshot │          │RunMetrics│    │ APIKey   │  │
│        └────┬─────┘          └──────────┘    └──────────┘  │
│             │                                                │
│            1│                                                │
│             │                                                │
│            1│                                                │
│        ┌────┴─────────┐                                      │
│        │SnapshotData  │ (JSONB - full snapshot payload)     │
│        └──────────────┘                                      │
│                                                              │
│  ┌──────────┐       ┌──────────────┐                         │
│  │Team/Org  │1────N│  TeamMember  │    (Pro/Enterprise)     │
│  └──────────┘       └──────────────┘                         │
│                                                              │
│  ┌──────────┐                                                │
│  │AuditLog  │   (Enterprise)                                │
│  └──────────┘                                                │
│                                                              │
└─────────────────────────────────────────────────────────────┘

8. Deployment Architecture

┌─────────────────────────────────────────────────────────────┐
│                    Production Deployment                      │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  ┌─────────────────┐     ┌─────────────────┐               │
│  │   CDN / Proxy   │     │   Docker Hub    │               │
│  │   (CloudFlare)  │     │   / ghcr.io     │               │
│  └────────┬────────┘     └─────────────────┘               │
│           │                                                  │
│           ▼                                                  │
│  ┌────────────────────────────────────────┐                 │
│  │           Docker Compose / K8s          │                 │
│  │                                         │                 │
│  │  ┌──────────┐  ┌──────────┐           │                 │
│  │  │ Next.js  │  │  Worker  │           │                 │
│  │  │ (Web)    │  │ (BullMQ) │           │                 │
│  │  │ :3000    │  │          │           │                 │
│  │  └──────────┘  └──────────┘           │                 │
│  │                                         │                 │
│  │  ┌──────────┐  ┌──────────┐           │                 │
│  │  │PostgreSQL│  │  Redis   │           │                 │
│  │  │ :5432    │  │  :6379   │           │                 │
│  │  └──────────┘  └──────────┘           │                 │
│  │                                         │                 │
│  │  ┌──────────┐                          │                 │
│  │  │  MinIO   │  (File storage)          │                 │
│  │  │  :9000   │                          │                 │
│  │  └──────────┘                          │                 │
│  └────────────────────────────────────────┘                 │
│                                                              │
│  For Self-Hosted (Community):                                │
│  - Single docker-compose.yml                                 │
│  - 4 containers: web, worker, postgres, redis               │
│  - 2GB RAM minimum                                           │
│                                                              │
│  For Enterprise:                                             │
│  - Kubernetes Helm Chart                                     │
│  - Horizontal scaling for workers                            │
│  - Managed PostgreSQL / Redis                                │
│  - SSO (SAML/OIDC)                                          │
│  - Audit logging                                             │
│                                                              │
└─────────────────────────────────────────────────────────────┘

9. Security Architecture

┌─────────────────────────────────────────────────────────────┐
│                     Security Layers                           │
├─────────────────────────────────────────────────────────────┤
│                                                              │
│  Layer 1: Transport                                          │
│  - HTTPS everywhere                                          │
│  - HSTS headers                                              │
│  - TLS 1.3 minimum                                          │
│                                                              │
│  Layer 2: Authentication                                     │
│  - NextAuth.js v5 (JWT + Database sessions)                  │
│  - OAuth 2.0 (Google, GitHub)                               │
│  - API Key auth for programmatic access                      │
│  - MFA/2FA (Pro/Enterprise)                                 │
│                                                              │
│  Layer 3: Authorization                                      │
│  - RBAC: Owner > Admin > Editor > Viewer                    │
│  - Project-level permissions                                 │
│  - API Key scopes: read, write, admin                       │
│                                                              │
│  Layer 4: Data Protection                                    │
│  - API Key hashing (SHA-256)                                 │
│  - Sensitive data encryption at rest                         │
│  - LLM API keys encrypted (AES-256-GCM)                     │
│  - PII masking in traces (configurable)                     │
│                                                              │
│  Layer 5: Rate Limiting                                      │
│  - Per-user rate limiting                                    │
│  - Per-API-Key rate limiting                                 │
│  - Per-IP rate limiting                                      │
│  - LLM Judge rate limiting (cost control)                   │
│                                                              │
│  Layer 6: Audit                                              │
│  - All mutations logged                                      │
│  - Sensitive operations logged                               │
│  - Audit log retention policy                                │
│                                                              │
└─────────────────────────────────────────────────────────────┘

10. Provider Plugin Architecture [NEW in v0.3.0]

10.1 AgentBenchProvider Interface

The pluggable provider architecture allows any LLM provider to be integrated with minimal code. All providers implement the AgentBenchProvider interface:

// @agentbench/core/src/types/provider.ts

interface AgentBenchProvider {
  /** Unique provider identifier (e.g., 'openai', 'gemini', 'deepseek') */
  readonly id: string

  /** Human-readable display name */
  readonly name: string

  /** Initialize the provider with credentials and options */
  initialize(config: ProviderConfig): Promise<void>

  /** Create a chat completion (non-streaming) */
  createChatCompletion(params: ChatCompletionParams): Promise<ChatCompletionResult>

  /** Create a streaming chat completion */
  createStreamingChatCompletion(
    params: ChatCompletionParams,
    callbacks: StreamingCallbacks
  ): Promise<ChatCompletionResult>

  /** List available models for this provider */
  listModels(): Promise<ModelInfo[]>

  /** Validate API credentials */
  validateCredentials(): Promise<boolean>

  /** Get token count for messages (for cost estimation) */
  countTokens(messages: Message[]): Promise<number>

  /** Clean up resources */
  dispose(): Promise<void>
}

interface ProviderConfig {
  apiKey?: string
  baseURL?: string
  organization?: string
  defaultModel?: string
  timeout?: number
  maxRetries?: number
  extra?: Record<string, unknown>
}

10.2 OpenAICompatibleProvider Base Class

For providers using OpenAI-compatible APIs (DeepSeek, OpenRouter, Groq, Ollama, Azure), the @agentbench/provider-utils package provides a base class:

// @agentbench/provider-utils/src/openai-compatible-provider.ts

abstract class OpenAICompatibleProvider implements AgentBenchProvider {
  protected client: OpenAI  // OpenAI-compatible client

  constructor(
    protected readonly id: string,
    protected readonly name: string,
    protected readonly defaultBaseURL: string
  ) {}

  // Default implementations for all AgentBenchProvider methods
  async createChatCompletion(params: ChatCompletionParams): Promise<ChatCompletionResult> { ... }
  async createStreamingChatCompletion(params, callbacks): Promise<ChatCompletionResult> { ... }
  async listModels(): Promise<ModelInfo[]> { ... }
  async countTokens(messages: Message[]): Promise<number> { ... }
  async validateCredentials(): Promise<boolean> { ... }

  // Subclasses override only what's different
  protected abstract mapMessages(messages: Message[]): OpenAI.Chat.Completions.ChatCompletionMessageParam[]
  protected abstract mapResponse(response: OpenAI.Chat.Completions.ChatCompletion): ChatCompletionResult
}

10.3 Provider Registration

// Providers are auto-discovered and registered
import { registerProvider, getProvider, listProviders } from '@agentbench/core'

// Manually register a custom provider
registerProvider(new MyCustomProvider())

// Discover and initialize all installed providers
const providers = await discoverProviders()
for (const provider of providers) {
  await provider.initialize(config)
}

// CLI auto-discovers providers from installed packages
// $ agentbench run --provider groq --model llama-3.1-70b

11. Dataset Module [NEW in v0.3.0]

11.1 Dataset Engine Architecture

The Dataset module supports full dataset lifecycle management — import, export, validation, splitting, versioning, diffing, and comparison.

@agentbench/core/src/dataset/
├── index.ts
├── dataset-manager.ts        # Main dataset lifecycle manager
├── import/                   # Dataset import
│   ├── index.ts
│   ├── csv-importer.ts       # CSV import
│   ├── json-importer.ts      # JSON import
│   ├── jsonl-importer.ts     # JSONL import
│   └── auto-detect.ts        # Format auto-detection
├── export/                   # Dataset export
│   ├── index.ts
│   ├── csv-exporter.ts
│   ├── json-exporter.ts
│   └── jsonl-exporter.ts
├── validation/               # Dataset validation
│   ├── index.ts
│   ├── schema-validator.ts   # Schema conformance
│   ├── integrity-check.ts    # Data integrity
│   └── quality-check.ts      # Quality metrics (missing, duplicates)
├── split/                    # Dataset splitting
│   ├── index.ts
│   ├── random-split.ts       # Random train/test/val
│   ├── stratified-split.ts   # Stratified by label
│   └── cross-fold.ts         # K-fold cross-validation
├── sample/                   # Sampling
│   ├── index.ts              # Random, stratified, weighted sampling
│   └── reservoir.ts          # Reservoir sampling for large files
├── version/                  # Dataset versioning
│   ├── index.ts
│   ├── version-store.ts      # Version metadata storage
│   └── diff-engine.ts        # Dataset version diff
└── compare/                  # Dataset comparison
    ├── index.ts
    └── comparator.ts         # Statistical comparison of datasets

11.2 Dataset Format

interface Dataset {
  id: string
  name: string
  description?: string
  format: 'csv' | 'json' | 'jsonl'
  schema: DatasetSchema
  version: number
  versions: DatasetVersion[]
  items: DatasetItem[]
  metadata: DatasetMetadata
  createdAt: Date
  updatedAt: Date
}

interface DatasetItem {
  id: string
  input: {
    messages: Message[]
    variables?: Record<string, string>
    context?: Record<string, unknown>
  }
  expected?: {
    output?: string
    toolCalls?: ToolCall[]
    score?: number
    labels?: string[]
  }
  metadata: Record<string, unknown>
  tags: string[]
}

12. Config System [NEW in v0.3.0]

12.1 defineConfig and Resolution Order

v0.3.0 introduces a unified configuration system with defineConfig and a multi-source resolution order:

// agentbench.config.ts
import { defineConfig } from '@agentbench/core'

export default defineConfig({
  name: 'my-agent-project',
  version: '0.3.0',

  // Provider configuration (new in v0.3.0)
  providers: {
    openai: {
      apiKey: process.env.OPENAI_API_KEY,
      defaultModel: 'gpt-4o',
    },
    anthropic: {
      apiKey: process.env.ANTHROPIC_API_KEY,
      defaultModel: 'claude-sonnet-4-20250514',
    },
    gemini: {
      apiKey: process.env.GEMINI_API_KEY,
      defaultModel: 'gemini-2.5-pro',
    },
    deepseek: {
      apiKey: process.env.DEEPSEEK_API_KEY,
      baseURL: 'https://api.deepseek.com/v1',
    },
    ollama: {
      baseURL: 'http://localhost:11434',
      defaultModel: 'llama3',
    },
  },

  // Test configuration
  tests: {
    timeout: 30000,
    maxSteps: 10,
    retries: 1,
    concurrency: 4,
  },

  // Dataset configuration (new in v0.3.0)
  datasets: {
    directory: './datasets',
    defaultFormat: 'jsonl',
    autoValidate: true,
  },

  // Benchmark configuration (new in v0.3.0)
  benchmarks: {
    directory: './benchmarks',
    registry: 'https://registry.agentbench.dev',
  },

  // Reporting
  reports: {
    formats: ['json', 'html', 'markdown', 'junit'],
    outputDir: './reports',
  },
})

12.2 Configuration Resolution Order

Config is resolved from multiple sources, with later sources overriding earlier ones:

1. Default config         — @agentbench/core built-in defaults
2. agentbench.config.ts   — Project-level config file
3. agentbench.config.local.ts — Local overrides (gitignored)
4. Environment variables  — AGENTBENCH_* prefixed env vars
5. CLI flags              — Command-line arguments (highest priority)
# Environment variable overrides
AGENTBENCH_PROVIDERS_OPENAI_API_KEY=sk-...
AGENTBENCH_TESTS_TIMEOUT=60000
AGENTBENCH_DATASETS_DIR=./custom-data

13. VS Code Extension Architecture [NEW in v0.3.0]

13.1 Extension Overview

The AgentBench VS Code extension (agentbench-vscode) provides in-editor testing for AI agents:

agentbench-vscode/
├── package.json             # Extension manifest
├── src/
│   ├── extension.ts         # Activation entry point
│   │
│   ├── providers/           # VS Code data providers
│   │   ├── test-tree.ts     # Test Explorer tree provider
│   │   ├── run-history.ts   # Run history view
│   │   └── coverage-view.ts # Coverage visualization
│   │
│   ├── panels/              # Webview panels
│   │   ├── trace-viewer.ts  # Interactive trace viewer
│   │   ├── diff-viewer.ts   # Side-by-side diff viewer
│   │   └── benchmark-view.ts # Benchmark results
│   │
│   ├── commands/            # VS Code commands
│   │   ├── run-test.ts      # Run test at cursor
│   │   ├── run-suite.ts     # Run entire suite
│   │   ├── replay.ts        # Replay a run
│   │   └── snapshot.ts      # Create snapshot
│   │
│   ├── decorations/         # Editor decorations
│   │   ├── coverage-gutter.ts   # Coverage in gutter
│   │   ├── inline-results.ts    # Inline assertion results
│   │   └── status-bar.ts        # Run status in status bar
│   │
│   └── tasks/               # VS Code task integration
│       ├── test-task.ts
│       └── benchmark-task.ts
│
└── media/                   # Webview resources
    ├── trace-viewer/
    └── diff-viewer/

13.2 Key Features

  • Test Explorer: Browse and run test suites/cases from the VS Code sidebar
  • Inline Results: Pass/fail assertions shown inline in the editor gutter
  • Trace Viewer: Interactive flame graph and step-by-step execution replay
  • Run Launcher: Right-click to run tests with different models/providers
  • Coverage Gutter: See which code paths are covered/untested
  • Status Bar: Live test status, run progress, token usage

14. GitHub Integration Architecture [NEW in v0.3.0]

14.1 GitHub App & Actions

agentbench-github/
├── action.yml                # GitHub Action definition
├── src/
│   ├── action.ts             # Action entry point (post-commit)
│   │
│   ├── checks/               # GitHub Checks API
│   │   ├── check-run.ts      # Create/update check runs
│   │   ├── annotations.ts    # Line-level annotations
│   │   └── summary.ts        # Check run summary markdown
│   │
│   ├── comments/             # PR Comments
│   │   ├── comment-builder.ts # Build comparison tables
│   │   ├── regression-alert.ts # Regression detection comment
│   │   └── benchmark-report.ts # Benchmark run report
│   │
│   ├── status/               # Commit Statuses
│   │   ├── status-check.ts   # Set commit status
│   │   └── badge.ts          # CI badge generation
│   │
│   ├── app/                  # GitHub App (Pro)
│   │   ├── auth.ts           # App authentication
│   │   ├── webhook.ts        # Webhook event handling
│   │   └── permissions.ts    # Permission scoping
│   │
│   └── config/               # Integration config
│       └── workflow.ts       # Workflow template generation
│
└── templates/                # Workflow templates
    ├── agent-test.yml        # Basic test workflow
    ├── agent-benchmark.yml   # Benchmark workflow
    └── agent-regression.yml  # Regression detection workflow

14.2 GitHub Actions Workflow

# .github/workflows/agent-test.yml
name: Agent Tests
on:
  pull_request:
    paths:
      - 'agent/**'
      - 'prompts/**'
      - 'agentbench.config.ts'

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: agentbench/github-action@v0.3
        with:
          config: agentbench.config.ts
          mode: test
          fail-on-regression: true
          comment-pr: true

14.3 PR Comment Integration

When a PR modifies agent code or prompts, the GitHub integration:

  1. Runs the test suite against the PR branch
  2. Runs the same tests against the base branch
  3. Posts a comparison comment showing:
    • Pass/fail status changes
    • Token usage delta
    • Cost delta
    • Latency delta
    • New regressions detected
  4. Adds line annotations for failed assertions
  5. Sets commit status (green/red check)

14.4 CI Badge

[![Agent Tests](https://img.shields.io/endpoint?url=https://agentbench.dev/api/v1/projects/{projectId}/badge)](https://agentbench.dev)

Next Step: Database Detailed Design (Prisma Schema)

AgentBench v0.3.0

Home

Getting Started

Core Concepts

  • Core-Concepts
  • Replay & Snapshots
  • Assertions & Evaluation
  • Coverage & Non-Determinism

How-To Guides

Reference

Cookbook

  • Cookbook
  • Prompt Regressions
  • Model Migration
  • Cost Budgets
  • Safety Testing
  • A/B Testing

Community

Ecosystem

Clone this wiki locally