跳转到内容

输入关键词开始搜索文档。

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;资源挂载、凭据、可写边界和生命周期仍由应用管理。

<source-root>/sandboxes/mirage.ts (abridged)
// 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。你的应用负责资源挂载、凭据、可写边界和工作区生命周期。

参见沙箱、在 Node.js 上部署、在 Cloudflare 上部署和沙箱适配器 API。