# aicodetools

Simple, lightweight AI code tools with Docker-only support. No complex dependencies.

Provides four essential tools for AI agents: **read**, **write**, **edit**, and **run** commands.
Runs in a secure Docker container with automatic setup and management.


## Installation

You can install the package using pip:

```bash
pip install aicodetools
```

Or for development:

```bash
pip install -e .
```


**tiktoken** → which requires the Rust toolchain. 

---

### 🔧 Fix: Install Rust

On Linux/WSL/macOS:

```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env
```

On Windows (PowerShell):

```powershell
scoop bucket add main
scoop install main/rust
```

After installation, check:

```bash
rustc --version
cargo --version
```


## Quick Start

```python
from aicodetools.client import CodeToolsClient

# Auto-starts Docker server if needed (uses python:3.11-slim + pip install)
client = CodeToolsClient(auto_start=True)

# Get simple functional tools
tools = client.tools(selection_list=["read_file", "write_file", "edit_file", "run_command"])
read, write, edit, run_cmd = tools

# Read a file with smart token management
result = read("example.py")
print(result["content"])

# Write a file (with safety checks)
write("hello.py", "print('Hello, World!')")

# Edit file using string replacement
edit("hello.py", "Hello", "Hi")

# Run commands (non-interactive)
result = run_cmd("python hello.py", interactive=False)
print(result["stdout"])

# Interactive commands still available on client
client.run_command("python -i", interactive=True)
client.send_input("2 + 2")
output = client.get_output()

# Clean up when done
client.stop_server()
```

## Docker Configuration

### Using Custom Docker Images

The framework automatically installs `aicodetools` via pip inside any Python container:

```python
from aicodetools import CodeToolsClient

# Default: uses python:3.11-slim + pip install aicodetools
client = CodeToolsClient(auto_start=True)

# Use different Python version
client = CodeToolsClient(
    auto_start=True,
    docker_image="python:3.12-alpine"
)

# Use custom port (default is 18080 to avoid conflicts)
client = CodeToolsClient(
    auto_start=True,
    port=19080
)

# Use your own custom Python image
client = CodeToolsClient(
    auto_start=True,
    docker_image="my-company/python-base:latest"
)
```

### Docker Image Requirements

Your custom Docker image only needs:
- Python 3.10+ installed
- `pip` available
- Internet access (to install aicodetools package)

### Example Custom Dockerfile

```dockerfile
FROM python:3.11-slim

# Install system dependencies if needed
RUN apt-get update && apt-get install -y git curl && rm -rf /var/lib/apt/lists/*

# Pre-install aicodetools (optional - will be installed automatically if not present)
RUN pip install aicodetools

# Optional: Pre-install common packages for your use case
RUN pip install numpy pandas requests beautifulsoup4

# Set working directory
WORKDIR /workspace

CMD ["/bin/bash"]
```

### Manual Docker Usage

If you prefer to manage Docker yourself:

```bash
# Use any Python image and install aicodetools
docker run -d -p 18080:8080 --name my-aicodetools --rm python:3.11-slim \
  bash -c "pip install --break-system-packages aicodetools && python -m aicodetools.server --host 0.0.0.0 --port 8080"

# Then connect without auto_start
client = CodeToolsClient(auto_start=False, server_url="http://localhost:18080")

# Or use a different port
docker run -d -p 19080:8080 --name my-aicodetools-alt --rm python:3.12-alpine \
  bash -c "pip install --break-system-packages aicodetools && python -m aicodetools.server --host 0.0.0.0 --port 8080"
client = CodeToolsClient(auto_start=False, server_url="http://localhost:19080")

# With your own custom image
docker run -d -p 20080:8080 --name my-custom --rm my-company/python-base:latest \
  bash -c "pip install --break-system-packages aicodetools && python -m aicodetools.server --host 0.0.0.0 --port 8080"
```

## Core Tools

Four essential tools, designed for simplicity and reliability:

### 📖 **Read Tool**
- Smart file reading with tiered token management (4k/10k modes)
- Regex pattern matching with context lines
- Line range support for targeted reading
- Automatic compression for long lines (6k max per line)

### ✏️ **Write Tool**
- Safe file writing with read-first validation for existing files
- Automatic backup creation with timestamps
- UTF-8 encoding by default (simplified for Linux containers)
- Directory creation if needed

