Add exec-sandbox code executor (self-hosted QEMU microVMs)
- Ngôn ngữ chính
- Python
- Star
- 21.5k
- Fork
- 4k
- Merge trung bình
- 1 ngày 14 giờ
- Pull request đã merge (30 ngày)
- 37
Mô tả
# Add exec-sandbox code executor (self-hosted QEMU microVMs)
## Summary
Proposing [exec-sandbox](https://github.com/dualeai/exec-sandbox) as a new `BaseCodeExecutor` backend. It runs code in ephemeral QEMU microVMs with hardware-level isolation (KVM on Linux, HVF on macOS) — self-hosted, no cloud account needed.
## Why
- **Self-hosted** — ContainerCodeExecutor needs Docker, GkeCodeExecutor needs GKE, VertexAiCodeExecutor needs Vertex. exec-sandbox runs on bare metal with just QEMU. Data never leaves the machine — relevant for customer data privacy, regulated environments, and cheaper at scale.
- **macOS + Linux** — HVF on macOS, KVM on Linux. Same codebase for dev and prod.
- **Fast** — ~1-2ms from warm pool, ~200ms from memory snapshots.
- **Stronger isolation than containers** — Hardware-level VM boundary vs Docker process isolation.
- **Apache-2.0**
## How it maps
exec-sandbox is a Python library with an async API. A `BaseCodeExecutor` subclass bridges async → sync, following the same pattern as ContainerCodeExecutor:
```python
import asyncio
from exec_sandbox import Scheduler
class ExecSandboxCodeExecutor(BaseCodeExecutor):
stateful: bool = True
def __init__(self, **kwargs):
super().__init__(**kwargs)
self._loop = asyncio.new_event_loop()
self._scheduler = self._loop.run_until_complete(Scheduler().__aenter__())
self._sessions: dict[str, Session] = {}
def execute_code(self, invocation_context, code_execution_input):
# Reuse session for stateful execution
eid = code_execution_input.execution_id
if eid and eid in self._sessions:
session = self._sessions[eid]
else:
session = self._loop.run_until_complete(
self._scheduler.session(language="python")
)
if eid:
self._sessions[eid] = session
result = self._loop.run_until_complete(session.exec(code_execution_input.code))
return CodeExecutionResult(
stdout=result.stdout,
stderr=result.stderr,
)
```
Usage:
```python
agent = LlmAgent(
code_executor=ExecSandboxCodeExecutor(),
...
)
```
## Open questions
- **Async/sync bridge** — exec-sandbox is fully async. The sketch uses a dedicated event loop. A background-thread loop would be safer if called from an existing async context.
- **File I/O** — `CodeExecutionInput.input_files` and `CodeExecutionResult.output_files` could use exec-sandbox's native `write_file`/`read_file` APIs instead of writing to a shared volume.
- **Shipping** — External package (`exec-sandbox[adk]` extra) vs upstream in `code_executors/` following the GkeCodeExecutor pattern from PR #1629.
## Links
- [Repo](https://github.com/dualeai/exec-sandbox) · [PyPI](https://pypi.org/project/exec-sandbox/)
- Reference: `gke_code_executor.py` in `code_executors/` (same integration pattern)
Happy to submit a PR if there's interest.
Hướng dẫn đóng góp
Đánh giá
Issue này chưa được đánh giá.