@struktoai/mirage-openai-agents 0.0.8-alpha.1 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +140 -46
- package/dist/index.d.ts +26 -4
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +10 -10
package/README.md
CHANGED
|
@@ -5,6 +5,14 @@
|
|
|
5
5
|
<img src="https://raw.githubusercontent.com/strukto-ai/mirage/main/assets/mirage-header-light.svg" width="100%" alt="Mirage: A Virtual Terminal for AI Agents" />
|
|
6
6
|
</picture>
|
|
7
7
|
</a>
|
|
8
|
+
<a href="https://agentvfs.org">
|
|
9
|
+
<picture>
|
|
10
|
+
<source media="(max-width: 767px) and (prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/strukto-ai/mirage/main/assets/agentvfs-banner-narrow-dark.svg">
|
|
11
|
+
<source media="(max-width: 767px)" srcset="https://raw.githubusercontent.com/strukto-ai/mirage/main/assets/agentvfs-banner-narrow-light.svg">
|
|
12
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/strukto-ai/mirage/main/assets/agentvfs-banner-dark.svg">
|
|
13
|
+
<img src="https://raw.githubusercontent.com/strukto-ai/mirage/main/assets/agentvfs-banner-light.svg" width="100%" alt="AgentVFS: the open, vendor-neutral virtual filesystem interface for AI agents" />
|
|
14
|
+
</picture>
|
|
15
|
+
</a>
|
|
8
16
|
</h1>
|
|
9
17
|
|
|
10
18
|
<p align="center">
|
|
@@ -16,6 +24,8 @@
|
|
|
16
24
|
<img src="https://img.shields.io/badge/made by-strukto.ai-0C0C0C?labelColor=F0ECE2" /></a>
|
|
17
25
|
<a href="https://github.com/strukto-ai/mirage/blob/main/LICENSE" alt="License">
|
|
18
26
|
<img src="https://img.shields.io/badge/license-Apache--2.0-0C0C0C?labelColor=F0ECE2" /></a>
|
|
27
|
+
<a href="https://doi.org/10.5281/zenodo.23504502" alt="DOI">
|
|
28
|
+
<img src="https://img.shields.io/badge/DOI-10.5281%2Fzenodo.23504502-0C0C0C?labelColor=F0ECE2" alt="DOI 10.5281/zenodo.23504502" /></a>
|
|
19
29
|
<a href="https://discord.gg/u8BPQ65KsS" alt="Discord">
|
|
20
30
|
<img src="https://img.shields.io/badge/discord-join-0C0C0C?labelColor=F0ECE2&logo=discord&logoColor=0C0C0C" /></a>
|
|
21
31
|
<br/>
|
|
@@ -40,7 +50,7 @@
|
|
|
40
50
|
<a href="https://github.com/strukto-ai/mirage/blob/main/readme/README.ko.md"><img alt="README 한국어" src="https://img.shields.io/badge/%ED%95%9C%EA%B5%AD%EC%96%B4-F0ECE2"></a>
|
|
41
51
|
</p>
|
|
42
52
|
|
|
43
|
-
Mirage is **a Virtual Terminal for AI Agents
|
|
53
|
+
Mirage is **a Virtual Terminal for AI Agents**: one shell over data, CLIs and runtimes. Unix tools reach every service, and `grep` runs on each service's own search, such as Gmail's or Slack's. Mirage routes each command to the runtime that fits it, so most lines run in-process and only heavy work reaches a sandbox, which cuts infrastructure cost and tokens. The terminal itself is light: a workspace takes **about 100 KB** of memory and each new session **about 10 KB**, so one process serves many agents at once. Profiles decide what an agent can run and even what it can see, and scriptable policies refuse anything those rules cannot express.
|
|
44
54
|
|
|
45
55
|
<p align="center">
|
|
46
56
|
<picture>
|
|
@@ -54,24 +64,56 @@ Here is an example of launching Mirage inside an application:
|
|
|
54
64
|
```python
|
|
55
65
|
ws = Workspace(
|
|
56
66
|
{
|
|
57
|
-
"/
|
|
58
|
-
"/redis": (RedisVFS(url=redis_url), MountMode.WRITE),
|
|
67
|
+
"/s3": (S3VFS(S3Config(bucket="my-bucket")), MountMode.WRITE),
|
|
59
68
|
"/slack": (SlackVFS(SlackConfig(token=slack_bot_token)), MountMode.EXEC),
|
|
69
|
+
"/gmail": (GmailVFS(GmailConfig(**google_credentials)), MountMode.READ),
|
|
60
70
|
},
|
|
61
|
-
#
|
|
62
|
-
|
|
71
|
+
# Install the Slack CLI, run by name and listed by `man` and `which` like any program
|
|
72
|
+
clis={"slack": (SLACK, {"token": slack_bot_token})},
|
|
73
|
+
# the analyst profile hides /s3/secrets and denies posting to Slack and curl
|
|
74
|
+
profiles={
|
|
75
|
+
"analyst": {
|
|
76
|
+
"paths": {"hide": ["/s3/secrets"]},
|
|
77
|
+
"commands": {"deny": ["slack send-message", "curl"]},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
runtimes=[
|
|
81
|
+
MontyRuntime(captures=["python", "python3"]),
|
|
82
|
+
E2BRuntime(
|
|
83
|
+
captures=["python", "python3"],
|
|
84
|
+
config={"sandbox_id": sandbox_id, "mount_type": "ssh"},
|
|
85
|
+
),
|
|
86
|
+
],
|
|
87
|
+
# route the underlying computation: numpy lines run in the e2b sandbox, the rest on monty
|
|
88
|
+
route_policy=lambda ctx: "e2b" if "numpy" in ctx.line else None,
|
|
63
89
|
)
|
|
64
90
|
|
|
65
|
-
#
|
|
66
|
-
await ws.
|
|
91
|
+
# Add an agent using the analyst profile
|
|
92
|
+
alice = await ws.session("alice", profile="analyst")
|
|
93
|
+
|
|
94
|
+
# one grep sweeps S3, Slack and Gmail, on each service's own search where it has one
|
|
95
|
+
await alice.shell("grep -rlw invoice /s3 /slack /gmail")
|
|
67
96
|
|
|
68
|
-
# run a script that lives in Slack, file the report into
|
|
69
|
-
await
|
|
97
|
+
# run a script that lives in Slack on monty, file the report into S3
|
|
98
|
+
await alice.shell("python3 /slack/channels/general__C0123/2026-10-21/files/report__F0456.py > /s3/report.txt")
|
|
70
99
|
|
|
71
|
-
#
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
100
|
+
# numpy is not in monty, so the route policy sends this line to e2b
|
|
101
|
+
await alice.shell("python3 -c 'import numpy; print(numpy.arange(10).sum())'")
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
And what `alice` sees in the shell:
|
|
105
|
+
|
|
106
|
+
```console
|
|
107
|
+
$ grep -rlw invoice /s3 /slack /gmail
|
|
108
|
+
/s3/billing/2026-10.csv
|
|
109
|
+
/gmail/INBOX/2026-10-21/Invoice_1042__18f3a9c2b7d1e0f4.gmail.json
|
|
110
|
+
$ ls /s3
|
|
111
|
+
billing
|
|
112
|
+
report.txt
|
|
113
|
+
$ cat /s3/secrets/aws.txt
|
|
114
|
+
cat: /s3/secrets/aws.txt: No such file or directory
|
|
115
|
+
$ slack send-message --channel general --text "report is up"
|
|
116
|
+
slack: Permission denied
|
|
75
117
|
```
|
|
76
118
|
|
|
77
119
|
## About
|
|
@@ -81,6 +123,7 @@ await ws.shell('slack send-message --channel general --text "report is up"')
|
|
|
81
123
|
- **Virtual command line tools (CLIs).** `git`, `slack` and `ntn` are answered by Mirage itself, so an agent drives the service with nothing installed, across different runtimes and machines, and one tool can be virtualized into two or more, each under its own name with its own credentials.
|
|
82
124
|
- **Routed, dynamic runtimes.** Python, JavaScript and any other command can be sent to a configured runtime, in process, sandboxed or remote, which decouples computation from storage and lets either change without touching the other.
|
|
83
125
|
- **The virtualized Mirage shell.** It binds the filesystem, the CLIs and the runtimes into one command line, so pipes, redirection, variables, jobs and history work across all three.
|
|
126
|
+
- **Lightweight by design.** A workspace, the virtual terminal itself, takes about 100 KB of memory and each new session about 10 KB, so one process serves many agents without a container or VM per agent.
|
|
84
127
|
- **Profiles designed for agents.** `allow`, `ask` and `deny` govern commands and CLIs, while `hide` and `show` govern files and folders, so a hidden path is not merely unreadable but absent from the filesystem the agent sees.
|
|
85
128
|
- **A scriptable policy engine.** A policy script can prohibit any dangerous action before it runs, and the same stack gates every VFS op and session write, so neither a file nor an environment variable leaks.
|
|
86
129
|
- **Notifications wired into the VFS and agents.** External changes become an event stream on the mount, so a new Slack reply surfaces as a change to the chat file in the virtual filesystem, and the agent reacts to it instead of rescanning the tree.
|
|
@@ -158,8 +201,8 @@ in Mirage can resolve straight to a credential held in one of them.
|
|
|
158
201
|
|
|
159
202
|
## Installation
|
|
160
203
|
|
|
161
|
-
- **Python** ≥ 3.
|
|
162
|
-
- **Node.js**
|
|
204
|
+
- **Python** ≥ 3.12 for the `mirage-ai` package and the `mirage` CLI
|
|
205
|
+
- **Node.js** 22.20+ on Node 22, 24.12+ on Node 24, or 25+ for the TypeScript SDK
|
|
163
206
|
|
|
164
207
|
### Python
|
|
165
208
|
|
|
@@ -181,58 +224,109 @@ Both runtime packages pull in `@struktoai/mirage-core` automatically.
|
|
|
181
224
|
### CLI
|
|
182
225
|
|
|
183
226
|
```bash
|
|
184
|
-
curl -fsSL https://strukto.ai/mirage/install.sh | sh
|
|
185
|
-
# or
|
|
186
227
|
npm install -g @struktoai/mirage-cli
|
|
187
228
|
# or
|
|
188
|
-
uvx mirage-ai
|
|
229
|
+
uvx --from mirage-ai mirage
|
|
189
230
|
# or
|
|
190
231
|
npx @struktoai/mirage-cli
|
|
191
232
|
```
|
|
192
233
|
|
|
193
|
-
|
|
234
|
+
To get started, see the quickstarts for
|
|
235
|
+
[Python](https://docs.mirage.strukto.ai/python/quickstart),
|
|
236
|
+
[TypeScript](https://docs.mirage.strukto.ai/typescript/quickstart) and the
|
|
237
|
+
[CLI](https://docs.mirage.strukto.ai/home/access/cli).
|
|
194
238
|
|
|
195
|
-
|
|
239
|
+
## Scriptable Policy
|
|
240
|
+
|
|
241
|
+
A profile can name policy scripts for what its rules cannot express. A script
|
|
242
|
+
reads the command as JSON, can open the files it names, and prints a deny, an
|
|
243
|
+
ask or nothing. This one disables `rm`, and a Python script whose code
|
|
244
|
+
deletes files:
|
|
196
245
|
|
|
197
246
|
```python
|
|
198
|
-
|
|
199
|
-
from mirage.vfs.ram import RAMVFS
|
|
200
|
-
from mirage.vfs.s3 import S3Config, S3VFS
|
|
247
|
+
import json, os
|
|
201
248
|
|
|
202
|
-
|
|
203
|
-
"/data": RAMVFS(),
|
|
204
|
-
"/s3": S3VFS(S3Config(bucket="my-bucket")),
|
|
205
|
-
})
|
|
249
|
+
ctx = json.loads(os.environ["MIRAGE_POLICY_CTX"])
|
|
206
250
|
|
|
207
|
-
await ws.shell("cp /s3/report.csv /data/report.csv")
|
|
208
|
-
await ws.shell("grep alert /s3/data/log.jsonl | wc -l")
|
|
209
251
|
|
|
210
|
-
|
|
211
|
-
|
|
252
|
+
def deletes(path):
|
|
253
|
+
try:
|
|
254
|
+
code = open(path).read()
|
|
255
|
+
except OSError:
|
|
256
|
+
return False
|
|
257
|
+
return any(call in code for call in ("os.remove", "os.unlink", "shutil.rmtree"))
|
|
212
258
|
|
|
213
|
-
### TypeScript
|
|
214
259
|
|
|
215
|
-
|
|
216
|
-
|
|
260
|
+
if ctx["command"] == "rm" or (
|
|
261
|
+
ctx["command"].startswith("python") and any(deletes(p) for p in ctx["paths"])
|
|
262
|
+
):
|
|
263
|
+
print(json.dumps({"kind": "deny", "reason": "deleting files is disabled"}))
|
|
264
|
+
```
|
|
217
265
|
|
|
218
|
-
|
|
219
|
-
'/data': new RAMVFS(),
|
|
220
|
-
'/s3': new S3VFS({ bucket: 'my-bucket' }),
|
|
221
|
-
})
|
|
266
|
+
Register it in a profile, here to run on Monty before every command:
|
|
222
267
|
|
|
223
|
-
|
|
224
|
-
|
|
268
|
+
```python
|
|
269
|
+
ws = Workspace(
|
|
270
|
+
{"/s3": (S3VFS(S3Config(bucket="my-bucket")), MountMode.WRITE)},
|
|
271
|
+
profiles={
|
|
272
|
+
"analyst": {
|
|
273
|
+
"policy": {
|
|
274
|
+
"pre_command": [{"script": ScriptSource(Path("guard.py").read_text()), "runtime": "monty"}],
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
profile="analyst",
|
|
279
|
+
)
|
|
280
|
+
```
|
|
225
281
|
|
|
226
|
-
|
|
282
|
+
```console
|
|
283
|
+
$ cat /s3/clean.py
|
|
284
|
+
import os
|
|
285
|
+
os.remove("/s3/report.txt")
|
|
286
|
+
$ rm /s3/report.txt
|
|
287
|
+
rm: Permission denied
|
|
288
|
+
$ python3 /s3/clean.py
|
|
289
|
+
python3: Permission denied
|
|
227
290
|
```
|
|
228
291
|
|
|
229
|
-
|
|
292
|
+
See [policy scripts](https://docs.mirage.strukto.ai/home/policy/scripts) for
|
|
293
|
+
the other stages a script can answer at.
|
|
294
|
+
|
|
295
|
+
## Embedded Terminal
|
|
296
|
+
|
|
297
|
+
Most of the time an agent does not need a sandbox, only a terminal-like
|
|
298
|
+
interface, and Mirage embeds one in an application server. Each terminal is a
|
|
299
|
+
Mirage session with its own working directory, environment and history, and Python
|
|
300
|
+
runs in-process on Monty, so a terminal starts with no container or VM. Here
|
|
301
|
+
it is in Express; the FastAPI version is in the
|
|
302
|
+
[docs](https://docs.mirage.strukto.ai/home/examples/embedded-terminal).
|
|
230
303
|
|
|
231
304
|
```bash
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
305
|
+
npm install @struktoai/mirage-node @pydantic/monty express
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
```ts
|
|
309
|
+
import express from 'express'
|
|
310
|
+
import { MontyRuntime, MountMode, RAMVFS, Workspace } from '@struktoai/mirage-node'
|
|
311
|
+
|
|
312
|
+
const ws = new Workspace(
|
|
313
|
+
{ '/work': new RAMVFS() },
|
|
314
|
+
{ mode: MountMode.EXEC, runtimes: [new MontyRuntime({ captures: ['python', 'python3'] })] },
|
|
315
|
+
)
|
|
316
|
+
const app = express()
|
|
317
|
+
app.use(express.json())
|
|
318
|
+
|
|
319
|
+
app.post('/sessions/:id', (req, res) => {
|
|
320
|
+
ws.createSession(req.params.id)
|
|
321
|
+
res.sendStatus(201)
|
|
322
|
+
})
|
|
323
|
+
|
|
324
|
+
app.post('/sessions/:id/run', async (req, res) => {
|
|
325
|
+
const r = await ws.shell(req.body.command, { sessionId: req.params.id })
|
|
326
|
+
res.json({ stdout: r.stdoutText, stderr: r.stderrText, exitCode: r.exitCode })
|
|
327
|
+
})
|
|
328
|
+
|
|
329
|
+
app.listen(3000, '127.0.0.1')
|
|
236
330
|
```
|
|
237
331
|
|
|
238
332
|
## Contributors
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,10 @@ import { MirageToolOperationsOptions } from '@struktoai/mirage-core/workspace/to
|
|
|
6
6
|
import { z } from 'zod';
|
|
7
7
|
export { BuildSystemPromptOptions, MIRAGE_SYSTEM_PROMPT, buildSystemPrompt } from '@struktoai/mirage-core/agents/prompt';
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* The serializable state of a `MirageSandboxSession`: the SDK's sandbox
|
|
11
|
+
* state plus `mirageSessionId`, the Mirage session it runs in.
|
|
12
|
+
*/
|
|
9
13
|
interface MirageSandboxSessionState extends SandboxSessionState {
|
|
10
14
|
mirageSessionId: string;
|
|
11
15
|
}
|
|
@@ -83,6 +87,10 @@ declare class MirageCapability extends Capability {
|
|
|
83
87
|
instructions(_manifest: Manifest): Promise<string>;
|
|
84
88
|
}
|
|
85
89
|
|
|
90
|
+
/**
|
|
91
|
+
* An `Editor` that applies patches through the workspace's file operations;
|
|
92
|
+
* pass it to `applyPatchTool({ editor })`.
|
|
93
|
+
*/
|
|
86
94
|
declare class MirageEditor implements Editor {
|
|
87
95
|
private readonly ws;
|
|
88
96
|
constructor(ws: Workspace);
|
|
@@ -98,10 +106,12 @@ declare class MirageEditor implements Editor {
|
|
|
98
106
|
}
|
|
99
107
|
|
|
100
108
|
/**
|
|
101
|
-
* Mirage's
|
|
102
|
-
*
|
|
103
|
-
* profile
|
|
104
|
-
*
|
|
109
|
+
* Returns Mirage's tools (`shell`, `read`, `write`, `edit`, `ls`, `grep`,
|
|
110
|
+
* `glob`) as OpenAI Agents function tools, limited to what the session's
|
|
111
|
+
* profile allows.
|
|
112
|
+
*
|
|
113
|
+
* The set is `MirageToolOperations.names`. Each tool has the shared input
|
|
114
|
+
* schema and answers with the text the MCP tool of the same name answers. `read` also hands an
|
|
105
115
|
* image or a PDF to the model as input it can see. They work with Chat
|
|
106
116
|
* Completions and Responses; with Responses, `shellTool` over
|
|
107
117
|
* `MirageShellExecutor` and `applyPatchTool` over `MirageEditor` are the hosted
|
|
@@ -109,11 +119,23 @@ declare class MirageEditor implements Editor {
|
|
|
109
119
|
*/
|
|
110
120
|
declare function mirageTools(ws: Workspace, options?: MirageToolOperationsOptions): _openai_agents_core.FunctionTool<unknown, never, string>[];
|
|
111
121
|
|
|
122
|
+
/**
|
|
123
|
+
* What the `read_file` tool returns: text, an image, or a file such as a
|
|
124
|
+
* PDF, as the model receives it.
|
|
125
|
+
*/
|
|
112
126
|
type MirageReadFileOutput = ToolOutputText | ToolOutputImage | ToolOutputFileContent;
|
|
127
|
+
/**
|
|
128
|
+
* Returns a `read_file` function tool: text comes back as text, images as
|
|
129
|
+
* image input and PDFs as file input the model can see.
|
|
130
|
+
*/
|
|
113
131
|
declare function mirageReadFileTool(ws: Workspace): _openai_agents_core.FunctionTool<unknown, z.ZodObject<{
|
|
114
132
|
path: z.ZodString;
|
|
115
133
|
}, z.core.$strip>, string>;
|
|
116
134
|
|
|
135
|
+
/**
|
|
136
|
+
* A `Shell` that runs each command in the workspace's shell; pass it to
|
|
137
|
+
* `shellTool({ shell })`.
|
|
138
|
+
*/
|
|
117
139
|
declare class MirageShellExecutor implements Shell {
|
|
118
140
|
private readonly ws;
|
|
119
141
|
constructor(ws: Workspace);
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,6 @@ import { Capability } from "@openai/agents/sandbox";
|
|
|
3
3
|
|
|
4
4
|
// src/constants.ts
|
|
5
5
|
var INTERRUPT = "";
|
|
6
|
-
var INTERRUPTED_EXIT_CODE = 130;
|
|
7
6
|
var DEFAULT_EXEC_YIELD_MS = 1e4;
|
|
8
7
|
var DEFAULT_WRITE_YIELD_MS = 250;
|
|
9
8
|
var NO_STDIN = "stdin is not available for this process";
|
|
@@ -38,6 +37,7 @@ import { splitManifestAndBlobs } from "@struktoai/mirage-core/workspace/snapshot
|
|
|
38
37
|
import { applyStateDict, toStateDict } from "@struktoai/mirage-core/workspace/snapshot/state";
|
|
39
38
|
import { readSnapshotTar, writeSnapshotTar } from "@struktoai/mirage-core/workspace/snapshot/tar_io";
|
|
40
39
|
import { decode, withRefusal } from "@struktoai/mirage-core/workspace/tools/io_text";
|
|
40
|
+
import { INTERRUPTED_STATUS } from "@struktoai/mirage-core/shell/constants";
|
|
41
41
|
var Line = class {
|
|
42
42
|
controller = new AbortController();
|
|
43
43
|
settled;
|
|
@@ -54,7 +54,7 @@ var Line = class {
|
|
|
54
54
|
},
|
|
55
55
|
(error) => {
|
|
56
56
|
if (this.controller.signal.aborted) {
|
|
57
|
-
this.outcome = { stdout: "", stderr: "", exitCode:
|
|
57
|
+
this.outcome = { stdout: "", stderr: "", exitCode: INTERRUPTED_STATUS };
|
|
58
58
|
} else {
|
|
59
59
|
this.failure = error instanceof Error ? error : new Error(String(error));
|
|
60
60
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/capability.ts","../src/constants.ts","../src/sandbox.ts","../src/editor.ts","../src/tools.ts","../src/read_file.ts","../src/shell.ts","../src/index.ts"],"sourcesContent":["// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { Capability, type Manifest, type SandboxSessionLike } from '@openai/agents/sandbox'\nimport { MOUNTS_INTRO, NOT_MIRAGE_SESSION } from './constants.ts'\nimport { MirageSandboxSession } from './sandbox.ts'\n\n/**\n * Tell a SandboxAgent's model which Mirage mounts it is working in.\n *\n * The SDK describes the filesystem from its manifest alone, so the mounts\n * behind a Mirage sandbox never reach the model. This adds the workspace's\n * own mount listing (backend, mode, commands) to the agent's instructions.\n * It binds only to a session from `MirageSandboxClient`.\n */\nexport class MirageCapability extends Capability {\n readonly type = 'mirage'\n\n override bind(session: SandboxSessionLike): this {\n mirageSession(session)\n return super.bind(session)\n }\n\n override async instructions(_manifest: Manifest): Promise<string> {\n const session = mirageSession(this._session)\n return `${MOUNTS_INTRO}\\n\\n${await session.workspace.vfsMd(undefined, { sessionId: session.sessionId })}`\n }\n}\n\nexport function mirageSession(session: SandboxSessionLike | undefined): MirageSandboxSession {\n if (!(session instanceof MirageSandboxSession)) throw new TypeError(NOT_MIRAGE_SESSION)\n return session\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nexport const INTERRUPT = '\\u0003'\nexport const INTERRUPTED_EXIT_CODE = 130\nexport const DEFAULT_EXEC_YIELD_MS = 10_000\nexport const DEFAULT_WRITE_YIELD_MS = 250\nexport const NO_STDIN = 'stdin is not available for this process'\nexport const MOUNTS_INTRO = 'The filesystem is a Mirage workspace with these mounts:'\nexport const NOT_MIRAGE_SESSION = 'MirageCapability needs a session from MirageSandboxClient'\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { applyDiff, type Editor, type ToolOutputImage } from '@openai/agents'\nimport {\n Manifest,\n SandboxUnsupportedFeatureError,\n normalizeSandboxClientCreateArgs,\n type Entry,\n type ExecCommandArgs,\n type ListDirectoryArgs,\n type MaterializeEntryArgs,\n type ReadFileArgs,\n type SandboxClient,\n type SandboxClientCreateArgs,\n type SandboxClientOptions,\n type SandboxDirectoryEntry,\n type SandboxExecResult,\n type SandboxSession,\n type SandboxSessionState,\n type ViewImageArgs,\n type WorkspaceArchiveData,\n type WriteStdinArgs,\n} from '@openai/agents/sandbox'\nimport {\n deserializeManifest,\n elapsedSeconds,\n formatExecResponse,\n imageOutputFromBytes,\n mergeManifestDelta,\n mergeManifestEntryDelta,\n normalizePosixPath,\n posixDirname,\n readOptionalRecord,\n readString,\n serializeManifestRecord,\n shellQuote,\n toUint8Array,\n truncateOutput,\n} from '@openai/agents-core/sandbox/internal'\nimport { FileType } from '@struktoai/mirage-core/types'\nimport { splitManifestAndBlobs } from '@struktoai/mirage-core/workspace/snapshot/manifest'\nimport { applyStateDict, toStateDict } from '@struktoai/mirage-core/workspace/snapshot/state'\nimport { readSnapshotTar, writeSnapshotTar } from '@struktoai/mirage-core/workspace/snapshot/tar_io'\nimport type { WorkspaceStateDict } from '@struktoai/mirage-core/workspace/snapshot/types'\nimport type { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace'\nimport type { ExecuteResult } from '@struktoai/mirage-core/workspace/workspace/types'\nimport { decode, withRefusal } from '@struktoai/mirage-core/workspace/tools/io_text'\nimport {\n DEFAULT_EXEC_YIELD_MS,\n DEFAULT_WRITE_YIELD_MS,\n INTERRUPT,\n INTERRUPTED_EXIT_CODE,\n NO_STDIN,\n} from './constants.ts'\n\nexport interface MirageSandboxSessionState extends SandboxSessionState {\n mirageSessionId: string\n}\n\ninterface LineOutcome {\n stdout: string\n stderr: string\n exitCode: number\n}\n\nclass Line {\n readonly controller = new AbortController()\n readonly settled: Promise<void>\n outcome: LineOutcome | null = null\n failure: Error | null = null\n\n constructor(run: (signal: AbortSignal) => Promise<ExecuteResult>) {\n this.settled = run(this.controller.signal).then(\n (io) => {\n this.outcome = {\n stdout: io.stdoutText,\n stderr: withRefusal(io.stderrText, io.refusal),\n exitCode: io.exitCode,\n }\n },\n (error: unknown) => {\n if (this.controller.signal.aborted) {\n this.outcome = { stdout: '', stderr: '', exitCode: INTERRUPTED_EXIT_CODE }\n } else {\n this.failure = error instanceof Error ? error : new Error(String(error))\n }\n },\n )\n }\n\n finished(): LineOutcome {\n if (this.failure !== null) throw this.failure\n if (this.outcome === null) throw new Error('line has not settled')\n return this.outcome\n }\n}\n\nasync function settleWithin(line: Line, ms: number): Promise<boolean> {\n let timer: ReturnType<typeof setTimeout> | undefined\n const expired = new Promise<boolean>((resolve) => {\n timer = setTimeout(() => {\n resolve(false)\n }, ms)\n })\n try {\n return await Promise.race([line.settled.then(() => true), expired])\n } finally {\n clearTimeout(timer)\n }\n}\n\nfunction errorText(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\nexport function combinedOutput(outcome: LineOutcome): string {\n const { stdout, stderr } = outcome\n if (stdout !== '' && stderr !== '') {\n return `${stdout}${stdout.endsWith('\\n') ? '' : '\\n'}${stderr}`\n }\n return stdout || stderr\n}\n\n/**\n * One SDK sandbox session, backed by its own Mirage shell session.\n *\n * Every command starts at the manifest root (or the model's `workdir`),\n * the way each `exec_command` is a fresh `sh -lc` in the SDK's other\n * sandboxes, so a `cd` or `export` never outlives its call. Lines of one\n * session run one at a time, like one shell. A line still running after\n * its yield time keeps running and is polled through `writeStdin`.\n */\nexport class MirageSandboxSession implements SandboxSession<MirageSandboxSessionState> {\n state: MirageSandboxSessionState\n private readonly lines = new Map<number, Line>()\n private nextProcessId = 1\n private closed = false\n\n constructor(\n readonly workspace: Workspace,\n state: MirageSandboxSessionState,\n ) {\n this.state = state\n workspace.createSession(state.mirageSessionId)\n }\n\n get sessionId(): string {\n return this.state.mirageSessionId\n }\n\n supportsPty(): boolean {\n return true\n }\n\n createEditor(): Editor {\n return {\n createFile: async (op) => {\n const path = this.resolve(op.path)\n try {\n await this.mkdirP(posixDirname(path))\n } catch (error) {\n return { status: 'failed', output: errorText(error) }\n }\n await this.workspace.vfs.write(path, applyDiff('', op.diff, 'create'), this.sessionId)\n return { status: 'completed' }\n },\n updateFile: async (op) => {\n const path = this.resolve(op.path)\n let current: string\n try {\n current = decode(await this.workspace.vfs.read(path, {}, this.sessionId))\n } catch (error) {\n return { status: 'failed', output: errorText(error) }\n }\n await this.workspace.vfs.write(path, applyDiff(current, op.diff), this.sessionId)\n return { status: 'completed' }\n },\n deleteFile: async (op) => {\n const path = this.resolve(op.path)\n if (!(await this.workspace.vfs.exists(path, this.sessionId))) {\n return { status: 'failed', output: `File not found: ${op.path}` }\n }\n await this.workspace.vfs.unlink(path, this.sessionId)\n return { status: 'completed' }\n },\n }\n }\n\n async execCommand(args: ExecCommandArgs): Promise<string> {\n return formatExecResponse(await this.exec(args))\n }\n\n async exec(args: ExecCommandArgs): Promise<SandboxExecResult> {\n const start = Date.now()\n const cwd = this.resolve(args.workdir ?? '.')\n const env = await this.state.manifest.resolveEnvironment()\n const line = new Line((signal) =>\n this.workspace.shell(args.cmd, {\n sessionId: this.sessionId,\n cwd,\n signal,\n ...(Object.keys(env).length > 0 ? { env } : {}),\n }),\n )\n if (!(await settleWithin(line, args.yieldTimeMs ?? DEFAULT_EXEC_YIELD_MS))) {\n const sessionId = this.nextProcessId++\n this.lines.set(sessionId, line)\n return {\n output: '',\n stdout: '',\n stderr: '',\n wallTimeSeconds: elapsedSeconds(start),\n sessionId,\n }\n }\n const outcome = line.finished()\n const output = truncateOutput(combinedOutput(outcome), args.maxOutputTokens)\n return {\n output: output.text,\n stdout: outcome.stdout,\n stderr: outcome.stderr,\n wallTimeSeconds: elapsedSeconds(start),\n exitCode: outcome.exitCode,\n ...(output.originalTokenCount !== undefined\n ? { originalTokenCount: output.originalTokenCount }\n : {}),\n }\n }\n\n async writeStdin(args: WriteStdinArgs): Promise<string> {\n const line = this.lines.get(args.sessionId)\n if (line === undefined) {\n return formatExecResponse({\n output: `write_stdin failed: session not found: ${String(args.sessionId)}`,\n wallTimeSeconds: 0,\n exitCode: 1,\n })\n }\n const chars = args.chars ?? ''\n if (chars.split(INTERRUPT).join('') !== '') throw new Error(NO_STDIN)\n if (chars.includes(INTERRUPT)) line.controller.abort()\n const start = Date.now()\n if (!(await settleWithin(line, args.yieldTimeMs ?? DEFAULT_WRITE_YIELD_MS))) {\n return formatExecResponse({\n output: '',\n wallTimeSeconds: elapsedSeconds(start),\n sessionId: args.sessionId,\n })\n }\n this.lines.delete(args.sessionId)\n const outcome = line.finished()\n const output = truncateOutput(combinedOutput(outcome), args.maxOutputTokens)\n return formatExecResponse({\n output: output.text,\n wallTimeSeconds: elapsedSeconds(start),\n exitCode: outcome.exitCode,\n ...(output.originalTokenCount !== undefined\n ? { originalTokenCount: output.originalTokenCount }\n : {}),\n })\n }\n\n async viewImage(args: ViewImageArgs): Promise<ToolOutputImage> {\n const bytes = await this.workspace.vfs.read(this.resolve(args.path), {}, this.sessionId)\n return imageOutputFromBytes(args.path, bytes)\n }\n\n async readFile(args: ReadFileArgs): Promise<Uint8Array> {\n const bytes = await this.workspace.vfs.read(this.resolve(args.path), {}, this.sessionId)\n if (args.maxBytes !== undefined && bytes.byteLength > args.maxBytes) {\n return bytes.subarray(0, args.maxBytes)\n }\n return bytes\n }\n\n async listDir(args: ListDirectoryArgs): Promise<SandboxDirectoryEntry[]> {\n const dir = this.resolve(args.path)\n const names = await this.workspace.vfs.readdir(dir, this.sessionId)\n return Promise.all(\n names.map(async (name): Promise<SandboxDirectoryEntry> => {\n const path = name.startsWith('/') ? name : normalizePosixPath(`${dir}/${name}`)\n const stat = await this.workspace.vfs.stat(path, this.sessionId)\n const type =\n stat.type === FileType.DIRECTORY ? 'dir' : stat.type === FileType.FILE ? 'file' : 'other'\n return { name: path.slice(path.lastIndexOf('/') + 1), path, type }\n }),\n )\n }\n\n async pathExists(path: string): Promise<boolean> {\n return this.workspace.vfs.exists(this.resolve(path), this.sessionId)\n }\n\n async directoryExists(path: string): Promise<boolean> {\n return this.workspace.vfs.isDir(this.resolve(path), this.sessionId)\n }\n\n async materializeEntry(args: MaterializeEntryArgs): Promise<void> {\n await this.writeEntry(this.resolve(args.path), args.entry)\n if (!args.path.startsWith('/')) {\n this.state.manifest = mergeManifestEntryDelta(\n this.state.manifest,\n normalizePosixPath(args.path),\n args.entry,\n )\n }\n }\n\n async applyManifest(manifest: Manifest): Promise<void> {\n await this.materializeManifest(manifest)\n this.state.manifest = mergeManifestDelta(this.state.manifest, manifest)\n }\n\n async materializeManifest(manifest: Manifest): Promise<void> {\n await this.mkdirP(manifest.root)\n for (const [path, entry] of Object.entries(manifest.entries)) {\n await this.writeEntry(normalizePosixPath(`${manifest.root}/${path}`), entry)\n }\n }\n\n async persistWorkspace(): Promise<Uint8Array> {\n // The SDK stores a snapshot as one buffer, so the tar is built in\n // memory; it is captured while new lines wait, so the disk files it\n // reads are the ones the lines left.\n return this.workspace.quiesced(async () => {\n const state = await toStateDict(this.workspace)\n const [manifest, blobs] = splitManifestAndBlobs(state as unknown as Record<string, unknown>)\n return writeSnapshotTar(manifest, blobs)\n })\n }\n\n async hydrateWorkspace(data: WorkspaceArchiveData): Promise<void> {\n const state = (await readSnapshotTar(await toUint8Array(data))) as WorkspaceStateDict\n await applyStateDict(this.workspace, state)\n }\n\n async close(): Promise<void> {\n if (this.closed) return\n this.closed = true\n const lines = [...this.lines.values()]\n this.lines.clear()\n for (const line of lines) line.controller.abort()\n await Promise.all(lines.map((line) => line.settled))\n await this.workspace.closeSession(this.sessionId)\n }\n\n private resolve(path: string): string {\n return normalizePosixPath(path.startsWith('/') ? path : `${this.state.manifest.root}/${path}`)\n }\n\n private async writeEntry(path: string, entry: Entry): Promise<void> {\n if (entry.type === 'dir') {\n await this.mkdirP(path)\n for (const [name, child] of Object.entries(entry.children ?? {})) {\n await this.writeEntry(normalizePosixPath(`${path}/${name}`), child)\n }\n return\n }\n if (entry.type === 'file') {\n await this.mkdirP(posixDirname(path))\n await this.workspace.vfs.write(path, entry.content, this.sessionId)\n return\n }\n throw new SandboxUnsupportedFeatureError(\n `MirageSandboxClient cannot materialize a ${entry.type} entry`,\n { path, type: entry.type },\n )\n }\n\n private async mkdirP(path: string): Promise<void> {\n const io = await this.workspace.shell(`mkdir -p -- ${shellQuote(path)}`, {\n sessionId: this.sessionId,\n record: false,\n })\n if (io.exitCode !== 0) throw new Error(io.stderrText.trim())\n }\n}\n\nfunction isSdkDefaultManifest(manifest: Manifest): boolean {\n const base = new Manifest()\n return (\n manifest.root === base.root &&\n Object.keys(manifest.entries).length === 0 &&\n Object.keys(manifest.environment).length === 0 &&\n manifest.users.length === 0 &&\n manifest.groups.length === 0 &&\n manifest.extraPathGrants.length === 0 &&\n JSON.stringify(manifest.remoteMountCommandAllowlist) ===\n JSON.stringify(base.remoteMountCommandAllowlist)\n )\n}\n\n/**\n * The manifest a session runs under: the SDK's untouched default becomes\n * the Mirage root, since a workspace need not mount anything at\n * `/workspace`; any configured manifest is kept as given.\n */\nfunction mirageManifest(manifest: Manifest): Manifest {\n return isSdkDefaultManifest(manifest) ? new Manifest({ root: '/' }) : manifest\n}\n\n/**\n * The OpenAI Agents SDK sandbox client over an in-process Mirage workspace.\n *\n * Every session shares the one workspace; each gets its own Mirage\n * session. A session the SDK deleted mid-run (an approval pause) is\n * rebuilt from its state on resume, keeping the files the agent wrote.\n */\nexport class MirageSandboxClient implements SandboxClient<\n SandboxClientOptions,\n MirageSandboxSessionState\n> {\n readonly backendId = 'mirage'\n readonly supportsDefaultOptions = true\n private readonly sessions = new Map<string, MirageSandboxSession>()\n\n constructor(readonly workspace: Workspace) {}\n\n async create(\n args?: SandboxClientCreateArgs | Manifest,\n options?: SandboxClientOptions,\n ): Promise<MirageSandboxSession> {\n const manifest = mirageManifest(normalizeSandboxClientCreateArgs(args, options).manifest)\n const session = this.open({\n manifest,\n mirageSessionId: `openai-${crypto.randomUUID().replaceAll('-', '')}`,\n workspaceReady: false,\n })\n await this.materializeOrClose(session, manifest)\n return session\n }\n\n resolveTrustedManifestForResume(manifest: Manifest): Manifest {\n return mirageManifest(manifest)\n }\n\n async resume(state: MirageSandboxSessionState): Promise<MirageSandboxSession> {\n const live = this.sessions.get(state.mirageSessionId)\n if (live !== undefined) return live\n const session = this.open(state)\n const preserved =\n state.workspaceReady === true &&\n (await this.workspace.vfs.exists(state.manifest.root, session.sessionId))\n if (!preserved) await this.materializeOrClose(session, state.manifest)\n return session\n }\n\n async delete(state: MirageSandboxSessionState): Promise<void> {\n const session = this.sessions.get(state.mirageSessionId)\n this.sessions.delete(state.mirageSessionId)\n await session?.close()\n }\n\n serializeSessionState(state: MirageSandboxSessionState): Promise<Record<string, unknown>> {\n return Promise.resolve({\n manifest: serializeManifestRecord(state.manifest),\n mirageSessionId: state.mirageSessionId,\n workspaceReady: state.workspaceReady ?? false,\n })\n }\n\n deserializeSessionState(record: Record<string, unknown>): Promise<MirageSandboxSessionState> {\n return Promise.resolve({\n manifest: deserializeManifest(readOptionalRecord(record.manifest)),\n mirageSessionId: readString(record, 'mirageSessionId'),\n workspaceReady: record.workspaceReady === true,\n })\n }\n\n private async materializeOrClose(\n session: MirageSandboxSession,\n manifest: Manifest,\n ): Promise<void> {\n try {\n await session.materializeManifest(manifest)\n } catch (error) {\n await this.delete(session.state)\n throw error\n }\n session.state.workspaceReady = true\n }\n\n private open(state: MirageSandboxSessionState): MirageSandboxSession {\n const session = new MirageSandboxSession(this.workspace, state)\n this.sessions.set(state.mirageSessionId, session)\n return session\n }\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { ensureParents } from '@struktoai/mirage-core/workspace/tools/tool_operations'\nimport { decode } from '@struktoai/mirage-core/workspace/tools/io_text'\nimport type { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace'\nimport { applyDiff } from '@openai/agents'\nimport type { ApplyPatchOperation, ApplyPatchResult, Editor } from '@openai/agents'\n\nexport class MirageEditor implements Editor {\n constructor(private readonly ws: Workspace) {}\n\n async createFile(\n op: Extract<ApplyPatchOperation, { type: 'create_file' }>,\n ): Promise<ApplyPatchResult> {\n await ensureParents(this.ws.vfs, op.path)\n const content = applyDiff('', op.diff, 'create')\n await this.ws.vfs.write(op.path, content)\n return { status: 'completed' }\n }\n\n async updateFile(\n op: Extract<ApplyPatchOperation, { type: 'update_file' }>,\n ): Promise<ApplyPatchResult> {\n let current: string\n try {\n current = decode(await this.ws.vfs.read(op.path))\n } catch {\n return { status: 'failed', output: `File not found: ${op.path}` }\n }\n const next = applyDiff(current, op.diff)\n await this.ws.vfs.write(op.path, next)\n return { status: 'completed' }\n }\n\n async deleteFile(\n op: Extract<ApplyPatchOperation, { type: 'delete_file' }>,\n ): Promise<ApplyPatchResult> {\n if (!(await this.ws.vfs.exists(op.path))) {\n return { status: 'failed', output: `File not found: ${op.path}` }\n }\n await this.ws.vfs.unlink(op.path)\n return { status: 'completed' }\n }\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport type { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace'\nimport { tool } from '@openai/agents'\nimport {\n EDIT_DESCRIPTION,\n EDIT_INPUT,\n GLOB_DESCRIPTION,\n GLOB_INPUT,\n GREP_DESCRIPTION,\n GREP_INPUT,\n LS_DESCRIPTION,\n LS_INPUT,\n READ_DESCRIPTION,\n READ_INPUT,\n SHELL_DESCRIPTION,\n SHELL_INPUT,\n WRITE_DESCRIPTION,\n WRITE_INPUT,\n} from '@struktoai/mirage-core/workspace/tools/tool_descriptions'\nimport {\n MirageToolOperations,\n type MirageToolOperationsOptions,\n} from '@struktoai/mirage-core/workspace/tools/tool_operations'\nimport { Session } from '@struktoai/mirage-core/workspace/workspace/workspace'\n\n/**\n * Mirage's tool table as OpenAI Agents function tools: shell, read, write,\n * edit, ls, grep and glob, each with the shared input schema, as far as the session's\n * profile leaves them (`MirageToolOperations.names`), and answering\n * with the text the MCP tool of the same name answers. `read` also hands an\n * image or a PDF to the model as input it can see. They work with Chat\n * Completions and Responses; with Responses, `shellTool` over\n * `MirageShellExecutor` and `applyPatchTool` over `MirageEditor` are the hosted\n * alternative.\n */\nexport function mirageTools(ws: Workspace, options: MirageToolOperationsOptions = {}) {\n const session = new Session(ws, options.sessionId ?? null)\n const operations =\n options.staleWriteProtection === false\n ? new MirageToolOperations(session, false)\n : session.tools\n const names = operations.names()\n const call = async (name: string, args: unknown): Promise<string> =>\n (await operations.call(name, args as Record<string, unknown>)).content[0]?.text ?? ''\n const mirageTool = (name: string, description: string, input: object) =>\n tool({\n name,\n description,\n parameters: { ...input, additionalProperties: true } as never,\n strict: false,\n execute: (args) => call(name, args),\n })\n return [\n mirageTool('shell', SHELL_DESCRIPTION, SHELL_INPUT),\n tool({\n name: 'read',\n description: `${READ_DESCRIPTION} Images and PDFs come back as input the model can see.`,\n parameters: { ...READ_INPUT, additionalProperties: true } as never,\n strict: false,\n execute: async (args) => {\n const { path, offset, limit } = args as { path: string; offset?: number; limit?: number }\n const out = await operations.readMedia(path, offset, limit)\n if ('content' in out) return out.content[0]?.text ?? ''\n const data = Uint8Array.from(out.data)\n if (out.kind === 'file') {\n return {\n type: 'file' as const,\n file: { data, mediaType: out.mimeType, filename: out.filename },\n }\n }\n return { type: 'image' as const, image: { data, mediaType: out.mimeType } }\n },\n }),\n mirageTool('write', WRITE_DESCRIPTION, WRITE_INPUT),\n mirageTool('edit', EDIT_DESCRIPTION, EDIT_INPUT),\n mirageTool('ls', LS_DESCRIPTION, LS_INPUT),\n mirageTool('grep', GREP_DESCRIPTION, GREP_INPUT),\n mirageTool('glob', GLOB_DESCRIPTION, GLOB_INPUT),\n ].filter((entry) => names.includes(entry.name))\n}\n","import type { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace'\nimport {\n tool,\n type ToolOutputFileContent,\n type ToolOutputImage,\n type ToolOutputText,\n} from '@openai/agents'\nimport { z } from 'zod'\nimport { readWorkspaceFile } from '@struktoai/mirage-core/workspace/tools/read_file'\n\nexport type MirageReadFileOutput = ToolOutputText | ToolOutputImage | ToolOutputFileContent\n\nasync function readFileOutput(ws: Workspace, path: string): Promise<MirageReadFileOutput> {\n try {\n const result = await readWorkspaceFile(ws.vfs, path)\n if (result.kind === 'text') {\n return { type: 'text', text: result.content }\n }\n if (result.kind === 'image') {\n return {\n type: 'image',\n image: { data: Uint8Array.from(result.data), mediaType: result.mimeType },\n }\n }\n if (result.kind === 'file') {\n return {\n type: 'file',\n file: {\n data: Uint8Array.from(result.data),\n mediaType: result.mimeType,\n filename: result.filename,\n },\n }\n }\n return { type: 'text', text: result.note }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return { type: 'text', text: `Unable to read ${path}: ${message}` }\n }\n}\n\nexport function mirageReadFileTool(ws: Workspace) {\n return tool({\n name: 'read_file',\n description:\n 'Read a file from the Mirage workspace. Returns UTF-8 text directly, images as model-visible image input, PDFs as model-visible file input, and a metadata description for other binary formats.',\n parameters: z.object({\n path: z.string().describe('Absolute path inside the Mirage workspace.'),\n }),\n execute: async ({ path }) => readFileOutput(ws, path),\n })\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport type { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace'\nimport type { Shell, ShellAction, ShellResult, ShellOutputResult } from '@openai/agents'\nimport { withRefusal } from '@struktoai/mirage-core/workspace/tools/io_text'\n\nexport class MirageShellExecutor implements Shell {\n constructor(private readonly ws: Workspace) {}\n\n async run(action: ShellAction): Promise<ShellResult> {\n const output: ShellOutputResult[] = []\n for (const cmd of action.commands) {\n const io = await this.ws.shell(cmd)\n output.push({\n stdout: io.stdoutText,\n stderr: withRefusal(io.stderrText, io.refusal),\n outcome: { type: 'exit', exitCode: io.exitCode },\n })\n }\n return { output }\n }\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nexport { MirageCapability } from './capability.ts'\nexport { MirageEditor } from './editor.ts'\nexport { mirageTools } from './tools.ts'\nexport { mirageReadFileTool, type MirageReadFileOutput } from './read_file.ts'\nexport { MirageSandboxClient, MirageSandboxSession } from './sandbox.ts'\nexport type { MirageSandboxSessionState } from './sandbox.ts'\nexport { MirageShellExecutor } from './shell.ts'\nexport { MIRAGE_SYSTEM_PROMPT, buildSystemPrompt } from '@struktoai/mirage-core/agents/prompt'\nexport type { BuildSystemPromptOptions } from '@struktoai/mirage-core/agents/prompt'\n"],"mappings":"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","names":["decode","applyDiff","tool","withRefusal"]}
|
|
1
|
+
{"version":3,"sources":["../src/capability.ts","../src/constants.ts","../src/sandbox.ts","../src/editor.ts","../src/tools.ts","../src/read_file.ts","../src/shell.ts","../src/index.ts"],"sourcesContent":["// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { Capability, type Manifest, type SandboxSessionLike } from '@openai/agents/sandbox'\nimport { MOUNTS_INTRO, NOT_MIRAGE_SESSION } from './constants.ts'\nimport { MirageSandboxSession } from './sandbox.ts'\n\n/**\n * Tell a SandboxAgent's model which Mirage mounts it is working in.\n *\n * The SDK describes the filesystem from its manifest alone, so the mounts\n * behind a Mirage sandbox never reach the model. This adds the workspace's\n * own mount listing (backend, mode, commands) to the agent's instructions.\n * It binds only to a session from `MirageSandboxClient`.\n */\nexport class MirageCapability extends Capability {\n readonly type = 'mirage'\n\n override bind(session: SandboxSessionLike): this {\n mirageSession(session)\n return super.bind(session)\n }\n\n override async instructions(_manifest: Manifest): Promise<string> {\n const session = mirageSession(this._session)\n return `${MOUNTS_INTRO}\\n\\n${await session.workspace.vfsMd(undefined, { sessionId: session.sessionId })}`\n }\n}\n\nexport function mirageSession(session: SandboxSessionLike | undefined): MirageSandboxSession {\n if (!(session instanceof MirageSandboxSession)) throw new TypeError(NOT_MIRAGE_SESSION)\n return session\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nexport const INTERRUPT = '\\u0003'\nexport const DEFAULT_EXEC_YIELD_MS = 10_000\nexport const DEFAULT_WRITE_YIELD_MS = 250\nexport const NO_STDIN = 'stdin is not available for this process'\nexport const MOUNTS_INTRO = 'The filesystem is a Mirage workspace with these mounts:'\nexport const NOT_MIRAGE_SESSION = 'MirageCapability needs a session from MirageSandboxClient'\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { applyDiff, type Editor, type ToolOutputImage } from '@openai/agents'\nimport {\n Manifest,\n SandboxUnsupportedFeatureError,\n normalizeSandboxClientCreateArgs,\n type Entry,\n type ExecCommandArgs,\n type ListDirectoryArgs,\n type MaterializeEntryArgs,\n type ReadFileArgs,\n type SandboxClient,\n type SandboxClientCreateArgs,\n type SandboxClientOptions,\n type SandboxDirectoryEntry,\n type SandboxExecResult,\n type SandboxSession,\n type SandboxSessionState,\n type ViewImageArgs,\n type WorkspaceArchiveData,\n type WriteStdinArgs,\n} from '@openai/agents/sandbox'\nimport {\n deserializeManifest,\n elapsedSeconds,\n formatExecResponse,\n imageOutputFromBytes,\n mergeManifestDelta,\n mergeManifestEntryDelta,\n normalizePosixPath,\n posixDirname,\n readOptionalRecord,\n readString,\n serializeManifestRecord,\n shellQuote,\n toUint8Array,\n truncateOutput,\n} from '@openai/agents-core/sandbox/internal'\nimport { FileType } from '@struktoai/mirage-core/types'\nimport { splitManifestAndBlobs } from '@struktoai/mirage-core/workspace/snapshot/manifest'\nimport { applyStateDict, toStateDict } from '@struktoai/mirage-core/workspace/snapshot/state'\nimport { readSnapshotTar, writeSnapshotTar } from '@struktoai/mirage-core/workspace/snapshot/tar_io'\nimport type { WorkspaceStateDict } from '@struktoai/mirage-core/workspace/snapshot/types'\nimport type { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace'\nimport type { ExecuteResult } from '@struktoai/mirage-core/workspace/workspace/types'\nimport { decode, withRefusal } from '@struktoai/mirage-core/workspace/tools/io_text'\nimport { DEFAULT_EXEC_YIELD_MS, DEFAULT_WRITE_YIELD_MS, INTERRUPT, NO_STDIN } from './constants.ts'\nimport { INTERRUPTED_STATUS } from '@struktoai/mirage-core/shell/constants'\n\n/**\n * The serializable state of a `MirageSandboxSession`: the SDK's sandbox\n * state plus `mirageSessionId`, the Mirage session it runs in.\n */\nexport interface MirageSandboxSessionState extends SandboxSessionState {\n mirageSessionId: string\n}\n\ninterface LineOutcome {\n stdout: string\n stderr: string\n exitCode: number\n}\n\nclass Line {\n readonly controller = new AbortController()\n readonly settled: Promise<void>\n outcome: LineOutcome | null = null\n failure: Error | null = null\n\n constructor(run: (signal: AbortSignal) => Promise<ExecuteResult>) {\n this.settled = run(this.controller.signal).then(\n (io) => {\n this.outcome = {\n stdout: io.stdoutText,\n stderr: withRefusal(io.stderrText, io.refusal),\n exitCode: io.exitCode,\n }\n },\n (error: unknown) => {\n if (this.controller.signal.aborted) {\n this.outcome = { stdout: '', stderr: '', exitCode: INTERRUPTED_STATUS }\n } else {\n this.failure = error instanceof Error ? error : new Error(String(error))\n }\n },\n )\n }\n\n finished(): LineOutcome {\n if (this.failure !== null) throw this.failure\n if (this.outcome === null) throw new Error('line has not settled')\n return this.outcome\n }\n}\n\nasync function settleWithin(line: Line, ms: number): Promise<boolean> {\n let timer: ReturnType<typeof setTimeout> | undefined\n const expired = new Promise<boolean>((resolve) => {\n timer = setTimeout(() => {\n resolve(false)\n }, ms)\n })\n try {\n return await Promise.race([line.settled.then(() => true), expired])\n } finally {\n clearTimeout(timer)\n }\n}\n\nfunction errorText(error: unknown): string {\n return error instanceof Error ? error.message : String(error)\n}\n\nexport function combinedOutput(outcome: LineOutcome): string {\n const { stdout, stderr } = outcome\n if (stdout !== '' && stderr !== '') {\n return `${stdout}${stdout.endsWith('\\n') ? '' : '\\n'}${stderr}`\n }\n return stdout || stderr\n}\n\n/**\n * One SDK sandbox session, backed by its own Mirage shell session.\n *\n * Every command starts at the manifest root (or the model's `workdir`),\n * the way each `exec_command` is a fresh `sh -lc` in the SDK's other\n * sandboxes, so a `cd` or `export` never outlives its call. Lines of one\n * session run one at a time, like one shell. A line still running after\n * its yield time keeps running and is polled through `writeStdin`.\n */\nexport class MirageSandboxSession implements SandboxSession<MirageSandboxSessionState> {\n state: MirageSandboxSessionState\n private readonly lines = new Map<number, Line>()\n private nextProcessId = 1\n private closed = false\n\n constructor(\n readonly workspace: Workspace,\n state: MirageSandboxSessionState,\n ) {\n this.state = state\n workspace.createSession(state.mirageSessionId)\n }\n\n get sessionId(): string {\n return this.state.mirageSessionId\n }\n\n supportsPty(): boolean {\n return true\n }\n\n createEditor(): Editor {\n return {\n createFile: async (op) => {\n const path = this.resolve(op.path)\n try {\n await this.mkdirP(posixDirname(path))\n } catch (error) {\n return { status: 'failed', output: errorText(error) }\n }\n await this.workspace.vfs.write(path, applyDiff('', op.diff, 'create'), this.sessionId)\n return { status: 'completed' }\n },\n updateFile: async (op) => {\n const path = this.resolve(op.path)\n let current: string\n try {\n current = decode(await this.workspace.vfs.read(path, {}, this.sessionId))\n } catch (error) {\n return { status: 'failed', output: errorText(error) }\n }\n await this.workspace.vfs.write(path, applyDiff(current, op.diff), this.sessionId)\n return { status: 'completed' }\n },\n deleteFile: async (op) => {\n const path = this.resolve(op.path)\n if (!(await this.workspace.vfs.exists(path, this.sessionId))) {\n return { status: 'failed', output: `File not found: ${op.path}` }\n }\n await this.workspace.vfs.unlink(path, this.sessionId)\n return { status: 'completed' }\n },\n }\n }\n\n async execCommand(args: ExecCommandArgs): Promise<string> {\n return formatExecResponse(await this.exec(args))\n }\n\n async exec(args: ExecCommandArgs): Promise<SandboxExecResult> {\n const start = Date.now()\n const cwd = this.resolve(args.workdir ?? '.')\n const env = await this.state.manifest.resolveEnvironment()\n const line = new Line((signal) =>\n this.workspace.shell(args.cmd, {\n sessionId: this.sessionId,\n cwd,\n signal,\n ...(Object.keys(env).length > 0 ? { env } : {}),\n }),\n )\n if (!(await settleWithin(line, args.yieldTimeMs ?? DEFAULT_EXEC_YIELD_MS))) {\n const sessionId = this.nextProcessId++\n this.lines.set(sessionId, line)\n return {\n output: '',\n stdout: '',\n stderr: '',\n wallTimeSeconds: elapsedSeconds(start),\n sessionId,\n }\n }\n const outcome = line.finished()\n const output = truncateOutput(combinedOutput(outcome), args.maxOutputTokens)\n return {\n output: output.text,\n stdout: outcome.stdout,\n stderr: outcome.stderr,\n wallTimeSeconds: elapsedSeconds(start),\n exitCode: outcome.exitCode,\n ...(output.originalTokenCount !== undefined\n ? { originalTokenCount: output.originalTokenCount }\n : {}),\n }\n }\n\n async writeStdin(args: WriteStdinArgs): Promise<string> {\n const line = this.lines.get(args.sessionId)\n if (line === undefined) {\n return formatExecResponse({\n output: `write_stdin failed: session not found: ${String(args.sessionId)}`,\n wallTimeSeconds: 0,\n exitCode: 1,\n })\n }\n const chars = args.chars ?? ''\n if (chars.split(INTERRUPT).join('') !== '') throw new Error(NO_STDIN)\n if (chars.includes(INTERRUPT)) line.controller.abort()\n const start = Date.now()\n if (!(await settleWithin(line, args.yieldTimeMs ?? DEFAULT_WRITE_YIELD_MS))) {\n return formatExecResponse({\n output: '',\n wallTimeSeconds: elapsedSeconds(start),\n sessionId: args.sessionId,\n })\n }\n this.lines.delete(args.sessionId)\n const outcome = line.finished()\n const output = truncateOutput(combinedOutput(outcome), args.maxOutputTokens)\n return formatExecResponse({\n output: output.text,\n wallTimeSeconds: elapsedSeconds(start),\n exitCode: outcome.exitCode,\n ...(output.originalTokenCount !== undefined\n ? { originalTokenCount: output.originalTokenCount }\n : {}),\n })\n }\n\n async viewImage(args: ViewImageArgs): Promise<ToolOutputImage> {\n const bytes = await this.workspace.vfs.read(this.resolve(args.path), {}, this.sessionId)\n return imageOutputFromBytes(args.path, bytes)\n }\n\n async readFile(args: ReadFileArgs): Promise<Uint8Array> {\n const bytes = await this.workspace.vfs.read(this.resolve(args.path), {}, this.sessionId)\n if (args.maxBytes !== undefined && bytes.byteLength > args.maxBytes) {\n return bytes.subarray(0, args.maxBytes)\n }\n return bytes\n }\n\n async listDir(args: ListDirectoryArgs): Promise<SandboxDirectoryEntry[]> {\n const dir = this.resolve(args.path)\n const names = await this.workspace.vfs.readdir(dir, this.sessionId)\n return Promise.all(\n names.map(async (name): Promise<SandboxDirectoryEntry> => {\n const path = name.startsWith('/') ? name : normalizePosixPath(`${dir}/${name}`)\n const stat = await this.workspace.vfs.stat(path, this.sessionId)\n const type =\n stat.type === FileType.DIRECTORY ? 'dir' : stat.type === FileType.FILE ? 'file' : 'other'\n return { name: path.slice(path.lastIndexOf('/') + 1), path, type }\n }),\n )\n }\n\n async pathExists(path: string): Promise<boolean> {\n return this.workspace.vfs.exists(this.resolve(path), this.sessionId)\n }\n\n async directoryExists(path: string): Promise<boolean> {\n return this.workspace.vfs.isDir(this.resolve(path), this.sessionId)\n }\n\n async materializeEntry(args: MaterializeEntryArgs): Promise<void> {\n await this.writeEntry(this.resolve(args.path), args.entry)\n if (!args.path.startsWith('/')) {\n this.state.manifest = mergeManifestEntryDelta(\n this.state.manifest,\n normalizePosixPath(args.path),\n args.entry,\n )\n }\n }\n\n async applyManifest(manifest: Manifest): Promise<void> {\n await this.materializeManifest(manifest)\n this.state.manifest = mergeManifestDelta(this.state.manifest, manifest)\n }\n\n async materializeManifest(manifest: Manifest): Promise<void> {\n await this.mkdirP(manifest.root)\n for (const [path, entry] of Object.entries(manifest.entries)) {\n await this.writeEntry(normalizePosixPath(`${manifest.root}/${path}`), entry)\n }\n }\n\n async persistWorkspace(): Promise<Uint8Array> {\n // The SDK stores a snapshot as one buffer, so the tar is built in\n // memory; it is captured while new lines wait, so the disk files it\n // reads are the ones the lines left.\n return this.workspace.quiesced(async () => {\n const state = await toStateDict(this.workspace)\n const [manifest, blobs] = splitManifestAndBlobs(state as unknown as Record<string, unknown>)\n return writeSnapshotTar(manifest, blobs)\n })\n }\n\n async hydrateWorkspace(data: WorkspaceArchiveData): Promise<void> {\n const state = (await readSnapshotTar(await toUint8Array(data))) as WorkspaceStateDict\n await applyStateDict(this.workspace, state)\n }\n\n async close(): Promise<void> {\n if (this.closed) return\n this.closed = true\n const lines = [...this.lines.values()]\n this.lines.clear()\n for (const line of lines) line.controller.abort()\n await Promise.all(lines.map((line) => line.settled))\n await this.workspace.closeSession(this.sessionId)\n }\n\n private resolve(path: string): string {\n return normalizePosixPath(path.startsWith('/') ? path : `${this.state.manifest.root}/${path}`)\n }\n\n private async writeEntry(path: string, entry: Entry): Promise<void> {\n if (entry.type === 'dir') {\n await this.mkdirP(path)\n for (const [name, child] of Object.entries(entry.children ?? {})) {\n await this.writeEntry(normalizePosixPath(`${path}/${name}`), child)\n }\n return\n }\n if (entry.type === 'file') {\n await this.mkdirP(posixDirname(path))\n await this.workspace.vfs.write(path, entry.content, this.sessionId)\n return\n }\n throw new SandboxUnsupportedFeatureError(\n `MirageSandboxClient cannot materialize a ${entry.type} entry`,\n { path, type: entry.type },\n )\n }\n\n private async mkdirP(path: string): Promise<void> {\n const io = await this.workspace.shell(`mkdir -p -- ${shellQuote(path)}`, {\n sessionId: this.sessionId,\n record: false,\n })\n if (io.exitCode !== 0) throw new Error(io.stderrText.trim())\n }\n}\n\nfunction isSdkDefaultManifest(manifest: Manifest): boolean {\n const base = new Manifest()\n return (\n manifest.root === base.root &&\n Object.keys(manifest.entries).length === 0 &&\n Object.keys(manifest.environment).length === 0 &&\n manifest.users.length === 0 &&\n manifest.groups.length === 0 &&\n manifest.extraPathGrants.length === 0 &&\n JSON.stringify(manifest.remoteMountCommandAllowlist) ===\n JSON.stringify(base.remoteMountCommandAllowlist)\n )\n}\n\n/**\n * The manifest a session runs under: the SDK's untouched default becomes\n * the Mirage root, since a workspace need not mount anything at\n * `/workspace`; any configured manifest is kept as given.\n */\nfunction mirageManifest(manifest: Manifest): Manifest {\n return isSdkDefaultManifest(manifest) ? new Manifest({ root: '/' }) : manifest\n}\n\n/**\n * The OpenAI Agents SDK sandbox client over an in-process Mirage workspace.\n *\n * Every session shares the one workspace; each gets its own Mirage\n * session. A session the SDK deleted mid-run (an approval pause) is\n * rebuilt from its state on resume, keeping the files the agent wrote.\n */\nexport class MirageSandboxClient implements SandboxClient<\n SandboxClientOptions,\n MirageSandboxSessionState\n> {\n readonly backendId = 'mirage'\n readonly supportsDefaultOptions = true\n private readonly sessions = new Map<string, MirageSandboxSession>()\n\n constructor(readonly workspace: Workspace) {}\n\n async create(\n args?: SandboxClientCreateArgs | Manifest,\n options?: SandboxClientOptions,\n ): Promise<MirageSandboxSession> {\n const manifest = mirageManifest(normalizeSandboxClientCreateArgs(args, options).manifest)\n const session = this.open({\n manifest,\n mirageSessionId: `openai-${crypto.randomUUID().replaceAll('-', '')}`,\n workspaceReady: false,\n })\n await this.materializeOrClose(session, manifest)\n return session\n }\n\n resolveTrustedManifestForResume(manifest: Manifest): Manifest {\n return mirageManifest(manifest)\n }\n\n async resume(state: MirageSandboxSessionState): Promise<MirageSandboxSession> {\n const live = this.sessions.get(state.mirageSessionId)\n if (live !== undefined) return live\n const session = this.open(state)\n const preserved =\n state.workspaceReady === true &&\n (await this.workspace.vfs.exists(state.manifest.root, session.sessionId))\n if (!preserved) await this.materializeOrClose(session, state.manifest)\n return session\n }\n\n async delete(state: MirageSandboxSessionState): Promise<void> {\n const session = this.sessions.get(state.mirageSessionId)\n this.sessions.delete(state.mirageSessionId)\n await session?.close()\n }\n\n serializeSessionState(state: MirageSandboxSessionState): Promise<Record<string, unknown>> {\n return Promise.resolve({\n manifest: serializeManifestRecord(state.manifest),\n mirageSessionId: state.mirageSessionId,\n workspaceReady: state.workspaceReady ?? false,\n })\n }\n\n deserializeSessionState(record: Record<string, unknown>): Promise<MirageSandboxSessionState> {\n return Promise.resolve({\n manifest: deserializeManifest(readOptionalRecord(record.manifest)),\n mirageSessionId: readString(record, 'mirageSessionId'),\n workspaceReady: record.workspaceReady === true,\n })\n }\n\n private async materializeOrClose(\n session: MirageSandboxSession,\n manifest: Manifest,\n ): Promise<void> {\n try {\n await session.materializeManifest(manifest)\n } catch (error) {\n await this.delete(session.state)\n throw error\n }\n session.state.workspaceReady = true\n }\n\n private open(state: MirageSandboxSessionState): MirageSandboxSession {\n const session = new MirageSandboxSession(this.workspace, state)\n this.sessions.set(state.mirageSessionId, session)\n return session\n }\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport { ensureParents } from '@struktoai/mirage-core/workspace/tools/tool_operations'\nimport { decode } from '@struktoai/mirage-core/workspace/tools/io_text'\nimport type { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace'\nimport { applyDiff } from '@openai/agents'\nimport type { ApplyPatchOperation, ApplyPatchResult, Editor } from '@openai/agents'\n\n/**\n * An `Editor` that applies patches through the workspace's file operations;\n * pass it to `applyPatchTool({ editor })`.\n */\nexport class MirageEditor implements Editor {\n constructor(private readonly ws: Workspace) {}\n\n async createFile(\n op: Extract<ApplyPatchOperation, { type: 'create_file' }>,\n ): Promise<ApplyPatchResult> {\n await ensureParents(this.ws.vfs, op.path)\n const content = applyDiff('', op.diff, 'create')\n await this.ws.vfs.write(op.path, content)\n return { status: 'completed' }\n }\n\n async updateFile(\n op: Extract<ApplyPatchOperation, { type: 'update_file' }>,\n ): Promise<ApplyPatchResult> {\n let current: string\n try {\n current = decode(await this.ws.vfs.read(op.path))\n } catch {\n return { status: 'failed', output: `File not found: ${op.path}` }\n }\n const next = applyDiff(current, op.diff)\n await this.ws.vfs.write(op.path, next)\n return { status: 'completed' }\n }\n\n async deleteFile(\n op: Extract<ApplyPatchOperation, { type: 'delete_file' }>,\n ): Promise<ApplyPatchResult> {\n if (!(await this.ws.vfs.exists(op.path))) {\n return { status: 'failed', output: `File not found: ${op.path}` }\n }\n await this.ws.vfs.unlink(op.path)\n return { status: 'completed' }\n }\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport type { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace'\nimport { tool } from '@openai/agents'\nimport {\n EDIT_DESCRIPTION,\n EDIT_INPUT,\n GLOB_DESCRIPTION,\n GLOB_INPUT,\n GREP_DESCRIPTION,\n GREP_INPUT,\n LS_DESCRIPTION,\n LS_INPUT,\n READ_DESCRIPTION,\n READ_INPUT,\n SHELL_DESCRIPTION,\n SHELL_INPUT,\n WRITE_DESCRIPTION,\n WRITE_INPUT,\n} from '@struktoai/mirage-core/workspace/tools/tool_descriptions'\nimport {\n MirageToolOperations,\n type MirageToolOperationsOptions,\n} from '@struktoai/mirage-core/workspace/tools/tool_operations'\nimport { Session } from '@struktoai/mirage-core/workspace/workspace/workspace'\n\n/**\n * Returns Mirage's tools (`shell`, `read`, `write`, `edit`, `ls`, `grep`,\n * `glob`) as OpenAI Agents function tools, limited to what the session's\n * profile allows.\n *\n * The set is `MirageToolOperations.names`. Each tool has the shared input\n * schema and answers with the text the MCP tool of the same name answers. `read` also hands an\n * image or a PDF to the model as input it can see. They work with Chat\n * Completions and Responses; with Responses, `shellTool` over\n * `MirageShellExecutor` and `applyPatchTool` over `MirageEditor` are the hosted\n * alternative.\n */\nexport function mirageTools(ws: Workspace, options: MirageToolOperationsOptions = {}) {\n const session = new Session(ws, options.sessionId ?? null)\n const operations =\n options.staleWriteProtection === false\n ? new MirageToolOperations(session, false)\n : session.tools\n const names = operations.names()\n const call = async (name: string, args: unknown): Promise<string> =>\n (await operations.call(name, args as Record<string, unknown>)).content[0]?.text ?? ''\n const mirageTool = (name: string, description: string, input: object) =>\n tool({\n name,\n description,\n parameters: { ...input, additionalProperties: true } as never,\n strict: false,\n execute: (args) => call(name, args),\n })\n return [\n mirageTool('shell', SHELL_DESCRIPTION, SHELL_INPUT),\n tool({\n name: 'read',\n description: `${READ_DESCRIPTION} Images and PDFs come back as input the model can see.`,\n parameters: { ...READ_INPUT, additionalProperties: true } as never,\n strict: false,\n execute: async (args) => {\n const { path, offset, limit } = args as { path: string; offset?: number; limit?: number }\n const out = await operations.readMedia(path, offset, limit)\n if ('content' in out) return out.content[0]?.text ?? ''\n const data = Uint8Array.from(out.data)\n if (out.kind === 'file') {\n return {\n type: 'file' as const,\n file: { data, mediaType: out.mimeType, filename: out.filename },\n }\n }\n return { type: 'image' as const, image: { data, mediaType: out.mimeType } }\n },\n }),\n mirageTool('write', WRITE_DESCRIPTION, WRITE_INPUT),\n mirageTool('edit', EDIT_DESCRIPTION, EDIT_INPUT),\n mirageTool('ls', LS_DESCRIPTION, LS_INPUT),\n mirageTool('grep', GREP_DESCRIPTION, GREP_INPUT),\n mirageTool('glob', GLOB_DESCRIPTION, GLOB_INPUT),\n ].filter((entry) => names.includes(entry.name))\n}\n","import type { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace'\nimport {\n tool,\n type ToolOutputFileContent,\n type ToolOutputImage,\n type ToolOutputText,\n} from '@openai/agents'\nimport { z } from 'zod'\nimport { readWorkspaceFile } from '@struktoai/mirage-core/workspace/tools/read_file'\n\n/**\n * What the `read_file` tool returns: text, an image, or a file such as a\n * PDF, as the model receives it.\n */\nexport type MirageReadFileOutput = ToolOutputText | ToolOutputImage | ToolOutputFileContent\n\nasync function readFileOutput(ws: Workspace, path: string): Promise<MirageReadFileOutput> {\n try {\n const result = await readWorkspaceFile(ws.vfs, path)\n if (result.kind === 'text') {\n return { type: 'text', text: result.content }\n }\n if (result.kind === 'image') {\n return {\n type: 'image',\n image: { data: Uint8Array.from(result.data), mediaType: result.mimeType },\n }\n }\n if (result.kind === 'file') {\n return {\n type: 'file',\n file: {\n data: Uint8Array.from(result.data),\n mediaType: result.mimeType,\n filename: result.filename,\n },\n }\n }\n return { type: 'text', text: result.note }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n return { type: 'text', text: `Unable to read ${path}: ${message}` }\n }\n}\n\n/**\n * Returns a `read_file` function tool: text comes back as text, images as\n * image input and PDFs as file input the model can see.\n */\nexport function mirageReadFileTool(ws: Workspace) {\n return tool({\n name: 'read_file',\n description:\n 'Read a file from the Mirage workspace. Returns UTF-8 text directly, images as model-visible image input, PDFs as model-visible file input, and a metadata description for other binary formats.',\n parameters: z.object({\n path: z.string().describe('Absolute path inside the Mirage workspace.'),\n }),\n execute: async ({ path }) => readFileOutput(ws, path),\n })\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nimport type { Workspace } from '@struktoai/mirage-core/workspace/workspace/workspace'\nimport type { Shell, ShellAction, ShellResult, ShellOutputResult } from '@openai/agents'\nimport { withRefusal } from '@struktoai/mirage-core/workspace/tools/io_text'\n\n/**\n * A `Shell` that runs each command in the workspace's shell; pass it to\n * `shellTool({ shell })`.\n */\nexport class MirageShellExecutor implements Shell {\n constructor(private readonly ws: Workspace) {}\n\n async run(action: ShellAction): Promise<ShellResult> {\n const output: ShellOutputResult[] = []\n for (const cmd of action.commands) {\n const io = await this.ws.shell(cmd)\n output.push({\n stdout: io.stdoutText,\n stderr: withRefusal(io.stderrText, io.refusal),\n outcome: { type: 'exit', exitCode: io.exitCode },\n })\n }\n return { output }\n }\n}\n","// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n// ========= Copyright 2026 @ Strukto.AI All Rights Reserved. =========\n\nexport { MirageCapability } from './capability.ts'\nexport { MirageEditor } from './editor.ts'\nexport { mirageTools } from './tools.ts'\nexport { mirageReadFileTool, type MirageReadFileOutput } from './read_file.ts'\nexport { MirageSandboxClient, MirageSandboxSession } from './sandbox.ts'\nexport type { MirageSandboxSessionState } from './sandbox.ts'\nexport { MirageShellExecutor } from './shell.ts'\nexport { MIRAGE_SYSTEM_PROMPT, buildSystemPrompt } from '@struktoai/mirage-core/agents/prompt'\nexport type { BuildSystemPromptOptions } from '@struktoai/mirage-core/agents/prompt'\n"],"mappings":"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","names":["decode","applyDiff","tool","withRefusal"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@struktoai/mirage-openai-agents",
|
|
3
|
-
"version": "0.0.8
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "Run @openai/agents against a Mirage workspace with shell, editor, file-reading tools, and a SandboxAgent client",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"mirage",
|
|
@@ -38,24 +38,24 @@
|
|
|
38
38
|
"dist"
|
|
39
39
|
],
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"zod": "^4.
|
|
42
|
-
"@struktoai/mirage-core": "0.0.8
|
|
41
|
+
"zod": "^4.6.6",
|
|
42
|
+
"@struktoai/mirage-core": "0.0.8"
|
|
43
43
|
},
|
|
44
44
|
"peerDependencies": {
|
|
45
|
-
"@openai/agents": "^0.
|
|
46
|
-
"@openai/agents-core": "^0.
|
|
45
|
+
"@openai/agents": "^0.21.0",
|
|
46
|
+
"@openai/agents-core": "^0.21.0"
|
|
47
47
|
},
|
|
48
48
|
"devDependencies": {
|
|
49
|
-
"@openai/agents": "^0.
|
|
50
|
-
"@openai/agents-core": "^0.
|
|
49
|
+
"@openai/agents": "^0.21.0",
|
|
50
|
+
"@openai/agents-core": "^0.21.0",
|
|
51
51
|
"@types/node": "^22.0.0",
|
|
52
52
|
"tsup": "^8.5.0",
|
|
53
53
|
"typescript": "^6.0.0",
|
|
54
|
-
"vitest": "^4.1.
|
|
55
|
-
"@struktoai/mirage-node": "0.0.8
|
|
54
|
+
"vitest": "^4.1.12",
|
|
55
|
+
"@struktoai/mirage-node": "0.0.8"
|
|
56
56
|
},
|
|
57
57
|
"scripts": {
|
|
58
|
-
"build": "tsup",
|
|
58
|
+
"build": "tsup --config ../../tsup.base.config.ts",
|
|
59
59
|
"test": "vitest run",
|
|
60
60
|
"typecheck": "tsc --noEmit"
|
|
61
61
|
}
|