Harness abstraction
Vercel AI SDK Harnesses
Vercel AI SDK Harnesses provides an experimental application-side abstraction for running multiple agent harness runtimes behind one HarnessAgent API. Its HarnessV1 adapter contract and ACP bridge are useful interoperability architecture, but they are not UHP and do not establish native UHP adoption.
Status first
Section titled “Status first”Vercel AI SDK Harnesses is an experimental application/library layer for running different agent harnesses through one HarnessAgent surface. Current source identifies @ai-sdk/harness as 1.0.100 and explicitly marks the package experimental. The corresponding @ai-sdk/harness-acp package is 1.0.38 and adapts npm-installed Agent Client Protocol (ACP) version 1 implementations into the same HarnessV1 contract.
The abstraction first emerged in June 2026: Vercel’s initial harness-specification work introduced HarnessV1, HarnessAgent, bridge foundations and adapter utilities after the sandbox expansion package. The project has since grown into a multi-runtime adapter family rather than a one-off Claude Code or Codex wrapper.
What HarnessAgent standardizes inside AI SDK
Section titled “What HarnessAgent standardizes inside AI SDK”The current @ai-sdk/harness README says adapter authors implement a HarnessV1 factory and HarnessV1Session; the framework then owns the consumer-facing agent surface, streaming, tool execution and multi-turn state. The current interface includes:
- session creation plus generate and stream turns;
- typed/schema-backed output;
- custom tools and skills;
- permission modes and built-in-tool filtering where the underlying runtime permits it;
- resumable lifecycle state through detach, stop and destroy operations;
- continuation of interrupted turns;
- sandbox preparation and reusable bootstrap/template flows;
- per-turn response-format enforcement, with capability errors when a runtime cannot honor a requested format.
This is a normalization boundary around agent runtimes. It lets application code depend on one AI SDK surface while runtime-specific adapters translate into Claude Code, Codex, OpenCode, Pi or other agent semantics.
Current adapter set
Section titled “Current adapter set”The official AI SDK Harness Adapters documentation currently lists these adapters:
| Adapter | Current runtime location in official docs |
|---|---|
| Claude Code | Sandbox bridge |
| Cline | Host process |
| Codex | Sandbox bridge |
| Cursor | Sandbox via ACP |
| Deep Agents | Sandbox bridge |
| fx | Sandbox via ACP |
| Grok Build | Sandbox via ACP |
| OpenCode | Sandbox bridge |
| Pi | Host process |
The same page currently labels Amp, Goose and Mastra as “Coming Soon.” That label is documentation state, not a claim that those adapters are already released or complete.
The ACP bridge is the important interoperability signal
Section titled “The ACP bridge is the important interoperability signal”@ai-sdk/harness-acp provides a generic HarnessV1 adapter backed by an npm-installed ACP v1 implementation. Its bridge runs inside the sandbox, communicates with the host over WebSocket through a sandbox-proxied loopback port, and launches the configured ACP implementation alongside the bridge.
That creates a composition path like:
Application → HarnessAgent → HarnessV1 ACP adapter → sandbox bridge → ACP implementation → agent runtime
The official adapter example configures Codex through @agentclientprotocol/codex-acp. The adapter also maps runtime-specific model selection, instructions, authentication and permission behavior into the HarnessV1 surface. Skills can be written into an implementation’s native skills directory rather than being flattened into a generic prompt.
Credential handling is explicitly part of the boundary: sandboxes that support additive request transformations can receive placeholders while the host injects the real secret only into a matching outbound request. Sandboxes without that capability retain legacy direct forwarding. That distinction matters when evaluating whether “sandboxed agent” also means “provider credential is isolated from the agent process.”
Fresh lifecycle and interaction hardening
Section titled “Fresh lifecycle and interaction hardening”The latest released @ai-sdk/harness-acp changelog is 1.0.38. Its 2 September 2026 continuation fix (74d252a) repairs a cross-process resume race where a terminal ACP event could be replayed before the continued turn had installed its stream listeners. Without the fix, a valid resumed continuation could fail with an apparent “no in-flight ACP turn” condition.
Current AI SDK main has advanced beyond that release. On 3 September, merge a554cc8 added an unreleased Claude Code adapter fix so a CLI result carrying is_error: true is treated as a terminal error even when its subtype says success.
The subsequent current-main merge 951c54d adds a normalized askUserQuestions tool across the harness abstraction. It preserves pending question state across suspension and cross-process continuation and translates native question flows where an adapter can provide an answerable client request. The merge records support for Claude Code, Cline, Grok Build and OpenCode, plus Claude Code ACP and Codex ACP examples; Codex, Cursor, Deep Agents, fx and Pi remain unsupported through their listed native adapter paths for the reasons stated upstream. The changeset touches @ai-sdk/harness, @ai-sdk/harness-acp and relevant adapters, so this guide records the feature as current-main / unreleased evidence, not as behavior guaranteed by the currently published package versions above.
How this differs from UHP, ACP and HarnessRouter
Section titled “How this differs from UHP, ACP and HarnessRouter”| Layer | Primary boundary | What it normalizes |
|---|---|---|
Vercel AI SDK HarnessV1 | Application/library → selected agent runtime | Sessions, stream events, tools, usage, lifecycle, configuration and sandbox integration |
| ACP | Client/editor → agent | Interactive client-agent session/protocol semantics |
| UHP | Client → UHP server → complete harness | Network-addressable harness discovery, tasks/responses, streaming, sessions, files and related interoperability semantics |
| HarnessRouter | UHP server/reference implementation → upstream harnesses | Concrete backend adaptation behind UHP |
@ai-sdk/harness-acp is therefore a bridge from ACP implementations into Vercel’s HarnessV1 abstraction. It is not an ACP-to-UHP bridge. Likewise, a HarnessV1 adapter for OpenCode or Codex proves AI SDK integration with that runtime, not native UHP adoption by the runtime.
Why it matters for harness engineering
Section titled “Why it matters for harness engineering”AI SDK Harnesses is evidence that the ecosystem is converging on a second normalization problem beyond model-provider APIs: applications increasingly need a common contract over complete agent runtimes, not only over LLM calls. The adapter family covers session lifecycle, tool semantics, streaming, sandbox ownership, permissions, credentials and resume behavior — the same broad class of concerns that makes harness interoperability materially harder than model interchangeability.
For UHP, the useful comparison is scope rather than competition. HarnessV1 can normalize multiple runtimes inside one JavaScript application architecture; UHP can expose complete harness execution through a network protocol. An implementation could theoretically compose both layers, but no standardized UHP↔HarnessV1 binding or HarnessRouter integration was verified at this cutoff.
Related pages
Section titled “Related pages”Read Harness composition for multi-agent/runtime topology, UHP vs ACP for the editor/client protocol boundary, UHP ecosystem for adoption classifications, and HarnessRouter for the current UHP reference-implementation backend set.
Primary sources
Section titled “Primary sources”- AI SDK
@ai-sdk/harnessREADME - AI SDK Harness Adapters documentation
@ai-sdk/harnesspackage definition@ai-sdk/harness-acpREADME@ai-sdk/harness-acppackage definition@ai-sdk/harness-acpchangelog- ACP continuation replay fix
74d252a - Initial HarnessV1/HarnessAgent implementation
21d3d60 - Claude Code terminal-error fix
a554cc8 - Current-main normalized question flow
951c54d