Skip to main content

Installation

Install Mirage:
uv add mirage-ai
If you are not using uv:
pip install mirage-ai
For resources with extra dependencies, install the matching extra:
uv add "mirage-ai[s3]"

Create a Workspace

Start with the RAM resource so you can try Mirage without credentials.
import asyncio

from mirage import MountMode, Workspace
from mirage.resource.ram import RAMResource


async def main() -> None:
    ws = Workspace({"/data": RAMResource()}, mode=MountMode.WRITE)

    await ws.execute('echo "hello mirage" | tee /data/hello.txt')
    result = await ws.execute("cat /data/hello.txt")
    print(await result.stdout_str())

    await ws.close()


asyncio.run(main())

Run Commands

Once a resource is mounted, you can use Mirage like a shell over your virtual filesystem:
import asyncio

from mirage import MountMode, Workspace
from mirage.resource.ram import RAMResource


async def main() -> None:
    ws = Workspace({"/data": RAMResource()}, mode=MountMode.WRITE)

    await ws.execute('echo \'{"name": "alice"}\' | tee /data/user.json')

    result = await ws.execute("ls /data/")
    print(await result.stdout_str())

    result = await ws.execute("cat /data/hello.txt")
    print(await result.stdout_str())

    result = await ws.execute('jq ".name" /data/user.json')
    print(await result.stdout_str())

    result = await ws.execute("grep hello /data/hello.txt")
    print(await result.stdout_str())

    await ws.close()


asyncio.run(main())

Output Safeguards

To keep huge reads from flooding an agent, cat, grep, rg, head, and tail cap their final output at 2000 lines by default. When a cap fires, the agent sees the truncated bytes plus a stderr notice (output truncated at safeguard limit (2000 lines); ...); exit code stays 0. Caps fire only on the terminal command of a pipeline, so cat big.txt | head -n 30 still shows 30 lines.

Configure per mount

Limits are per-command and per-mount. Attach them when you mount a resource by passing a (resource, mode, {command: CommandSafeguard}) tuple. Each guard sets max_lines / max_bytes (output cap) and/or timeout_seconds (deadline); on_exceed is TRUNCATE (default, exit 0 plus notice) or ERROR (exit 1 plus notice):
from mirage import MountMode, Workspace
from mirage.resource.ram import RAMResource
from mirage.types import CommandSafeguard, OnExceed

ws = Workspace(
    {
        "/data": (
            RAMResource(),
            MountMode.WRITE,
            {
                "head": CommandSafeguard(max_lines=100),  # cap, keep going
                "grep": CommandSafeguard(max_lines=50, on_exceed=OnExceed.ERROR),
                "rg": CommandSafeguard(timeout_seconds=30),  # deadline
            },
        ),
    },
    mode=MountMode.WRITE,
)
The same limits are available to the CLI as a command_safeguards block in the workspace YAML.

Next Steps