Skip to content

Releases: e2b-dev/E2B

e2b@2.31.0

Choose a tag to compare

@github-actions github-actions released this 25 Jun 18:04
de0c401

Minor Changes

  • 7e7e951: Add an object form to the sandbox lifecycle.onTimeout (on_timeout in Python)
    that controls the snapshot kind taken when a sandbox auto-pauses on timeout, via
    keepMemory (keep_memory).

    onTimeout now accepts either the existing bare action ('pause' / 'kill') or
    the object form. The object form is a discriminated union on action:
    keepMemory is only accepted alongside action: 'pause' — pairing it with
    action: 'kill' is a compile-time type error (and is rejected at runtime for
    untyped callers). When keepMemory is false, a timeout auto-pause drops the
    in-memory state and persists only the filesystem (a filesystem-only snapshot);
    resuming such a sandbox cold-boots (reboots) it from disk, losing running
    processes and open connections. Defaults to true (full memory snapshot). It
    cannot be combined with auto-resume: auto-resume wakes a paused sandbox on
    inbound traffic by restoring its memory snapshot in place, and a filesystem-only
    snapshot has no memory to restore (resuming cold-boots it), so it must be resumed
    explicitly. The bare string form is unchanged.

    # Python
    sbx = Sandbox.create(
        lifecycle={"on_timeout": {"action": "pause", "keep_memory": False}}
    )
    // JS/TS
    const sbx = await Sandbox.create({
      lifecycle: { onTimeout: { action: 'pause', keepMemory: false } },
    })
  • cb5a387: Add a keepMemory (keep_memory in Python) option to pause for
    filesystem-only snapshots.

    When keepMemory is false, pausing drops the in-memory state and captures
    only the filesystem (no memory snapshot); resuming such a snapshot cold-boots
    (reboots) the sandbox from disk, losing running processes and open connections.
    Defaults to true (full memory snapshot), so existing callers are unaffected.

    # Python
    sbx.pause(keep_memory=False)          # filesystem-only snapshot
    // JS/TS
    await sandbox.pause({ keepMemory: false }) // filesystem-only snapshot

Patch Changes

  • de0c401: Fix three filesystem watch handle bugs:
    • JS: WatchHandle now awaits async onEvent/onExit callbacks. A rejecting async onEvent is routed to onExit and stops the watch instead of becoming an unhandled promise rejection that can crash Node, and async callbacks get backpressure/ordering — matching CommandHandle.
    • Python (sync): WatchHandle.get_new_events() and stop() now send a request timeout (default 60s, overridable via request_timeout) so a stalled call can't hang the thread forever, and include the authentication header so the polling/stop calls aren't sent unauthenticated on older envd.
    • Python (async): AsyncWatchHandle now invokes on_exit when the stream ends cleanly (with None) and when stop() is called, in addition to on error — matching the JS SDK.

e2b@2.30.6

Choose a tag to compare

@github-actions github-actions released this 25 Jun 06:10
5370d54

Patch Changes

  • 2a98cce: Fix CommandHandle.disconnect() leaking the output subscription in the JS SDK. disconnect() now cooperatively gates event handling with a flag that is checked before every dispatch, so onStdout/onStderr/onPty are guaranteed not to fire for output that arrives after the call (previously they could keep firing when the underlying HTTP/2 abort did not promptly tear down the stream). The call returns promptly and never blocks on an idle command's stream.

@e2b/python-sdk@2.30.0

Choose a tag to compare

@github-actions github-actions released this 25 Jun 18:04
de0c401

Minor Changes

  • 7e7e951: Add an object form to the sandbox lifecycle.onTimeout (on_timeout in Python)
    that controls the snapshot kind taken when a sandbox auto-pauses on timeout, via
    keepMemory (keep_memory).

    onTimeout now accepts either the existing bare action ('pause' / 'kill') or
    the object form. The object form is a discriminated union on action:
    keepMemory is only accepted alongside action: 'pause' — pairing it with
    action: 'kill' is a compile-time type error (and is rejected at runtime for
    untyped callers). When keepMemory is false, a timeout auto-pause drops the
    in-memory state and persists only the filesystem (a filesystem-only snapshot);
    resuming such a sandbox cold-boots (reboots) it from disk, losing running
    processes and open connections. Defaults to true (full memory snapshot). It
    cannot be combined with auto-resume: auto-resume wakes a paused sandbox on
    inbound traffic by restoring its memory snapshot in place, and a filesystem-only
    snapshot has no memory to restore (resuming cold-boots it), so it must be resumed
    explicitly. The bare string form is unchanged.

    # Python
    sbx = Sandbox.create(
        lifecycle={"on_timeout": {"action": "pause", "keep_memory": False}}
    )
    // JS/TS
    const sbx = await Sandbox.create({
      lifecycle: { onTimeout: { action: 'pause', keepMemory: false } },
    })
  • cb5a387: Add a keepMemory (keep_memory in Python) option to pause for
    filesystem-only snapshots.

    When keepMemory is false, pausing drops the in-memory state and captures
    only the filesystem (no memory snapshot); resuming such a snapshot cold-boots
    (reboots) the sandbox from disk, losing running processes and open connections.
    Defaults to true (full memory snapshot), so existing callers are unaffected.

    # Python
    sbx.pause(keep_memory=False)          # filesystem-only snapshot
    // JS/TS
    await sandbox.pause({ keepMemory: false }) // filesystem-only snapshot

