Skip to main content

Codex provider for Claif - AI-powered code generation and manipulation through OpenAI Codex CLI

Project description

claif_cod - Codex Provider for Claif

Quickstart

# Install and start using Codex
pip install claif_cod
claif-cod query "Write a Python fibonacci function"

# Or use it with the Claif framework
pip install claif[all]
claif query "Refactor this code for better performance" --provider codex

# Stream responses with live display
claif-cod stream "Create a REST API with FastAPI"

# Choose action mode for code safety
claif-cod query "Fix all bugs" --action-mode review  # Preview changes first

What is claif_cod?

claif_cod is an async Python wrapper that integrates OpenAI's Codex CLI into the Claif framework. It provides a subprocess-based transport layer that communicates with the Codex CLI through JSON streaming, enabling AI-powered code generation, refactoring, and manipulation with multiple safety modes.

Key Features:

  • Async subprocess management - Efficient streaming with native asyncio
  • Multiple action modes - Review, interactive, or full-auto code changes
  • Platform-aware CLI discovery - Works on Windows, macOS, and Linux
  • Timeout protection - Graceful handling of long operations
  • Rich CLI interface - Beautiful output with Fire and Rich
  • Type-safe API - Full type hints and IDE support
  • Clean JSON streaming - Reliable message parsing and error handling

Installation

Prerequisites

You need the Codex CLI binary installed. Set the path via environment variable:

export CODEX_CLI_PATH=/path/to/codex-cli

Or install it via npm:

npm install -g @openai/codex

Basic Installation

# Core package only
pip install claif_cod

# With Claif framework
pip install claif claif_cod

Development Installation

git clone https://github.com/twardoch/claif_cod.git
cd claif_cod
pip install -e ".[dev,test]"

# Or using uv for faster installation
uv pip install -e ".[dev,test]"

CLI Usage

claif_cod provides a Fire-based CLI with rich terminal output for all your code generation needs.

Basic Commands

# Simple code generation
claif-cod query "Write a sorting algorithm in Python"

# Use specific model
claif-cod query "Optimize this database query" --model o4

# Set parameters
claif-cod query "Add error handling" --temperature 0.2 --max-tokens 2000

# With system prompt
claif-cod query "Convert to TypeScript" --system "You are a TypeScript expert"

Action Modes

Control how code changes are applied to ensure safety:

# Review mode (default) - Preview all changes before applying
claif-cod query "Fix the bug in main.py" --action-mode review

# Interactive mode - Approve each change individually
claif-cod query "Update all docstrings" --action-mode interactive

# Full-auto mode - Apply all changes automatically (use with caution!)
claif-cod query "Format all files" --action-mode full-auto --auto-approve

Working with Projects

# Specify project directory
claif-cod query "Run tests and fix failures" --working-dir /path/to/project

# Use current directory
claif-cod query "Add type hints to all functions" --working-dir .

# Work on specific files
claif-cod query "Refactor user.py and auth.py" --working-dir ./src

Streaming Responses

# Stream responses in real-time
claif-cod stream "Implement a websocket server"

# Stream with specific model
claif-cod stream "Create comprehensive unit tests" --model o4-preview

Model Management

# List available models
claif-cod models

# Show model details
claif-cod model-info o4-mini

# List action modes
claif-cod modes

Configuration

# Show current configuration
claif-cod config show

# Set configuration values
claif-cod config set --codex-cli-path /usr/local/bin/codex-cli
claif-cod config set --default-model o4-mini
claif-cod config set --timeout 300

# Save configuration
claif-cod config save

Additional Commands

# Check service health
claif-cod health

# Show version
claif-cod version

Python API Usage

Basic Usage

import asyncio
from claif_cod import query, CodexOptions

async def main():
    # Simple query
    async for message in query("Write a sorting algorithm"):
        print(message.content)
    
    # With options
    options = CodexOptions(
        model="o4",
        temperature=0.2,
        max_tokens=1500,
        action_mode="review",
        system_prompt="You are an expert Python developer"
    )
    
    async for message in query("Optimize this function", options):
        print(message.content)

