agent-sandbox-e2b 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,14 @@
1
+ Metadata-Version: 2.4
2
+ Name: agent-sandbox-e2b
3
+ Version: 0.0.1
4
+ Summary: agent-sandbox E2B SDK patch — one-line switch to use AgentBox via the E2B Python SDK
5
+ License: Apache-2.0
6
+ Project-URL: Homepage, https://github.com/scitix/agent-sandbox
7
+ Requires-Python: >=3.10
8
+ Description-Content-Type: text/markdown
9
+ Provides-Extra: e2b
10
+ Requires-Dist: e2b<3.0.0,>=2.0.0; extra == "e2b"
11
+ Provides-Extra: dev
12
+ Requires-Dist: e2b==2.19.0; extra == "dev"
13
+ Requires-Dist: ruff>=0.4.0; extra == "dev"
14
+ Requires-Dist: httpx>=0.27.0; extra == "dev"
@@ -0,0 +1,6 @@
1
+ agentbox/__init__.py,sha256=158FWmlqVnN4eKgj8tdxjxRZ0MSVxhVOpHuUgPVuNPA,656
2
+ agentbox/patch_e2b.py,sha256=b1ZWr3DHjQcAGpOnRwyywiUTZIVuFHSUpcJeW48iTW4,8113
3
+ agent_sandbox_e2b-0.0.1.dist-info/METADATA,sha256=i9kF1-FVaE53kL462FQypaA1pPrsQrIU9ploWfip4a0,524
4
+ agent_sandbox_e2b-0.0.1.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
5
+ agent_sandbox_e2b-0.0.1.dist-info/top_level.txt,sha256=lNpen_9W4iU-XQIGpizrWb3jS7tj6k27fUBWT4u0HEQ,9
6
+ agent_sandbox_e2b-0.0.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ agentbox
agentbox/__init__.py ADDED
@@ -0,0 +1,21 @@
1
+ # Copyright 2026 ScitiX
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """
16
+ AgentBox __init__.py
17
+
18
+ AgentBox E2B SDK patch package.
19
+ """
20
+
21
+ __version__ = "0.0.1"
agentbox/patch_e2b.py ADDED
@@ -0,0 +1,199 @@
1
+ # Copyright 2026 ScitiX
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """
16
+ patch_e2b — AgentBox patch for e2b==2.19.0
17
+
18
+ This module monkey-patches the E2B SDK to redirect API calls and sandbox
19
+ connections to an AgentBox deployment.
20
+
21
+ Architecture Overview:
22
+ - Control Plane (E2B-compatible REST API): AgentBox exposes standard E2B routes
23
+ on port :8090. Paths are direct (e.g., /sandboxes, /templates) with no extra prefix.
24
+ E2B_API_URL should be set to http(s)://<e2b-api-host> (no path suffix).
25
+ - Data Plane (envd gRPC / connect-proto): Traffic goes through the Envoy ExtProc gateway,
26
+ using the standard URL path format: <gateway>/sandboxes/<sandboxID>/<port>/...
27
+ E2B_DOMAIN should be set to the gateway address, and the SDK's `get_host` will
28
+ automatically append the path.
29
+
30
+ Default In-Cluster Configuration (calling patch_e2b() directly without arguments):
31
+ - Data Plane Gateway: agentbox-data-plane.agentbox-system.svc.cluster.local
32
+ - Control Plane API: http://agentbox-e2b-api.agentbox-system.svc.cluster.local
33
+ - HTTPS: False
34
+
35
+ Usage (In-cluster, zero arguments):
36
+ from agentbox.patch_e2b import patch_e2b
37
+ patch_e2b()
38
+
39
+ from e2b import Sandbox
40
+ sandbox = Sandbox.create(template_id="my-gpu-pool")
41
+
42
+ Usage (Custom addresses):
43
+ from agentbox.patch_e2b import patch_e2b
44
+ patch_e2b(
45
+ https=False,
46
+ domain="agentbox-data-plane.agentbox-system.svc.cluster.local",
47
+ api_url="http://agentbox-e2b-api.agentbox-system.svc.cluster.local",
48
+ )
49
+
50
+ from e2b import Sandbox
51
+ sandbox = Sandbox.create(template_id="my-gpu-pool")
52
+ """
53
+
54
+ import os
55
+ from typing import Optional
56
+ from urllib.parse import urlparse
57
+
58
+ #: e2b SDK version this patch was written and tested against.
59
+ #: If your installed e2b version differs, the patch may still work but is not guaranteed.
60
+ COMPATIBLE_E2B_VERSION = "2.19.0"
61
+
62
+ # Default in-cluster service addresses
63
+ _DEFAULT_DOMAIN = "agentbox-data-plane.agentbox-system.svc.cluster.local"
64
+ _DEFAULT_API_URL = "http://agentbox-e2b-api.agentbox-system.svc.cluster.local"
65
+
66
+
67
+ def _strip_scheme(url: str) -> str:
68
+ """Remove http:// or https:// scheme prefix from a URL, keeping only host[:port]."""
69
+ parsed = urlparse(url)
70
+ if parsed.scheme in ("http", "https"):
71
+ return parsed.netloc or parsed.path
72
+ return url.rstrip("/")
73
+
74
+
75
+ def _get_api_url(domain: str, https: bool) -> str:
76
+ """Build the E2B-compatible API base URL for AgentBox.
77
+
78
+ AgentBox E2B-compatible API routes are registered directly under the root path
79
+ (/sandboxes, /templates, etc.) with no extra path prefix. Therefore, we only
80
+ need to return scheme://host.
81
+ """
82
+ scheme = "https" if https else "http"
83
+ host = _strip_scheme(domain)
84
+ return f"{scheme}://{host}"
85
+
86
+
87
+ def _make_sandbox_get_host(resolved_domain: Optional[str]):
88
+ """Return a get_host method for SandboxBase that uses the standard URL path format.
89
+
90
+ Always uses the domain that was passed to patch_e2b(), completely ignoring
91
+ sandbox_domain from the API response (which may contain a scheme-prefixed
92
+ internal cluster URL like http://e2b-api.svc.cluster.local).
93
+ """
94
+
95
+ def _get_host(self, port: int) -> str:
96
+ dom = resolved_domain or os.environ.get("E2B_DOMAIN", "localhost")
97
+ dom = _strip_scheme(dom)
98
+ sid = getattr(self, "sandbox_id", None) or ""
99
+ return f"{dom}/sandboxes/{sid}/{port}"
100
+
101
+ return _get_host
102
+
103
+
104
+ def patch_e2b(
105
+ https: bool = False,
106
+ domain: Optional[str] = None,
107
+ api_url: Optional[str] = None,
108
+ ) -> None:
109
+ """
110
+ Patch the E2B SDK to route API calls and sandbox connections to AgentBox.
111
+
112
+ This function must be called BEFORE importing/using any E2B Sandbox classes.
113
+
114
+ Args:
115
+ https: If True, use HTTPS for the API URL. Defaults to False (in-cluster HTTP).
116
+ domain: Data plane Envoy gateway address.
117
+ Priority: Argument > E2B_DOMAIN environment variable > Default in-cluster value
118
+ (agentbox-data-plane.agentbox-system.svc.cluster.local)
119
+ api_url: Control plane E2B-compatible API full URL (including scheme).
120
+ Priority: Argument > E2B_API_URL environment variable > Default in-cluster value
121
+ (http://agentbox-e2b-api.agentbox-system.svc.cluster.local)
122
+ This argument can be omitted if the E2B_API_URL environment variable is already set.
123
+
124
+ Raises:
125
+ ImportError: If the e2b package is not installed.
126
+
127
+ Example:
128
+ # Zero-argument call within the cluster (using default ClusterIP addresses):
129
+ from agentbox.patch_e2b import patch_e2b
130
+ patch_e2b()
131
+
132
+ # Custom addresses (e.g., local debugging via port-forward):
133
+ patch_e2b(https=False, domain="localhost:9081", api_url="http://localhost:9082")
134
+
135
+ # Controlled via environment variables (CI/CD scenarios):
136
+ # export E2B_DOMAIN=agentbox-data-plane.agentbox-system.svc.cluster.local
137
+ # export E2B_API_URL=http://agentbox-e2b-api.agentbox-system.svc.cluster.local
138
+ # export E2B_API_KEY=agbx_your_key
139
+ patch_e2b()
140
+ """
141
+ try:
142
+ import e2b # noqa: F401
143
+ except ImportError as exc:
144
+ raise ImportError(
145
+ "The 'e2b' package is required. Install it with: pip install e2b"
146
+ ) from exc
147
+
148
+ # Resolve domain (data plane gateway): Argument > Environment variable > Default in-cluster value
149
+ resolved_domain = (
150
+ domain or os.environ.get("E2B_DOMAIN", "") or _DEFAULT_DOMAIN
151
+ )
152
+
153
+ # Resolve api_url (control plane API): Argument > Environment variable > Default in-cluster value
154
+ # If E2B_API_URL is already set externally and no argument is passed,
155
+ # keep the environment variable; otherwise, use the default value.
156
+ resolved_api_url = (
157
+ api_url or os.environ.get("E2B_API_URL", "") or _DEFAULT_API_URL
158
+ )
159
+ os.environ["E2B_API_URL"] = resolved_api_url
160
+
161
+ # Patch the SandboxBase.get_host method to use standard URL path format
162
+ try:
163
+ from e2b.sandbox.main import SandboxBase # type: ignore[import]
164
+
165
+ SandboxBase.get_host = _make_sandbox_get_host(resolved_domain)
166
+ except ImportError:
167
+ # Older versions of e2b may have a different module structure
168
+ pass
169
+
170
+ # Patch ConnectionConfig.get_host and get_sandbox_url if available
171
+ try:
172
+ from e2b.connection_config import ConnectionConfig # type: ignore[import]
173
+
174
+ def _connection_config_get_host(
175
+ _, sandbox_id: str, sandbox_domain: str, port: int
176
+ ) -> str:
177
+ # Always use the configured gateway domain — ignore sandbox_domain from the
178
+ # API response since it may be an internal cluster URL with a scheme prefix.
179
+ dom = _strip_scheme(
180
+ resolved_domain or sandbox_domain or "localhost"
181
+ )
182
+ return f"{dom}/sandboxes/{sandbox_id}/{port}"
183
+
184
+ ConnectionConfig.get_host = _connection_config_get_host
185
+
186
+ # Patch get_sandbox_url to respect the https flag passed to patch_e2b().
187
+ # The default SDK implementation always uses https:// when debug=False,
188
+ # which breaks local development against HTTP-only gateways.
189
+ def _connection_config_get_sandbox_url(
190
+ self, sandbox_id: str, sandbox_domain: str
191
+ ) -> str:
192
+ if self._sandbox_url:
193
+ return self._sandbox_url
194
+ scheme = "https" if https else "http"
195
+ return f"{scheme}://{self.get_host(sandbox_id, sandbox_domain, self.envd_port)}"
196
+
197
+ ConnectionConfig.get_sandbox_url = _connection_config_get_sandbox_url
198
+ except (ImportError, AttributeError):
199
+ pass