> ## Documentation Index
> Fetch the complete documentation index at: https://praison.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Codex CLI Integration

> Integrate OpenAI's Codex CLI for non-interactive code execution

# Codex CLI Integration

PraisonAI provides integration with OpenAI's Codex CLI for non-interactive code execution, file modifications, and structured output.

## Installation

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Install Codex CLI
npm install -g @openai/codex

# Verify installation
codex --version
```

## Quick Start

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.integrations import CodexCLIIntegration

# Create integration
codex = CodexCLIIntegration(
    workspace="/path/to/project",
    full_auto=True
)

# Execute a coding task
result = await codex.execute("Fix the authentication bug")
print(result)
```

## Use as Agent Backend

Delegate an Agent's LLM turns to `codex exec` instead of the OpenAI API — uses your ChatGPT subscription.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent

agent = Agent(name="assistant", cli_backend="codex-cli")
agent.start("Hello")
```

<Note>
  `cli_backend=` is deprecated (removal in 2.0.0). Prefer `runtime="codex-cli"`. Run `praisonai doctor fix --execute` to auto-migrate YAML.
</Note>

### Backend Configuration

The `codex-cli` backend ships with this default configuration:

| Option       | Type        | Default                             | Description                                  |
| ------------ | ----------- | ----------------------------------- | -------------------------------------------- |
| `command`    | `str`       | `"codex"`                           | CLI command (must be on PATH)                |
| `args`       | `List[str]` | `["exec", "--skip-git-repo-check"]` | Default flags passed on every turn           |
| `output`     | `str`       | `"text"`                            | Output format expected from the CLI          |
| `input`      | `str`       | `"arg"`                             | Prompt is passed as the final argument       |
| `clear_env`  | `List[str]` | `["OPENAI_API_KEY"]`                | Env vars stripped before the subprocess runs |
| `timeout_ms` | `int`       | `300000`                            | Subprocess timeout (5 minutes)               |

<Warning>
  `clear_env=["OPENAI_API_KEY"]` explicitly strips the env var so `codex` uses your subscription session, not any leftover API key.
</Warning>

### Backend CLI Flags

The backend builds the `codex` command with these flags:

| Flag                    | Purpose                                        |
| ----------------------- | ---------------------------------------------- |
| `exec`                  | Non-interactive execution mode                 |
| `--skip-git-repo-check` | Allow non-git workspaces                       |
| `-C <cwd>`              | Working directory                              |
| `-c instructions="..."` | System prompt injection                        |
| `--image <path>`        | Attach image(s)                                |
| `resume <session_id>`   | Session resume (only when `session.is_resume`) |

## Configuration Options

| Option          | Type | Default   | Description                                   |
| --------------- | ---- | --------- | --------------------------------------------- |
| `workspace`     | str  | "."       | Working directory for CLI execution           |
| `timeout`       | int  | 300       | Timeout in seconds                            |
| `full_auto`     | bool | False     | Allow file modifications                      |
| `sandbox`       | str  | "default" | Sandbox mode: "default", "danger-full-access" |
| `json_output`   | bool | False     | Enable JSON Lines streaming output            |
| `output_schema` | str  | None      | Path to JSON schema for structured output     |
| `output_file`   | str  | None      | Path to save output                           |

## Examples

### Basic Execution

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.integrations import CodexCLIIntegration

codex = CodexCLIIntegration(workspace="/project")

result = await codex.execute("Explain the main.py file")
print(result)
```

### Full Auto Mode

Enable file modifications:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
codex = CodexCLIIntegration(
    workspace="/project",
    full_auto=True  # Allow file edits
)

result = await codex.execute("Refactor the utils module")
```

### Sandbox Modes

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Default sandbox (restricted)
codex = CodexCLIIntegration(
    workspace="/project",
    sandbox="default"
)

# Full access (for network operations)
codex = CodexCLIIntegration(
    workspace="/project",
    sandbox="danger-full-access"
)
```

### JSON Streaming Output

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
codex = CodexCLIIntegration(
    workspace="/project",
    json_output=True
)

