AdithyaSK's picture
AdithyaSK HF Staff
Deploy standalone SmolDataEnv Native OpenCode
81663e8 verified
Raw History Blame Contribute Delete
4.72 kB
"""Daytona implementation of the standalone OpenCode sandbox protocol."""
from __future__ import annotations
import math
import os
import shlex
import time
import uuid
from functools import lru_cache
from opencode_env.sandbox.base import ExecResult
@lru_cache(maxsize=1)
def client():
from daytona import Daytona
return Daytona()
class DaytonaBgJob:
def __init__(self, handle, directory, pid):
self.handle, self.directory, self._pid = handle, directory, pid
@property
def pid(self):
return self._pid
def wait(self, timeout=None):
deadline = time.monotonic() + timeout if timeout is not None else float("inf")
while time.monotonic() < deadline:
if self.handle.exists(self.directory + "/exit"):
return int(self.handle.read_text(self.directory + "/exit").strip())
time.sleep(min(0.5, max(0, deadline - time.monotonic())))
raise TimeoutError("Background command exceeded its deadline")
def kill(self):
self.handle.exec(f"kill -TERM -- -{self.pid} 2>/dev/null || true", timeout=10)
class DaytonaSandboxHandle:
def __init__(self, sandbox):
self._sandbox = sandbox
self._deleted = False
@property
def sandbox_id(self):
return self._sandbox.id
def exec(self, cmd, *, envs=None, cwd=None, timeout=60):
# The SDK's exec is not a shell. Quote the complete script once and let bash
# interpret it; neither user text nor environment values are interpolated.
result = self._sandbox.process.exec(
"bash -lc " + shlex.quote(cmd),
cwd=cwd,
env=envs,
timeout=max(1, math.ceil(timeout)) if timeout is not None else None,
)
code = result.exit_code
return ExecResult(124 if code is None else int(code), result.result or "", "")
def write_text(self, path, content):
parent = path.rsplit("/", 1)[0] or "."
result = self.exec("mkdir -p " + shlex.quote(parent))
if result.exit_code:
raise RuntimeError("Could not create sandbox directory")
self._sandbox.fs.upload_file(content.encode(), path)
def read_text(self, path):
return self._sandbox.fs.download_file(path).decode()
def exists(self, path):
return self.exec("test -e " + shlex.quote(path), timeout=15).exit_code == 0
def start_bg(self, cmd, *, envs=None, cwd=None):
directory = "/tmp/openenv-process-" + uuid.uuid4().hex
self.write_text(
directory + "/run.sh",
"#!/bin/bash\n(\n"
+ cmd
+ "\n)"
+ "\ncode=$?\nprintf '%s' \"$code\" > "
+ shlex.quote(directory + "/exit")
+ "\n",
)
result = self.exec(
"setsid bash "
+ shlex.quote(directory + "/run.sh")
+ " > "
+ shlex.quote(directory + "/output")
+ " 2>&1 < /dev/null & echo $!",
envs=envs,
cwd=cwd,
timeout=15,
)
if result.exit_code:
raise RuntimeError("Could not launch background command")
return DaytonaBgJob(
self, directory, int(result.stdout.strip().splitlines()[-1])
)
def kill(self):
if not self._deleted:
client().delete(self._sandbox, timeout=60, wait=True)
self._deleted = True
class DaytonaSandboxBackend:
def __init__(self, *, image, snapshot=None):
self.image, self.snapshot = (
image,
snapshot or os.environ.get("DATA_AGENT_DAYTONA_SNAPSHOT"),
)
def create(self, *, timeout_s=900, envs=None, metadata=None):
from daytona import (
CreateSandboxFromImageParams,
CreateSandboxFromSnapshotParams,
Resources,
)
options = {
"language": "python",
"os_user": "root",
"env_vars": envs,
"labels": {
**(metadata or {}),
"openenv_component": "blackbox-opencode",
"openenv_owner": os.environ.get("RUN_OWNER", "local"),
},
"public": False,
"auto_stop_interval": max(30, math.ceil(timeout_s / 60)),
"auto_delete_interval": 0,
}
if self.snapshot:
params = CreateSandboxFromSnapshotParams(snapshot=self.snapshot, **options)
else:
params = CreateSandboxFromImageParams(
image=self.image,
resources=Resources(cpu=1, memory=4, disk=5),
**options,
)
return DaytonaSandboxHandle(client().create(params, timeout=300))