---
title: CAMEL-AI
description: Run CAMEL-AI ChatAgents against a Mirage workspace using MirageTerminalToolkit and MirageFileToolkit.
icon: /images/camel-logo.svg
---

[CAMEL-AI](https://github.com/camel-ai/camel) is a multi-agent framework with a large ecosystem of toolkits. Mirage ships two of those toolkits, terminal and file, backed by a `Workspace` instead of the host. The agent's shell, file reads/writes, and search all run inside Mirage; mount RAM, S3, GDrive, Slack, etc. and the agent uses them through the same camel API.

## Install

```bash
uv add 'mirage-ai[camel]'
```

This pulls in `camel-ai>=0.2.40,<0.3` and `markitdown>=0.1.5`. Note: `mirage-ai[camel]` is mutually exclusive with `[openai]`, `[openhands]`, and `[pydantic-ai]`, camel pins `pydantic<=2.12.0` while the other agent SDKs require `>=2.12.2`. Pick one stack per environment.

## Usage

```python
import asyncio

from camel.agents import ChatAgent
from camel.messages import BaseMessage
from camel.models import ModelFactory
from camel.types import ModelPlatformType, ModelType

from mirage import MountMode, Workspace
from mirage.agents.camel import MirageFileToolkit, MirageTerminalToolkit
from mirage.resource.ram import RAMResource

ws = Workspace({"/": RAMResource()}, mode=MountMode.WRITE)

terminal = MirageTerminalToolkit(ws)
files = MirageFileToolkit(ws)

model = ModelFactory.create(
    model_platform=ModelPlatformType.OPENAI,
    model_type=ModelType.GPT_5_MINI,
)

agent = ChatAgent(
    system_message=BaseMessage.make_assistant_message(
        role_name="Mirage Camel Agent",
        content="You operate over a Mirage virtual filesystem mounted at /.",
    ),
    model=model,
    tools=[*terminal.get_tools(), *files.get_tools()],
)

response = await asyncio.to_thread(
    agent.step,
    "Write /data/numbers.csv with 3 rows, then read it back.",
)
print(response.msgs[-1].content)

terminal.close()
files.close()
```

## Toolkits

### `MirageTerminalToolkit`

Drop-in replacement for camel's `TerminalToolkit`. Same 6 functions, all routed through `Workspace.execute()`:

| Method | Mirage translation |
| --- | --- |
| `shell_exec(id, cmd, block=True)` | `await ws.execute(cmd)` |
| `shell_exec(id, cmd, block=False)` | `await ws.execute(f"{cmd} &")`, uses Mirage's [JobTable](/python/quickstart) |
| `shell_view(id)` | `jobs` (status) or `wait %N` (final stdout) |
| `shell_kill_process(id)` | `kill %N` |
| `shell_write_content_to_file` | `cat > path` with `stdin=` |
| `shell_write_to_process` | Returns a clear error, Mirage's shell is non-interactive |

No docker backend, no env-cloning, no safe-mode allowlist. Mirage Workspace already isolates execution.

### `MirageFileToolkit`

Subclasses camel's `FileToolkit`, inherits all 7 public methods *and* every format writer (PDF, DOCX, JSON, CSV, HTML, ipynb, plain text). Path resolution and IO are overridden to route through Mirage; format writers operate on a tempfile and the result is pushed via `Workspace.execute(f"cat > {path}", stdin=...)`.

| Method | Behavior |
| --- | --- |
| `write_to_file(title, content, filename)` | Format writer runs in tempdir → bytes pushed to Mirage path |
| `read_file(file_paths)` | Bytes pulled from Mirage → tempfile → camel's MarkItDown converter |
| `edit_file(file_path, old, new)` | In-place text replacement via Mirage |
| `search_files(file_name, path)` | `find <path> -name <file_name>` |
| `glob_files(pattern, path)` | Same as `search_files` |
| `grep_files(pattern, path)` | `grep -rn <pattern> <path>` |

## Exports

| Symbol | Purpose |
| --- | --- |
| `MirageTerminalToolkit` | Camel `BaseToolkit` exposing the 6 shell tools, backed by `Workspace.execute`. |
| `MirageFileToolkit` | Subclass of camel's `FileToolkit` routing path/IO through Mirage. |

## Examples

- [`examples/python/agents/camel/sandbox_agent.py`](https://github.com/strukto-ai/mirage/blob/main/examples/python/agents/camel/sandbox_agent.py), `ChatAgent` with both toolkits over a RAM workspace.
