--- title: "Agent Harness Plugins" sidebarTitle: "Agent Harness" summary: "Experimental SDK surface for plugins that replace the low level embedded agent executor" read_when: - You are changing the embedded agent runtime or harness registry - You are registering an agent harness from a bundled or trusted plugin - You need to understand how the Codex plugin relates to model providers --- # Agent Harness Plugins An **agent harness** is the low level executor for one prepared OpenClaw agent turn. It is not a model provider, not a channel, and not a tool registry. Use this surface only for bundled or trusted native plugins. The contract is still experimental because the parameter types intentionally mirror the current embedded runner. ## When to use a harness Register an agent harness when a model family has its own native session runtime and the normal OpenClaw provider transport is the wrong abstraction. Examples: - a native coding-agent server that owns threads and compaction - a local CLI or daemon that must stream native plan/reasoning/tool events - a model runtime that needs its own resume id in addition to the OpenClaw session transcript Do **not** register a harness just to add a new LLM API. For normal HTTP or WebSocket model APIs, build a [provider plugin](/plugins/sdk-provider-plugins). ## What core still owns Before a harness is selected, OpenClaw has already resolved: - provider and model - runtime auth state - thinking level and context budget - the OpenClaw transcript/session file - workspace, sandbox, and tool policy - channel reply callbacks and streaming callbacks - model fallback and live model switching policy That split is intentional. A harness runs a prepared attempt; it does not pick providers, replace channel delivery, or silently switch models. ## Register a harness **Import:** `openclaw/plugin-sdk/agent-harness` ```typescript import type { AgentHarness } from "openclaw/plugin-sdk/agent-harness"; import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry"; const myHarness: AgentHarness = { id: "my-harness", label: "My native agent harness", supports(ctx) { return ctx.provider === "my-provider" ? { supported: true, priority: 100 } : { supported: false }; }, async runAttempt(params) { // Start or resume your native thread. // Use params.prompt, params.tools, params.images, params.onPartialReply, // params.onAgentEvent, and the other prepared attempt fields. return await runMyNativeTurn(params); }, }; export default definePluginEntry({ id: "my-native-agent", name: "My Native Agent", description: "Runs selected models through a native agent daemon.", register(api) { api.registerAgentHarness(myHarness); }, }); ``` ## Selection policy OpenClaw chooses a harness after provider/model resolution: 1. `OPENCLAW_AGENT_RUNTIME=` forces a registered harness with that id. 2. `OPENCLAW_AGENT_RUNTIME=pi` forces the built-in PI harness. 3. `OPENCLAW_AGENT_RUNTIME=auto` asks registered harnesses if they support the resolved provider/model. 4. If no registered harness matches, OpenClaw uses PI. Forced plugin harness failures surface as run failures. In `auto` mode, OpenClaw may fall back to PI when the selected plugin harness fails before a turn has produced side effects. The bundled Codex plugin registers `codex` as its harness id. For compatibility, `codex-app-server` and `app-server` also resolve to that same harness when you set `OPENCLAW_AGENT_RUNTIME` manually. ## Provider plus harness pairing Most harnesses should also register a provider. The provider makes model refs, auth status, model metadata, and `/model` selection visible to the rest of OpenClaw. The harness then claims that provider in `supports(...)`. The bundled Codex plugin follows this pattern: - provider id: `codex` - user model refs: `codex/gpt-5.4`, `codex/gpt-5.2`, or another model returned by the Codex app server - harness id: `codex` - auth: synthetic provider availability, because the Codex harness owns the native Codex login/session - app-server request: OpenClaw sends the bare model id to Codex and lets the harness talk to the native app-server protocol The Codex plugin is additive. Plain `openai/gpt-*` refs remain OpenAI provider refs and continue to use the normal OpenClaw provider path. Select `codex/gpt-*` when you want Codex-managed auth, Codex model discovery, native threads, and Codex app-server execution. `/model` can switch among the Codex models returned by the Codex app server without requiring OpenAI provider credentials. ## Native sessions and transcript mirror A harness may keep a native session id, thread id, or daemon-side resume token. Keep that binding explicitly associated with the OpenClaw session, and keep mirroring user-visible assistant/tool output into the OpenClaw transcript. The OpenClaw transcript remains the compatibility layer for: - channel-visible session history - transcript search and indexing - switching back to the built-in PI harness on a later turn - generic `/new`, `/reset`, and session deletion behavior If your harness stores a sidecar binding, implement `reset(...)` so OpenClaw can clear it when the owning OpenClaw session is reset. ## Tool and media results Core constructs the OpenClaw tool list and passes it into the prepared attempt. When a harness executes a dynamic tool call, return the tool result back through the harness result shape instead of sending channel media yourself. This keeps text, image, video, music, TTS, approval, and messaging-tool outputs on the same delivery path as PI-backed runs. ## Current limitations - The public import path is generic, but some attempt/result type aliases still carry `Pi` names for compatibility. - Third-party harness installation is experimental. Prefer provider plugins until you need a native session runtime. - Harness switching is supported across turns. Do not switch harnesses in the middle of a turn after native tools, approvals, assistant text, or message sends have started. ## Related - [SDK Overview](/plugins/sdk-overview) - [Runtime Helpers](/plugins/sdk-runtime) - [Provider Plugins](/plugins/sdk-provider-plugins) - [Model Providers](/concepts/model-providers)