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
| Surface | Command | For |
|---|---|---|
| Terminal | oharness | A full-screen TUI |
| Headless | oharness-headless | JSONL on stdout, for scripts |
| Browser | oharness-web | HTTP + 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
- Getting started — install, keys, first run
- Providers and models — the catalog, discovery, auth
- Permissions — modes, rules, the audit trail
- Frontends — terminal, headless, browser, desktop
Configure and operate it
- Configuration files — what lives where, and which file wins
- Memory and sync — local notes, recall, extraction and cloud reconciliation
- Self-hosted sync — deploy the bundled server and point clients at 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
- Architecture — package boundaries and data flow
- Runtime plugins — the host, and what a plugin may do
- Cloud connectors — connecting an account the platform holds
- Composio plugin — one connector shipped as an example
Contribute and release safely
- Contributing — development workflow and pull requests
- Security — supported versions and private vulnerability reporting
- Code of Conduct — community expectations
- Changelog — released behaviour and upgrade notes