Xingyao Wang c2f46200c0
chore(lint): Apply comprehensive linting and formatting fixes (#10287)
Co-authored-by: openhands <openhands@all-hands.dev>
2025-08-13 21:13:19 +02:00

120 lines
4.0 KiB
Python

import importlib
from openhands.runtime.base import Runtime
from openhands.runtime.impl.cli.cli_runtime import CLIRuntime
from openhands.runtime.impl.docker.docker_runtime import (
DockerRuntime,
)
from openhands.runtime.impl.kubernetes.kubernetes_runtime import KubernetesRuntime
from openhands.runtime.impl.local.local_runtime import LocalRuntime
from openhands.runtime.impl.remote.remote_runtime import RemoteRuntime
from openhands.utils.import_utils import get_impl
# mypy: disable-error-code="type-abstract"
_DEFAULT_RUNTIME_CLASSES: dict[str, type[Runtime]] = {
'eventstream': DockerRuntime,
'docker': DockerRuntime,
'remote': RemoteRuntime,
'local': LocalRuntime,
'kubernetes': KubernetesRuntime,
'cli': CLIRuntime,
}
# Try to import third-party runtimes if available
_THIRD_PARTY_RUNTIME_CLASSES: dict[str, type[Runtime]] = {}
# Dynamically discover and import third-party runtimes
# Check if third_party package exists and discover runtimes
try:
import third_party.runtime.impl
third_party_base = 'third_party.runtime.impl'
# List of potential third-party runtime modules to try
# These are discovered from the third_party directory structure
potential_runtimes = []
try:
import pkgutil
for importer, modname, ispkg in pkgutil.iter_modules(
third_party.runtime.impl.__path__
):
if ispkg:
potential_runtimes.append(modname)
except Exception:
# If discovery fails, no third-party runtimes will be loaded
potential_runtimes = []
# Try to import each discovered runtime
for runtime_name in potential_runtimes:
try:
module_path = f'{third_party_base}.{runtime_name}.{runtime_name}_runtime'
module = importlib.import_module(module_path)
# Try different class name patterns
possible_class_names = [
f'{runtime_name.upper()}Runtime', # E2BRuntime
f'{runtime_name.capitalize()}Runtime', # E2bRuntime, DaytonaRuntime, etc.
]
runtime_class = None
for class_name in possible_class_names:
try:
runtime_class = getattr(module, class_name)
break
except AttributeError:
continue
if runtime_class:
_THIRD_PARTY_RUNTIME_CLASSES[runtime_name] = runtime_class
except ImportError:
# ImportError means the library is not installed (expected for optional dependencies)
pass
except Exception as e:
# Other exceptions mean the library is present but broken, which should be logged
from openhands.core.logger import openhands_logger as logger
logger.warning(f'Failed to import third-party runtime {module_path}: {e}')
pass
except ImportError:
# third_party package not available
pass
# Combine core and third-party runtimes
_ALL_RUNTIME_CLASSES = {**_DEFAULT_RUNTIME_CLASSES, **_THIRD_PARTY_RUNTIME_CLASSES}
def get_runtime_cls(name: str) -> type[Runtime]:
"""If name is one of the predefined runtime names (e.g. 'docker'), return its class.
Otherwise attempt to resolve name as subclass of Runtime and return it.
Raise on invalid selections.
"""
if name in _ALL_RUNTIME_CLASSES:
return _ALL_RUNTIME_CLASSES[name]
try:
return get_impl(Runtime, name)
except Exception as e:
known_keys = _ALL_RUNTIME_CLASSES.keys()
raise ValueError(
f'Runtime {name} not supported, known are: {known_keys}'
) from e
# Build __all__ list dynamically based on available runtimes
__all__ = [
'Runtime',
'RemoteRuntime',
'DockerRuntime',
'KubernetesRuntime',
'CLIRuntime',
'LocalRuntime',
'get_runtime_cls',
]
# Add third-party runtimes to __all__ if they're available
for runtime_name, runtime_class in _THIRD_PARTY_RUNTIME_CLASSES.items():
__all__.append(runtime_class.__name__)