Patch Changes

  • de0c401: Fix three filesystem watch handle bugs:
    • JS: WatchHandle now awaits async onEvent/onExit callbacks. A rejecting async onEvent is routed to onExit and stops the watch instead of becoming an unhandled promise rejection that can crash Node, and async callbacks get backpressure/ordering — matching CommandHandle.
    • Python (sync): WatchHandle.get_new_events() and stop() now send a request timeout (default 60s, overridable via request_timeout) so a stalled call can't hang the thread forever, and include the authentication header so the polling/stop calls aren't sent unauthenticated on older envd.
    • Python (async): AsyncWatchHandle now invokes on_exit when the stream ends cleanly (with None) and when stop() is called, in addition to on error — matching the JS SDK.

@e2b/python-sdk@2.29.6

Choose a tag to compare

@github-actions github-actions released this 25 Jun 06:10
5370d54

Patch Changes

  • 2a98cce: Fix CommandHandle (sync and async) recording the command result after yielding the flushed end-event chunks. The decoders are now flushed and the CommandResult is recorded before the trailing chunks are yielded, so a consumer that stops iterating on the first flushed chunk still observes the exit code.
  • 21af1f8: Avoid quadratic-time stdout/stderr accumulation in command handles by buffering decoded chunks in a list and joining on read instead of repeatedly concatenating onto an instance attribute.

@e2b/cli@2.13.0

Choose a tag to compare

@github-actions github-actions released this 25 Jun 06:10
5370d54

Minor Changes

  • 5370d54: Replace legacy access token auth with OAuth 2.0 refresh token flow. The CLI now authenticates via a public OAuth client using PKCE, receiving Hydra JWTs that are refreshed automatically. Config schema bumped to v1 with nested identity, oauth, and tokens sections. Old flat configs are deprecated and require re-login.

Patch Changes

  • Updated dependencies [2a98cce]
    • e2b@2.30.6

e2b@2.30.5

Choose a tag to compare

@github-actions github-actions released this 22 Jun 19:39
c1415f3

Patch Changes

  • 60feee3: Stream uploads instead of buffering streaming input entirely in memory:

    • Sandbox.files.write() / write_files(): ReadableStream data (JS, outside the browser) and file-like objects (Python) are streamed to the sandbox, including when gzip is enabled (compression now happens chunk by chunk). useOctetStream/use_octet_stream now defaults to auto-detect — octet-stream is used when any entry is streamable (so streamed uploads aren't silently buffered) and multipart/form-data otherwise; browsers always use multipart/form-data. A streamed upload is bounded by a per-chunk timeout on the wire (Python's per-write httpx timeout, default the request timeout); a stalled upload that this can't observe is bounded server-side. On Python's AsyncSandbox, the blocking file reads and gzip compression of a streamed upload now run in a worker thread so a large upload doesn't stall the event loop.
    • Sandbox.files.read(format="stream"): the request timeout now bounds only the initial handshake instead of killing the stream while it's being consumed. The body is bounded by a per-chunk idle timeout on the wire (streamIdleTimeoutMs in JS, stream_idle_timeout in Python, default the request timeout — 60s — 0/None to disable): it aborts only when the server stops sending mid-stream, and a slow or paused consumer never trips it (a held-but-unread stream is reclaimed server-side). Use signal (JS) to cancel an in-flight stream. A dropped connection during the stream handshake now surfaces the same typed, health-checked error as non-stream reads. The stream holds a pooled connection until it is consumed to the end, cancelled/closed, errors, or the idle timeout fires — consume it fully, use the context manager, or close it.
    • Python Sandbox.files.read(format="stream"): the response body is now streamed from the sandbox instead of being downloaded into memory before iteration (sync and async).
    • JS Sandbox.files.read() with blob or stream format now returns an empty Blob/ReadableStream for empty files instead of "".
  • c1415f3: Stream volume file uploads and downloads instead of buffering in memory:

    • Volume.writeFile() / Volume.write_file(): ReadableStream data (JS, outside the browser) and file-like objects (Python) are now streamed to the API in chunks.
    • Volume.readFile(format="stream") / read_file(format="stream"): the request timeout now bounds only the initial handshake instead of killing the stream while it's being consumed (Python disables the read timeout; JS bounds the handshake and supports signal to cancel an in-flight stream). A dropped connection during the stream handshake now surfaces the same typed, health-checked error as non-stream reads.

