chore: bump e2b to 2.38.3 (JS) / 2.38.0 (Python), fix HTTP/1.1 transport - #328
chore: bump e2b to 2.38.3 (JS) / 2.38.0 (Python), fix HTTP/1.1 transport#328mishushakov wants to merge 2 commits into
Conversation
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
PR SummaryMedium Risk Overview Sync and async Jupyter clients no longer call the SDK Reviewed by Cursor Bugbot for commit d268be9. Bugbot is set up for automated code reviews on this repo. Configure here. |
There was a problem hiding this comment.
This is a version-bump PR, but it breaks the Python SDK: e2b 2.38.0 changed get_transport() to no longer accept the http2 kwarg, and both code_interpreter_sync.py and code_interpreter_async.py still pass http2=False. That will raise a TypeError on first use of _client in every sync/async sandbox call, so this needs a fix before merging (see inline comment).
Extended reasoning...
Verified directly against the actual e2b 2.38.0 wheel: both e2b/api/client_sync/__init__.py and e2b/api/client_async/__init__.py define get_transport(config) with a single positional parameter and no **kwargs. This repo's code_interpreter_sync.py:84 and code_interpreter_async.py:89 call get_transport(self.connection_config, http2=False), which will raise TypeError: get_transport() got an unexpected keyword argument 'http2' the first time _client is accessed — i.e., on essentially every run_code/context call in both sandbox flavors. This is a real, high-severity regression introduced by the dependency bump (the PR itself only touches lockfiles/manifests, but the new pinned version is incompatible with existing call sites), not a false positive from the finder agents. Deferring rather than approving.
e2b 2.38.0 moved the Python SDK's HTTP stack onto pyqwest, dropping the `http2` argument from the internal `get_transport()` helper. Passing it raised `TypeError` on every `_client` access, and simply dropping it would have left Jupyter requests on ALPN-negotiated HTTP/2, where a cancelled request only resets the stream and the server never sees the disconnect. Build the transport in `e2b_code_interpreter.transport` instead, with `http_version` pinned to HTTP/1.1 and the SDK's pool tuning and connect-only retry policy, so client disconnects still arrive as a TCP close and long-running executions stay cancellable. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Bumps
e2bin both packages — JS^2.28.0→^2.38.3and Python^2.26.0→^2.38.0— with both lockfiles regenerated and a patch changeset added.The Python bump is a breaking one for us: e2b 2.38.0 moved the SDK's HTTP stack onto
pyqwestand the internale2b.api.client_{sync,async}.get_transport()no longer acceptshttp2, so ourget_transport(config, http2=False)raisedTypeErroron every_clientaccess and broke all Jupyter traffic. Dropping the argument alone would have been a silent regression instead, since the shared transport lets ALPN negotiate HTTP/2 against the sandbox, where a cancelled request only resets the stream and the server never receives thehttp.disconnectthe template relies on to interrupt the kernel. Jupyter requests therefore build their own transport now, inpython/e2b_code_interpreter/transport.py, withhttp_versionpinned to HTTP/1.1 and the SDK's pool tuning and connect-only retry policy reused.Verified locally: the
pyqwest.accesslog confirms our transport negotiates HTTP/1.1 where the SDK's shared one negotiates HTTP/2, both_clientproperties construct,ruff check/formatand the offlinetests/test_sandbox_url.pypass, all 137 Python tests collect, andtsc --noEmitpasses on the JS package — which reaches Jupyter through globalfetchrather than the SDK's dispatchers and so needed no change. The integration suites that actually exercise disconnect-driven cancellation need a live API key and are left to CI.🤖 Generated with Claude Code