Overview

A model-agnostic agent harness: the agent loop, tool execution, context management and permissions as one layer, with the model as a replaceable backend.

Three runtime dependencies: zod, plus ink and react for the terminal frontend. Every provider is reached over raw fetch and SSE — no vendor SDKs, and the engine itself still depends only on zod.

What it is

The pivot is that conversation history is stored in a provider-neutral format. The adapter layer renders it into a vendor's wire format at the moment a request goes out, which is why switching models mid-session needs no migration: the next request simply uses a different renderer.

Three frontends, one engine

SurfaceCommandFor
TerminaloharnessA full-screen TUI
Headlessoharness-headlessJSONL on stdout, for scripts
Browseroharness-webHTTP + SSE, and the desktop shell

The engine never writes to stdout and never touches the terminal, which is what lets a second frontend exist without changing it. That boundary is enforced by tests, not by convention.

Choose a path

Links are to the .md files themselves rather than to the rendered .html, because this directory is read in two places and only one of them renders it. A .html link is correct on the site and a 404 for anyone reading the same page on the repository, which is where most people meet it first; a .md link works there, and every generator worth using rewrites it for the site.

Start using OHarness

Configure and operate it

Implement a Sync service

  • Sync protocol — authentication, session feeds, Memory CAS, errors and compatibility checks

Session sync can be implemented on its own. Memory sync is a separate optional protocol at the same origin; it does not require Supabase or R2 when another implementation provides equivalent identity and storage semantics.

Understand and extend the system

Contribute and release safely