Migrate from AgentBay to FC Agent Sandbox Desktop

Updated at:

A guide to migrating from Wuying AgentBay (linux_latest) to the FC Agent Sandbox e2b-desktop SDK.

1. Capability mapping

Method names and signatures follow the e2b-desktop SDK release. Some capabilities are covered by shell commands inside the sandbox and are marked as "shell-aligned".

Wuying AgentBay session.computer.*e2b-desktop equivalentNotes
Mouse
click_mouse(x, y)left_click(x, y)Pass coordinates directly; or use move_mouse + left_click() in two steps
click_mouse(x, y, button="right")right_click(x, y)Same as above
move_mouse(x, y)move_mouse(x, y)Same name
drag_mouse(x1, y1, x2, y2)drag((x1, y1), (x2, y2))Different signature; takes tuples
double_click()double_click()Same name
scroll(x, y, direction, amount)move_mouse(x, y) + scroll(direction, amount)No coordinate parameter; move first, then scroll
get_cursor_position()commands.run("xdotool getmouselocation")Shell-aligned
Keyboard
input_text(text)write(text)Different method name
press_keys(keys)press(key) / press(["ctrl", "c"])Single key or key combination list
release_keyscommands.run("xdotool keyup <key>")Shell-aligned
Screenshot
screenshot()screenshot()Same name; PNG bytes
beta_take_screenshot(format)commands.run("scrot -q 80 /tmp/s.jpg") + files.read(path, format="bytes")Shell-aligned (scrot supports jpg/png; jpg must be read explicitly as bytes)
Screen info
get_screen_size()commands.run("xdpyinfo -display :0 | grep dimensions")Shell-aligned
get_current_window_id()get_current_window_id()Same name
Window management
list_root_windowscommands.run('xdotool search --onlyvisible --name ""')Shell-aligned
activate_windowcommands.run("xdotool windowactivate --sync <id>")Shell-aligned
maximize_windowcommands.run("xprop -id <id> -f _NET_WM_STATE 32a -set _NET_WM_STATE _NET_WM_STATE_MAXIMIZED_VERT,_NET_WM_STATE_MAXIMIZED_HORZ")Shell-aligned
minimize_windowcommands.run("xdotool windowminimize <id>")Shell-aligned
resize_windowcommands.run("xdotool windowsize --sync <id> <w> <h>")Shell-aligned (terminal apps snap to character cells)
close_windowcommands.run("xdotool windowclose <id>")Shell-aligned
focus_modecommands.run("xfconf-query -c xfwm4 -p /general/click_to_focus -s ...")Shell-aligned
App management
start_app(app, work_directory)commands.run("cd <workdir> && <app> &")Shell-aligned (launch(app[, url]) also works)
stop_appcommands.run("pkill <app>")Shell-aligned
get_installed_appscommands.run("ls /usr/share/applications/")Shell-aligned
list_visible_appscommands.run('xdotool search --onlyvisible --name ""')Shell-aligned
Agent (differences)
execute_taskNoneC-1: not supported
get_task_statusNoneC-2: not supported
terminate_taskNoneC-3: not supported
Desktop observation
get_link_url / VNCstream.start() + get_url()Built-in auth; see §5
  • C-1 to C-3 (natural-language Agent) have no delivery plan and are outside the FC Agent Sandbox product scope. Everything else can be aligned through the SDK or shell commands.

  • When Computer Use is not needed: use Browser Use (CDP) for web-only operations, and commands/code for pure batch processing.

  • The mapping above was verified item by item with e2b-desktop==2.4.1 and the desktop:v0.0.44 template (35/35).

  • The template ships with xdotool / scrot / xdpyinfo / xprop / xwininfo / xfconf-query preinstalled, but notwmctrl (use the equivalent xdotool/xprop commands above for window management; if you need wmctrl semantics, run apt-get install -y wmctrl, the sandbox can reach Debian repositories).

  • The §6.2 frontend was verified in a real Chrome (RFB connection, screen rendering, and live desktop refresh all passed).

2. Scope limits

Linux desktop (Computer Use) migration uses the e2b-desktop SDK:

  • Mouse / keyboard / screenshot are existing SDK methods (two-step style); the VNC live stream is built in with auth.

  • You must use its Sandbox subclass to create sandboxes. Sandbox lifecycle semantics are the same as e2b (still used as create/connect/list/kill).

  • Superset capabilities such as window and app management are outside this SDK; see the capability mapping in §1.

3. Built-in template mapping

AgentBayFC E2BNotes
linux_latest (Computer Use)desktop template (internal image fc-e2b-registry.cn-beijing.cr.aliyuncs.com/runtime/desktop:v0.0.44)The FC image ships with a desktop environment; build it with Template.build(), see §4

4. Prerequisites: Desktop template

The desktop template is not a built-in template available out of the box; you must build it from the FC Desktop image. The image already includes Xvfb + xfce4 + x11vnc + websockify + Chrome, so no Dockerfile is needed.

4.1 Set environment variables

export E2B_API_KEY=<key>
export E2B_API_URL=https://api.cn-beijing.e2b.fc.aliyuncs.com
export E2B_DOMAIN=cn-beijing.e2b.fc.aliyuncs.com

4.2 Build the template

pip install "e2b>=2.31.0" e2b-desktop==2.4.1 python-dotenv
# build.py
from dotenv import load_dotenv
from e2b import Template, default_build_logger

