claif_cla


Nameclaif_cla JSON
Version 1.0.30 PyPI version JSON
download
home_pageNone
SummaryA Claif provider for Anthropic Claude, compatible with the OpenAI Responses API.
upload_time2025-07-29 01:49:29
maintainerNone
docs_urlNone
authorNone
requires_python>=3.10
licenseMIT
keywords ai anthropic artificial-intelligence claif claude cli command-line llm openai responses-api
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage
            # claif_cla - Claude Provider for Claif

A Claif provider for Anthropic's Claude with full OpenAI client API compatibility. This package wraps the `claude-code-sdk` to provide a consistent interface following the `client.chat.completions.create()` pattern.

## Features

- **OpenAI Client API Compatible**: Use the familiar `client.chat.completions.create()` pattern
- **Full Type Safety**: Returns standard `ChatCompletion` and `ChatCompletionChunk` objects
- **Streaming Support**: Real-time streaming with proper chunk handling
- **Session Management**: Persistent conversation history with atomic operations
- **Tool Approval**: Fine-grained control over MCP tool usage
- **Response Caching**: Intelligent caching to reduce API costs
- **Fire-based CLI**: Rich terminal interface with multiple output formats

## Quickstart

```bash
# Install
pip install claif_cla

# Basic usage - OpenAI compatible
python -c "
from claif_cla import ClaudeClient
client = ClaudeClient()
response = client.chat.completions.create(
    messages=[{'role': 'user', 'content': 'Hello Claude!'}],
    model='claude-3-5-sonnet-20241022'
)
print(response.choices[0].message.content)
"

# CLI usage
claif-cla query "Explain quantum computing"
claif-cla chat --model claude-3-opus-20240229
```

## What is claif_cla?

`claif_cla` is a Python wrapper that integrates Anthropic's Claude into the Claif framework with full OpenAI client API compatibility. It provides a thin layer over the [`claude_code_sdk`](https://github.com/anthropics/claude-code-sdk-python) package, adding session management, tool approval strategies, and response caching while maintaining full compatibility with Claude's capabilities.

**Key Features:**
- **Session persistence** - Save and restore conversations across sessions
- **Tool approval strategies** - Fine-grained control over MCP tool usage
- **Response caching** - Reduce API costs with intelligent caching
- **Rich CLI** - Beautiful terminal interface with Fire framework
- **Async support** - Full async/await for efficient operations
- **Type safety** - Comprehensive type hints throughout

## Installation

### Basic Installation

```bash
# Core package only
pip install claif_cla

# With Claif framework
pip install claif claif_cla
```

### Installing Claude CLI

The Claude CLI can be installed automatically:

```bash
# Using claif_cla installer
python -m claif_cla.install

# Or manually via npm
npm install -g @anthropic-ai/claude-code

# Or using Claif's installer
pip install claif && claif install claude
```

### Development Installation

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

## Usage

### Basic Usage (OpenAI-Compatible)

```python
from claif_cla import ClaudeClient

# Initialize the client
client = ClaudeClient(
    api_key="your-api-key"  # Optional, uses ANTHROPIC_API_KEY env var
)

# Create a chat completion - exactly like OpenAI
response = client.chat.completions.create(
    model="claude-3-5-sonnet-20241022",
    messages=[
        {"role": "system", "content": "You are a helpful assistant"},
        {"role": "user", "content": "Explain machine learning"}
    ],
    temperature=0.7,
    max_tokens=1000
)

# Access the response
print(response.choices[0].message.content)
print(f"Model: {response.model}")
print(f"Usage: {response.usage}")
```

### Streaming Responses

```python
from claif_cla import ClaudeClient

client = ClaudeClient()

# Stream responses in real-time
stream = client.chat.completions.create(
    model="claude-3-5-sonnet-20241022",
    messages=[
        {"role": "user", "content": "Write a haiku about programming"}
    ],
    stream=True
)

# Process streaming chunks
for chunk in stream:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)
```

## CLI Usage

```bash
# Basic query
claif-cla query "What is the theory of relativity?"

# With specific model
claif-cla query "Explain Python decorators" --model claude-3-opus-20240229

# Interactive chat mode
claif-cla chat --model claude-3-5-sonnet-20241022

# List available models
claif-cla models

# JSON output
claif-cla query "Hello" --json-output
```

### Session Management

```bash
# List all sessions
python -m claif_cla.cli session list

# Create new session with optional metadata
python -m claif_cla.cli session create --metadata '{"project": "my-app"}'

# Show session messages
python -m claif_cla.cli session show SESSION_ID

# Continue existing session
python -m claif_cla.cli ask "Continue our discussion" --session SESSION_ID

# Export session to file
python -m claif_cla.cli session export SESSION_ID --format markdown --output chat.md
python -m claif_cla.cli session export SESSION_ID --format json --output chat.json

# Delete session
python -m claif_cla.cli session delete SESSION_ID
```

### Advanced Features

```bash
# Benchmark response time
python -m claif_cla.cli benchmark "Complex analysis task" --iterations 5

# Set approval strategy for tools
python -m claif_cla.cli ask "Analyze this file" --approval allow_list --allowed-tools "read_file,search"

# Use with caching
python -m claif_cla.cli ask "Expensive computation" --cache --cache-ttl 3600

# Verbose mode for debugging
python -m claif_cla.cli ask "Debug this" --verbose
```

