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):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:
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 adoptscli_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)
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:-
cli_backend:in aprocess: workflowYAML is now rejected — the workflow engine runs agents natively: -
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: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 objectasync def execute(prompt, *, session=None, images=None, system_prompt=None, **kwargs) -> CliBackendResult— Single executionasync def stream(prompt, **kwargs) -> AsyncIterator[CliBackendDelta]— Streaming executiondef capabilities() -> RuntimeCapabilityMatrix— Required (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
Prefer YAML for production
Prefer YAML for production
Use the YAML
cli_backend: field for versioned, declarative configuration. Use --cli-backend flag for quick one-off commands and testing.Set timeout overrides for slow CLIs
Set timeout overrides for slow CLIs
Use a framework whose adapter sets SUPPORTS_RUNTIME_FEATURES
Use a framework whose adapter sets SUPPORTS_RUNTIME_FEATURES
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.Don't combine with --external-agent
Don't combine with --external-agent
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
Ensure claude CLI is on PATH
Ensure claude CLI is on PATH
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.Related
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