asyncio.run(main())

Advanced Configuration

from pathlib import Path
from claif_cod import query, CodexOptions

async def generate_code():
    options = CodexOptions(
        model="o4-preview",
        temperature=0.3,
        max_tokens=2000,
        action_mode="interactive",
        working_dir=Path("./src"),
        system_prompt="You are an expert in clean code and design patterns",
        auto_approve_everything=False,
        timeout=300
    )
    
    async for message in query("Refactor user authentication module", options):
        if hasattr(message, 'content'):
            print(f"Content: {message.content}")
        
        # Handle different content types
        if hasattr(message.content, '__iter__'):
            for block in message.content:
                if block.type == "code":
                    print(f"Generated code:\n{block.text}")
                elif block.type == "error":
                    print(f"Error: {block.text}")

asyncio.run(generate_code())

Working with Transport Layer

from claif_cod.transport import CodexTransport
from claif_cod.types import CodexOptions

async def custom_transport():
    # Create transport with custom settings
    transport = CodexTransport(
        cli_path="/usr/local/bin/codex-cli",
        timeout=600  # 10 minutes for complex operations
    )
    
    # Execute query
    options = CodexOptions(
        model="o4",
        action_mode="review",
        working_dir=Path("./project")
    )
    
    async for message in transport.send_query("Refactor entire module", options):
        print(f"{message.message_type}: {message.content}")

asyncio.run(custom_transport())

Error Handling

from claif.common import ProviderError, TimeoutError
from claif_cod import query, CodexOptions

async def safe_query():
    try:
        options = CodexOptions(timeout=120)
        async for message in query("Complex refactoring task", options):
            print(message.content)
            
    except TimeoutError:
        print("Operation timed out - try breaking into smaller tasks")
        
    except ProviderError as e:
        print(f"Codex error: {e}")
        
    except Exception as e:
        print(f"Unexpected error: {e}")

asyncio.run(safe_query())

Using with Claif Framework

from claif import query as claif_query, Provider, ClaifOptions

async def use_with_claif():
    # Query through Claif framework
    options = ClaifOptions(
        provider=Provider.CODEX,
        model="o4-mini",
        temperature=0.2,
        system_prompt="Focus on performance and readability"
    )
    
    async for message in claif_query("Optimize database queries", options):
        print(message.content)

asyncio.run(use_with_claif())

How It Works

Architecture Overview

┌─────────────────────┐
│    User Code        │
├─────────────────────┤
│   Claif Core       │  ← Unified interface (Message types)
├─────────────────────┤
│   claif_cod        │  ← This package (provider adapter)
├─────────────────────┤
│   CodexClient      │  ← Client orchestration layer
├─────────────────────┤
│  CodexTransport    │  ← Async subprocess management
├─────────────────────┤
│  Codex CLI Binary  │  ← External process (JSON I/O)
└─────────────────────┘

Core Components

Main Module (__init__.py)

Entry point providing the query() function:

async def query(
    prompt: str,
    options: ClaifOptions | None = None
) -> AsyncIterator[Message]:
    """Query Codex with unified Claif interface."""
    # Convert options
    codex_options = _convert_options(options) if options else CodexOptions()
    
    # Use module-level client
    async for message in _client.query(prompt, codex_options):
        yield message

Features:

  • Minimal overhead (22 lines)
  • Option conversion from Claif to Codex formats
  • Loguru debug logging
  • Clean async generator interface

CLI Module (cli.py)

Fire-based CLI with rich terminal output (334 lines):

class CodexCLI:
    def query(self, prompt: str, **kwargs):
        """Execute a code generation query."""
        
    def stream(self, prompt: str, **kwargs):
        """Stream responses in real-time."""
        
    def models(self):
        """List available models."""
        
    def config(self, action: str = "show", **kwargs):
        """Manage configuration."""

Key features:

  • Rich progress spinners and tables
  • Response formatting (text, json, code)
  • Async execution with proper error handling
  • Configuration management

Client Module (client.py)