## API Compatibility

This package is fully compatible with the OpenAI Python client API:

```python
# You can use it as a drop-in replacement
from claif_cla import ClaudeClient as OpenAI

client = OpenAI()
# Now use exactly like the OpenAI client
response = client.chat.completions.create(
    model="claude-3-5-sonnet-20241022",
    messages=[{"role": "user", "content": "Hello!"}]
)
```

## Migration from Old Async API

If you were using the old async-based Claif API:

```python
# Old API (deprecated)
import asyncio
from claif_cla import query
from claif.common import ClaifOptions

async def old_way():
    async for message in query("Hello, Claude!"):
        print(f"{message.role}: {message.content}")
    
# New API (OpenAI-compatible)
from claif_cla import ClaudeClient

def new_way():
    client = ClaudeClient()
    response = client.chat.completions.create(
        messages=[{"role": "user", "content": "Hello, Claude!"}],
        model="claude-3-5-sonnet-20241022"
    )
    print(response.choices[0].message.content)
```

### Key Changes

1. **Synchronous by default**: No more `async/await` for basic usage
2. **OpenAI-compatible structure**: `client.chat.completions.create()` pattern
3. **Standard message format**: `[{"role": "user", "content": "..."}]`
4. **Streaming support**: Use `stream=True` for real-time responses
5. **Type-safe responses**: Returns `ChatCompletion` objects from OpenAI types

### Session Management

```python
from claif_cla.session import SessionManager, Session
from claif.common import Message, MessageRole

# Initialize session manager
session_mgr = SessionManager()

# Create new session
session_id = session_mgr.create_session(
    metadata={"project": "my-app", "user": "john"}
)

# Add messages to session
user_msg = Message(
    role=MessageRole.USER,
    content="What is machine learning?"
)
session_mgr.add_message(session_id, user_msg)

# Get session history
session = session_mgr.get_session(session_id)
for msg in session.messages:
    print(f"{msg.role}: {msg.content}")

# Export session
markdown_export = session_mgr.export_session(session_id, export_format="markdown")
print(markdown_export)

# Save session to disk
session_mgr.save_session(session_id)
```

### Tool Approval Strategies

```python
from claif_cla.approval import create_approval_strategy

# Strategy 1: Allow specific tools only
safe_tools = create_approval_strategy("allow_list", {
    "allowed_tools": ["read_file", "list_files", "search"]
})

# Strategy 2: Deny dangerous tools
deny_dangerous = create_approval_strategy("deny_list", {
    "denied_tools": ["delete_file", "execute_command", "write_file"]
})

# Strategy 3: Pattern-based approval
patterns = create_approval_strategy("pattern", {
    "patterns": ["read_.*", "list_.*", "search_.*"],
    "deny": False  # Allow matching patterns
})

# Strategy 4: Threshold-based (by risk score)
threshold = create_approval_strategy("threshold", {
    "max_risk": 3  # Only allow tools with risk <= 3
})

# Use strategy in query
from claif_cla import ClaudeCodeOptions

options = ClaudeCodeOptions(
    tool_approval_strategy=safe_tools,
    model="claude-3-opus-20240229"
)
```

### Response Caching

```python
from claif_cla.wrapper import ClaudeWrapper, ResponseCache

# Create wrapper with caching
wrapper = ClaudeWrapper(
    cache_ttl=3600,  # 1 hour cache
    enable_cache=True
)

# First call - hits API
response1 = await wrapper.query("Expensive analysis", options)

# Second call - returns from cache
response2 = await wrapper.query("Expensive analysis", options)

# Clear cache if needed
wrapper.cache.clear()
```

### Using with Claif Framework

```python
from claif import query as claif_query, Provider, ClaifOptions

# Query through Claif framework
options = ClaifOptions(
    provider=Provider.CLAUDE,
    model="claude-3-opus-20240229",
    temperature=0.5
)

async for message in claif_query("Hello from Claif!", options):
    print(message.content)
```

## How It Works

### Architecture Overview

```
┌─────────────────────────────┐
│    User Application         │
├─────────────────────────────┤
│    claif_cla CLI           │ ← Fire-based CLI with rich output
├─────────────────────────────┤
│    claif_cla Core          │ ← Main query function & types
├─────────────────────────────┤
│    Session Manager         │ ← Conversation persistence
├─────────────────────────────┤
│    Approval Strategies     │ ← Tool usage control
├─────────────────────────────┤
│    Response Cache          │ ← Cost optimization
├─────────────────────────────┤
│    claude_code_sdk         │ ← Anthropic's SDK
└─────────────────────────────┘
```

### Core Components

#### Main Module (`__init__.py`)

The entry point that provides the `query` function:

```python
async def query(
    prompt: str,
    options: ClaifOptions | None = None
) -> AsyncIterator[Message]:
    """Query Claude with Claif-compatible interface."""
    # Convert Claif options to Claude options
    claude_options = _convert_options(options)
    
    # Delegate to claude_code_sdk
    async for message in claude_query(prompt, claude_options):
        yield message
```

Key features:
- Thin wrapper design for minimal overhead
- Option conversion between Claif and Claude formats
- Direct message passthrough
- Loguru-based debug logging

#### CLI Module (`cli.py`)

