Implementation:OpenHands OpenHands DaytonaRuntime Close
| Knowledge Sources | |
|---|---|
| Domains | Cloud_Infrastructure, Runtime_Management |
| Last Updated | 2026-02-11 21:00 GMT |
Overview
Concrete tool for gracefully terminating a Daytona cloud sandbox and releasing provider resources, provided by the OpenHands third-party runtime layer.
Description
DaytonaRuntime.close shuts down a Daytona sandbox at the end of an agent session. It first checks the DAYTONA_KEEP_SANDBOX environment variable: if set, the sandbox is preserved for debugging and the method returns early without destroying the sandbox. Otherwise, it calls the Daytona SDK to remove the sandbox, then resets internal state references.
The method is designed to be idempotent and robust. If the sandbox has already been destroyed (e.g., due to a provider timeout or external termination), the method handles the resulting errors gracefully without raising exceptions to the caller.
Other third-party runtimes implement their own cleanup logic:
- E2BRuntime.close (e2b_runtime.py:L154-177) skips sandbox destruction if attach_to_existing was True, preserving sandboxes that were not created by this session. Otherwise, it calls the E2B SDK to kill the sandbox.
- ModalRuntime.close (modal_runtime.py:L266-271) unconditionally terminates the Modal sandbox via the Modal SDK's terminate method.
- RunloopRuntime.close (runloop_runtime.py:L174-181) shuts down the Runloop devbox, with the rm_all_containers flag controlling whether all associated containers are removed during cleanup.
All four runtimes share the goal of deterministic resource release: after close() returns, no provider resources should remain allocated (unless preservation is explicitly configured).
Usage
Call close() at the end of an agent session, or ensure it is called automatically via context managers or shutdown hooks. It must be called even if the session ended with an error, to prevent resource leaks.
Code Reference
Source Location
- Repository: OpenHands
- File:
third_party/runtime/impl/daytona/daytona_runtime.py - Lines: L250-266
Signature
def close(self) -> None:
Import
from third_party.runtime.impl.daytona.daytona_runtime import DaytonaRuntime
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| self | DaytonaRuntime | Yes | A DaytonaRuntime instance with an active or previously active sandbox |
Outputs
| Name | Type | Description |
|---|---|---|
| None | None | The method returns None. On success, the Daytona sandbox has been destroyed (or preserved if DAYTONA_KEEP_SANDBOX is set). Internal state references are reset. |
Usage Examples
Basic Usage
from third_party.runtime.impl.daytona.daytona_runtime import DaytonaRuntime
runtime = DaytonaRuntime(
config=openhands_config,
event_stream=event_stream,
sid="session-004",
)
await runtime.connect()
# ... perform agent actions ...
# Clean up the sandbox when done:
runtime.close()
Preserving Sandbox for Debugging
import os
# Set the environment variable before closing:
os.environ["DAYTONA_KEEP_SANDBOX"] = "1"
# close() will skip sandbox destruction and log
# that the sandbox is being preserved:
runtime.close()
# The sandbox remains running for manual inspection.
Error-Safe Cleanup
runtime = DaytonaRuntime(
config=openhands_config,
event_stream=event_stream,
)
await runtime.connect()
try:
# Perform agent actions that may raise exceptions:
observation = await runtime.run(action)
finally:
# Always clean up, even on error:
runtime.close()