adk-code-mode-sandbox 1.2.0__tar.gz → 1.3.0__tar.gz
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.
- {adk_code_mode_sandbox-1.2.0 → adk_code_mode_sandbox-1.3.0}/PKG-INFO +1 -1
- {adk_code_mode_sandbox-1.2.0 → adk_code_mode_sandbox-1.3.0}/src/adk_code_mode_sandbox/__about__.py +1 -1
- {adk_code_mode_sandbox-1.2.0 → adk_code_mode_sandbox-1.3.0}/src/adk_code_mode_sandbox/_entry.py +37 -1
- {adk_code_mode_sandbox-1.2.0 → adk_code_mode_sandbox-1.3.0}/src/adk_code_mode_sandbox/_http_server.py +4 -3
- {adk_code_mode_sandbox-1.2.0 → adk_code_mode_sandbox-1.3.0}/src/adk_code_mode_sandbox/protocol.py +11 -1
- {adk_code_mode_sandbox-1.2.0 → adk_code_mode_sandbox-1.3.0}/.gitignore +0 -0
- {adk_code_mode_sandbox-1.2.0 → adk_code_mode_sandbox-1.3.0}/README.md +0 -0
- {adk_code_mode_sandbox-1.2.0 → adk_code_mode_sandbox-1.3.0}/pyproject.toml +0 -0
- {adk_code_mode_sandbox-1.2.0 → adk_code_mode_sandbox-1.3.0}/src/adk_code_mode_sandbox/__init__.py +0 -0
- {adk_code_mode_sandbox-1.2.0 → adk_code_mode_sandbox-1.3.0}/src/adk_code_mode_sandbox/__main__.py +0 -0
- {adk_code_mode_sandbox-1.2.0 → adk_code_mode_sandbox-1.3.0}/src/adk_code_mode_sandbox/_rpc_client.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: adk-code-mode-sandbox
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.0
|
|
4
4
|
Summary: In-sandbox runtime shim for adk-code-mode. Installs inside the container image the host runtime launches.
|
|
5
5
|
Project-URL: Documentation, https://github.com/A2ANet/adk-code-mode#readme
|
|
6
6
|
Project-URL: Issues, https://github.com/A2ANet/adk-code-mode/issues
|
{adk_code_mode_sandbox-1.2.0 → adk_code_mode_sandbox-1.3.0}/src/adk_code_mode_sandbox/_entry.py
RENAMED
|
@@ -23,8 +23,10 @@ its stdout/stderr captured and shipped back in a per-block ``OutputFrame``; any
|
|
|
23
23
|
|
|
24
24
|
from __future__ import annotations
|
|
25
25
|
|
|
26
|
+
import importlib.metadata
|
|
26
27
|
import io
|
|
27
28
|
import os
|
|
29
|
+
import platform
|
|
28
30
|
import socket
|
|
29
31
|
import sys
|
|
30
32
|
import traceback
|
|
@@ -40,6 +42,11 @@ from adk_code_mode_sandbox.protocol import (
|
|
|
40
42
|
ShutdownFrame,
|
|
41
43
|
)
|
|
42
44
|
|
|
45
|
+
# Distributions that ship with the sandbox itself rather than being installed by
|
|
46
|
+
# whoever built the image. Reporting them would tell the model it has tools it
|
|
47
|
+
# was never meant to use (`websockets` is this wheel's only dependency).
|
|
48
|
+
_PACKAGE_DENYLIST = frozenset({"adk-code-mode-sandbox", "websockets", "pip", "setuptools", "wheel"})
|
|
49
|
+
|
|
43
50
|
CONTROL_FD_ENV = "ADK_CODE_MODE_CONTROL_FD"
|
|
44
51
|
CONTROL_SOCKET_ENV = "ADK_CODE_MODE_CONTROL_SOCKET"
|
|
45
52
|
CONTROL_TCP_ENV = "ADK_CODE_MODE_CONTROL_TCP"
|
|
@@ -50,6 +57,35 @@ TOOLS_DIR = os.environ.get(TOOLS_DIR_ENV, "/tools")
|
|
|
50
57
|
WORKDIR = os.environ.get(WORKDIR_ENV, "/workspace")
|
|
51
58
|
|
|
52
59
|
|
|
60
|
+
def ready_frame() -> ReadyFrame:
|
|
61
|
+
"""Build the ``ReadyFrame`` announcing this image's Python and packages.
|
|
62
|
+
|
|
63
|
+
Both transports send this, so image introspection stays in one place.
|
|
64
|
+
"""
|
|
65
|
+
distributions = {
|
|
66
|
+
dist.name.casefold(): (dist.name, dist.version)
|
|
67
|
+
for dist in sorted(
|
|
68
|
+
importlib.metadata.distributions(),
|
|
69
|
+
key=lambda dist: (dist.name.casefold(), dist.name, dist.version),
|
|
70
|
+
)
|
|
71
|
+
if dist.name.casefold() not in _PACKAGE_DENYLIST
|
|
72
|
+
}
|
|
73
|
+
packages: dict[str, dict[str, str]] = {}
|
|
74
|
+
package_distributions = importlib.metadata.packages_distributions()
|
|
75
|
+
for import_name in sorted(package_distributions, key=lambda name: (name.casefold(), name)):
|
|
76
|
+
providers: dict[str, str] = {}
|
|
77
|
+
for distribution_name in sorted(
|
|
78
|
+
package_distributions[import_name],
|
|
79
|
+
key=lambda name: (name.casefold(), name),
|
|
80
|
+
):
|
|
81
|
+
distribution = distributions.get(distribution_name.casefold())
|
|
82
|
+
if distribution is not None:
|
|
83
|
+
providers[distribution[0]] = distribution[1]
|
|
84
|
+
if providers:
|
|
85
|
+
packages[import_name] = providers
|
|
86
|
+
return ReadyFrame(python_version=platform.python_version(), packages=packages)
|
|
87
|
+
|
|
88
|
+
|
|
53
89
|
def _open_control_streams() -> tuple[Any, Any]:
|
|
54
90
|
"""Open the host control pipe as a (reader, writer) pair."""
|
|
55
91
|
tcp_endpoint = os.environ.get(CONTROL_TCP_ENV)
|
|
@@ -204,7 +240,7 @@ def main() -> int:
|
|
|
204
240
|
# One persistent globals dict + one /workspace for the whole connection, so
|
|
205
241
|
# variables and files carry across the turn's successive code blocks.
|
|
206
242
|
globs = _make_globals()
|
|
207
|
-
client.send(
|
|
243
|
+
client.send(ready_frame())
|
|
208
244
|
|
|
209
245
|
while True:
|
|
210
246
|
frame = client.recv()
|
|
@@ -49,6 +49,7 @@ from adk_code_mode_sandbox._entry import (
|
|
|
49
49
|
_prepare_sys_path,
|
|
50
50
|
_prepare_workdir,
|
|
51
51
|
_sanitize_environ,
|
|
52
|
+
ready_frame,
|
|
52
53
|
run_block,
|
|
53
54
|
)
|
|
54
55
|
from adk_code_mode_sandbox._rpc_client import RpcClient
|
|
@@ -57,7 +58,6 @@ from adk_code_mode_sandbox.protocol import (
|
|
|
57
58
|
DoneFrame,
|
|
58
59
|
OutputFrame,
|
|
59
60
|
ProtocolError,
|
|
60
|
-
ReadyFrame,
|
|
61
61
|
RunFrame,
|
|
62
62
|
ShutdownFrame,
|
|
63
63
|
decode,
|
|
@@ -188,8 +188,9 @@ async def _handle_connection(ws: Any) -> None:
|
|
|
188
188
|
globs = _make_globals()
|
|
189
189
|
loop = asyncio.get_running_loop()
|
|
190
190
|
|
|
191
|
-
# 4. Announce readiness once (carries the protocol version
|
|
192
|
-
|
|
191
|
+
# 4. Announce readiness once (carries the protocol version, Python
|
|
192
|
+
# version, and installed packages).
|
|
193
|
+
await ws.send(encode(ready_frame()).decode("utf-8"))
|
|
193
194
|
|
|
194
195
|
# 5. Run code blocks until the client ends the turn or disconnects.
|
|
195
196
|
while await _run_one_block(ws, loop, globs, workspace_dir, max_workspace):
|
{adk_code_mode_sandbox-1.2.0 → adk_code_mode_sandbox-1.3.0}/src/adk_code_mode_sandbox/protocol.py
RENAMED
|
@@ -39,10 +39,20 @@ FrameKind = Literal[
|
|
|
39
39
|
|
|
40
40
|
@dataclass(frozen=True)
|
|
41
41
|
class ReadyFrame:
|
|
42
|
-
"""Sandbox → host. Sent once after boot.
|
|
42
|
+
"""Sandbox → host. Sent once after boot.
|
|
43
|
+
|
|
44
|
+
``python_version`` / ``packages`` describe the image the sandbox runs in so
|
|
45
|
+
the host can tell the model what it can import. ``packages`` maps each
|
|
46
|
+
top-level import name to the distributions that provide it and their
|
|
47
|
+
versions. Both are additive fields with defaults, so a host and a sandbox
|
|
48
|
+
on different releases still speak: ``decode`` drops unknown keys, and an
|
|
49
|
+
older sandbox that sends neither just leaves them empty.
|
|
50
|
+
"""
|
|
43
51
|
|
|
44
52
|
kind: Literal["ready"] = "ready"
|
|
45
53
|
protocol_version: int = PROTOCOL_VERSION
|
|
54
|
+
python_version: str = ""
|
|
55
|
+
packages: dict[str, dict[str, str]] = field(default_factory=dict)
|
|
46
56
|
|
|
47
57
|
|
|
48
58
|
@dataclass(frozen=True)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{adk_code_mode_sandbox-1.2.0 → adk_code_mode_sandbox-1.3.0}/src/adk_code_mode_sandbox/__init__.py
RENAMED
|
File without changes
|
{adk_code_mode_sandbox-1.2.0 → adk_code_mode_sandbox-1.3.0}/src/adk_code_mode_sandbox/__main__.py
RENAMED
|
File without changes
|
{adk_code_mode_sandbox-1.2.0 → adk_code_mode_sandbox-1.3.0}/src/adk_code_mode_sandbox/_rpc_client.py
RENAMED
|
File without changes
|