result = await codex.execute("Analyze the codebase")
# Result is parsed from JSON Lines
```

### Structured Output with Schema

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Create a schema file
schema = {
    "type": "object",
    "properties": {
        "summary": {"type": "string"},
        "issues": {
            "type": "array",
            "items": {"type": "string"}
        },
        "recommendations": {
            "type": "array",
            "items": {"type": "string"}
        }
    }
}

# Save schema
import json
with open("schema.json", "w") as f:
    json.dump(schema, f)

# Use with Codex
codex = CodexCLIIntegration(
    workspace="/project",
    output_schema="schema.json"
)

result = await codex.execute_with_schema(
    "Analyze code quality",
    schema_path="schema.json"
)
print(result)
# {'summary': '...', 'issues': [...], 'recommendations': [...]}
```

### Streaming Output

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
codex = CodexCLIIntegration(
    workspace="/project",
    json_output=True
)

async for event in codex.stream("Add comprehensive tests"):
    event_type = event.get("type")
    
    if event_type == "thread.started":
        print("Task started")
    elif event_type == "item.completed":
        item = event.get("item", {})
        if item.get("type") == "agent_message":
            print(f"Agent: {item.get('text')}")
    elif event_type == "turn.completed":
        print("Task completed")
```

### As Agent Tool

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai import Agent
from praisonai.integrations import CodexCLIIntegration

codex = CodexCLIIntegration(
    workspace="/project",
    full_auto=True
)

# Create tool
tool = codex.as_tool()

# Use with agent
agent = Agent(
    name="Code Fixer",
    role="Bug Fixer",
    goal="Find and fix bugs in code",
    tools=[tool]
)

result = agent.start("Fix all bugs in the authentication module")
```

### As a native async agent tool

Preferred when the agent runs on `agent.astart(...)` (or any async entrypoint) — the tool is awaited directly on the running loop with no thread hop.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent
from praisonai.integrations import CodexCLIIntegration

codex = CodexCLIIntegration(workspace="/project", full_auto=True)

agent = Agent(
    name="Code Fixer",
    role="Bug Fixer",
    goal="Find and fix bugs in code",
    tools=[codex.as_async_tool()],   # registers as `codex_atool`
)

await agent.astart("Fix all bugs in the authentication module")
```

`as_async_tool()` was added in PraisonAI PR #4022; `as_tool()` still works and is now also safe to call from inside an async agent runtime.

## Environment Variables

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# API Key (for exec mode)
export CODEX_API_KEY=your-key
# or use ChatGPT authentication
```

## CLI Flags Used

The integration uses the following Codex CLI flags:

| Flag              | Description                    |
| ----------------- | ------------------------------ |
| `exec`            | Non-interactive execution mode |
| `--full-auto`     | Allow file modifications       |
| `--sandbox`       | Sandbox mode selection         |
| `--json`          | JSON Lines streaming output    |
| `--output-schema` | Structured output schema       |
| `-o`              | Output file path               |

## JSON Lines Output Format

When `json_output=True`, the output is a stream of JSON events:

```json theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
{"type":"thread.started","thread_id":"abc123"}
{"type":"item.completed","item":{"type":"agent_message","text":"Analyzing..."}}
{"type":"item.completed","item":{"type":"tool_use","name":"read_file"}}
{"type":"turn.completed"}
```

## Error Handling

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.integrations import CodexCLIIntegration

codex = CodexCLIIntegration(timeout=120)

try:
    result = await codex.execute("Complex refactoring")
except TimeoutError:
    print("Task timed out")
except Exception as e:
    print(f"Error: {e}")
```

## Robustness (PR #4111)

* A subprocess `TimeoutError` is now returned as `CliBackendResult(error=...)` instead of escaping as an exception.
* On `CalledProcessError`, the CLI's actual stderr diagnostic is surfaced (previously only the exit status was shown).
* The system-prompt argument is JSON-escaped for TOML basic-string compatibility — prompts containing quotes/newlines no longer break.
* The resume shape is now `codex exec resume <id> --skip-git-repo-check ...` (previously `resume` was misplaced after `--skip-git-repo-check`, which failed).
* `-m` (model) and `-C` (cwd) are threaded through, so scheduled runs can pin a model and run in a workspace.
* `CliSessionBinding.is_resume` is now set on the second turn of a session, so the resume branch runs instead of re-sending the system prompt every turn.

## Best Practices

1. **Use full\_auto=True** only when file modifications are needed
2. **Use structured output** for CI/CD pipelines
3. **Set appropriate sandbox mode** based on security requirements
4. **Use JSON output** for programmatic processing
5. **Set timeouts** appropriate for task complexity
