Dory is in development. The invite-only beta has not opened yet; prices and limits are planned and may change.

TypeScript SDK

@computeengines/agent-computers needs Node 18 or later, ships ESM and CommonJS builds with TypeScript declarations, has no runtime dependencies and is licensed Apache-2.0.

Status. Not installable yet; available when the beta opens. (npm install @computeengines/agent-computers will work then.) See Status.

Configuration and lifecycle

import { Client, OperationFailed, WaitTimeout } from '@computeengines/agent-computers';

// Missing options use CE_API_KEY and CE_API_URL only. No dotenv or credential files.
const client = new Client();
try {
  const computer = await client.computers.create({
    size: 'ac-2', name: 'example', wait_timeout_seconds: 600,
    idempotency_key: 'retain-a-unique-key-for-this-create',
  });
  const result = await computer.exec('python3 -V');
  console.log(computer.id, computer.ready, result.exit_code, result.stdout);
  await computer.pause();
  await computer.resume();
  await computer.delete({ confirm: computer.id });
} catch (error) {
  // These IDs and the original key are recovery context, not automatic cancellation.
  if (error instanceof WaitTimeout || error instanceof OperationFailed) {
    console.error(error.computer_id, error.operation_id, error.idempotency_key);
  }
  throw error;
} finally {
  client.close(); // Disconnects requests, streams and sockets; does not delete computers.
}

Constructor options: api_key, api_url, fetch (injectable for tests), max_retries (3), timeout_seconds (65), stream_idle_timeout_seconds (120), max_retry_after_seconds (60), websocket, socket_factory. Explicit values override environment variables. Requests never follow redirects.

Methods are camelCase; request option and response field names stay snake_case. create, start, resume and restart return only after the computer is running and ready; pause and stop wait for their final states. One local deadline covers submission, retries, polling and final validation. signal: AbortSignal cancels the local waiter, not the server work. WaitTimeout is only a local deadline; OperationFailed keeps the server problem. An unready running computer may still be billed after a failure. delete returns acceptance, not completion or purge.

Commands, output and files

const computer = await client.computers.get('c4f7k2x9q1a8z');
const first = await computer.exec('echo hello', { idempotency_key: 'retained-exec-key' });
const started = await computer.processes.start(['python3', '-m', 'http.server', '8000']);
const process = await computer.processes.get(started.proc_id);
const stream = await computer.execStream('echo streamed');
try {
  for await (const frame of stream) console.log(frame);
} finally { await stream.close(); }
await computer.files.write('/home/dev/a.bin', new Uint8Array([0, 255]));
const bytes = await computer.files.read('/home/dev/a.bin');

Synchronous exec defaults to 60 seconds, maximum 600. Streaming defaults to 60; a background process has no deadline unless you supply one. Remote non-zero exits are results, not errors. Caller-keyed exec returns ExecResult | ProcessReplay, never invented output.

Process handles provide status, output, iterOutput, writeStdin, closeStdin, signal, kill and wait. wait is local and never kills. Output frames keep their utf8 or base64 encoding and independent byte offsets. StreamDisconnected keeps fully delivered offsets; reattach explicitly with process.iterOutput({stdout_offset, stderr_offset}). OutputGap keeps the earliest available offsets and is never skipped automatically; OutputExpired is terminal. Closing an iterator or the client only disconnects; killing needs process.kill(). Streams fail after 120 seconds without bytes by default (heartbeats count as activity).

All asynchronous request methods accept an optional signal. files.write and files.batch also accept an SDK-only timeout_seconds for upload stalls.

Resource surface

  • computers.create/list/get and the computer lifecycle, update, extend, setup, setupLog, usage, metrics, access, revokeAccess, health, ports, sshCommand, sshTunnel, closeSessions.
  • files.read/write/list/stat/mkdir/move/chmod/remove/batch with raw bytes.
  • desktop.screenshot, actions, click, type, key, launch, display, setDisplay, cursor, windows, focus, clipboard, control, viewer, connect and sessions.list/delete/token. Link creation does not mean a person connected; inspect control().
  • browser.create/cdpUrl/connect/connectPlaywright and browser.sessions.list/delete. Playwright receives the opaque URL; you supply your own browser-type object.
  • pty, ptySessions.list/delete; network.get/set; previews, hooks and snapshots; operations.get; images; billing (balance, ledger, usage, prices, topup, topups, spendLimit, receipt); keys; SSH keys; events; account.
  • Adapters: @computeengines/agent-computers/adapters/anthropic and .../adapters/openai; see Computer use with Claude.

Money strings and integer micro-USD are returned unchanged; the library does no floating-point money arithmetic. The Python side is on the Python SDK page, the command line on the CLI page.

Dory is in development; these pages describe the planned service and may change. Questions: support@computeengines.com.