Skip to content

Commit 68e32b7

Browse files
docs: sync Core Integrations API reference (mirage) on Docusaurus (#11880)
Co-authored-by: bogdankostic <48713846+bogdankostic@users.noreply.github.com>
1 parent 1216c61 commit 68e32b7

14 files changed

Lines changed: 4032 additions & 0 deletions

File tree

Lines changed: 288 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,288 @@
1+
---
2+
title: "Mirage"
3+
id: integrations-mirage
4+
description: "Mirage integration for Haystack"
5+
slug: "/integrations-mirage"
6+
---
7+
8+
9+
## haystack_integrations.tools.mirage.shell_tool
10+
11+
### MirageShellTool
12+
13+
Bases: <code>Tool</code>
14+
15+
A Haystack `Tool` that lets an `Agent` run bash commands across a Mirage virtual filesystem.
16+
17+
Mirage mounts heterogeneous backends (object storage, databases, SaaS apps, local disk) as one
18+
filesystem; this tool exposes Mirage's single `execute` surface to an Agent as one well-described
19+
tool with a `command` parameter. Output is normalized to text and truncated before it reaches the
20+
model.
21+
22+
### Security model
23+
24+
Mirage never shells out to the host: every command runs inside Mirage's own virtual-filesystem
25+
interpreter, so the blast radius is confined to the mounts you attach. Two controls shape what an
26+
Agent can do:
27+
28+
- **Per-mount read-only mode** (`MirageMount(..., read_only=True)`) is the authoritative write
29+
boundary. Mirage refuses any write to a read-only mount regardless of the command used, so this
30+
-- not the allowlist -- is how you prevent modification or deletion. Mount anything the Agent
31+
should not change as read-only.
32+
- **The command allowlist** (`allowed_commands`) restricts *which* commands may run. It is
33+
enforced against every command Mirage would execute, including commands nested inside
34+
`$(...)`, backticks, `<(...)` and subshells, so `ls "$(rm x)"` is rejected unless `rm`
35+
is also allowed. Treat it as a best-effort filter to steer the Agent, not a sandbox: allowing a
36+
command that itself runs other commands (`eval`, `bash`, `sh`, `source`, `xargs`,
37+
`timeout`) effectively allows anything, so do not list those for untrusted/hosted use.
38+
- **`denied_paths`** rejects any command whose text references one of the given path substrings.
39+
40+
### Usage example
41+
42+
```python
43+
from haystack.components.agents import Agent
44+
from haystack.components.generators.chat import OpenAIChatGenerator
45+
from haystack.dataclasses import ChatMessage
46+
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount, MirageShellTool
47+
48+
workspace = MirageWorkspace([
49+
MirageMount(path="/data", resource="ram"),
50+
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
51+
])
52+
tool = MirageShellTool(workspace, allowed_commands=["ls", "cat", "grep", "head", "wc", "cp"])
53+
54+
agent = Agent(chat_generator=OpenAIChatGenerator(model="gpt-4o-mini"), tools=[tool])
55+
result = agent.run(messages=[ChatMessage.from_user("How many lines in /s3/log.txt mention 'alert'?")])
56+
print(result["messages"][-1].text)
57+
```
58+
59+
#### __init__
60+
61+
```python
62+
__init__(
63+
workspace: MirageWorkspace,
64+
*,
65+
name: str = "mirage_shell",
66+
description: str | None = None,
67+
invocation_timeout: float = 60.0,
68+
max_output_chars: int = 20000,
69+
allowed_commands: list[str] | None = None,
70+
denied_paths: list[str] | None = None
71+
) -> None
72+
```
73+
74+
Initialize the Mirage shell tool.
75+
76+
**Parameters:**
77+
78+
- **workspace** (<code>MirageWorkspace</code>) – The :class:`MirageWorkspace` describing the mount tree.
79+
- **name** (<code>str</code>) – Tool name exposed to the LLM.
80+
- **description** (<code>str | None</code>) – Custom description. If None, one is generated from the mount tree.
81+
- **invocation_timeout** (<code>float</code>) – Maximum seconds to wait for a command to finish.
82+
- **max_output_chars** (<code>int</code>) – Truncate command output to this many characters before returning it.
83+
- **allowed_commands** (<code>list\[str\] | None</code>) – If set, only these command names may run, e.g.
84+
`["ls", "cat", "grep", "head", "wc"]`. The allowlist is enforced against *every* command
85+
Mirage would execute -- including commands nested in substitutions/subshells -- so
86+
`ls "$(rm x)"` is rejected unless `rm` is also allowed. It is a filter over Mirage's
87+
virtual commands to steer the Agent, not a security sandbox; the write boundary is
88+
per-mount `read_only` (see the class "Security model" section). If None, any command is
89+
allowed (not recommended for untrusted/hosted use).
90+
- **denied_paths** (<code>list\[str\] | None</code>) – If set, any command referencing one of these path substrings is rejected.
91+
92+
#### warm_up
93+
94+
```python
95+
warm_up() -> None
96+
```
97+
98+
Build the underlying live workspace eagerly. Called by `Agent.warm_up()`/`Pipeline.warm_up()`.
99+
100+
#### to_dict
101+
102+
```python
103+
to_dict() -> dict[str, Any]
104+
```
105+
106+
Serialize the tool to a dictionary in the `{"type": ..., "data": ...}` format.
107+
108+
#### from_dict
109+
110+
```python
111+
from_dict(data: dict[str, Any]) -> MirageShellTool
112+
```
113+
114+
Deserialize the tool from a dictionary.
115+
116+
#### close
117+
118+
```python
119+
close() -> None
120+
```
121+
122+
Close the underlying workspace.
123+
124+
## haystack_integrations.tools.mirage.workspace
125+
126+
### MirageMount
127+
128+
Declarative description of a single backend mounted into a :class:`MirageWorkspace`.
129+
130+
A mount is the serializable unit of a Mirage workspace: it names *where* a backend is mounted
131+
(`path`), *which* backend it is (`resource`, a Mirage registry name such as `"s3"` or `"gdrive"`),
132+
and *how* to configure it (`config`).
133+
134+
`config` values may be plain values, Haystack `Secret` objects for credentials, or an OAuth token
135+
source (e.g. `OAuthRefreshTokenSource`) for backends whose config accepts a token-provider callable
136+
(such as Mirage's OneDrive `access_token`). Secrets and token sources are resolved only when the
137+
live workspace is built.
138+
139+
Every backend is created the same way. Use the Mirage registry name and the config keys that backend expects
140+
(discover names with `MirageMount.available_resources()`; config keys come from the backend's Mirage config class):
141+
142+
```python
143+
from haystack.utils import Secret
144+
145+
MirageMount(path="/data", resource="ram") # in-memory scratch
146+
MirageMount(path="/local", resource="disk", config={"root": "/srv/data"}) # local disk
147+
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True)
148+
MirageMount(
149+
path="/drive",
150+
resource="gdrive",
151+
config={"client_id": "...", "refresh_token": Secret.from_env_var("GDRIVE_REFRESH_TOKEN")},
152+
read_only=True,
153+
)
154+
```
155+
156+
**Parameters:**
157+
158+
- **path** (<code>str</code>) – Mount point in the virtual filesystem, e.g. `"/s3"`.
159+
- **resource** (<code>str</code>) – Mirage registry name of the backend, e.g. `"ram"`, `"disk"`, `"s3"`, `"gdrive"`.
160+
See `mirage.resource.registry.REGISTRY` or `MirageMount.available_resources()` for the full list.
161+
- **config** (<code>dict\[str, Any\]</code>) – Keyword arguments passed to the backend's Mirage config. Values may be `Secret`s, or
162+
an OAuth token source that is turned into a token-provider callable when the workspace is built.
163+
- **read_only** (<code>bool</code>) – If True, the mount is mounted in Mirage's READ mode and writes are rejected by
164+
Mirage itself.
165+
166+
#### available_resources
167+
168+
```python
169+
available_resources() -> list[str]
170+
```
171+
172+
Return the Mirage registry names usable as `resource`.
173+
174+
These are short backend names such as `"s3"`, `"gdrive"`, `"postgres"`. Pass one to
175+
`MirageMount(resource=...)`; the config keys each backend expects come from its Mirage
176+
config class.
177+
178+
### MirageWorkspace
179+
180+
A description of a Mirage mount tree that lazily builds a live `mirage.Workspace`.
181+
182+
`MirageWorkspace` is the shared backend behind the Mirage tools and components: it holds the list of
183+
:class:`MirageMount`s and the cache configuration, serializes cleanly (resolving `Secret`s only at
184+
build time), and constructs the live workspace on first use via Mirage's resource registry.
185+
186+
### Usage example
187+
188+
```python
189+
from haystack.utils import Secret
190+
from haystack_integrations.tools.mirage import MirageWorkspace, MirageMount
191+
192+
ws = MirageWorkspace(
193+
mounts=[
194+
MirageMount(path="/data", resource="ram"),
195+
MirageMount(path="/s3", resource="s3", config={"bucket": "my-bucket"}, read_only=True),
196+
]
197+
)
198+
print(ws.run("ls /s3"))
199+
```
200+
201+
#### __init__
202+
203+
```python
204+
__init__(
205+
mounts: list[MirageMount], *, cache_limit: str | int = "512MB"
206+
) -> None
207+
```
208+
209+
Initialize the workspace description.
210+
211+
**Parameters:**
212+
213+
- **mounts** (<code>list\[MirageMount\]</code>) – The backends to mount, as a list of :class:`MirageMount`.
214+
- **cache_limit** (<code>str | int</code>) – Mirage file-cache size limit (e.g. `"512MB"` or an int byte count).
215+
216+
**Raises:**
217+
218+
- <code>MirageConfigError</code> – If no mounts are provided or mount paths are not unique.
219+
220+
#### warm_up
221+
222+
```python
223+
warm_up() -> None
224+
```
225+
226+
Build the live `mirage.Workspace` eagerly. Idempotent.
227+
228+
#### close
229+
230+
```python
231+
close() -> None
232+
```
233+
234+
Close the live workspace and release its resources, if it was built. Thread-safe.
235+
236+
#### run
237+
238+
```python
239+
run(
240+
command: str, *, timeout: float = 60.0, max_chars: int | None = None
241+
) -> str
242+
```
243+
244+
Run a bash `command` against the mount tree from a synchronous context and return its output.
245+
246+
**Parameters:**
247+
248+
- **command** (<code>str</code>) – A bash command line, e.g. `"grep -r alert /s3/logs | wc -l"`.
249+
- **timeout** (<code>float</code>) – Maximum seconds to wait for the command.
250+
- **max_chars** (<code>int | None</code>) – If set, truncate the returned text to this many characters.
251+
252+
**Returns:**
253+
254+
- <code>str</code> – Combined stdout (plus a trailing error note on non-zero exit) as a string.
255+
256+
#### run_async
257+
258+
```python
259+
run_async(
260+
command: str, *, timeout: float = 60.0, max_chars: int | None = None
261+
) -> str
262+
```
263+
264+
Async counterpart of :meth:`run`.
265+
266+
#### to_dict
267+
268+
```python
269+
to_dict() -> dict[str, Any]
270+
```
271+
272+
Serialize the workspace description to a dictionary (Secret-safe).
273+
274+
#### from_dict
275+
276+
```python
277+
from_dict(data: dict[str, Any]) -> MirageWorkspace
278+
```
279+
280+
Deserialize a workspace description from a dictionary.
281+
282+
#### describe
283+
284+
```python
285+
describe() -> str
286+
```
287+
288+
Return a human/LLM-readable summary of the mount tree (used in tool descriptions).

0 commit comments

Comments
 (0)