Skip to main content

Agent Harness

Harness (a13n-harness) is the embeddable execution SDK behind Harness UI and Service. It builds reusable agents, runs them with current tools and Environments, streams observations, and returns state for continuation. Start with the offline quickstart; the Python import is a13n_harness.

Capability composition

Build an AgentSpec with only the behavior your application needs. For example, to expose Environment tools and working state:

from a13n_harness import AgentSpec, HarnessBuilder
from a13n_harness.capabilities import WorkingStateCapability
from a13n_harness.environment import DynamicEnvironmentCapability, DynamicEnvironmentConfiguration

executable = HarnessBuilder().build(
    AgentSpec(model="openai-responses:gpt-5"),
    output_type=str,
    capabilities=(
        DynamicEnvironmentCapability(DynamicEnvironmentConfiguration()),
        WorkingStateCapability(),
    ),
)

Supply a Host-owned EnvironmentSource to each run(..., environment=...), or use environments={...} for named mounts. Harness invokes the source’s readiness preparation on first use, then opens and closes fresh fixed-target executions; your application selects their configuration, current state, access policy, and when to destroy a backing target. See Environments and Capabilities.

Browser tools

Connect to an existing Chromium instance through a trusted CDP endpoint. The application prepares Chromium and its profile; Harness does not install or launch a browser. cdp-use is included in the normal Python dependencies.

from a13n_harness import AgentSpec, HarnessBuilder, RunBindings
from a13n_harness.capabilities import BrowserUseCapability
from a13n_harness.capabilities.browser.scope import CdpBrowserBackend


async def inspect_page(cdp_url: str) -> str:
    executable = HarnessBuilder().build(
        AgentSpec(model="openai-responses:gpt-5"),
        capabilities=(BrowserUseCapability(),),
        output_type=str,
    )
    async with CdpBrowserBackend.connect(cdp_url) as browser:
        result = await executable.run(
            "Navigate to https://example.com and describe the page.",
            bindings=RunBindings.embedded(browser_backend=browser),
        )
        return result.output_or_raise()

The context manager creates an owned tab scope, closes its tabs on exit, and disconnects its CDP client while leaving the browser process and unrelated tabs alive. The endpoint can be an HTTP(S) CDP base URL or WS(S) debugger URL. Keep CDP private: it grants broad browser control.

For a long-lived Host, connect once with Chromium.connect(cdp_url) from a13n_harness.capabilities.browser.cdp, create independent CdpBrowserBackend(runtime) scopes, and open a tab with await scope.tabs("new"). The default tab_access="owned" exposes only that scope's tabs and popups. Use CdpBrowserBackend(runtime, tab_access="global") to list and operate all actual browser tabs, including user tabs and other scopes' tabs. Global listing and selection borrow existing pages; newly created tabs remain owned by their creator. Each binding has independent logical selection, and close() only cleans up its owned targets in either mode.

Reuse a backend across Runs, supplying fresh authorization through each Run binding. await scope.attach(target_id) validates an exact surviving page during Host-directed reattachment, claiming it in owned mode or borrowing it in global mode. Both modes share the profile's login/storage state. When another binding uses the same Page, previous element and screenshot references expire; observe again before acting.

Before human input, await scope.pause() for every scope on the controlled browser and prevent new scope admission. After revoking viewer input, call scope.resume(). Pending tools return a fresh-observation instruction without replaying their original action. scope.retire() revokes access; await scope.close() also closes owned tabs; await runtime.close() disconnects without destroying Chromium. Run completion performs none of these Host lifecycle operations.

The model receives nine tools: browser_observe, browser_read, browser_navigate, browser_act, browser_wait, browser_tabs, browser_files, browser_dialog, and browser_screenshot.

A typical task navigates, observes a focused region, acts on an eN reference or a unique semantic locator, and reads or waits to verify the outcome. browser_act takes one action at a time, including fill/type, click/hover, key chords, check, native select, and scroll. For example, its arguments can be:

{"action": {"kind": "fill", "target": {"kind": "locator", "role": "textbox", "name": "Email"}, "text": "ada@example.com"}}

