main.py
1 # Copyright 2025 Alibaba Group Holding Ltd. 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 Create an AIO sandbox via OpenSandbox SDK, then connect to it with agent-sandbox SDK. 17 18 This example is intentionally hard-coded for simplicity: 19 - OpenSandbox server: http://localhost:8080 20 - Image: ghcr.io/agent-infra/sandbox:latest 21 - AIO port: 8080 22 - Timeout: 300s 23 """ 24 25 import time 26 from datetime import timedelta 27 28 import requests 29 from agent_sandbox import Sandbox as AioSandboxClient 30 from opensandbox import SandboxSync 31 from opensandbox.config import ConnectionConfigSync 32 33 34 def check_aio_process(sbx: SandboxSync) -> bool: 35 """ 36 Health check: poll aio process at /v1/shell/sessions until it returns 200. 37 38 Returns: 39 True when ready 40 False on timeout or any exception 41 """ 42 try: 43 endpoint = sbx.get_endpoint(8080) 44 start = time.perf_counter() 45 url = f"http://{endpoint.endpoint}/v1/shell/sessions" 46 for _ in range(150): # max for ~30s 47 try: 48 resp = requests.get(url, timeout=1) 49 if resp.status_code == 200: 50 elapsed = time.perf_counter() - start 51 print(f"[check] sandbox ready after {elapsed:.1f}s") 52 return True 53 except Exception as exc: 54 # print(f"[check] aio sandbox check health failed: {exc}") 55 pass 56 time.sleep(0.2) 57 return False 58 except Exception as exc: 59 print(f"[check] failed: {exc}") 60 return False 61 62 63 def main() -> None: 64 server = "http://localhost:8080" 65 image = "ghcr.io/agent-infra/sandbox:latest" 66 timeout_seconds = 300 67 68 print(f"Creating AIO sandbox with image={image} on OpenSandbox server {server}...") 69 sandbox = SandboxSync.create( 70 image=image, 71 timeout=timedelta(seconds=timeout_seconds), 72 metadata={"example": "aio-sandbox"}, 73 entrypoint=["/opt/gem/run.sh"], 74 connection_config=ConnectionConfigSync(domain=server), 75 health_check=check_aio_process, 76 ) 77 78 with sandbox: 79 endpoint = sandbox.get_endpoint(8080) 80 print(f"AIO portal endpoint: {endpoint.endpoint}") 81 82 client = AioSandboxClient(base_url=f"http://{endpoint.endpoint}") 83 home_dir = client.sandbox.get_context().home_dir 84 85 result = client.shell.exec_command(command="ls -la", timeout=10) 86 print(result.data.output) 87 88 content = client.file.read_file(file=f"{home_dir}/.bashrc") 89 print(content.data.content) 90 91 screenshot_path = "sandbox_screenshot.png" 92 with open(screenshot_path, "wb") as f: 93 for chunk in client.browser.screenshot(): 94 f.write(chunk) 95 print(f"Screenshot saved to {screenshot_path}") 96 97 # kill sandbox finally 98 sandbox.kill() 99 100 101 if __name__ == "__main__": 102 main()