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

# AI Code Editing

> AI-powered code editing tools for agents to read, write, and modify code files with precision using SEARCH/REPLACE diffs

PraisonAI Code provides AI agents with powerful tools to read, write, and modify code files with surgical precision. Inspired by Kilo Code's architecture, it uses a SEARCH/REPLACE diff strategy with fuzzy matching for reliable code modifications.

## Quick Start

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.code import (
    set_workspace,
    code_read_file,
    code_write_file,
    code_apply_diff,
    code_list_files,
    code_execute_command,
    CODE_TOOLS,
)

# Set the workspace root
set_workspace("/path/to/your/project")

# Read a file with line numbers
content = code_read_file("src/main.py")
print(content)

# Apply a precise diff
diff = """<<<<<<< SEARCH
:start_line:10
-------
def old_function():
    pass
=======
def new_function():
    return True
>>>>>>> REPLACE"""

result = code_apply_diff("src/main.py", diff)
print(result)  # "Successfully applied 1 change(s) to src/main.py"
```

## Available Tools

| Tool                   | Description                                    |
| ---------------------- | ---------------------------------------------- |
| `code_read_file`       | Read file contents with optional line ranges   |
| `code_write_file`      | Create or overwrite files                      |
| `code_list_files`      | List directory contents with filtering         |
| `code_apply_diff`      | Apply SEARCH/REPLACE diffs with fuzzy matching |
| `code_search_replace`  | Simple search and replace operations           |
| `code_execute_command` | Run shell commands safely                      |

## Using with Agents

The `CODE_TOOLS` list contains all tools ready for use with PraisonAI agents:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent
from praisonai.code import CODE_TOOLS, set_workspace

# Set workspace before creating agent
set_workspace("/path/to/project")

# Create an agent with code editing capabilities
agent = Agent(
    name="Code Editor",
    instructions="""You are a code editing assistant. 
    Use the code tools to read, modify, and write files.
    Always read a file before modifying it.""",
    tools=CODE_TOOLS
)

# The agent can now edit code
agent.start("Add error handling to the main.py file")
```

## Tool Reference

### code\_read\_file

Read file contents with optional line ranges and line number annotations.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.code import code_read_file, set_workspace

set_workspace("/my/project")

# Read entire file
content = code_read_file("src/main.py")

# Read specific lines (1-indexed)
content = code_read_file("src/main.py", start_line=10, end_line=50)
```

**Output format:**

```
File: src/main.py (150 lines)

  1 | def hello():
  2 |     print("Hello, World!")
  3 |
  4 | def main():
  5 |     hello()
```

### code\_write\_file

Create new files or completely replace existing files.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.code import code_write_file, set_workspace

set_workspace("/my/project")

# Create a new file
result = code_write_file("src/new_module.py", """
def greet(name):
    return f"Hello, {name}!"
""")
print(result)  # "Created file: src/new_module.py (45 bytes)"

# Overwrite existing file
result = code_write_file("src/config.py", "DEBUG = True")
print(result)  # "Updated file: src/config.py (12 bytes)"
```

<Note>
  For partial modifications, use `code_apply_diff` instead of overwriting the entire file.
</Note>

### code\_list\_files

List files and directories with optional filtering.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.code import code_list_files, set_workspace

set_workspace("/my/project")

# List current directory
files = code_list_files(".")

# List recursively with extension filter
files = code_list_files("src", recursive=True, extensions="py,js")
```

**Output format:**

```
Contents of src:
  📁 utils/
  📁 models/
  📄 main.py (2.5KB)
  📄 config.py (512B)
  📄 helpers.js (1.2KB)
```

### code\_apply\_diff

Apply precise, surgical modifications using SEARCH/REPLACE diffs.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.code import code_apply_diff, set_workspace

set_workspace("/my/project")

diff = """<<<<<<< SEARCH
:start_line:5
-------
def calculate_total(items):
    total = 0
    for item in items:
        total += item
    return total
=======
def calculate_total(items):
    \"\"\"Calculate total with 10% markup.\"\"\"
    return sum(item * 1.1 for item in items)
>>>>>>> REPLACE"""

result = code_apply_diff("src/utils.py", diff)
```

#### Diff Format

The diff format uses clear markers:

```
<<<<<<< SEARCH
:start_line:N
-------
[exact content to find]
=======
[new content to replace with]
>>>>>>> REPLACE
```

* **`:start_line:N`** - Optional line number hint for faster matching
* **`-------`** - Separator after line hints
* **`=======`** - Divider between search and replace content
* Multiple blocks can be included in a single diff

#### Multiple Changes

Apply multiple changes in one operation:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
diff = """<<<<<<< SEARCH
:start_line:1
-------
import os
=======
import os
import sys
>>>>>>> REPLACE

<<<<<<< SEARCH
:start_line:20
-------
def old_function():
    pass
=======
def new_function():
    return True
>>>>>>> REPLACE"""

result = code_apply_diff("src/main.py", diff)
# "Successfully applied 2 change(s) to src/main.py"
```

### code\_search\_replace

Simple search and replace for straightforward text substitutions.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.code import code_search_replace, set_workspace

set_workspace("/my/project")

# Simple text replacement
result = code_search_replace(
    "src/main.py",
    search="old_variable_name",
    replace="new_variable_name"
)
print(result)  # "Replaced 5 occurrence(s) in src/main.py"

# Regex replacement
result = code_search_replace(
    "src/main.py",
    search=r"def (\w+)\(",
    replace=r"def renamed_\1(",
    is_regex=True
)
```