Observation filters and pagination keep large pages manageable; reading text, links, tables, or forms preserves the existing refs. Both support same-process and out-of-process frames. State values distinguish disabled, readonly, checked, selected, and expanded controls; password values are redacted. Inspect dispatch separately from verification: input delivery alone does not establish that a form submitted or a purchase succeeded.

Screenshots return JPEG content plus an sN identifier and CSS dimensions. For visual-only controls, click or hover accepts normalized coordinates in the latest viewport/clip screenshot; the reference is consumed once and checked for stale page/viewport state. Prefer semantic targets for moving content. Full-page screenshots are for observation. Use browser_files for Host-path uploads and accessible tracked download status, and browser_dialog for JavaScript prompts.

Browser access is outside the Agent Environment's sandbox and cannot enforce restrictive allowed_hosts. The Host must authorize the captured Run rather than relying on its Thread's defaults. See the browser contract.

Run the opt-in native fixtures with an already installed Chromium executable:

uv run --package a13n-harness --group test pytest \
  packages/a13n-harness/tests/test_browser_cdp_native.py \
  packages/a13n-harness/tests/test_browser_workflows_native.py \
  --browser-executable=/path/to/chromium

The fixtures use disposable profiles and a basic password store to avoid desktop keyring prompts. If the test environment requires disabling Chromium's sandbox, explicitly add --browser-no-sandbox; it is never selected automatically for root.

Model construction

Pass a native model directly through HarnessBuilder.build(model=...), or select one in AgentSpec.model. a13n_harness.infer_model() constructs a model from supported aliases and caller-owned provider factories. create_model_http_client() builds a caller-owned httpx2 client for provider requests. Configure credentials and close owned clients in your application. See Models and Model authentication.

Execution boundary and filters

Harness prepares images for the selected Model without changing saved history or original files. Configure HarnessModelCharacteristics.image_input with ImageInputPolicy, or set image_input=None to disable preparation. See Context.

Recognized provider-history repairs are on by default; configure them through SelfHealingModelCapability or disable automatic installation with HarnessBuilder(self_healing_enabled=False). For long Threads, opt into proactive history compaction. Context recovery is enabled by default and first tries normal compaction after native context-window overflow. Add other Capabilities for policy, memory, or delegation.

A completed Run returns a HarnessState with a stable thread_id. Pass it as previous_state to continue the Thread; each new Run receives a fresh run_id. The Host persists accepted state and reconstructs credentials and other current authority on resume. State and resume covers serialization and interrupted calls.

Runnable examples and guides

Versioning

Harness and a13n-stream-protocol publish together at one exact version. Harness UI releases independently. The Harness specification owns the accepted contracts.

Metadata

Release files for a13n-harness 0.32.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for a13n-harness 0.32.0
File Size Uploaded Provenance Actions
a13n_harness-0.32.0.tar.gz 1.5 MB Without provenance Details for a13n_harness-0.32.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for a13n-harness 0.32.0
File Interpreter ABI Platform Actions
a13n_harness-0.32.0-py3-none-any.whl Python 3 none any Details for a13n_harness-0.32.0-py3-none-any.whl

Total release size: 2.6 MB

Release files / a13n_harness-0.32.0.tar.gz

Download URL a13n_harness-0.32.0.tar.gz
Size 1.5 MB
Tags Source
SHA-256 checksum
How to use checksums
f83fab5ec3d2cc2f2aa8ed1501c0747483dcb12899b35a299e8778fe5e50212f
BLAKE2b-256 checksum
How to use checksums
9dfd5763e37a0f9eb00d7e050d8b9862e2426cba38a095f7c9cffa7781bdb215
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / a13n_harness-0.32.0-py3-none-any.whl

Download URL a13n_harness-0.32.0-py3-none-any.whl
Size 1.1 MB
Tags Python 3
SHA-256 checksum
How to use checksums
898dd58b10244997d3854d06829a4d0c20b0dbebe1b7aa5ec99e35f91ab27720
BLAKE2b-256 checksum
How to use checksums
3ab198a60f081f2871872db1776ac65a17e5b0cf18911fdcf9dd3448e223584a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.7 {"installer":{"name":"uv","version":"0.13.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for a13n-harness 0.32.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.32.0 This release

2 release files No provenance

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