Skip to main content

ThinHarness


A compact, SDK-only agent harness:
maximum performance, minimum framework code

CI License PyPI

Why keep it small

Minimal agent harnesses are becoming more common. Pi has shown how far a focused, token-efficient harness can go, and Deep Agents is close behind for cost/performance on Composio's benchmark. Vercel recently released fx, which is deliberately tiny and embeddable. ThinHarness takes the same direction to its limit: how little framework code can you keep without giving up capability or performance?

Larger harnesses are larger for good reasons. They support more providers, storage systems, sandboxes, durable jobs, deployment targets, integrations, and interactive interfaces. ThinHarness makes fewer promises. The core owns the model and tool loop and the behavior that must stay consistent across every run. Optional capabilities live in explicit plugins.

For a side project, that means less framework code to learn, configure, debug, update, and carry in a fork. It also means the project can become complete. ThinHarness does not need to keep growing into an agent platform after it has the features its agents need.

Benchmarking

Benchmarking is in progress.

ThinHarness powers Retrodict, a specialized ARC-AGI-3 agent that leads the reported cost-performance frontier for public ARC-AGI-3 harnesses. Its official competition-mode scorecard reports 99.86% mean RHAE across all 25 public games, with all 183 levels solved. See the ARC-AGI Community Leaderboard submission. This is application evidence, not an isolated comparison of generic harness loops.

Features

The core contains the run behavior every configuration shares. Plugins add complete capabilities without making them implicit dependencies.

Core

  • Plugin composition: explicit Python plugins can contribute tools, instructions, hooks, and connected resources.
  • Provider adapters: built-in OpenAI, Anthropic, and OpenRouter adapters, plus public model and session protocols for implementing another provider.
  • Custom typed tools: define sync or async ToolSpec handlers with Pydantic argument models, normalized ToolResult envelopes, parallel and approval flags, and per-tool retry settings.
  • Structured output: Pydantic-validated results with native, tool, prompted, and text modes.
  • Text and images: ordered text and image input in prompts and tool results, with JPEG, PNG, GIF, and WebP support across the built-in providers.
  • Resume: self-contained transcript state can replay text and images across built-in providers and models, preserve native reasoning on same-provider resume, and degrade it to text across providers.
  • Parallel tool calls: same-turn tool batches run concurrently when every called tool is parallel-safe.
  • Human approvals: approval-required tools pause before side effects and return the pending call plus the state needed to continue after an approve or reject decision.
  • Tool retries: tools raise ModelRetry to send structured feedback to the model and retry within a per-tool budget.
  • Limits and notices: request, tool-call, output-retry, and tool-retry budgets bound each run; near-limit guidance can warn the model before a budget is exhausted.
  • Hooks and events: lifecycle hooks can inspect or intercept prompts, tool calls, subagents, limits, and run boundaries; async streaming emits coarse run, model, tool, retry, limit, and subagent events.
  • Tracing: local plaintext JSONL traces plus OpenTelemetry-compatible spans for runs, provider calls, tools, and subagents.

Plugins

  • Filesystem: root-scoped read, write, batched exact-replacement edit, search, list, and glob, plus opt-in bounded read_image.
  • JSONL search: an opt-in FilesystemPlugin tool for structured search over line-delimited data, with ripgrep prefiltering, field projection, equality, contains, regex, and range filters, plus field-level snippets from large multiline values.
  • Bash: one-shot non-interactive commands with a contained working directory, filtered environment, bounded output, timeouts, cancellation cleanup, and optional approval. It is not a sandbox.
  • MCP: MCPPlugin support built on the FastMCP client, including in-process servers, lazy tool discovery, and collision checks.
  • Subagents: a default child, named child configurations, explicit safe-plugin inheritance, local child hooks, and no recursive delegation.
  • Parallel LLM: batches of independent one-shot prompts, with an optional separate model, structured results, and explicit read and write paths.
  • Skills: ordered skill_read and skill_run tools, with Python, shell, JavaScript, and Go script runners.

Install

uv add thinharness     # or pip install thinharness

Requires Python 3.11+.

Quick start

import asyncio
from thinharness import FilesystemPlugin, Harness, HarnessConfig

async def main():
    async with Harness(
        HarnessConfig(root=".", model="openai:gpt-5.5"),
        plugins=[FilesystemPlugin(tools=["read"])],
    ) as harness:
        result = await harness.run("Read README.md and summarize it.")
        print(result.text)

asyncio.run(main())

There's a synchronous wrapper too: Harness(...).run_sync(...).

Size

These are source lines of code in the smallest first-party opinionated configuration for each harness. The count includes required first-party runtime packages and excludes tests, documentation, examples, hosted services, and unrelated optional interfaces where the project structure makes that separation possible.

Harness Source LOC What is counted
ThinHarness 10,359 6,297 core + 4,062 bundled plugins and tools
DeepSeek Harness 72,737 The base and headless profiles + their first-party package dependency closure
Pydantic AI Coder 85,633 Pydantic AI runtime + the Coder capability and everything it composes
Pi 95,276 pi-coding-agent + its first-party workspace dependency closure
Deep Agents 118,977 Deep Agents + its required LangChain and LangGraph runtime
fx 379,826 The native coding-agent runtime and its first-party source closure

LOC is not a quality or performance score. It measures how much framework code comes with the comparable agent configuration. Moving code from a core package into required plugins does not make that configuration smaller, so the table counts both.

License

MIT. See LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

thinharness-0.7.0.tar.gz (147.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

thinharness-0.7.0-py3-none-any.whl (135.2 kB view details)

Uploaded Python 3

File details

Details for the file thinharness-0.7.0.tar.gz.

File metadata

  • Download URL: thinharness-0.7.0.tar.gz
  • Upload date:
  • Size: 147.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for thinharness-0.7.0.tar.gz
Algorithm Hash digest
SHA256 2e06de7bb7eef94d14f82a2bb07b534db6cb48f0ce4dcbdb28b89898d6bd782d
MD5 2e31d5d452242d9e08aa8f1f6bf607c9
BLAKE2b-256 020dcaede9201be6bbd51395d07134b0fdaef908d765a227a76094598b973906

See more details on using hashes here.

Provenance

The following attestation bundles were made for thinharness-0.7.0.tar.gz:

Publisher: release.yml on ryanbbrown/thinharness

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file thinharness-0.7.0-py3-none-any.whl.

File metadata

  • Download URL: thinharness-0.7.0-py3-none-any.whl
  • Upload date:
  • Size: 135.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for thinharness-0.7.0-py3-none-any.whl
Algorithm Hash digest
SHA256 404d2e3a8d593eef411498bcee2325584b0bb8500310999245068add6f90c08b
MD5 ad093f1cd5ed707cd2d7b3c5404619b0
BLAKE2b-256 5dfdf2fc3798f93e54bcb1d083bbfc6ab2d5f844e30ad4b4a92e64dd47011875

See more details on using hashes here.

Provenance

The following attestation bundles were made for thinharness-0.7.0-py3-none-any.whl:

Publisher: release.yml on ryanbbrown/thinharness

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.8.0

2 files

This release

0.7.0 This release

2 files

0.6.0

2 files

0.5.4

2 files

0.5.3

2 files

0.5.2

2 files

0.5.1

2 files

0.5.0

2 files

0.4.0

2 files

0.3.0

2 files

0.2.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page