BenchLocal Documentation

repository·main·Indexed 18 days ago

https://github.com/stevibe/benchlocal

A local-first desktop application for running and comparing LLM Bench Packs against local or remote models. The ecosystem includes @benchlocal/core for low-level protocol and configuration types, @benchlocal/sdk for authoring standard Bench Packs using defineBenchPack, and @benchlocal/web-sdk for building interactive browser-based Bench Packs with support for chat inference, run state management, and history persistence.

Tokens
46.1K
Snippets
117
Records
177
Agent score
63%

What's inside BenchLocal

  1. Overview of BenchLocal

    main

    BenchLocal is a local-first desktop application designed for running, comparing, and managing installable LLM Bench Packs against both local and remote models. It provides a shared desktop runtime that manages:

    • Provider configuration
    • Model registry
    • Bench Pack installation and updates
    • Per-tab sampling overrides
    • Run execution and result history
    • Verifier lifecycle management
    • Persisted desktop UI state

    Each Bench Pack is self-contained and owns its own scenario definitions, prompts, scoring logic, verifier contracts, and traces.

  2. What is @benchlocal/core and when to use it

    main

    @benchlocal/core is the low-level foundation of the BenchLocal ecosystem. It defines the shared data structures, protocols, and storage shapes that the BenchLocal desktop app, Bench Pack host runtime, and Bench Pack SDK all use to communicate.

    When to use it:

    • Bench Pack Authors: You should generally use @benchlocal/sdk instead of @benchlocal/core for standard development. Only use @benchlocal/core if you need direct access to the core protocol or configuration types.
    • App/Host Developers: Use it to implement the BenchLocal desktop app or Bench Pack host runtime.
    • Tooling Developers: Use it if you are building ecosystem tools that need to read or validate BenchLocal configuration or workspace state.
  3. How the BenchLocal runtime lifecycle works

    main

    When you run BenchLocal, the system follows a specific lifecycle to prepare the environment for benchmarking:

    1. Initialization: BenchLocal loads configuration from ~/.benchlocal/config.toml and current state from ~/.benchlocal/state.json.
    2. Inspection: It scans the ~/.benchlocal/benchpacks directory for installed Bench Packs.
    3. UI Rendering: The renderer displays available workspaces, tabs, providers, models, and Bench Packs.
    4. Run Execution:
      • Resolves the active Bench Pack and selected models for the current tab.
      • Resolves provider secrets.
      • Starts any required verifiers.
      • Constructs a HostContext.
      • Loads the Bench Pack's runtime entrypoint.
    5. Execution & Persistence: The Bench Pack executes scenarios and emits progress events. BenchLocal then persists logs, summaries, and history to ~/.benchlocal/runs.
  4. How @benchlocal/web-sdk works

    main

    The @benchlocal/web-sdk is designed for Interactive Web Bench Packs that run in a browser surface inside the BenchLocal desktop app.

    Mental Model:

    • The Web Page (Your App): Owns the visual experience, custom UI, progress bars, and the benchmark workflow.
    • BenchLocal (The Desktop App): Owns sensitive execution, including provider credentials, model configuration, and the actual inference engine.
    • Communication: The SDK communicates via a postMessage bridge. It is not a general HTTP proxy and does not expose API keys to the web page.

    Use this SDK when you need richer presentation than a standard table (e.g., form-filling, agent demos, or visual tool-use tests). For standard table-based benchmarks, use @benchlocal/sdk instead.

  5. Understand the BenchLocal and Bench Pack relationship

    main

    BenchLocal is a desktop host designed to install, configure, and run LLM Bench Packs. The system is divided into two distinct layers with clear ownership boundaries:

    BenchLocal (The Host)

    Responsible for the shared runtime and desktop environment, including:

    • Desktop UI and Electron processes.
    • Provider and model registries.
    • Bench Pack installation, updates, and state management.
    • Verifier lifecycle management (startup, health checks, and Docker lifecycle).
    • Run orchestration, persistence, and history.
    • Shared user configuration and local storage.

    Bench Packs (The Content)

    Responsible for benchmark-specific logic, including:

    • Scenarios, prompts, and tool logic.
    • Scoring logic and results (traces and summaries).
    • Verifier implementation and request/response contracts.
    • Recommended default sampling values and scenario metadata.
  6. How the Verifier model works

    main

    Bench Packs that require external validation declare their requirements in benchlocal.pack.json. The system uses a shared responsibility model for verifiers:

    BenchLocal Responsibilities

    • Mode Selection: Supports docker, cloud, or custom_url.
    • Lifecycle: Manages local Docker lifecycles and health checks.
    • Networking: Handles dynamic host port assignment.
    • UI: Displays verifier status to the user.

    Bench Pack Responsibilities

    • Implementation: Provides the actual verifier code.
    • Contract: Defines the request and response schema.
    • Endpoint Usage: Uses the resolved verifier endpoint.

    Crucial Networking Detail: The Bench Pack declares the verifier's internal listenPort, but BenchLocal automatically assigns the actual host port to avoid conflicts.

  7. How to use Verifiers in Bench Packs

    main

    Use a verifier only when a benchmark requires exact external execution or validation that cannot live entirely within the pack runtime.

    Implementation Steps:

    1. Declare in Manifest: Add a verifiers array to benchlocal.pack.json.
    2. Include Runtime: Ship the verifier code in the verification/ directory.
    3. Consume in Code: Use createHostHelpers(context).getRequiredVerifier(...) to access the resolved endpoint.

    Note on Ports: BenchLocal assigns the host port automatically. Your pack should only declare the internal listenPort used by the verifier.

    Example Manifest Fragment:

    {
      "verifiers": [
        {
          "id": "verifier",
          "transport": "http",
          "required": true,
          "defaultMode": "docker",
          "docker": {
            "buildContext": "./verification",
            "listenPort": 4010,
            "healthcheckPath": "/health"
          }
        }
      ]
    }
  8. Accessing Inference Endpoints safely

    main

    For non-verifier packs that need to interact with an external agent runtime (e.g., one expecting an OpenAI-compatible URL), do not wire provider secrets directly into the pack runtime. Instead, use the host-provided helpers to maintain ownership of credentials by BenchLocal.

    Recommended Pattern: Use createHostHelpers(context).getRequiredInferenceEndpoint(modelId).

    If your runtime lives inside a Docker verifier, forward dockerBaseUrl ?? baseUrl to the verifier.

  9. Understand the BenchLocal configuration storage layout

    main

    BenchLocal uses two distinct files for configuration and state, stored in ~/.benchlocal/:

    • config.toml: Contains durable configuration such as providers, models, installed Bench Packs, verifier preferences, and theme selection.
    • state.json: Contains transient UI state such as workspaces, tabs, selected models per tab, sampling overrides, and execution modes.

    The directory structure is as follows:

    ~/.benchlocal/
      config.toml
      state.json
      benchpacks/
      runs/
      logs/
      cache/
      themes/
  10. Understand Interactive Web Bench Packs

    main

    Interactive Web Bench Packs are a second presentation model in BenchLocal. Unlike standard table packs that render results in a table, web packs use a hosted web application to provide a richer, interactive benchmark experience.

    Key characteristics:

    • Local Authority: BenchLocal remains the local authority for credentials, providers, models, inference, history, and artifacts.
    • Security: The hosted web app is sandboxed and does not have access to provider credentials or the local filesystem.
    • Execution: Inference is performed through the local BenchLocal provider/model configuration, not by the web app itself.
    • Compatibility: web packs are an evolution of the protocol and coexist with existing table packs.
  11. Understand the BenchLocal Registry v1 structure

    main

    The benchlocal-registry serves as the official source of truth for Bench Packs published by the BenchLocal project. BenchLocal fetches this list dynamically rather than hardcoding it. Local configuration files (~/.benchlocal/config.toml and ~/.benchlocal/state.json) are used only for user-specific state (like install paths, enabled/disabled status, and model preferences) and should not be confused with the registry's public catalog metadata.

    If the registry is unreachable, BenchLocal will still function using previously installed Bench Packs.

    {
      "schemaVersion": 1,
      "packs": [
        {
          "id": "dataextract-15",
          "name": "DataExtract-15",
          "author": "stevibe",
          "description": "Deterministic data extraction benchmark with 15 fixed scenarios.",
          "version": "1.0.0",
          "source": {
            "type": "github",
            "repo": "stevibe/DataExtract-15",
            "tag": "v1.0.0"
          },
          "homepage": "https://github.com/stevibe/DataExtract-15",
          "license": "MIT",
          "scenarioCount": 15,
          "capabilities": {
            "tools": false,
            "multiTurn": false,
            "verification": false
          }
        }
      ]
    }
  12. Configure Generation Settings

    main

    Per-scenario generation settings are passed to the pack via a GenerationRequest. These settings allow fine-grained control over model sampling.

    Supported Fields:

    • temperature, top_p, top_k, min_p, repetition_penalty, presence_penalty.
    • request_timeout_seconds: Defaults to 300 unless overridden by the user or the pack.

    Behavior Rules:

    1. If a field is present, the pack may forward it to the provider client.
    2. If a field is omitted by both the pack and the user, BenchLocal omits it, allowing the inference backend to use its own defaults.
    3. The per-test run count is controlled by the BenchLocal host and is not part of the generation settings forwarded to providers.
    type GenerationRequest = {
      temperature?: number;
      top_p?: number;
      top_k?: number;
      min_p?: number;
      repetition_penalty?: number;
      presence_penalty?: number;
      request_timeout_seconds?: number;
    };