Agent/Task API.
Quick Start
How It Works
| Step | Component | Purpose |
|---|---|---|
| 1 | User/CLI | Specifies backend via flag or YAML |
| 2 | Resolver | Factory pattern for backend creation |
| 3 | Backend | Protocol implementation (e.g., ClaudeCodeBackend) |
| 4 | Process | External CLI subprocess execution |
| 5 | Result | Parsed response returned to Agent |
Configuration Surfaces
The cli_backend YAML Field
| Shape | Example | Behavior |
|---|---|---|
| Omitted | (field absent) | No backend used; Agent uses normal LLM client. No warning logged. |
| String | cli_backend: claude-code | Resolves via resolve_cli_backend("claude-code") |
| Dict | cli_backend: {id: claude-code, overrides: {timeout_ms: 60000}} | Resolves via resolve_cli_backend("claude-code", overrides={...}) |
Dict missing id | cli_backend: {overrides: {...}} | Returns None + logged warning. Does not raise. |
| Unknown id | cli_backend: nope | Returns None + logged warning. Does not raise. |
Invalid type (e.g. 123) | cli_backend: 123 | Returns None + logged warning. Does not raise. |
Built-in Backend: claude-code
The claude-code backend executes commands via the Claude Code CLI with these default settings:
| Option | Type | Default | Description |
|---|---|---|---|
command | str | "claude" | CLI command (must be on PATH) |
args | List[str] | ["-p", "--output-format", "stream-json", "--include-partial-messages", "--verbose", "--setting-sources", "user", "--permission-mode", "bypassPermissions"] | Default arguments passed to CLI |
resume_args | List[str] | ["-p", "--output-format", "stream-json", "--resume", "{session_id}"] | Arguments for resuming sessions |
output | str | "jsonl" | Output format expected from CLI |
input | str | "stdin" | How to pass prompts to CLI |
live_session | str | "claude-stdio" | Live session mode |
model_arg | str | "--model" | CLI argument for model selection |
model_aliases | Dict[str, str] | {"opus": "claude-opus-4-5", "sonnet": "claude-sonnet-4-5", "haiku": "claude-haiku-3-5"} | Model name shortcuts |
session_arg | str | "--session-id" | CLI argument for session ID |
session_mode | str | "always" | When to use sessions |
session_id_fields | List[str] | ["session_id"] | Fields containing session ID |
system_prompt_arg | str | "--append-system-prompt" | CLI argument for system prompts |
system_prompt_when | str | "first" | When to add system prompts |
image_arg | str | "--image" | CLI argument for images |
clear_env | List[str] | ["ANTHROPIC_API_KEY", "ANTHROPIC_BASE_URL", "ANTHROPIC_OAUTH_TOKEN", "CLAUDE_CODE_USE_BEDROCK", "CLAUDE_CODE_USE_VERTEX", "CLAUDE_CONFIG_DIR", "CLAUDE_CODE_OAUTH_TOKEN", "OTEL_EXPORTER_OTLP_ENDPOINT", "OTEL_EXPORTER_OTLP_HEADERS", "OTEL_RESOURCE_ATTRIBUTES", "GOOGLE_APPLICATION_CREDENTIALS", "AWS_PROFILE", "AWS_REGION", "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN"] | Environment variables sanitized before subprocess |
bundle_mcp | bool | True | Enable MCP bundling |
bundle_mcp_mode | str | "claude-config-file" | MCP bundling mode |
serialize | bool | True | Queue operations to avoid conflicts |
timeout_ms | int | 300000 | Subprocess timeout (5 minutes) |
The --cli-backend CLI Flag
| Flag | Type | Behavior |
|---|---|---|
--cli-backend BACKEND_ID | string | Choices populated dynamically from list_cli_backends(). Currently: claude-code. |
--cli-backend X --external-agent Y | — | Mutually exclusive — argparse rejects with “not allowed with argument” |
Unknown id (e.g. --cli-backend bogus) | — | Rejected by argparse with “invalid choice” |
The backends Subcommand
| Command | Behavior |
|---|---|
praisonai backends list | Prints each registered backend id on its own line |
praisonai backends | Same as list (list is the default) |
praisonai backends bogus | Prints [red]Unknown backends subcommand: bogus[/red] and the list of valid subcommands |
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 execution
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
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
External CLI Integrations
Legacy class-based CLI integration approach
Agent Configuration
Core Agent configuration and usage patterns