### code\_execute\_command

Execute shell commands safely within the workspace.

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.code import code_execute_command, set_workspace

set_workspace("/my/project")

# Run tests
result = code_execute_command("python -m pytest tests/")
print(result)

# Run linter
result = code_execute_command("ruff check src/")

# Run in subdirectory
result = code_execute_command("npm test", cwd="frontend")
```

## Fuzzy Matching

The diff strategy includes fuzzy matching using Levenshtein distance, which helps when:

* Code has been slightly modified since you read it
* There are minor whitespace differences
* Line numbers have shifted due to other changes

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

# The tool uses a 95% similarity threshold by default
# This allows for minor variations while preventing incorrect matches
```

## Indentation Preservation

When applying diffs, indentation is automatically preserved:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Original file:
class MyClass:
    def method(self):
        pass

# Diff with different base indentation:
diff = """<<<<<<< SEARCH
:start_line:2
-------
    def method(self):
        pass
=======
    def method(self):
        return self.value
>>>>>>> REPLACE"""

# Result maintains correct indentation:
class MyClass:
    def method(self):
        return self.value
```

## Security Features

### Workspace Isolation

All file operations are restricted to the configured workspace:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
set_workspace("/my/project")

# This works - within workspace
code_read_file("src/main.py")

# This fails - path traversal blocked
code_read_file("../../../etc/passwd")
# Error: Path '../../../etc/passwd' is outside the workspace
```

### Gitignore Support

The `code_list_files` tool respects `.gitignore` patterns by default:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Files in .gitignore are automatically excluded
files = code_list_files(".", recursive=True)
# node_modules/, __pycache__/, .git/ are excluded
```

### Safe Command Execution

Commands are executed with safety checks:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.code.tools.execute_command import is_safe_command

# Safe commands
is_safe_command("python test.py")  # True
is_safe_command("npm run build")   # True

# Potentially dangerous commands
is_safe_command("rm -rf /")        # False
is_safe_command("sudo apt install") # False
```

## Low-Level API

For advanced use cases, you can use the low-level functions directly:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.code import (
    read_file,
    write_file,
    apply_diff,
    DiffResult,
    apply_search_replace_diff,
)

# Low-level read (returns dict)
result = read_file("src/main.py", workspace="/my/project")
if result['success']:
    print(result['content'])
    print(f"Total lines: {result['total_lines']}")

# Low-level diff application
from praisonai.code.diff import apply_search_replace_diff

result = apply_search_replace_diff(
    original_content="def old(): pass",
    diff_content=diff,
    fuzzy_threshold=0.95,  # 95% similarity required
    buffer_lines=40,       # Search range around line hints
)

if result.success:
    print(result.content)
else:
    print(f"Error: {result.error}")
```

## Helper Functions

### Creating Diff Blocks Programmatically

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonai.code import create_diff_block, create_multi_diff

# Create a single diff block
diff = create_diff_block(
    search_content="def old():\n    pass",
    replace_content="def new():\n    return True",
    start_line=10
)

# Create multiple diff blocks
diff = create_multi_diff([
    {'search': 'old1', 'replace': 'new1', 'start_line': 5},
    {'search': 'old2', 'replace': 'new2', 'start_line': 20},
])
```

## Best Practices

<AccordionGroup>
  <Accordion title="Always read before modifying">
    Read the file first to get the exact content for your SEARCH block:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    content = code_read_file("src/main.py")
    # Use the exact content from the file in your diff
    ```
  </Accordion>

  <Accordion title="Use line number hints">
    Include `:start_line:N` for faster and more accurate matching:

    ```
    <<<<<<< SEARCH
    :start_line:42
    -------
    ```
  </Accordion>

  <Accordion title="Make atomic changes">
    Group related changes in a single diff, but keep unrelated changes separate for easier debugging.
  </Accordion>

  <Accordion title="Verify changes">
    After applying a diff, read the file again or run tests to verify:

    ```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
    result = code_apply_diff("src/main.py", diff)
    if "Successfully" in result:
        test_result = code_execute_command("python -m pytest tests/")
    ```
  </Accordion>
</AccordionGroup>

## Complete Example

Here's a complete workflow showing an agent that adds error handling to a function:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
from praisonaiagents import Agent
from praisonai.code import CODE_TOOLS, set_workspace

# Configure workspace
set_workspace("/path/to/my/project")

# Create coding agent
agent = Agent(
    name="Error Handler",
    instructions="""You are a Python expert. Your task is to:
    1. Read the specified file
    2. Identify functions without error handling
    3. Add appropriate try/except blocks
    4. Verify the changes compile correctly
    
    Always use code_read_file before making changes.
    Use code_apply_diff for precise modifications.
    Run tests after making changes.""",
    tools=CODE_TOOLS
)

# Run the agent
result = agent.start(
    "Add error handling to all database functions in src/database.py"
)
print(result)
```

## Related

<CardGroup cols={2}>
  <Card title="Code Interpreter" icon="terminal" href="/features/codeagent">
    Execute Python code dynamically
  </Card>

  <Card title="Tools" icon="wrench" href="/tools/tools">
    Learn about custom tools
  </Card>

  <Card title="Code UI" icon="browser" href="/ui/code-ui">
    Web interface for code interaction
  </Card>

  <Card title="Agents" icon="robot" href="/concepts/agents">
    Learn about PraisonAI agents
  </Card>
</CardGroup>
