Skip to main content

Supported harnesses

This release supports five harnesses. Each one is driven through its own programmatic interface, never by scraping a terminal

from enum import Enum

class Harness(Enum):
CLAUDE_CODE = "claude_code"
CODEX = "codex"
OPENCODE = "opencode"
DEEPAGENTS = "deepagents"
TOOL_LOOP = "tool_loop"

Harness is a plain Enum. A StrEnum member would compare equal to its string and let "codex" through, so litellm.agent() and the other entry points check isinstance(harness, Harness) and raise TypeError otherwise.

Capabilities​

CapabilityClaude CodeCodexOpenCodeDeep AgentsTool Loop
Any gateway model groupyesyesyesyesyes
Cost trackingyesyesyesyesyes
Skillsyesyesyesyesno
Structured outputyesyesyesyesyes
Detach and resumeyesyesyesyesno
Built-in tool filtering (disable_tools=)yesnoyesyesno
Custom Python tools (tools=)nononoyesyes
History (s.history())nononoyesyes
Permission modesread-only, edit, fullread-only, fullread-only, edit, fullread-only, edit, fullask, full

permissions="ask" with interactive approval isn't available on the CLI harnesses in this release. Asking a harness for something it doesn't support raises CapabilityUnsupported before the runtime starts, and it never falls back to a looser mode. You can read the same table in code.

caps = litellm.agent_capabilities(Harness.CODEX)
caps.tool_filtering # False
caps.permission_modes # frozenset({'read-only', 'full'})

How each one is driven​

HarnessDriven throughSpeaks to its modelRuns inNeeds in sandbox
CLAUDE_CODEclaude -p --output-format stream-jsonAnthropic Messagessandboxclaude
CODEXcodex exec --jsonOpenAI Responsessandboxcodex
OPENCODEopencode run --format jsonOpenAI Chat Completionssandboxopencode
DEEPAGENTSdeepagents Python APILangChain chat modelyour processnothing
TOOL_LOOPLiteLLM tool loopOpenAI Chat Completionsyour processnothing

The runtime binaries aren't installed for you in this release. Put them in your sandbox image, or on your PATH for sandbox.local. If the binary is missing, the call raises HarnessInstallFailed naming it.

Every harness takes a typed options class for settings that only make sense for that runtime. Passing another harness's options raises OptionsMismatch.

from litellm import Harness, CodexOptions

litellm.agent(
Harness.CODEX, task, sandbox=box,
options=CodexOptions(reasoning_effort="high"),
)
LiteLLM Enterprise
SSO/SAML, audit logs, spend tracking, multi-team management, and guardrails, built for production.
Learn more →