Fire-based command-line interface with rich formatting:

```python
class ClaudeCLI:
    def ask(self, prompt: str, **kwargs):
        """Ask Claude a question."""
        
    def stream(self, prompt: str, **kwargs):
        """Stream responses in real-time."""
        
    def interactive(self):
        """Start interactive chat session."""
        
    def session(self, action: str, **kwargs):
        """Manage conversation sessions."""
```

Commands:
- `ask` - Single query with options
- `stream` - Real-time streaming responses
- `interactive` - Chat mode with history
- `session` - CRUD operations for conversations
- `health` - Check Claude availability
- `benchmark` - Performance testing

#### Session Module (`session.py`)

Persistent conversation management:

```python
@dataclass
class Session:
    id: str
    messages: list[Message]
    metadata: dict[str, Any]
    created_at: datetime
    updated_at: datetime
    
class SessionManager:
    def __init__(self, session_dir: Path | None = None):
        self.session_dir = session_dir or Path.home() / ".claif" / "sessions"
```

Features:
- JSON-based session storage
- Atomic file operations
- Session templates (coding, analysis, creative)
- Export to Markdown/JSON formats
- Metadata for organization

#### Approval Module (`approval.py`)

Fine-grained control over MCP tool usage:

```python
class ApprovalStrategy(ABC):
    @abstractmethod
    def should_approve(self, tool_name: str, tool_metadata: dict) -> bool:
        """Decide if tool should be approved."""

# Eight concrete strategies:
1. AllowAllStrategy - Approve everything
2. DenyAllStrategy - Deny everything  
3. AllowListStrategy - Only allow specific tools
4. DenyListStrategy - Deny specific tools
5. PatternStrategy - Regex-based approval
6. ThresholdStrategy - Risk score based
7. CategoryStrategy - Approve by category
8. CompositeStrategy - Combine multiple strategies
```

Factory function for easy creation:
```python
strategy = create_approval_strategy("allow_list", {
    "allowed_tools": ["read_file", "search"]
})
```

#### Wrapper Module (`wrapper.py`)

Enhanced functionality around claude_code_sdk:

```python
class ResponseCache:
    """SHA256-based response caching."""
    def get_cache_key(self, prompt: str, options: dict) -> str:
        data = json.dumps({"prompt": prompt, "options": options})
        return hashlib.sha256(data.encode()).hexdigest()

class ClaudeWrapper:
    """Adds retry logic and caching."""
    async def query_with_retry(self, prompt: str, options, max_retries=3):
        for attempt in range(max_retries):
            try:
                return await self._query(prompt, options)
            except Exception as e:
                if attempt == max_retries - 1:
                    raise
                await asyncio.sleep(2 ** attempt)
```

Features:
- SHA256-based cache keys
- TTL support for cache entries
- Exponential backoff retry logic
- Graceful error handling

### Code Structure

```
claif_cla/
├── src/claif_cla/
│   ├── __init__.py      # Main query function and exports
│   ├── cli.py           # Fire-based CLI interface
│   ├── wrapper.py       # Caching and retry logic
│   ├── session.py       # Session management
│   ├── approval.py      # Tool approval strategies
│   └── install.py       # CLI installation helper
├── tests/
│   ├── test_session.py  # Session tests
│   ├── test_approval.py # Strategy tests
│   └── test_wrapper.py  # Cache tests
├── pyproject.toml       # Package configuration
├── README.md            # This file
└── CLAUDE.md            # Development guide
```

### Message Flow

1. **User Input** → CLI command or API call
2. **Option Conversion** → ClaifOptions → ClaudeCodeOptions
3. **Session Check** → Load existing session if specified
4. **Cache Lookup** → Check for cached response
5. **SDK Call** → Forward to claude_code_sdk
6. **Tool Approval** → Apply strategy if tools requested
7. **Response Stream** → Yield messages as they arrive
8. **Cache Storage** → Store response if caching enabled
9. **Session Update** → Save messages to session
10. **Output Format** → Display with rich formatting

### Configuration

Environment variables:
- `ANTHROPIC_API_KEY` - Required for Claude API
- `CLAIF_SESSION_DIR` - Custom session directory
- `CLAIF_CACHE_TTL` - Default cache duration
- `CLAIF_DEFAULT_MODEL` - Default Claude model

Config file (`~/.claif/config.json`):
```json
{
    "providers": {
        "claude": {
            "model": "claude-3-opus-20240229",
            "api_key_env": "ANTHROPIC_API_KEY",
            "cache_ttl": 3600,
            "enable_cache": true
        }
    }
}
```

## Installation with Bun

`claif_cla` includes an installer that uses Bun for fast installation:

```python
# install.py
def install_claude():
    """Install Claude Code CLI using bun."""
    # 1. Ensure bun is installed
    # 2. Install @anthropic-ai/claude-code globally
    # 3. Bundle with bun compile
    # 4. Copy to ~/.local/bin
```

Benefits:
- 10x faster than npm
- Creates standalone executables
- No Node.js conflicts
- Cross-platform support

## Why Use claif_cla?

### 1. **Minimal Overhead**
- Thin wrapper adds < 100ms latency
- Direct SDK passthrough
- No unnecessary abstractions

### 2. **Session Persistence**
- Continue conversations across runs
- Export chat history
- Organize with metadata