### ✂️ **Edit Tool**
- String-based find and replace editing
- Support for single or all occurrences (replace_all flag)
- Automatic backup before editing
- Detailed change reporting with diffs

### ⚡ **Run Tool**
- **Single function**: `run_command(command, timeout=300, interactive=False)`
- **Non-interactive**: Auto-kill on timeout, return complete results
- **Interactive**: Stream output, agent controls (get_output, send_input, stop_process)
- **Single command limit**: Only one command at a time (prevents agent confusion)

## Usage Examples

### Context Manager Usage

```python
from aicodetools.client import CodeToolsClient

# Recommended: Use context manager for automatic cleanup
with CodeToolsClient(auto_start=True) as client:
    # Get functional tools
    tools = client.tools(selection_list=["read_file", "write_file", "edit_file", "run_command"])
    read, write, edit, run_cmd = tools

    # Read file with regex pattern matching
    matches = read("example.py", regex=r"def \w+")

    # Safe file editing workflow
    read("config.py")  # Read first for safety
    edit("config.py", "DEBUG = False", "DEBUG = True")

    # Execute multiple commands (non-interactive)
    run_cmd("pip install requests", interactive=False)
    result = run_cmd("python -c 'import requests; print(requests.__version__)'", interactive=False)
    print(f"Requests version: {result['stdout']}")

# Server automatically stops when exiting context
```

### Interactive Command Example

```python
from aicodetools import CodeToolsClient
import time

client = CodeToolsClient(auto_start=True)

# Start a Python REPL (interactive mode)
result = client.run_command("python -i", interactive=True)
print(f"Python REPL started: {result['success']}")

# Send commands and get output
client.send_input("x = 10")
client.send_input("y = 20")
client.send_input("print(x + y)")

# Get accumulated output
time.sleep(1)  # Wait for commands to execute
output = client.get_output()
print("Python REPL output:", output["recent_stdout"])

# Stop the process
client.stop_process()
client.stop_server()
```

### AI Agent Integration

```python
from aicodetools.client import CodeToolsClient

def create_tool_functions():
    """Create tool functions for AI agent integration."""
    client = CodeToolsClient(auto_start=True)

    # Get the simplified functional tools
    tools = client.tools(selection_list=["read_file", "write_file", "edit_file", "run_command"])
    read, write, edit, run_cmd = tools

    return [read, write, edit, run_cmd], client

# Use with your favorite AI framework
tools, client = create_tool_functions()
read, write, edit, run_cmd = tools

# Your AI agent can now use these simple functions
# agent = YourAIAgent(tools=tools)
# response = agent.run("Create a Python script that calculates fibonacci numbers")

# Example usage:
content = read("example.py")  # Read file content
write("fibonacci.py", "def fib(n): return n if n < 2 else fib(n-1) + fib(n-2)")  # Write file
edit("fibonacci.py", "fib", "fibonacci")  # Edit file
result = run_cmd("python fibonacci.py", timeout=10)  # Run command

# Clean up when done
client.stop_server()
```

## Architecture

### 🐳 **Docker-Only Design**
- Simplified deployment: Only Docker containers supported
- Auto-fallback: Creates base container if Docker not running
- Secure isolation: All operations run in containerized environment
- No complex environment management

### 🏗️ **Server-Client Model**
- **Server**: Runs in Docker container, handles tool execution
- **Client**: Python interface, communicates via HTTP/JSON API
- **Auto-start**: Client automatically manages Docker server lifecycle
- **Stateless**: Clean separation between client and execution environment

### 🎯 **Key Benefits**
- **Simplicity**: 4 core tools vs 14+ complex tools in v1
- **Reliability**: Docker-only, predictable environment
- **Maintainability**: Simple codebase, clear architecture
- **Performance**: Lightweight, fast startup
- **Agent-Friendly**: Better error messages, token awareness

## Requirements

- Python 3.10+
- Docker (required - no local fallback)
- Minimal dependencies: `requests`, `tiktoken`

## Development

### Code Quality 🧹

- `make style` to format the code
- `make check_code_quality` to check code quality (PEP8 basically)
- `black .`
- `ruff . --fix`

### Tests 🧪

[`pytests`](https://docs.pytest.org/en/7.1.x/) is used to run our tests.

### Publishing 🚀

```bash
poetry build
poetry publish
```

## License

MIT