load_dotenv()

# Current stable version; will be updated later
FROM_IMAGE = "fc-e2b-registry.cn-beijing.cr.aliyuncs.com/runtime/desktop:v0.0.44"

build = Template.build(
    Template().from_image(FROM_IMAGE),
    name="my-desktop-template",  # any name you like
    cpu_count=4,
    memory_mb=8192,
    on_build_logs=default_build_logger(),
)
print(f"template_id: {build.template_id}")
python build.py
  • The image registry region must match E2B_API_URL / E2B_DOMAIN. For other regions, replace cn-beijing in the image address.

  • Recommended size: 4 vCPU, 8192 MB memory. The template needs no startup or readiness command; the Desktop SDK starts the desktop environment and live stream automatically.

5. Migration examples

5.1 Common interaction loop (screenshot + action)

# === Before migration: AgentBay ===
session = agent_bay.create(CreateSessionParams(image_id="linux_latest")).session
session.computer.move_mouse(640, 400)
session.computer.click_mouse(640, 400)
session.computer.input_text("echo hello")
session.computer.press_keys(["enter"])
png = session.computer.screenshot()

# === After migration: e2b-desktop SDK ===
from e2b_desktop import Sandbox

desktop = Sandbox.create(template="my-desktop-template", timeout=600)
try:
    # Launch Chrome and wait for rendering
    desktop.launch("google-chrome", "https://example.com")
    desktop.wait(10000)

    # Mouse: the E2B SDK is two-step (move + click); dragging uses tuples
    desktop.move_mouse(640, 400)
    desktop.left_click()
    desktop.double_click()
    desktop.drag((100, 100), (300, 300))
    desktop.scroll("down", 5)

    # Keyboard: write for text, press for a single key or a combination
    desktop.launch("xfce4-terminal")
    desktop.wait(3000)
    desktop.write("echo hello")
    desktop.press("enter")
    desktop.press(["ctrl", "c"])

    # Screenshot (PNG bytes, feed to a vision model)
    image = desktop.screenshot()
    with open("desktop.png", "wb") as f:
        f.write(image)
finally:
    desktop.kill()

5.2 VNC live stream (manual takeover)

# Replaces the link_url observation in Wuying desktop scenarios; the E2B SDK stream has built-in auth
desktop.stream.start()
stream_url = desktop.stream.get_url()
# Hand stream_url to your controlled backend or browser noVNC
desktop.stream.stop()

6. WebSDK integration

The browser connects to the sandbox VNC live stream directly through noVNC (CDN JS), with no control-plane SDK or npm build required. The sandbox lifecycle is managed by the backend (Python); the frontend only renders the desktop.

6.1 Backend: get the VNC stream URL

# Backend Python: create the sandbox and get the noVNC stream URL
from e2b_desktop import Sandbox

desktop = Sandbox.create(template="my-desktop-template", timeout=600)
desktop.stream.start()
stream_url = desktop.stream.get_url()

# If the FC E2B data plane requires a traffic access token, pass it as a query parameter

# token = getattr(desktop, "traffic_access_token", None)
# if token:
#     stream_url += f"&traffic_access_token={token}"

# Return stream_url to the frontend (for example, in an API response or over WebSocket)

6.2 Frontend: HTML + CDN noVNC

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>FC Desktop</title>
  <style>
    #vnc-screen { width: 100vw; height: 100vh; }
  </style>
</head>
<body>
  <div id="vnc-screen"></div>

  <script type="module">
    // ESM import of the official noVNC build (pinned version)
    import RFB from 'https://cdn.jsdelivr.net/gh/novnc/noVNC@v1.6.0/core/rfb.js';

    async function initVNC() {
      // Get stream_url from the backend API
      const resp = await fetch('/api/sandbox/vnc-url');
      const { streamUrl } = await resp.json();

      const rfb = new RFB(
        document.getElementById('vnc-screen'),
        streamUrl,           // https://{sandbox-host}/vnc.html?autoconnect=true&resize=scale
                             // One URL, two roles: opening it in a browser serves the noVNC page;
                             // RFB upgrades it to wss://{sandbox-host}/vnc.html as the WebSocket
                             // endpoint (proxied by websockify to x11vnc)
        { credentials: { password: '' } }   // empty when stream.start() has auth disabled
      );

      rfb.scaleViewport = true;
      rfb.resizeSession = false;
    }

    initVNC();
  </script>
</body>
</html>
  • The browser connects directly to wss://{sandbox-host}/vnc.html with no custom request headers (verified: GET 200, RFB handshake succeeds). VNC auth is controlled by stream.start(require_auth=True) + get_url(auth_key=...); when enabled, return auth_key to the frontend together with the URL and pass it in as credentials.password.

  • If the data plane requires a traffic access token, the FC backend supports passing it as a query parameter (appended to stream_url by the backend, see §6.1). The browser WebSocket needs no custom headers and no relay service; noVNC is transparent to extra query parameters (verified with the password= parameter).

  • No custom Web SDK is needed: noVNC (CDN ESM) is the complete data-plane client, with all connection parameters carried in the URL.

Context storage

FC Agent Sandbox provides storage as composable capabilities; use AgentFS or OSS for persistence and sharing:

  1. Dynamic OSS Mounts

  2. Mount an AgenticFS Volume

References

  1. wuying-agentbay-sdk

  2. novnc

  3. AgentBay Migration: Linux Desktop noVNC Integration Demo