Orchestrates transport lifecycle (55 lines):

class CodexClient:
    def __init__(self):
        self.transport = None
        
    async def query(self, prompt: str, options: CodexOptions):
        # Lazy transport creation
        if not self.transport:
            self.transport = CodexTransport(options.timeout)
            
        # Convert messages
        async for codex_msg in self.transport.send_query(prompt, options):
            yield self._convert_message(codex_msg)

Features:

  • Lazy transport initialization
  • Message format conversion
  • Clean separation of concerns
  • Module-level instance for reuse

Transport Module (transport.py)

Async subprocess management (171 lines):

class CodexTransport:
    async def send_query(self, prompt: str, options: CodexOptions):
        # Find CLI
        cli_path = self._find_cli_path()
        
        # Build command
        cmd = self._build_command(cli_path, prompt, options)
        
        # Execute with streaming
        async with await anyio.open_process(cmd) as proc:
            async for line in proc.stdout:
                if message := self._parse_output_line(line):
                    yield message

Key methods:

  • _find_cli_path() - Platform-aware CLI discovery
  • _build_command() - Safe argument construction
  • _parse_output_line() - Resilient JSON parsing
  • Timeout handling with process termination

Types Module (types.py)

Comprehensive type definitions (142 lines):

@dataclass
class CodexOptions:
    model: str | None = None
    temperature: float | None = None
    max_tokens: int | None = None
    action_mode: str | None = None
    working_dir: Path | None = None
    system_prompt: str | None = None
    auto_approve_everything: bool = False
    timeout: int | None = None
    
@dataclass
class CodexMessage:
    message_type: str
    content: list[ContentBlock]
    metadata: dict[str, Any] | None = None
    
    def to_claif_message(self) -> Message:
        """Convert to Claif format."""

Content block hierarchy:

  • ContentBlock (base)
  • TextBlock - Regular text
  • CodeBlock - Code snippets
  • ErrorBlock - Error messages

Message Flow

  1. User Input → CLI or Python API call
  2. Option ConversionClaifOptionsCodexOptions
  3. Client LayerCodexClient.query() manages lifecycle
  4. Transport LayerCodexTransport.send_query() spawns subprocess
  5. CLI Discovery → Check env var → PATH → common locations
  6. Command Building[cli_path, "query", "--model", model, ...]
  7. Subprocess Executionanyio.open_process() with JSON streaming
  8. Output Parsing → Line-by-line JSON parsing
  9. Message ConversionCodexMessage.to_claif_message()
  10. Async Yielding → Messages yielded back through generators

Code Structure

claif_cod/
├── src/claif_cod/
│   ├── __init__.py       # Main entry point (22 lines)
│   ├── cli.py           # Fire CLI interface (334 lines)
│   ├── client.py        # Client orchestration (55 lines)
│   ├── transport.py     # Subprocess management (171 lines)
│   └── types.py         # Type definitions (142 lines)
├── tests/
│   └── test_package.py  # Basic tests
├── pyproject.toml       # Package configuration
├── README.md            # This file
└── CLAUDE.md            # Development guide

Configuration

Environment variables:

  • CODEX_CLI_PATH - Path to Codex CLI binary
  • CODEX_DEFAULT_MODEL - Default model (o4-mini)
  • CODEX_ACTION_MODE - Default action mode (review)
  • CODEX_TIMEOUT - Default timeout in seconds

Configuration file (~/.claif/config.toml):

[providers.codex]
enabled = true
cli_path = "/usr/local/bin/codex-cli"
default_model = "o4-mini"
default_action_mode = "review"
timeout = 180

[providers.codex.models]
available = ["o3.5", "o4-mini", "o4", "o4-preview"]
default = "o4-mini"

Models Available

The package supports any model that the Codex CLI accepts:

  • o4-mini - Fast, efficient for quick tasks (default)
  • o4 - Balanced performance and capability
  • o4-preview - Latest features and improvements
  • o3.5 - Previous generation model

