Skip to main content
Deprecated — use Runtime Selection instead. cli_backend still works through 2.0.0 but emits DeprecationWarning. For YAML migration, run praisonai doctor fix --execute (or the equivalent praisonai doctor runtime --fix --execute) — see Runtime Config Migration.
Stricter protocol check (PR #3252): cli_backend= now validates the argument with isinstance(obj, CliBackendProtocol) (the @runtime_checkable protocol from praisonaiagents.cli_backend.protocols). Objects that merely expose execute() / stream() but lack config / capabilities() (e.g. a BaseCLIIntegration coding-CLI tool) now raise TypeError at construction with a hint to pass them via tools=[...] instead. Previously they were accepted silently and crashed deep in the agent loop.The rejection message (verbatim):
The user runs an agent turn; the CLI backend resolver spawns the external CLI and returns the result through the same Agent API. CLI Backends let you run an agent’s turn through an external CLI tool (like Claude Code) instead of a Python LLM client, while keeping the same Agent/Task API.

Quick Start

1

Simplest: CLI flag

2

Declarative: YAML

3

YAML with overrides

4

Discover what's registered


How It Works

Permission modes (Claude Code backend)

To opt into bypass:
With only unsafe=True or only the env var set, the backend overrides to default mode and logs a warning.

Configuration Surfaces


Observability

Confirm that PraisonAI is skipping the LiteLLM HTTP call and delegating to a CLI subprocess. A user adopts cli_backend="codex-cli" and wants proof delegation is actually happening. They set PRAISONAI_CLI_BACKEND_DEBUG=1, enable cli_backend_tracer, and see one log line per turn — with the prompt already redacted so the log stream is safe to ship to an aggregator. If it silently isn’t delegating, no log line appears — and they know something is wrong at config time.

Env var

Plugin

Hook (programmatic)

See Hook Events → CLI Backend Events for the full payload reference. The command field is redacted at the serialisation boundary — user prompts and system instructions never leak into log sinks.

The cli_backend YAML Field


Framework Compatibility

cli_backend is a runtime feature — it works only with an adapter whose SUPPORTS_RUNTIME_FEATURES = True (the built-in praisonai adapter has it). Third-party adapters opt in by setting SUPPORTS_RUNTIME_FEATURES = True on their subclass — see Capability Flags.
YAML cli_backend: behavior changes (PR #4111). The wrapper adapter now resolves cli_backend: via _resolve_yaml_cli_backend into the cli_backend kwarg core Agent expects, and the shipped examples/yaml/cli_backend.yaml works again. Two paths now fail loudly instead of silently misrouting:
  1. cli_backend: in a process: workflow YAML is now rejected — the workflow engine runs agents natively:
  2. Unresolvable backend ids now fail closed during wrapper resolution (previously they could silently misroute):
This is a behaviour change in PR #1797 — previously cli_backend was silently ignored under non-praisonai frameworks. Now it fails loudly at config-load time. A follow-up fix (PR #2004) restored this validation for framework: praisonai — previously a regression caused all cli_backend configs to fail at validation regardless of framework.

Using cli_backend in Python

YAML and Python now accept the exact same shapes (was previously YAML-only for dict).

Built-in backends

Four backends ship registered out of the box. Each routes through a CLI that owns its own subscription/OAuth session, so no raw API key is needed. Select any of them by ID — the shape is identical to claude-code:
cli_backend= is deprecated (removal in 2.0.0). Prefer the equivalent runtime= — see Runtime Selection.

Built-in Backend: claude-code

The claude-code backend executes commands via the Claude Code CLI with these default settings:

The --cli-backend CLI Flag


The backends Subcommand


Custom Backends (Advanced)

Register your own CLI backend for custom tools:
After registering, praisonai backends list shows it, --cli-backend my-backend accepts it, and cli_backend: my-backend works in YAML.

CliBackendProtocol Reference

For backend authors implementing the protocol:
  • config: CliBackendConfig — Configuration object
  • async def execute(prompt, *, session=None, images=None, system_prompt=None, **kwargs) -> CliBackendResult — Single execution
  • async def stream(prompt, **kwargs) -> AsyncIterator[CliBackendDelta] — Streaming execution
  • def capabilities() -> RuntimeCapabilityMatrixRequired (new). Returns the capability matrix for this backend.
Breaking change: CliBackendProtocol now requires a capabilities() -> RuntimeCapabilityMatrix method so the framework can validate capabilities at config time. Third-party backends must add this method. Without it, the backend will be treated as supporting only the reduced capability set (tool_loop, basic_chat, simple_tools).

Best Practices

Use the YAML cli_backend: field for versioned, declarative configuration. Use --cli-backend flag for quick one-off commands and testing.
Rather than monkey-patching, use the overrides system for custom timeouts.
The cli_backend field requires an adapter whose SUPPORTS_RUNTIME_FEATURES = True — the built-in framework: praisonai (the default) qualifies. PraisonAI validates this up front — if you try it with crewai, autogen, autogen_v4, or ag2, you’ll get a ValueError immediately, before any agent runs.
The --cli-backend flag and --external-agent flag are mutually exclusive. Pick one approach:
  • CLI Backends (new): Pluggable, configurable, YAML-supported
  • External Agent (legacy): Class-based, limited configuration
The claude-code backend requires the claude CLI to be installed and accessible. Install via the Claude Code SDK or ensure it’s in your system PATH.

How this differs from --external-agent

The legacy --external-agent claude and ClaudeCodeIntegration class still work and are unchanged (see External CLI Integrations). The CLI Backend Protocol is the new pluggable path: backends are registered by id, configured declaratively, and surfaced as a YAML field and --cli-backend flag.

Runtime Selection

Model-scoped runtime configuration (replaces cli_backend)

External CLI Integrations

Legacy class-based CLI integration approach

Agent Configuration

Core Agent configuration and usage patterns