Documentation

Quickstart

Get a computer-use agent controlling a managed desktop application environment in under five minutes.

Using another language? Read the REST API docs
01

Install the SDK

Install the Python SDK from PyPI. Requires Python 3.9 or later. Use version 0.2.0 or later for all methods on this page, including persistent execution and structured observations.

python -m pip install --upgrade 'isle-sdk>=0.2.0'
02

Get an API key

Continue with GitHub or email at tryisle.com, then create an API key in the dashboard.

export ISLE_API_KEY=isle_...
03

Create a sandbox

from isle import Client

isle = Client()

sandbox = isle.sandboxes.create(
    "kicad",
    name="Power supply board",
    idempotency_key="power-supply-board-v1",
)
sandbox.wait_until_ready()

print(f"Sandbox ready: {sandbox.id}")
print(f"Stream: {sandbox.stream_url}")
04

Control the environment

Use familiar computer-use primitives: screenshots, mouse, keyboard, and file transfer. Individual uploads and downloads are limited to 4 MiB.

# Take a screenshot
image = sandbox.screen.screenshot()

# Mouse control
sandbox.mouse.click(500, 300)
sandbox.mouse.move(200, 400)
sandbox.mouse.scroll(0, -500)

# Keyboard control
sandbox.keyboard.type("8 mm")
sandbox.keyboard.keypress(["CTRL", "S"])

# File transfer
sandbox.files.upload("input.step")
sandbox.files.download("/home/user/work/result.step")
05

Stop and resume

Retained recordings are finalized by the signed environment monitor and streamed directly to durable storage. A recording is capped at 512 MiB, six hours, or low disk space; the API reports whether it was truncated and why. Stop requests are durable and can be retried safely while shutdown is still in progress.

# Stop archives the sandbox. Files persist, billing pauses.
sandbox.stop()
sandbox.wait_until_stopped()

# Resume restores the sandbox on fresh hardware
sandbox.resume()  # blocks until running

Use sandbox.destroy() to permanently delete a stopped environment and its retained data.

Persistent Python

Python, files, and the desktop

Give your agent a persistent Python session on the application's desktop. Combine short PyAutoGUI action sequences, screenshots, installed command-line tools, and project files in/home/user/work. Variables and imports persist between cells in the default namespace.

Create a new KiCad or FreeCAD environment and use Isle SDK 0.2.0 or later. Existing environments keep their original image; check capabilities before submitting code. These APIs work with any model or agent framework that can call HTTP tools.

python -m pip install --upgrade 'isle-sdk>=0.2.0'
# Isle SDK 0.2.0+ and a new environment.
from isle import Client

client = Client()  # ISLE_API_KEY stays in this client process
sandbox = client.sandboxes.get("YOUR_SANDBOX_ID")
capabilities = sandbox.capabilities()
assert capabilities["execution"]["available"]
generation = capabilities["generation"]

result = sandbox.execution.run(
    "counter = 41\nlog(counter)\ndisplay(pyautogui.screenshot())",
    expected_generation=generation,
    timeout_seconds=30,
)
print(result["status"], result["stdout"])
assert result["status"] == "succeeded"

result = sandbox.execution.run(
    "counter += 1\nlog(counter)",
    expected_generation=generation,
)
print(result["stdout"])  # 42
observation = sandbox.screen.observe()

The namespace starts with pyautogui, time,log(), and display(). Keep PyAutoGUI's fail-safe enabled. Inspect the returned status and send emitted PNGs to the model as image inputs. Observations include the generation, capture time, screen dimensions, and scale factor;active_document is currently null.

Use execution.submit(), get(),wait(), and cancel() when you need to manage a cell separately. Preserve its UUID and generation before submission. An ExecutionSubmissionUnknown carries those identifiers: query the original execution before deciding on new work. A client wait timeout leaves the remote cell running.

One desktop operation runs at a time. Wait after an explicitdesktop_busy rejection. Cancellation and server timeouts stop the worker, verify held-key and mouse-button cleanup, and reset Python state. Completed file or application edits remain. Refresh capabilities and inspect the desktop after a generation change. Background Python processes pause between cells.

Cells allow up to 64 KiB of UTF-8 source and 120 seconds. Output is bounded; check capabilities["limits"]and output_truncated. Images fromdisplay() remain in runtime records; download them before eviction or restart. Retained observations use the existing screenshot storage.

Execution endpoints, limits, and retry handling

KiCad live PCB API

New IPC-enabled KiCad images include the official kipyPython client. Check for kicad_ipc in capability features, open the intended PCB in the editor, then run this inside an execution cell. It works with any model or agent.

from kipy import KiCad

kicad = KiCad(timeout_ms=2000)
kicad.ping()
board = kicad.get_board()
print(board.name)
print(len(board.get_footprints()))

IPC reads and edits the live PCB. Confirm the document before changing it, inspect the result, and call board.save()before CLI validation or checkpoints. Reconnect after a generation change; a timed-out edit may already have happened. Existing environments keep their original image. Schematic automation and headless IPC are outside this KiCad 10 integration.

FreeCAD Python and native files

Use FreeCAD's installed freecadcmd interpreter for its FreeCAD and Part modules. Run it from an execution cell, then open the saved document in the GUI to inspect its feature tree and shape. The persistent worker itself uses standard Python.

import subprocess