@e2b/python-sdk@2.29.5

Choose a tag to compare

@github-actions github-actions released this 22 Jun 19:39
c1415f3

Patch Changes

  • 60feee3: Stream uploads instead of buffering streaming input entirely in memory:

    • Sandbox.files.write() / write_files(): ReadableStream data (JS, outside the browser) and file-like objects (Python) are streamed to the sandbox, including when gzip is enabled (compression now happens chunk by chunk). useOctetStream/use_octet_stream now defaults to auto-detect — octet-stream is used when any entry is streamable (so streamed uploads aren't silently buffered) and multipart/form-data otherwise; browsers always use multipart/form-data. A streamed upload is bounded by a per-chunk timeout on the wire (Python's per-write httpx timeout, default the request timeout); a stalled upload that this can't observe is bounded server-side. On Python's AsyncSandbox, the blocking file reads and gzip compression of a streamed upload now run in a worker thread so a large upload doesn't stall the event loop.
    • Sandbox.files.read(format="stream"): the request timeout now bounds only the initial handshake instead of killing the stream while it's being consumed. The body is bounded by a per-chunk idle timeout on the wire (streamIdleTimeoutMs in JS, stream_idle_timeout in Python, default the request timeout — 60s — 0/None to disable): it aborts only when the server stops sending mid-stream, and a slow or paused consumer never trips it (a held-but-unread stream is reclaimed server-side). Use signal (JS) to cancel an in-flight stream. A dropped connection during the stream handshake now surfaces the same typed, health-checked error as non-stream reads. The stream holds a pooled connection until it is consumed to the end, cancelled/closed, errors, or the idle timeout fires — consume it fully, use the context manager, or close it.
    • Python Sandbox.files.read(format="stream"): the response body is now streamed from the sandbox instead of being downloaded into memory before iteration (sync and async).
    • JS Sandbox.files.read() with blob or stream format now returns an empty Blob/ReadableStream for empty files instead of "".
  • 8171a03: Fix Python SDK header precedence so a custom Authorization passed via api_headers is no longer overwritten by the deprecated access_token. The deprecated access token is now applied before api_headers, matching the JS SDK where a custom Authorization wins.

  • c1415f3: Stream volume file uploads and downloads instead of buffering in memory:

    • Volume.writeFile() / Volume.write_file(): ReadableStream data (JS, outside the browser) and file-like objects (Python) are now streamed to the API in chunks.
    • Volume.readFile(format="stream") / read_file(format="stream"): the request timeout now bounds only the initial handshake instead of killing the stream while it's being consumed (Python disables the read timeout; JS bounds the handshake and supports signal to cancel an in-flight stream). A dropped connection during the stream handshake now surfaces the same typed, health-checked error as non-stream reads.

e2b@2.30.4

Choose a tag to compare

@github-actions github-actions released this 19 Jun 19:38
726ced6

Patch Changes

  • 726ced6: Fix duplicate logo on NPM/PyPI by switching to <picture> element.

e2b@2.30.3

Choose a tag to compare

@github-actions github-actions released this 19 Jun 19:03
e03d1b8

Patch Changes

  • f3e7f33: Tidy up SDK authentication and deprecate the access token in ConnectionConfig.

    • Deprecated the accessToken (JS) / access_token (Python) option on ConnectionConfig. It still works exactly as before — when set (or via E2B_ACCESS_TOKEN), the Authorization: Bearer header is still sent — but you should pass custom auth through apiHeaders instead, e.g. new ConnectionConfig({ apiHeaders: { Authorization: 'Bearer <token>' } }).
    • The SDK now raises a clear error when no API key is supplied, pointing to the API Keys tab (https://e2b.dev/dashboard?tab=keys). In JS this is controlled by a requireApiKey option (default true) so callers that authenticate differently — like the CLI hitting /teams with an access token — can opt out; in Python the API key is always required.
    • Removed the unused access-token toggle from the API clients: requireAccessToken (JS) and require_access_token (Python). No caller ever set it to a non-default value, so behavior is unchanged.
    • The CLI now passes the access token to the /teams endpoint through apiHeaders instead of the deprecated option.
    • Decoupled the sandbox-scoped envd access token from ConnectionConfig: EnvdApiClient now owns its own accessToken field and sets the X-Access-Token header itself.
  • 0a5d524: Update package logos with theme-aware dark/light variants for GitHub.

@e2b/python-sdk@2.29.4

Choose a tag to compare

@github-actions github-actions released this 19 Jun 19:38
726ced6

Patch Changes

  • 726ced6: Fix duplicate logo on NPM/PyPI by switching to <picture> element.