### 3. **Tool Control**
- Eight approval strategies
- Combine strategies
- Custom implementations

### 4. **Cost Optimization**
- Response caching
- Retry logic
- Request deduplication

### 5. **Developer Experience**
- Type hints everywhere
- Rich CLI output
- Comprehensive logging
- Easy integration

## Contributing

See [CLAUDE.md](CLAUDE.md) for development guidelines.

### Development Setup

```bash
# Clone repository
git clone https://github.com/twardoch/claif_cla.git
cd claif_cla

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

# Run tests
pytest

# Code quality
ruff format src/claif_cla tests
ruff check src/claif_cla tests
mypy src/claif_cla
```

### Testing

```bash
# Unit tests
pytest tests/test_session.py -v
pytest tests/test_approval.py -v

# Integration tests
pytest tests/test_integration.py -v

# Coverage report
pytest --cov=src/claif_cla --cov-report=html
```

## License

MIT License - see [LICENSE](LICENSE) file for details.

Copyright (c) 2025 Adam Twardoch

## Links

### claif_cla Resources

- [GitHub Repository](https://github.com/twardoch/claif_cla) - Source code
- [PyPI Package](https://pypi.org/project/claif_cla/) - Latest release
- [Issue Tracker](https://github.com/twardoch/claif_cla/issues) - Bug reports
- [Discussions](https://github.com/twardoch/claif_cla/discussions) - Q&A

### Related Projects

**Claif Ecosystem:**
- [Claif](https://github.com/twardoch/claif) - Main framework
- [claif_gem](https://github.com/twardoch/claif_gem) - Gemini provider
- [claif_cod](https://github.com/twardoch/claif_cod) - Codex provider

**Upstream Projects:**
- [Claude Code](https://github.com/anthropics/claude-code) - Anthropic's CLI
- [claude-code-sdk](https://github.com/anthropics/claude-code-sdk-python) - Python SDK
- [Anthropic API](https://docs.anthropic.com/) - API documentation

**Tools & Libraries:**
- [Fire](https://github.com/google/python-fire) - CLI framework
- [Rich](https://github.com/Textualize/rich) - Terminal formatting
- [Loguru](https://github.com/Delgan/loguru) - Logging library
- [Bun](https://bun.sh) - Fast JavaScript runtime
            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "claif_cla",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": "ai, anthropic, artificial-intelligence, claif, claude, cli, command-line, llm, openai, responses-api",
    "author": null,
    "author_email": "Adam Twardoch <adam+github@twardoch.com>",
    "download_url": "https://files.pythonhosted.org/packages/3c/83/0490b981845b2a877a69da09eb6de160abb12240de28cc617fdf99be8414/claif_cla-1.0.30.tar.gz",
    "platform": null,
    "description": "# claif_cla - Claude Provider for Claif\n\nA Claif provider for Anthropic's Claude with full OpenAI client API compatibility. This package wraps the `claude-code-sdk` to provide a consistent interface following the `client.chat.completions.create()` pattern.\n\n## Features\n\n- **OpenAI Client API Compatible**: Use the familiar `client.chat.completions.create()` pattern\n- **Full Type Safety**: Returns standard `ChatCompletion` and `ChatCompletionChunk` objects\n- **Streaming Support**: Real-time streaming with proper chunk handling\n- **Session Management**: Persistent conversation history with atomic operations\n- **Tool Approval**: Fine-grained control over MCP tool usage\n- **Response Caching**: Intelligent caching to reduce API costs\n- **Fire-based CLI**: Rich terminal interface with multiple output formats\n\n## Quickstart\n\n```bash\n# Install\npip install claif_cla\n\n# Basic usage - OpenAI compatible\npython -c \"\nfrom claif_cla import ClaudeClient\nclient = ClaudeClient()\nresponse = client.chat.completions.create(\n    messages=[{'role': 'user', 'content': 'Hello Claude!'}],\n    model='claude-3-5-sonnet-20241022'\n)\nprint(response.choices[0].message.content)\n\"\n\n# CLI usage\nclaif-cla query \"Explain quantum computing\"\nclaif-cla chat --model claude-3-opus-20240229\n```\n\n## What is claif_cla?\n\n`claif_cla` is a Python wrapper that integrates Anthropic's Claude into the Claif framework with full OpenAI client API compatibility. It provides a thin layer over the [`claude_code_sdk`](https://github.com/anthropics/claude-code-sdk-python) package, adding session management, tool approval strategies, and response caching while maintaining full compatibility with Claude's capabilities.\n\n**Key Features:**\n- **Session persistence** - Save and restore conversations across sessions\n- **Tool approval strategies** - Fine-grained control over MCP tool usage\n- **Response caching** - Reduce API costs with intelligent caching\n- **Rich CLI** - Beautiful terminal interface with Fire framework\n- **Async support** - Full async/await for efficient operations\n- **Type safety** - Comprehensive type hints throughout\n\n## Installation\n\n### Basic Installation\n\n```bash\n# Core package only\npip install claif_cla\n\n# With Claif framework\npip install claif claif_cla\n```\n\n### Installing Claude CLI\n\nThe Claude CLI can be installed automatically:\n\n```bash\n# Using claif_cla installer\npython -m claif_cla.install\n\n# Or manually via npm\nnpm install -g @anthropic-ai/claude-code\n\n# Or using Claif's installer\npip install claif && claif install claude\n```\n\n### Development Installation\n\n```bash\ngit clone https://github.com/twardoch/claif_cla.git\ncd claif_cla\npip install -e \".[dev,test]\"\n```\n\n## Usage\n\n### Basic Usage (OpenAI-Compatible)\n\n```python\nfrom claif_cla import ClaudeClient\n\n# Initialize the client\nclient = ClaudeClient(\n    api_key=\"your-api-key\"  # Optional, uses ANTHROPIC_API_KEY env var\n)\n\n# Create a chat completion - exactly like OpenAI\nresponse = client.chat.completions.create(\n    model=\"claude-3-5-sonnet-20241022\",\n    messages=[\n        {\"role\": \"system\", \"content\": \"You are a helpful assistant\"},\n        {\"role\": \"user\", \"content\": \"Explain machine learning\"}\n    ],\n    temperature=0.7,\n    max_tokens=1000\n)\n\n# Access the response\nprint(response.choices[0].message.content)\nprint(f\"Model: {response.model}\")\nprint(f\"Usage: {response.usage}\")\n```\n\n### Streaming Responses\n\n```python\nfrom claif_cla import ClaudeClient\n\nclient = ClaudeClient()\n\n# Stream responses in real-time\nstream = client.chat.completions.create(\n    model=\"claude-3-5-sonnet-20241022\",\n    messages=[\n        {\"role\": \"user\", \"content\": \"Write a haiku about programming\"}\n    ],\n    stream=True\n)\n\n# Process streaming chunks\nfor chunk in stream:\n    if chunk.choices[0].delta.content:\n        print(chunk.choices[0].delta.content, end=\"\", flush=True)\n```\n\n## CLI Usage\n\n```bash\n# Basic query\nclaif-cla query \"What is the theory of relativity?\"\n\n# With specific model\nclaif-cla query \"Explain Python decorators\" --model claude-3-opus-20240229\n\n# Interactive chat mode\nclaif-cla chat --model claude-3-5-sonnet-20241022\n\n# List available models\nclaif-cla models\n\n# JSON output\nclaif-cla query \"Hello\" --json-output\n```\n\n### Session Management\n\n```bash\n# List all sessions\npython -m claif_cla.cli session list\n\n# Create new session with optional metadata\npython -m claif_cla.cli session create --metadata '{\"project\": \"my-app\"}'\n\n# Show session messages\npython -m claif_cla.cli session show SESSION_ID\n\n# Continue existing session\npython -m claif_cla.cli ask \"Continue our discussion\" --session SESSION_ID\n\n# Export session to file\npython -m claif_cla.cli session export SESSION_ID --format markdown --output chat.md\npython -m claif_cla.cli session export SESSION_ID --format json --output chat.json\n\n# Delete session\npython -m claif_cla.cli session delete SESSION_ID\n```\n\n### Advanced Features\n\n```bash\n# Benchmark response time\npython -m claif_cla.cli benchmark \"Complex analysis task\" --iterations 5\n\n# Set approval strategy for tools\npython -m claif_cla.cli ask \"Analyze this file\" --approval allow_list --allowed-tools \"read_file,search\"\n\n# Use with caching\npython -m claif_cla.cli ask \"Expensive computation\" --cache --cache-ttl 3600\n\n# Verbose mode for debugging\npython -m claif_cla.cli ask \"Debug this\" --verbose\n```\n\n## API Compatibility\n\nThis package is fully compatible with the OpenAI Python client API:\n\n```python\n# You can use it as a drop-in replacement\nfrom claif_cla import ClaudeClient as OpenAI\n\nclient = OpenAI()\n# Now use exactly like the OpenAI client\nresponse = client.chat.completions.create(\n    model=\"claude-3-5-sonnet-20241022\",\n    messages=[{\"role\": \"user\", \"content\": \"Hello!\"}]\n)\n```\n\n## Migration from Old Async API\n\nIf you were using the old async-based Claif API:\n\n```python\n# Old API (deprecated)\nimport asyncio\nfrom claif_cla import query\nfrom claif.common import ClaifOptions\n\nasync def old_way():\n    async for message in query(\"Hello, Claude!\"):\n        print(f\"{message.role}: {message.content}\")\n    \n# New API (OpenAI-compatible)\nfrom claif_cla import ClaudeClient\n\ndef new_way():\n    client = ClaudeClient()\n    response = client.chat.completions.create(\n        messages=[{\"role\": \"user\", \"content\": \"Hello, Claude!\"}],\n        model=\"claude-3-5-sonnet-20241022\"\n    )\n    print(response.choices[0].message.content)\n```\n\n### Key Changes\n\n1. **Synchronous by default**: No more `async/await` for basic usage\n2. **OpenAI-compatible structure**: `client.chat.completions.create()` pattern\n3. **Standard message format**: `[{\"role\": \"user\", \"content\": \"...\"}]`\n4. **Streaming support**: Use `stream=True` for real-time responses\n5. **Type-safe responses**: Returns `ChatCompletion` objects from OpenAI types\n\n### Session Management\n\n```python\nfrom claif_cla.session import SessionManager, Session\nfrom claif.common import Message, MessageRole\n\n# Initialize session manager\nsession_mgr = SessionManager()\n\n# Create new session\nsession_id = session_mgr.create_session(\n    metadata={\"project\": \"my-app\", \"user\": \"john\"}\n)\n\n# Add messages to session\nuser_msg = Message(\n    role=MessageRole.USER,\n    content=\"What is machine learning?\"\n)\nsession_mgr.add_message(session_id, user_msg)\n\n# Get session history\nsession = session_mgr.get_session(session_id)\nfor msg in session.messages:\n    print(f\"{msg.role}: {msg.content}\")\n\n# Export session\nmarkdown_export = session_mgr.export_session(session_id, export_format=\"markdown\")\nprint(markdown_export)\n\n# Save session to disk\nsession_mgr.save_session(session_id)\n```\n\n### Tool Approval Strategies\n\n```python\nfrom claif_cla.approval import create_approval_strategy\n\n# Strategy 1: Allow specific tools only\nsafe_tools = create_approval_strategy(\"allow_list\", {\n    \"allowed_tools\": [\"read_file\", \"list_files\", \"search\"]\n})\n\n# Strategy 2: Deny dangerous tools\ndeny_dangerous = create_approval_strategy(\"deny_list\", {\n    \"denied_tools\": [\"delete_file\", \"execute_command\", \"write_file\"]\n})\n\n# Strategy 3: Pattern-based approval\npatterns = create_approval_strategy(\"pattern\", {\n    \"patterns\": [\"read_.*\", \"list_.*\", \"search_.*\"],\n    \"deny\": False  # Allow matching patterns\n})\n\n# Strategy 4: Threshold-based (by risk score)\nthreshold = create_approval_strategy(\"threshold\", {\n    \"max_risk\": 3  # Only allow tools with risk <= 3\n})\n\n# Use strategy in query\nfrom claif_cla import ClaudeCodeOptions\n\noptions = ClaudeCodeOptions(\n    tool_approval_strategy=safe_tools,\n    model=\"claude-3-opus-20240229\"\n)\n```\n\n### Response Caching\n\n```python\nfrom claif_cla.wrapper import ClaudeWrapper, ResponseCache\n\n# Create wrapper with caching\nwrapper = ClaudeWrapper(\n    cache_ttl=3600,  # 1 hour cache\n    enable_cache=True\n)\n\n# First call - hits API\nresponse1 = await wrapper.query(\"Expensive analysis\", options)\n\n# Second call - returns from cache\nresponse2 = await wrapper.query(\"Expensive analysis\", options)\n\n# Clear cache if needed\nwrapper.cache.clear()\n```\n\n### Using with Claif Framework\n\n```python\nfrom claif import query as claif_query, Provider, ClaifOptions\n\n# Query through Claif framework\noptions = ClaifOptions(\n    provider=Provider.CLAUDE,\n    model=\"claude-3-opus-20240229\",\n    temperature=0.5\n)\n\nasync for message in claif_query(\"Hello from Claif!\", options):\n    print(message.content)\n```\n\n## How It Works\n\n### Architecture Overview\n\n```\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502    User Application         \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502    claif_cla CLI           \u2502 \u2190 Fire-based CLI with rich output\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502    claif_cla Core          \u2502 \u2190 Main query function & types\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502    Session Manager         \u2502 \u2190 Conversation persistence\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502    Approval Strategies     \u2502 \u2190 Tool usage control\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502    Response Cache          \u2502 \u2190 Cost optimization\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502    claude_code_sdk         \u2502 \u2190 Anthropic's SDK\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n```\n\n### Core Components\n\n#### Main Module (`__init__.py`)\n\nThe entry point that provides the `query` function:\n\n```python\nasync def query(\n    prompt: str,\n    options: ClaifOptions | None = None\n) -> AsyncIterator[Message]:\n    \"\"\"Query Claude with Claif-compatible interface.\"\"\"\n    # Convert Claif options to Claude options\n    claude_options = _convert_options(options)\n    \n    # Delegate to claude_code_sdk\n    async for message in claude_query(prompt, claude_options):\n        yield message\n```\n\nKey features:\n- Thin wrapper design for minimal overhead\n- Option conversion between Claif and Claude formats\n- Direct message passthrough\n- Loguru-based debug logging\n\n#### CLI Module (`cli.py`)\n\nFire-based command-line interface with rich formatting:\n\n```python\nclass ClaudeCLI:\n    def ask(self, prompt: str, **kwargs):\n        \"\"\"Ask Claude a question.\"\"\"\n        \n    def stream(self, prompt: str, **kwargs):\n        \"\"\"Stream responses in real-time.\"\"\"\n        \n    def interactive(self):\n        \"\"\"Start interactive chat session.\"\"\"\n        \n    def session(self, action: str, **kwargs):\n        \"\"\"Manage conversation sessions.\"\"\"\n```\n\nCommands:\n- `ask` - Single query with options\n- `stream` - Real-time streaming responses\n- `interactive` - Chat mode with history\n- `session` - CRUD operations for conversations\n- `health` - Check Claude availability\n- `benchmark` - Performance testing\n\n#### Session Module (`session.py`)\n\nPersistent conversation management:\n\n```python\n@dataclass\nclass Session:\n    id: str\n    messages: list[Message]\n    metadata: dict[str, Any]\n    created_at: datetime\n    updated_at: datetime\n    \nclass SessionManager:\n    def __init__(self, session_dir: Path | None = None):\n        self.session_dir = session_dir or Path.home() / \".claif\" / \"sessions\"\n```\n\nFeatures:\n- JSON-based session storage\n- Atomic file operations\n- Session templates (coding, analysis, creative)\n- Export to Markdown/JSON formats\n- Metadata for organization\n\n#### Approval Module (`approval.py`)\n\nFine-grained control over MCP tool usage:\n\n```python\nclass ApprovalStrategy(ABC):\n    @abstractmethod\n    def should_approve(self, tool_name: str, tool_metadata: dict) -> bool:\n        \"\"\"Decide if tool should be approved.\"\"\"\n\n# Eight concrete strategies:\n1. AllowAllStrategy - Approve everything\n2. DenyAllStrategy - Deny everything  \n3. AllowListStrategy - Only allow specific tools\n4. DenyListStrategy - Deny specific tools\n5. PatternStrategy - Regex-based approval\n6. ThresholdStrategy - Risk score based\n7. CategoryStrategy - Approve by category\n8. CompositeStrategy - Combine multiple strategies\n```\n\nFactory function for easy creation:\n```python\nstrategy = create_approval_strategy(\"allow_list\", {\n    \"allowed_tools\": [\"read_file\", \"search\"]\n})\n```\n\n#### Wrapper Module (`wrapper.py`)\n\nEnhanced functionality around claude_code_sdk:\n\n```python\nclass ResponseCache:\n    \"\"\"SHA256-based response caching.\"\"\"\n    def get_cache_key(self, prompt: str, options: dict) -> str:\n        data = json.dumps({\"prompt\": prompt, \"options\": options})\n        return hashlib.sha256(data.encode()).hexdigest()\n\nclass ClaudeWrapper:\n    \"\"\"Adds retry logic and caching.\"\"\"\n    async def query_with_retry(self, prompt: str, options, max_retries=3):\n        for attempt in range(max_retries):\n            try:\n                return await self._query(prompt, options)\n            except Exception as e:\n                if attempt == max_retries - 1:\n                    raise\n                await asyncio.sleep(2 ** attempt)\n```\n\nFeatures:\n- SHA256-based cache keys\n- TTL support for cache entries\n- Exponential backoff retry logic\n- Graceful error handling\n\n### Code Structure\n\n```\nclaif_cla/\n\u251c\u2500\u2500 src/claif_cla/\n\u2502   \u251c\u2500\u2500 __init__.py      # Main query function and exports\n\u2502   \u251c\u2500\u2500 cli.py           # Fire-based CLI interface\n\u2502   \u251c\u2500\u2500 wrapper.py       # Caching and retry logic\n\u2502   \u251c\u2500\u2500 session.py       # Session management\n\u2502   \u251c\u2500\u2500 approval.py      # Tool approval strategies\n\u2502   \u2514\u2500\u2500 install.py       # CLI installation helper\n\u251c\u2500\u2500 tests/\n\u2502   \u251c\u2500\u2500 test_session.py  # Session tests\n\u2502   \u251c\u2500\u2500 test_approval.py # Strategy tests\n\u2502   \u2514\u2500\u2500 test_wrapper.py  # Cache tests\n\u251c\u2500\u2500 pyproject.toml       # Package configuration\n\u251c\u2500\u2500 README.md            # This file\n\u2514\u2500\u2500 CLAUDE.md            # Development guide\n```\n\n### Message Flow\n\n1. **User Input** \u2192 CLI command or API call\n2. **Option Conversion** \u2192 ClaifOptions \u2192 ClaudeCodeOptions\n3. **Session Check** \u2192 Load existing session if specified\n4. **Cache Lookup** \u2192 Check for cached response\n5. **SDK Call** \u2192 Forward to claude_code_sdk\n6. **Tool Approval** \u2192 Apply strategy if tools requested\n7. **Response Stream** \u2192 Yield messages as they arrive\n8. **Cache Storage** \u2192 Store response if caching enabled\n9. **Session Update** \u2192 Save messages to session\n10. **Output Format** \u2192 Display with rich formatting\n\n### Configuration\n\nEnvironment variables:\n- `ANTHROPIC_API_KEY` - Required for Claude API\n- `CLAIF_SESSION_DIR` - Custom session directory\n- `CLAIF_CACHE_TTL` - Default cache duration\n- `CLAIF_DEFAULT_MODEL` - Default Claude model\n\nConfig file (`~/.claif/config.json`):\n```json\n{\n    \"providers\": {\n        \"claude\": {\n            \"model\": \"claude-3-opus-20240229\",\n            \"api_key_env\": \"ANTHROPIC_API_KEY\",\n            \"cache_ttl\": 3600,\n            \"enable_cache\": true\n        }\n    }\n}\n```\n\n## Installation with Bun\n\n`claif_cla` includes an installer that uses Bun for fast installation:\n\n```python\n# install.py\ndef install_claude():\n    \"\"\"Install Claude Code CLI using bun.\"\"\"\n    # 1. Ensure bun is installed\n    # 2. Install @anthropic-ai/claude-code globally\n    # 3. Bundle with bun compile\n    # 4. Copy to ~/.local/bin\n```\n\nBenefits:\n- 10x faster than npm\n- Creates standalone executables\n- No Node.js conflicts\n- Cross-platform support\n\n## Why Use claif_cla?\n\n### 1. **Minimal Overhead**\n- Thin wrapper adds < 100ms latency\n- Direct SDK passthrough\n- No unnecessary abstractions\n\n### 2. **Session Persistence**\n- Continue conversations across runs\n- Export chat history\n- Organize with metadata\n\n### 3. **Tool Control**\n- Eight approval strategies\n- Combine strategies\n- Custom implementations\n\n### 4. **Cost Optimization**\n- Response caching\n- Retry logic\n- Request deduplication\n\n### 5. **Developer Experience**\n- Type hints everywhere\n- Rich CLI output\n- Comprehensive logging\n- Easy integration\n\n## Contributing\n\nSee [CLAUDE.md](CLAUDE.md) for development guidelines.\n\n### Development Setup\n\n```bash\n# Clone repository\ngit clone https://github.com/twardoch/claif_cla.git\ncd claif_cla\n\n# Install with dev dependencies\npip install -e \".[dev,test]\"\n\n# Run tests\npytest\n\n# Code quality\nruff format src/claif_cla tests\nruff check src/claif_cla tests\nmypy src/claif_cla\n```\n\n### Testing\n\n```bash\n# Unit tests\npytest tests/test_session.py -v\npytest tests/test_approval.py -v\n\n# Integration tests\npytest tests/test_integration.py -v\n\n# Coverage report\npytest --cov=src/claif_cla --cov-report=html\n```\n\n## License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n\nCopyright (c) 2025 Adam Twardoch\n\n## Links\n\n### claif_cla Resources\n\n- [GitHub Repository](https://github.com/twardoch/claif_cla) - Source code\n- [PyPI Package](https://pypi.org/project/claif_cla/) - Latest release\n- [Issue Tracker](https://github.com/twardoch/claif_cla/issues) - Bug reports\n- [Discussions](https://github.com/twardoch/claif_cla/discussions) - Q&A\n\n### Related Projects\n\n**Claif Ecosystem:**\n- [Claif](https://github.com/twardoch/claif) - Main framework\n- [claif_gem](https://github.com/twardoch/claif_gem) - Gemini provider\n- [claif_cod](https://github.com/twardoch/claif_cod) - Codex provider\n\n**Upstream Projects:**\n- [Claude Code](https://github.com/anthropics/claude-code) - Anthropic's CLI\n- [claude-code-sdk](https://github.com/anthropics/claude-code-sdk-python) - Python SDK\n- [Anthropic API](https://docs.anthropic.com/) - API documentation\n\n**Tools & Libraries:**\n- [Fire](https://github.com/google/python-fire) - CLI framework\n- [Rich](https://github.com/Textualize/rich) - Terminal formatting\n- [Loguru](https://github.com/Delgan/loguru) - Logging library\n- [Bun](https://bun.sh) - Fast JavaScript runtime",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "A Claif provider for Anthropic Claude, compatible with the OpenAI Responses API.",
    "version": "1.0.30",
    "project_urls": {
        "Documentation": "https://github.com/twardoch/claif_cla#readme",
        "Issues": "https://github.com/twardoch/claif_cla/issues",
        "Source": "https://github.com/twardoch/claif_cla"
    },
    "split_keywords": [
        "ai",
        " anthropic",
        " artificial-intelligence",
        " claif",
        " claude",
        " cli",
        " command-line",
        " llm",
        " openai",
        " responses-api"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "924d48d0f1281546b8edc0eb7787774503a49600754634f4618d759fdbffec0b",
                "md5": "0f92380f8a6df909412e6453baaeea7b",
                "sha256": "9a97425521425a680d46723c85728ef2b73035d23f1b80f56339e0c805b6db84"
            },
            "downloads": -1,
            "filename": "claif_cla-1.0.30-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "0f92380f8a6df909412e6453baaeea7b",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 14606,
            "upload_time": "2025-07-29T01:49:30",
            "upload_time_iso_8601": "2025-07-29T01:49:30.988420Z",
            "url": "https://files.pythonhosted.org/packages/92/4d/48d0f1281546b8edc0eb7787774503a49600754634f4618d759fdbffec0b/claif_cla-1.0.30-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "3c830490b981845b2a877a69da09eb6de160abb12240de28cc617fdf99be8414",
                "md5": "014e77887fcd5f4a33e708fd842468d2",
                "sha256": "22ee2ce0d5f583e8ca939928ac53d2fe0920cfd3eff51bd2ead4deac785c38a1"
            },
            "downloads": -1,
            "filename": "claif_cla-1.0.30.tar.gz",
            "has_sig": false,
            "md5_digest": "014e77887fcd5f4a33e708fd842468d2",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 53897,
            "upload_time": "2025-07-29T01:49:29",
            "upload_time_iso_8601": "2025-07-29T01:49:29.387273Z",
            "url": "https://files.pythonhosted.org/packages/3c/83/0490b981845b2a877a69da09eb6de160abb12240de28cc617fdf99be8414/claif_cla-1.0.30.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-29 01:49:29",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "twardoch",
    "github_project": "claif_cla#readme",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "lcname": "claif_cla"
}
        
Elapsed time: 1.12831s