result = subprocess.run(
    ["/usr/local/bin/freecadcmd", "-c",
     "import FreeCAD as App; print(App.Version())"],
    capture_output=True, text=True, timeout=30, check=True,
)
print(result.stdout)

Save the native project at /home/user/work/project.FCStdfor checkpoints. Download STEP and other exports through the file API. Save GUI edits before checking files, and avoid rewriting a document from another process while it is open.

Model integration example

Astra

The repository's examples/astra/run.py connects the OpenAI Responses API with Astra to the same execution and observation tools available to any model. Use the SDK and environment described above, then install the example's client dependencies:

python -m pip install -r examples/astra/requirements.txt
python examples/astra/run.py YOUR_SANDBOX_ID

Keep OPENAI_API_KEY in your client process, outside Python cells and desktop files. The example sends returned PNGs as image inputs, preserves tool call IDs, and reconciles uncertain executions. It uses serial calls; asynchronous model tools and steering are not implemented.

examples/astra/validate.py checks saved KiCad copies with CLI ERC, DRC, and schematic parity. The live PCB API is documented above; an Isle MCP connector is not included. Bounded KiCad and FreeCAD tasks have been validated through Codex, including saved-file checks and visual review. The optional Responses adapter has offline coverage; its own live API run remains unverified.

Complete workflow

Full example

A complete script that creates a KiCad sandbox, uploads a file, performs some operations, and downloads the result.

from isle import Client

isle = Client()  # uses ISLE_API_KEY env var

# Create environment
sandbox = isle.sandboxes.create("kicad", name="Power supply board")
sandbox.wait_until_ready()

# Upload input
sandbox.files.upload("schematic.kicad_sch")

# Your agent takes over here
# Use sandbox.screen.screenshot() to see the screen
# Use sandbox.mouse and sandbox.keyboard to interact

# Download result
sandbox.files.download("/home/user/work/board.kicad_pcb", "board.kicad_pcb")

# Stop when done, then permanently delete the environment.
sandbox.stop()
sandbox.wait_until_stopped()
sandbox.destroy()

Applications

Available environments

EDA

KiCad

Schematic capture, PCB layout, and electronics design. Supports KiCad native, Gerber, and BOM export formats.

CAD

FreeCAD

3D modeling, parametric design, and engineering tasks. Supports STEP, IGES, STL, OBJ, and native FreeCAD formats.

Reliability

Checkpoints & recovery controls

Create a checkpoint explicitly before an important operation. When you need to return to it, call sandbox.recover() to restore the latest safe checkpoint and restart the application.

# Manual checkpoint
sandbox.checkpoint()

# Check monitor health
status = sandbox.monitor_status()
print(status)  # {"status": "running", "checkpoints": 5, ...}

# Lifecycle failures are also available on every sandbox response
sandbox.refresh()
if sandbox.last_error:
    print(sandbox.last_error, sandbox.last_error_at)

# Full error history, newest first
errors = sandbox.errors()

# List checkpoints
checkpoints = sandbox.checkpoints()

# Manually trigger recovery
sandbox.recover()  # restores last safe checkpoint + restarts app

Checkpoint workflow

  • Create with sandbox.checkpoint()
  • List with sandbox.checkpoints()
  • Restore with sandbox.recover()

Application containment

Each environment is scoped to its intended application. Terminal, browser, package manager, and system-settings windows are blocked. On execution-enabled images, Python and installed CLI tools run inside the restricted worker with the shared workspace and no external network access.

SDK methods

API reference

MethodDescription
sandboxes.create(env, name=...)Create a named environment
sandboxes.list()List all sandboxes
sandboxes.get(id)Get a sandbox by ID
sandbox.wait_until_ready()Wait for sandbox to start
sandbox.capabilities()Discover runtime support, limits, and generation
sandbox.screen.observe()Capture a structured desktop observation
sandbox.execution.run(code, ...)Submit one cell and wait for its result
sandbox.execution.submit(code, ...)Submit one cell with an execution ID and generation
sandbox.execution.get(id, generation=...)Read an existing execution result
sandbox.execution.wait(id, generation=...)Wait for an existing execution to finish
sandbox.execution.cancel(id, ...)Cancel a cell and inspect namespace reset
sandbox.screen.screenshot()Capture screenshot (PNG bytes)
sandbox.mouse.click(x, y)Click at coordinates
sandbox.mouse.move(x, y)Move cursor
sandbox.mouse.scroll(x, y)Scroll
sandbox.keyboard.type(text)Type text
sandbox.keyboard.keypress(["CTRL", "S"])Press key combo
sandbox.files.upload(path)Upload a file
sandbox.files.download(path)Download a file
sandbox.checkpoint()Create a safe checkpoint of the artifact
sandbox.recover()Restore the last checkpoint and restart the app
sandbox.checkpoints()List all checkpoints
sandbox.download_checkpoint(id)Get a checkpoint download URL
sandbox.events()List command trace events
sandbox.errors()List timestamped lifecycle errors
sandbox.recording_url()Get the environment recording URL
sandbox.export_json()Export actions and recording/screenshot links
sandbox.recording_info()Get URL plus recording truncation metadata
sandbox.monitor_status()Get application health status
sandbox.last_errorLatest lifecycle error returned by the API
sandbox.last_error_atTimestamp of the latest lifecycle error
sandbox.stop()Stop and archive a sandbox
sandbox.wait_until_stopped()Wait for a stop operation to finish
sandbox.resume()Resume a stopped sandbox
sandbox.destroy()Permanently delete a stopped environment