chore: import upstream snapshot with attribution
Integ / changes (push) Has been skipped
Pre-commit / pre-commit (push) Failing after 1s
CLI exit codes / changes (push) Has been skipped
Test (Install) / changes (push) Has been skipped
Test (Python) / changes (push) Has been skipped
Test (TypeScript) / changes (push) Has been skipped
CLI exit codes / cli-gate (push) Has been cancelled
Test (Install) / test-install-gate (push) Has been cancelled
Integ / integ-gate (push) Has been cancelled
Test (Python) / test-python-gate (push) Has been cancelled
Test (TypeScript) / test-typescript-gate (push) Has been cancelled
Test (Install) / python-minimal (3.12) (push) Has been cancelled
Test (Install) / python-minimal (3.11) (push) Has been cancelled
Test (Install) / python-extra (agno, mirage.agents.agno) (push) Has been cancelled
Test (Install) / python-extra (chroma, mirage.resource.chroma) (push) Has been cancelled
Test (Install) / python-extra (pdf, mirage.core.filetype.pdf) (push) Has been cancelled
Integ / integ (push) Has been cancelled
Integ / integ-database (push) Has been cancelled
Integ / integ-database-ts (push) Has been cancelled
Integ / integ-data (push) Has been cancelled
Integ / integ-ssh (push) Has been cancelled
Integ / integ-ssh-ts (push) Has been cancelled
Test (Python) / audit (push) Has been cancelled
Test (TypeScript) / test (push) Has been cancelled
Test (TypeScript) / python-fs-shim (push) Has been cancelled
CLI exit codes / Python CLI (push) Has been cancelled
CLI exit codes / TypeScript CLI (push) Has been cancelled
CLI exit codes / Cross-language snapshot interop (push) Has been cancelled
Test (Python) / test (push) Has been cancelled
Test (Python) / import-isolation (deepagents, openai, mirage.agents.openai_agents) (push) Has been cancelled
Test (Python) / import-isolation (deepagents, pydantic-ai, mirage.agents.pydantic_ai) (push) Has been cancelled
Integ / integ-ts (push) Has been cancelled
Integ / integ-fuse (push) Has been cancelled
Test (Install) / python-extra (databricks, mirage.resource.databricks_volume) (push) Has been cancelled
Test (Install) / python-extra (deepagents, mirage.agents.langchain) (push) Has been cancelled
Test (Install) / python-extra (email, mirage.resource.email) (push) Has been cancelled
Test (Install) / python-extra (fuse, mirage.fuse.mount) (push) Has been cancelled
Test (Install) / python-extra (hdf5, mirage.core.filetype.hdf5) (push) Has been cancelled
Test (Install) / python-extra (hf, mirage.resource.hf_buckets) (push) Has been cancelled
Test (Install) / python-extra (lancedb, mirage.resource.lancedb) (push) Has been cancelled
Test (Install) / python-extra (langfuse, mirage.resource.langfuse) (push) Has been cancelled
Test (Install) / python-extra (mongodb, mirage.resource.mongodb) (push) Has been cancelled
Test (Install) / python-extra (nextcloud, mirage.resource.nextcloud) (push) Has been cancelled
Test (Install) / python-extra (openai, mirage.agents.openai_agents) (push) Has been cancelled
Test (Install) / python-extra (openhands, mirage.agents.openhands, 3.12) (push) Has been cancelled
Test (Install) / python-extra (parquet, mirage.core.filetype.parquet) (push) Has been cancelled
Test (Install) / python-extra (postgres, mirage.resource.postgres) (push) Has been cancelled
Test (Install) / python-extra (pydantic-ai, mirage.agents.pydantic_ai) (push) Has been cancelled
Test (Install) / python-extra (qdrant, mirage.resource.qdrant) (push) Has been cancelled
Test (Install) / python-extra (redis, mirage.resource.redis) (push) Has been cancelled
Test (Install) / python-extra (s3, mirage.resource.s3) (push) Has been cancelled
Test (Install) / python-extra (ssh, mirage.resource.ssh) (push) Has been cancelled
Test (Install) / ts-minimal (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 12:30:44 +08:00
commit bcbd1bdb22
5748 changed files with 562488 additions and 0 deletions
+70
View File
@@ -0,0 +1,70 @@
---
title: Agno
description: Give Agno agents shell-based filesystem access to any Mirage workspace using MirageToolkit.
icon: /images/agno-logo.svg
---
[Agno](https://github.com/agno-agi/agno) is an agent framework that groups related tools into `Toolkit` classes. Mirage ships `MirageToolkit`, a toolkit backed by a `Workspace` instead of the host machine. The agent gets five shell-style tools (`execute`, `read`, `write`, `ls`, `grep`); mount RAM, S3, GDrive, Slack, etc. and the agent uses them through the same Agno API.
## Install
```bash
uv add 'mirage-ai[agno]'
```
Requires `agno>=2.4.0`: the toolkit registers async variants through Agno's `async_tools` parameter, which was added in 2.4.0.
## Usage
```python
import asyncio
from agno.agent import Agent
from agno.models.openai import OpenAIChat
from mirage import MountMode, RAMResource, Workspace
from mirage.agents.agno import MirageToolkit
ws = Workspace({"/data": RAMResource()}, mode=MountMode.WRITE)
agent = Agent(
model=OpenAIChat(id="gpt-4o"),
tools=[MirageToolkit(ws)],
instructions=("You have access to a virtual filesystem via shell "
"tools. Use them to explore and read files."),
markdown=True,
)
async def main() -> None:
await ws.execute('echo "hello from mirage" | tee /data/hello.txt')
await agent.aprint_response(
"List all files under /data and show the contents of each one.")
asyncio.run(main())
```
## Tools
Every tool is registered as a sync + async pair under one name; Agno picks the async variant in `arun`/`aprint_response` and the sync variant otherwise.
| Tool | Mirage translation |
| --- | --- |
| `execute(command)` | `await ws.execute(command)`, full shell with pipes |
| `read(path)` | `cat <path>` |
| `write(path, content)` | `tee <path>` with `stdin=` |
| `ls(path="/")` | `ls <path>` |
| `grep(pattern, path)` | `grep -r <pattern> <path>` |
## Exports
| Symbol | Purpose |
| --- | --- |
| `MirageToolkit` | Agno `Toolkit` exposing the 5 shell tools, backed by `Workspace.execute`. |
| `MIRAGE_SYSTEM_PROMPT` | Default system prompt describing the virtual filesystem. |
| `build_system_prompt` | Compose the default prompt with mount info and extra instructions. |
## Examples
- [`examples/python/agents/agno/agno_example.py`](https://github.com/strukto-ai/mirage/blob/main/examples/python/agents/agno/agno_example.py), `Agent` with `MirageToolkit` over a RAM workspace, sync and async.
+99
View File
@@ -0,0 +1,99 @@
---
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.
+72
View File
@@ -0,0 +1,72 @@
---
title: Claude Agent SDK
description: Run Anthropic's Claude Agent SDK against a Mirage workspace via an in-process MCP server exposing execute, read, write, edit, ls, and grep tools.
icon: /images/claude-logo.svg
---
The [Claude Agent SDK](https://code.claude.com/docs/en/agent-sdk/) builds agents on Claude. Mirage exposes any `Workspace` to the SDK as an in-process MCP server, so every file and shell operation the agent runs is routed through Mirage instead of the host filesystem.
This is distinct from [Claude Code](/python/agents/claude-code), which points the `claude` CLI at a [FUSE](/python/setup/fuse) mountpoint. Use this SDK integration when you build your own agent with `claude_agent_sdk.query()` and want Mirage tools rather than the built-in file tools.
## Install
```bash
uv add 'mirage-ai[claude-agent-sdk]'
```
## Usage
`build_options` wires a workspace into a ready-to-use `ClaudeAgentOptions`: it registers the Mirage MCP server, restricts the agent to Mirage's tools, and injects a system prompt describing the mounted paths.
```python
from claude_agent_sdk import query
from mirage import Workspace
from mirage.agents.claude_agent_sdk import build_options
from mirage.resource.s3 import S3Config, S3Resource
ws = Workspace({"/s3": S3Resource(S3Config(bucket="my-bucket"))})
async for msg in query(
prompt="cat /s3/data.csv | grep error",
options=build_options(ws),
):
print(msg)
```
## Composing with other MCP servers
Use `MirageServer` directly to combine Mirage with other servers:
```python
from claude_agent_sdk import ClaudeAgentOptions
from mirage.agents.claude_agent_sdk import MirageServer, build_system_prompt
options = ClaudeAgentOptions(
mcp_servers={"mirage": MirageServer(ws), "github": github_server},
allowed_tools=["mcp__mirage__*", "mcp__github__*"],
tools=[],
system_prompt=build_system_prompt(workspace=ws),
)
```
## Tools
| Tool | Maps to |
| --- | --- |
| `execute_command` | `Workspace.execute()`, the full shell pipeline (cat, grep, find, pipe, ...). |
| `read` | Line-paginated file read with `offset` and `limit`. |
| `write` | Create a new file (fails if it already exists). |
| `edit` | Replace a string in an existing file. |
| `ls` | List a directory. |
| `grep` | Recursive `grep -rn` over the workspace. |
## Exports
| Symbol | Purpose |
| --- | --- |
| `MirageServer` | In-process MCP server exposing the Mirage tools; pass to `ClaudeAgentOptions(mcp_servers=...)`. |
| `build_options` | Returns a ready-to-use `ClaudeAgentOptions` backed by a workspace. |
| `build_system_prompt` | Generates a system prompt that describes mounted paths to the model. |
| `MIRAGE_SYSTEM_PROMPT` | The default system prompt template. |
+48
View File
@@ -0,0 +1,48 @@
---
title: Claude Code
description: Run Anthropic's Claude Code CLI against any Mirage workspace by mounting it as a real filesystem via FUSE.
icon: /images/claude-logo.svg
---
[Claude Code](https://github.com/anthropics/claude-code) is Anthropic's CLI for Claude. It expects a real filesystem and doesn't expose a pluggable backend, so instead of an SDK integration, Mirage exposes any workspace as a real filesystem via [FUSE](/python/setup/fuse) and lets you point `claude` at the mountpoint.
## Install
```bash
uv add 'mirage-ai[fuse]'
```
Then install [Claude Code](https://docs.claude.com/en/docs/claude-code/setup) separately.
## Usage
```python
from mirage import Mount, MountMode, Workspace
from mirage.resource.ram import RAMResource
from mirage.resource.s3 import S3Config, S3Resource
s3 = S3Resource(S3Config(bucket="my-bucket"))
with Workspace(
{"/": Mount(RAMResource(), mode=MountMode.WRITE, fuse=True),
"/s3": Mount(s3, mode=MountMode.READ)},
) as ws:
print(f"cd {ws.fuse_mountpoint} && claude")
input("Press Enter when done...")
```
The mountpoint behaves like a regular directory. `claude` reads, writes, runs `bash`, and patches files just like it would on a normal disk, every operation goes through Mirage's ops layer, so writes to `/s3/...` hit S3, writes to `/` stay in RAM.
## Why FUSE instead of an SDK integration?
Claude Code's tool-use loop is fully internal, there's no `Backend` interface to swap. FUSE gives Mirage a single unforced way in: present a real path, let the agent be the agent.
You lose:
- Per-tool prompt customization
- Observation hooks on tool calls
- Mirage's op-record telemetry on the agent's specific calls (host syscalls aren't recorded the same way)
You gain:
- Zero integration effort
- Compatibility with every Claude Code feature, including future ones
- The same approach works for any other directory-based agent ([OpenAI Codex](/python/agents/codex), `aider`, etc.)
+35
View File
@@ -0,0 +1,35 @@
---
title: OpenAI Codex
description: Run OpenAI's Codex CLI against any Mirage workspace by mounting it as a real filesystem via FUSE.
icon: /images/openai-logo.svg
---
[OpenAI Codex](https://github.com/openai/codex) is OpenAI's coding-agent CLI. Like [Claude Code](/python/agents/claude-code), it operates on a real filesystem and doesn't expose a pluggable backend, so Mirage integrates by [FUSE-mounting](/python/setup/fuse) a workspace and letting you point `codex` at the mountpoint.
## Install
```bash
uv add 'mirage-ai[fuse]'
```
Then install [OpenAI Codex](https://github.com/openai/codex) separately.
## Usage
```python
from mirage import Mount, MountMode, Workspace
from mirage.resource.ram import RAMResource
with Workspace(
{"/": Mount(RAMResource(), mode=MountMode.WRITE, fuse=True)}) as ws:
print(f"cd {ws.fuse_mountpoint} && codex")
input("Press Enter when done...")
```
The mountpoint behaves like a regular directory. Codex's `read_file`, `write_file`, and `run_shell` tools all dispatch through Mirage's ops layer.
## Why FUSE instead of an SDK integration?
The Codex CLI's tool surface isn't pluggable, it expects host file operations. FUSE makes those host operations *be* Mirage operations.
You lose per-tool customization and Mirage's op-record telemetry; you gain zero integration effort and compatibility with every Codex feature. Same trade-off as [Claude Code](/python/agents/claude-code).
+47
View File
@@ -0,0 +1,47 @@
---
title: Agents
description: Drop a Mirage workspace into the Python agent framework you already use.
icon: robot
---
Each integration ships behind an optional extra. Install only what you use.
```bash
uv add 'mirage-ai[openai]' # openai-agents
uv add 'mirage-ai[deepagents]' # LangChain deepagents
uv add 'mirage-ai[openhands]' # OpenHands SDK
uv add 'mirage-ai[pydantic-ai]' # pydantic-ai
uv add 'mirage-ai[camel]' # CAMEL-AI
uv add 'mirage-ai[agno]' # Agno
uv add 'mirage-ai[claude-agent-sdk]' # Claude Agent SDK
```
<CardGroup cols={2}>
<Card title="OpenAI Agents" icon="/images/openai-logo.svg" href="/python/agents/openai-agents">
For the openai-agents SDK.
</Card>
<Card title="LangChain · deepagents" icon="/images/langchain-logo.svg" href="/python/agents/langchain">
For deepagents and LangGraph-style agents.
</Card>
<Card title="OpenHands" icon="/images/openhands-logo.svg" href="/python/agents/openhands">
For the OpenHands agent SDK.
</Card>
<Card title="pydantic-ai" icon="/images/pydantic-logo.svg" href="/python/agents/pydantic-ai">
For pydantic-ai and pydantic-deepagents.
</Card>
<Card title="CAMEL-AI" icon="/images/camel-logo.svg" href="/python/agents/camel">
For CAMEL-AI's `ChatAgent`.
</Card>
<Card title="Agno" icon="/images/agno-logo.svg" href="/python/agents/agno">
For Agno's `Agent` via `MirageToolkit`.
</Card>
<Card title="Claude Code" icon="/images/claude-logo.svg" href="/python/agents/claude-code">
Mount a workspace via FUSE and run `claude` against it.
</Card>
<Card title="Claude Agent SDK" icon="/images/claude-logo.svg" href="/python/agents/claude-agent-sdk">
For `claude-agent-sdk` via an in-process MCP server.
</Card>
<Card title="Codex" icon="/images/openai-logo.svg" href="/python/agents/codex">
Same pattern as Claude Code: mount, then `codex`.
</Card>
</CardGroup>
+59
View File
@@ -0,0 +1,59 @@
---
title: LangChain (deepagents)
description: Back deepagents and other LangGraph-style agents with a Mirage workspace via LangchainWorkspace.
icon: /images/langchain-logo.svg
---
[deepagents](https://github.com/langchain-ai/deepagents) is LangChain's framework for long-horizon coding agents. It accepts a pluggable `backend` for filesystem and shell operations, Mirage ships one.
## Install
```bash
uv add 'mirage-ai[deepagents]' langchain-anthropic
```
This pulls in `deepagents>=0.4.12`. Bring your own LangChain chat model (`langchain-anthropic`, `langchain-openai`, etc.).
## Usage
```python
from deepagents import create_deep_agent
from langchain_anthropic import ChatAnthropic
from mirage import MountMode, Workspace
from mirage.agents.langchain import (
LangchainWorkspace,
build_system_prompt,
extract_text,
)
from mirage.resource.ram import RAMResource
ws = Workspace({"/": RAMResource()}, mode=MountMode.WRITE)
agent = create_deep_agent(
model=ChatAnthropic(model="claude-sonnet-4-20250514"),
system_prompt=build_system_prompt(
mount_info={"/": "In-memory filesystem (read/write)"},
),
backend=LangchainWorkspace(ws),
)
result = agent.invoke({
"messages": [{"role": "user", "content": "Create /report.md and summarize."}],
})
for text in extract_text(result["messages"]):
print(text)
```
## Exports
| Symbol | Purpose |
| --- | --- |
| `LangchainWorkspace` | `Backend` implementation for deepagents, wires reads, writes, edits, and shell. |
| `extract_text` | Pulls the text content out of LangChain messages. |
| `build_system_prompt` | Generates a system prompt that describes mounted paths to the model. |
## Examples
- [`examples/python/agents/langchain/s3_deepagent.py`](https://github.com/strukto-ai/mirage/blob/main/examples/python/agents/langchain/s3_deepagent.py), read-only S3 exploration.
- [`examples/python/agents/langchain/databricks_volume_deepagent.py`](https://github.com/strukto-ai/mirage/blob/main/examples/python/agents/langchain/databricks_volume_deepagent.py), Databricks volume exploration inside Databricks Apps or local SDK-auth setups.
+70
View File
@@ -0,0 +1,70 @@
---
title: OpenAI Agents SDK
description: Run openai-agents against a Mirage workspace using MirageShellExecutor, MirageEditor, and MirageSandboxClient.
icon: /images/openai-logo.svg
---
The OpenAI Agents Python SDK ([openai-agents](https://github.com/openai/openai-agents-python)) ships built-in `ShellTool` and `ApplyPatchTool` primitives, plus the newer `SandboxAgent`. Mirage provides drop-in replacements that route every shell command, patch, and sandbox call through your `Workspace` instead of the host.
## Install
```bash
uv add 'mirage-ai[openai]'
```
This pulls in `openai>=2.30` and `openai-agents>=0.14.7`.
## Tools (`ShellTool` + `ApplyPatchTool`)
```python
from agents import Agent, ApplyPatchTool, Runner, ShellTool
from mirage import MountMode, Workspace
from mirage.agents.openai_agents import (
MirageEditor,
MirageShellExecutor,
build_system_prompt,
)
from mirage.resource.ram import RAMResource
ws = Workspace({"/": RAMResource()}, mode=MountMode.WRITE)
agent = Agent(
name="Mirage RAM Agent",
model="gpt-5.5-mini",
instructions=build_system_prompt(
mount_info={"/": "In-memory filesystem (read/write)"},
),
tools=[
ShellTool(executor=MirageShellExecutor(ws)),
ApplyPatchTool(editor=MirageEditor(ws)),
],
)
```
## Sandbox Agent
For the new `SandboxAgent` API, use `MirageSandboxClient`:
```python
from agents.sandbox import SandboxAgent
from mirage.agents.openai_agents import MirageSandboxClient
client = MirageSandboxClient(ws)
agent = SandboxAgent(name="...", model="gpt-5.5", instructions=ws.file_prompt)
```
## Exports
| Symbol | Purpose |
| --- | --- |
| `MirageShellExecutor` | Drop-in `ShellTool` executor, runs inside `Workspace.execute()`. |
| `MirageEditor` | Drop-in `ApplyPatchTool` editor, patches go through Mirage FS ops. |
| `MirageSandboxClient` | Adapter for `agents.sandbox.SandboxAgent`. |
| `MirageSandboxSession` | Per-conversation session bound to a workspace. |
| `build_system_prompt` | Generates a system prompt that describes mounted paths to the model. |
## Examples
- [`examples/python/agents/openai_agents/ram_agent.py`](https://github.com/strukto-ai/mirage/blob/main/examples/python/agents/openai_agents/ram_agent.py), RAM-only sandbox.
- [`examples/python/agents/openai_agents/sandbox_agent.py`](https://github.com/strukto-ai/mirage/blob/main/examples/python/agents/openai_agents/sandbox_agent.py), `SandboxAgent` over RAM + S3 + Slack.
+56
View File
@@ -0,0 +1,56 @@
---
title: OpenHands
description: Run the All-Hands OpenHands SDK against a Mirage workspace using MirageWorkspace and the Mirage terminal tool.
icon: /images/openhands-logo.svg
---
[OpenHands](https://github.com/All-Hands-AI/OpenHands) is All-Hands' agent SDK for autonomous software engineering. It models a `Workspace` and a `Terminal` tool, Mirage ships drop-in implementations of both so the agent operates entirely inside a Mirage workspace.
## Install
```bash
uv add 'mirage-ai[openhands]'
```
This pulls in `openhands-sdk>=1.18.0` and `openhands-tools>=1.18.0`. The OpenHands SDK requires Python >= 3.12, on 3.11 this extra installs nothing.
## Usage
```python
import os
from openhands.sdk import LLM, Agent, Conversation, Tool
from mirage import MountMode, Workspace
from mirage.agents.openhands import MirageWorkspace, register_mirage_terminal
from mirage.resource.ram import RAMResource
ws = Workspace({"/": RAMResource()}, mode=MountMode.WRITE)
llm = LLM(
model=os.getenv("LLM_MODEL", "anthropic/claude-sonnet-4-6"),
api_key=os.getenv("LLM_API_KEY"),
)
with MirageWorkspace(workspace=ws, working_dir="/") as mirage_ws:
tool_name = register_mirage_terminal(mirage_ws)
agent = Agent(
llm=llm,
tools=[Tool(name=tool_name)],
system_message=ws.file_prompt,
)
conversation = Conversation(agent=agent, workspace=mirage_ws)
conversation.send_message("Create /hello.txt with 'hi' and ls /.")
conversation.run()
```
## Exports
| Symbol | Purpose |
| --- | --- |
| `MirageWorkspace` | OpenHands `Workspace` implementation backed by a Mirage workspace. |
| `MirageTerminalExecutor` | Terminal executor that pipes through `Workspace.execute()`. |
| `register_mirage_terminal` | Registers the Mirage terminal tool so the agent can `Tool(name=...)` it. |
## Examples
- [`examples/python/agents/openhands/sandbox_agent.py`](https://github.com/strukto-ai/mirage/blob/main/examples/python/agents/openhands/sandbox_agent.py), RAM + S3 + Slack composed into one workspace.
+70
View File
@@ -0,0 +1,70 @@
---
title: pydantic-deepagents
description: Implements pydantic-ai-backend's SandboxProtocol so pydantic-deepagents and any pydantic-ai agent can run inside a Mirage workspace.
icon: /images/pydantic-logo.svg
---
[pydantic-deepagents](https://github.com/vstorm-co/pydantic-deepagents) is a Claude Codestyle deep agent harness built on [pydantic-ai](https://github.com/pydantic/pydantic-ai). It uses [`pydantic-ai-backend`](https://pypi.org/project/pydantic-ai-backend/)'s `SandboxProtocol` for filesystem, shell, grep, and edit operations, Mirage's `PydanticAIWorkspace` is a drop-in implementation of that protocol.
## Install
```bash
uv add 'mirage-ai[pydantic-ai]'
```
This pulls in `pydantic-ai>=1.35` and `pydantic-ai-backend>=0.1.0`. To use it with [pydantic-deepagents](https://github.com/vstorm-co/pydantic-deepagents):
```bash
uv add pydantic-deep
```
## Usage
```python
from dataclasses import dataclass
from pydantic_ai import Agent
from pydantic_ai_backends import create_console_toolset
from mirage import MountMode, Workspace
from mirage.agents.pydantic_ai import PydanticAIWorkspace, build_system_prompt
from mirage.resource.ram import RAMResource
ws = Workspace({"/": RAMResource()}, mode=MountMode.WRITE)
backend = PydanticAIWorkspace(ws)
@dataclass
class Deps:
backend: PydanticAIWorkspace
agent = Agent(
"openai:gpt-4.1",
system_prompt=build_system_prompt(
mount_info={"/": "In-memory filesystem (read/write)"},
),
deps_type=Deps,
toolsets=[create_console_toolset()],
)
result = agent.run_sync(
"Create /hello.txt with 'hi' and cat it.",
deps=Deps(backend=backend),
)
print(result.output)
```
## Exports
| Symbol | Purpose |
| --- | --- |
| `PydanticAIWorkspace` | `SandboxProtocol` implementation backed by a Mirage workspace. |
| `build_system_prompt` | Generates a system prompt that describes mounted paths to the model. |
`PydanticAIWorkspace` routes file operations through the Ops layer directly and shell operations through `Workspace.execute()` for full pipe and flag support. PDF reads are converted to images via `pages_to_images` so the agent can pass them as `BinaryContent`.
## Examples
- [`examples/python/agents/pydantic_ai/s3_agent.py`](https://github.com/strukto-ai/mirage/blob/main/examples/python/agents/pydantic_ai/s3_agent.py), read-only S3 exploration.
- [`examples/python/agents/pydantic_ai/s3_pdf_agent.py`](https://github.com/strukto-ai/mirage/blob/main/examples/python/agents/pydantic_ai/s3_pdf_agent.py), PDF page-to-image pipeline.