Mirage
最后更新 查看 Markdown 源文件
Mirage 适配器将应用自有的 Mirage Workspace 适配为 Flue 的沙箱接口。Mirage 为 Node 和浏览器类运行时提供运行时包,允许在 Node 或 Cloudflare 上使用适配器模式(当你选择兼容的资源时)。
快速开始
使用 Mirage 蓝图为现有 Flue 项目添加挂载工作区沙箱能力。在终端或你选择的编码智能体中运行以下命令:
flue add sandbox mirage
概述
Mirage 蓝图会根据需要为 Node 安装 @struktoai/mirage-node 或为 Cloudflare 安装 @struktoai/mirage-browser,然后在你的源码根目录下创建 sandboxes/mirage.ts。生成的适配器接受应用创建的 Workspace;资源挂载、凭据、可写边界和生命周期仍由应用管理。
// flue-blueprint: sandbox/mirage@1
import { sandboxFromDriver } from '@flue/runtime';
import type { SandboxDriver, SandboxFactory, Sandbox, FileStat } from '@flue/runtime';
import type { Workspace as MirageWorkspace } from '@struktoai/mirage-core';
export interface MirageAdapterOptions {
cwd?: string;
}
/* ... 生成的 shellQuote() 辅助工具 ... */
class MirageSandboxDriver implements SandboxDriver {
constructor(
private workspace: MirageWorkspace,
private flueContextId: string,
) {}
/* ... 生成的 workspace.fs 操作;rm 在操作前拒绝递归和 force ... */
async stat(path: string): Promise<FileStat> {
const s = await this.workspace.fs.stat(path);
return {
isFile: s.type === 'file',
isDirectory: s.type === 'directory',
...(s.size === null ? {} : { size: s.size }),
...(s.modified === null ? {} : { mtime: new Date(s.modified) }),
};
}
async exec(
command: string,
options?: {
cwd?: string;
env?: Record<string, string>;
timeoutMs?: number;
signal?: AbortSignal;
},
): Promise<{ stdout: string; stderr: string; exitCode: number }> {
return this.runShell(command, options);
}
private async runShell(
command: string,
options?: {
cwd?: string;
env?: Record<string, string>;
timeoutMs?: number;
signal?: AbortSignal;
},
): Promise<{ stdout: string; stderr: string; exitCode: number }> {
const timeoutSignal =
typeof options?.timeoutMs === 'number' ? AbortSignal.timeout(options.timeoutMs) : undefined;
const callerSignal = options?.signal;
const signal =
callerSignal && timeoutSignal
? AbortSignal.any([callerSignal, timeoutSignal])
: (callerSignal ?? timeoutSignal);
try {
const result = await this.workspace.execute(command, {
sessionId: this.flueContextId,
cwd: options?.cwd,
env: options?.env,
signal,
});
return {
stdout: result.stdoutText,
stderr: result.stderrText,
exitCode: result.exitCode,
};
} catch (err) {
if (callerSignal?.aborted) throw err;
const isTimeout =
timeoutSignal?.aborted &&
(err === timeoutSignal.reason ||
(err instanceof Error && (err.name === 'AbortError' || err.name === 'TimeoutError')));
if (isTimeout) {
return {
stdout: '',
stderr: `[flue:mirage] 命令在 ${options?.timeoutMs} 毫秒后超时。`,
exitCode: 124,
};
}
throw err;
}
}
}
export function mirage(workspace: MirageWorkspace, options?: MirageAdapterOptions): SandboxFactory {
return {
async createSandbox({ id }: { id: string }): Promise<Sandbox> {
try {
workspace.createSession(id);
} catch {
workspace.getSession(id);
}
const sandboxCwd = options?.cwd ?? '/';
const driver = new MirageSandboxDriver(workspace, id);
return sandboxFromDriver(driver, sandboxCwd);
},
};
}将 mirage(workspace) 作为智能体的 sandbox 传入,通过按 Flue 上下文 ID 标识的 Mirage 会话暴露挂载的资源。文件统计信息通过省略未知的大小或修改时间字段来保留 Mirage 的原始数据;timeoutMs 创建毫秒级超时信号,调用方取消优先,只有超时取消才会变为退出码 124 结果。Mirage 的直接文件系统 API 不实现递归或强制删除,因此适配器会在操作前拒绝这两个选项。
配置
| 覀求 | 用途 |
|---|---|
@struktoai/mirage-node 包 | Node.js 上必需 — 提供 Node 兼容的 Mirage Workspace 资源。 |
@struktoai/mirage-browser 包 | Cloudflare 上必需 — 仅提供浏览器兼容的 Workspace 资源。 |
| 应用自有的资源配置 | 必需 — 定义挂载、凭据、可写边界和生命周期。 |
| 环境变量凭据 | 非必需 — Mirage 资源凭据由应用配置。 |
生成的适配器使用 Mirage 的共享工作区契约。某些 Mirage 资源(如 SSH 或面向数据库的 Node 资源)需要 Node 运行时,不得导入到 Cloudflare 构建中。
适用场景
当你的应用希望从明确的挂载资源组装工作区,并通过单一沙箱边界将该工作区呈现给智能体时,使用 Mirage。你的应用负责资源挂载、凭据、可写边界和工作区生命周期。