Action Modes

  • review (default) - Preview changes before applying
  • interactive - Approve each change individually
  • full-auto - Apply all changes automatically

Installation with Bun

While the Codex CLI is typically installed via npm, you can use Bun for faster installation:

# Install bun if needed
curl -fsSL https://bun.sh/install | bash

# Install Codex CLI with bun
bun add -g @openai/codex

# The CLI will be available at
~/.bun/bin/codex

Why Use claif_cod?

1. Unified Interface

  • Consistent API across all Claif providers
  • Easy switching between Codex, Claude, and Gemini
  • Standardized message format

2. Safety First

  • Default review mode prevents unwanted changes
  • Multiple action modes for different risk levels
  • Working directory isolation
  • Timeout protection

3. Developer Experience

  • Rich CLI with beautiful output
  • Full async support
  • Comprehensive type hints
  • Clear error messages

4. Production Ready

  • Robust subprocess handling
  • Graceful error recovery
  • Platform-specific optimizations
  • Extensive logging

5. Integration

  • Seamless Claif framework integration
  • Plugin architecture
  • Configuration inheritance
  • Compatible with existing codebases

Best Practices

  1. Always start with review mode to understand changes
  2. Use specific prompts for better results
  3. Set appropriate timeouts for complex operations
  4. Test generated code thoroughly
  5. Use version control before applying changes
  6. Configure working directory to limit scope
  7. Check CLI path with health command
  8. Use verbose mode for debugging

Contributing

See CLAUDE.md for development guidelines.

Development Setup

# Clone repository
git clone https://github.com/twardoch/claif_cod.git
cd claif_cod

# Install with dev dependencies
pip install -e ".[dev,test]"

# Install pre-commit hooks
pre-commit install

Running Tests

# Run all tests
pytest

# Run with coverage
pytest --cov=claif_cod --cov-report=html

# Run specific test
pytest tests/test_transport.py -v

Code Quality

# Format code
ruff format src/claif_cod tests

# Lint code
ruff check src/claif_cod tests --fix

# Type checking
mypy src/claif_cod

# Run all checks (as per CLAUDE.md)
fd -e py -x ruff format {}
fd -e py -x ruff check --fix --unsafe-fixes {}
python -m pytest

License

MIT License - see LICENSE file for details.

Copyright (c) 2025 Adam Twardoch

Links

claif_cod Resources

Related Projects

Claif Ecosystem:

Upstream Projects:

Tools & Libraries:

  • Fire - CLI framework
  • Rich - Terminal formatting
  • anyio - Async compatibility
  • Loguru - Logging library

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

claif_cod-1.0.20.tar.gz (50.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

claif_cod-1.0.20-py3-none-any.whl (26.5 kB view details)

Uploaded Python 3

File details

Details for the file claif_cod-1.0.20.tar.gz.

File metadata

  • Download URL: claif_cod-1.0.20.tar.gz
  • Upload date:
  • Size: 50.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.28.1

File hashes

Hashes for claif_cod-1.0.20.tar.gz
Algorithm Hash digest
SHA256 24d3fa76a8e9b662608f2db493cdf5d3b8cc27359573bb1cfb5a6eeff3eb8df6
MD5 e9930b104b4556202dd6cb91e6aab42b
BLAKE2b-256 d2363d791ac0ee7258118f36b8050392919a19162ecda73264d8927ba3d3ac98

See more details on using hashes here.

File details

Details for the file claif_cod-1.0.20-py3-none-any.whl.

File metadata

  • Download URL: claif_cod-1.0.20-py3-none-any.whl
  • Upload date:
  • Size: 26.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: python-httpx/0.28.1

File hashes

Hashes for claif_cod-1.0.20-py3-none-any.whl
Algorithm Hash digest
SHA256 8a79383511bbe678510390c761bca088a2369e65bbc1e8618e214c117c0ac975
MD5 bc6116d2f3b3e4f06eb50ad817c299c0
BLAKE2b-256 f244b5a89ee2a2c9ee8cd606f9ee8e21fcafa9d9d2862a3b21bc82f6f97f1240

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page