mirror of
https://github.com/OpenHands/OpenHands.git
synced 2025-12-26 05:48:36 +08:00
fix: daytona runtime sandbox handling (#9187)
Signed-off-by: Ivan Dagelic <dagelic.ivan@gmail.com>
This commit is contained in:
parent
30c71776e7
commit
bae6bd77f4
@ -1,14 +1,13 @@
|
||||
import json
|
||||
from typing import Callable
|
||||
|
||||
import httpx
|
||||
import tenacity
|
||||
from daytona_sdk import (
|
||||
CreateWorkspaceParams,
|
||||
from daytona import (
|
||||
CreateSandboxFromSnapshotParams,
|
||||
Daytona,
|
||||
DaytonaConfig,
|
||||
Sandbox,
|
||||
SessionExecuteRequest,
|
||||
Workspace,
|
||||
)
|
||||
|
||||
from openhands.core.config.openhands_config import OpenHandsConfig
|
||||
@ -24,11 +23,11 @@ from openhands.runtime.utils.request import RequestHTTPError
|
||||
from openhands.utils.async_utils import call_sync_from_async
|
||||
from openhands.utils.tenacity_stop import stop_if_should_exit
|
||||
|
||||
WORKSPACE_PREFIX = 'openhands-sandbox-'
|
||||
OPENHANDS_SID_LABEL = 'OpenHands_SID'
|
||||
|
||||
|
||||
class DaytonaRuntime(ActionExecutionClient):
|
||||
"""The DaytonaRuntime class is a DockerRuntime that utilizes Daytona workspace as a runtime environment."""
|
||||
"""The DaytonaRuntime class is a DockerRuntime that utilizes Daytona Sandboxes as runtime environments."""
|
||||
|
||||
_sandbox_port: int = 4444
|
||||
_vscode_port: int = 4445
|
||||
@ -50,8 +49,7 @@ class DaytonaRuntime(ActionExecutionClient):
|
||||
|
||||
self.config = config
|
||||
self.sid = sid
|
||||
self.workspace_id = WORKSPACE_PREFIX + sid
|
||||
self.workspace: Workspace | None = None
|
||||
self.sandbox: Sandbox | None = None
|
||||
self._vscode_url: str | None = None
|
||||
|
||||
daytona_config = DaytonaConfig(
|
||||
@ -81,20 +79,24 @@ class DaytonaRuntime(ActionExecutionClient):
|
||||
git_provider_tokens,
|
||||
)
|
||||
|
||||
def _get_workspace(self) -> Workspace | None:
|
||||
def _get_sandbox(self) -> Sandbox | None:
|
||||
try:
|
||||
workspace = self.daytona.get_current_workspace(self.workspace_id)
|
||||
self.log(
|
||||
'info', f'Attached to existing workspace with id: {self.workspace_id}'
|
||||
)
|
||||
sandboxes = self.daytona.list({OPENHANDS_SID_LABEL: self.sid})
|
||||
if len(sandboxes) == 0:
|
||||
return None
|
||||
assert len(sandboxes) == 1, 'Multiple sandboxes found for SID'
|
||||
|
||||
sandbox = sandboxes[0]
|
||||
|
||||
self.log('info', f'Attached to existing sandbox with id: {self.sid}')
|
||||
except Exception:
|
||||
self.log(
|
||||
'warning',
|
||||
f'Failed to attach to existing workspace with id: {self.workspace_id}',
|
||||
f'Failed to attach to existing sandbox with id: {self.sid}',
|
||||
)
|
||||
workspace = None
|
||||
sandbox = None
|
||||
|
||||
return workspace
|
||||
return sandbox
|
||||
|
||||
def _get_creation_env_vars(self) -> dict[str, str]:
|
||||
env_vars: dict[str, str] = {
|
||||
@ -108,37 +110,28 @@ class DaytonaRuntime(ActionExecutionClient):
|
||||
|
||||
return env_vars
|
||||
|
||||
def _create_workspace(self) -> Workspace:
|
||||
workspace_params = CreateWorkspaceParams(
|
||||
id=self.workspace_id,
|
||||
def _create_sandbox(self) -> Sandbox:
|
||||
sandbox_params = CreateSandboxFromSnapshotParams(
|
||||
language='python',
|
||||
image=self.config.sandbox.runtime_container_image,
|
||||
snapshot=self.config.sandbox.runtime_container_image,
|
||||
public=True,
|
||||
env_vars=self._get_creation_env_vars(),
|
||||
labels={OPENHANDS_SID_LABEL: self.sid},
|
||||
)
|
||||
workspace = self.daytona.create(workspace_params)
|
||||
return workspace
|
||||
return self.daytona.create(sandbox_params)
|
||||
|
||||
def _construct_api_url(self, port: int) -> str:
|
||||
assert self.workspace is not None, 'Workspace is not initialized'
|
||||
assert self.workspace.instance.info is not None, (
|
||||
'Workspace info is not available'
|
||||
)
|
||||
assert self.workspace.instance.info.provider_metadata is not None, (
|
||||
'Provider metadata is not available'
|
||||
)
|
||||
assert self.sandbox is not None, 'Sandbox is not initialized'
|
||||
assert self.sandbox.runner_domain is not None, 'Runner domain is not available'
|
||||
|
||||
node_domain = json.loads(self.workspace.instance.info.provider_metadata)[
|
||||
'nodeDomain'
|
||||
]
|
||||
return f'https://{port}-{self.workspace.id}.{node_domain}'
|
||||
return f'https://{port}-{self.sandbox.id}.{self.sandbox.runner_domain}'
|
||||
|
||||
@property
|
||||
def action_execution_server_url(self) -> str:
|
||||
return self.api_url
|
||||
|
||||
def _start_action_execution_server(self) -> None:
|
||||
assert self.workspace is not None, 'Workspace is not initialized'
|
||||
assert self.sandbox is not None, 'Sandbox is not initialized'
|
||||
|
||||
start_command: list[str] = get_action_execution_server_startup_command(
|
||||
server_port=self._sandbox_port,
|
||||
@ -158,9 +151,9 @@ class DaytonaRuntime(ActionExecutionClient):
|
||||
)
|
||||
|
||||
exec_session_id = 'action-execution-server'
|
||||
self.workspace.process.create_session(exec_session_id)
|
||||
self.sandbox.process.create_session(exec_session_id)
|
||||
|
||||
exec_command = self.workspace.process.execute_session_command(
|
||||
exec_command = self.sandbox.process.execute_session_command(
|
||||
exec_session_id,
|
||||
SessionExecuteRequest(command=start_command_str, var_async=True),
|
||||
)
|
||||
@ -180,27 +173,27 @@ class DaytonaRuntime(ActionExecutionClient):
|
||||
should_start_action_execution_server = False
|
||||
|
||||
if self.attach_to_existing:
|
||||
self.workspace = await call_sync_from_async(self._get_workspace)
|
||||
self.sandbox = await call_sync_from_async(self._get_sandbox)
|
||||
else:
|
||||
should_start_action_execution_server = True
|
||||
|
||||
if self.workspace is None:
|
||||
if self.sandbox is None:
|
||||
self.set_runtime_status(RuntimeStatus.BUILDING_RUNTIME)
|
||||
self.workspace = await call_sync_from_async(self._create_workspace)
|
||||
self.log('info', f'Created new workspace with id: {self.workspace_id}')
|
||||
self.sandbox = await call_sync_from_async(self._create_sandbox)
|
||||
self.log('info', f'Created a new sandbox with id: {self.sid}')
|
||||
|
||||
self.api_url = self._construct_api_url(self._sandbox_port)
|
||||
|
||||
state = self.workspace.instance.state
|
||||
state = self.sandbox.state
|
||||
|
||||
if state == 'stopping':
|
||||
self.log('info', 'Waiting for Daytona workspace to stop...')
|
||||
await call_sync_from_async(self.workspace.wait_for_workspace_stop)
|
||||
self.log('info', 'Waiting for the Daytona sandbox to stop...')
|
||||
await call_sync_from_async(self.sandbox.wait_for_sandbox_stop)
|
||||
state = 'stopped'
|
||||
|
||||
if state == 'stopped':
|
||||
self.log('info', 'Starting Daytona workspace...')
|
||||
await call_sync_from_async(self.workspace.start)
|
||||
self.log('info', 'Starting the Daytona sandbox...')
|
||||
await call_sync_from_async(self.sandbox.start)
|
||||
should_start_action_execution_server = True
|
||||
|
||||
if should_start_action_execution_server:
|
||||
@ -247,8 +240,8 @@ class DaytonaRuntime(ActionExecutionClient):
|
||||
if self.attach_to_existing:
|
||||
return
|
||||
|
||||
if self.workspace:
|
||||
self.daytona.remove(self.workspace)
|
||||
if self.sandbox:
|
||||
self.sandbox.delete()
|
||||
|
||||
@property
|
||||
def vscode_url(self) -> str | None:
|
||||
@ -260,9 +253,9 @@ class DaytonaRuntime(ActionExecutionClient):
|
||||
'warning', 'Failed to get VSCode token while trying to get VSCode URL'
|
||||
)
|
||||
return None
|
||||
if not self.workspace:
|
||||
if not self.sandbox:
|
||||
self.log(
|
||||
'warning', 'Workspace is not initialized while trying to get VSCode URL'
|
||||
'warning', 'Sandbox is not initialized while trying to get VSCode URL'
|
||||
)
|
||||
return None
|
||||
self._vscode_url = (
|
||||
|
||||
188
poetry.lock
generated
188
poetry.lock
generated
@ -1,4 +1,50 @@
|
||||
# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand.
|
||||
# This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "aioboto3"
|
||||
version = "14.3.0"
|
||||
description = "Async boto3 wrapper"
|
||||
optional = false
|
||||
python-versions = "<4.0,>=3.8"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "aioboto3-14.3.0-py3-none-any.whl", hash = "sha256:aec5de94e9edc1ffbdd58eead38a37f00ddac59a519db749a910c20b7b81bca7"},
|
||||
{file = "aioboto3-14.3.0.tar.gz", hash = "sha256:1d18f88bb56835c607b62bb6cb907754d717bedde3ddfff6935727cb48a80135"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
aiobotocore = {version = "2.22.0", extras = ["boto3"]}
|
||||
aiofiles = ">=23.2.1"
|
||||
|
||||
[package.extras]
|
||||
chalice = ["chalice (>=1.24.0)"]
|
||||
s3cse = ["cryptography (>=44.0.1)"]
|
||||
|
||||
[[package]]
|
||||
name = "aiobotocore"
|
||||
version = "2.22.0"
|
||||
description = "Async client for aws services using botocore and aiohttp"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "aiobotocore-2.22.0-py3-none-any.whl", hash = "sha256:b4e6306f79df9d81daff1f9d63189a2dbee4b77ce3ab937304834e35eaaeeccf"},
|
||||
{file = "aiobotocore-2.22.0.tar.gz", hash = "sha256:11091477266b75c2b5d28421c1f2bc9a87d175d0b8619cb830805e7a113a170b"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
aiohttp = ">=3.9.2,<4.0.0"
|
||||
aioitertools = ">=0.5.1,<1.0.0"
|
||||
boto3 = {version = ">=1.37.2,<1.37.4", optional = true, markers = "extra == \"boto3\""}
|
||||
botocore = ">=1.37.2,<1.37.4"
|
||||
jmespath = ">=0.7.1,<2.0.0"
|
||||
multidict = ">=6.0.0,<7.0.0"
|
||||
python-dateutil = ">=2.1,<3.0.0"
|
||||
wrapt = ">=1.10.10,<2.0.0"
|
||||
|
||||
[package.extras]
|
||||
awscli = ["awscli (>=1.38.2,<1.38.4)"]
|
||||
boto3 = ["boto3 (>=1.37.2,<1.37.4)"]
|
||||
|
||||
[[package]]
|
||||
name = "aiofiles"
|
||||
@ -147,6 +193,22 @@ files = [
|
||||
[package.dependencies]
|
||||
aiohttp = "*"
|
||||
|
||||
[[package]]
|
||||
name = "aioitertools"
|
||||
version = "0.12.0"
|
||||
description = "itertools and builtins for AsyncIO and mixed iterables"
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "aioitertools-0.12.0-py3-none-any.whl", hash = "sha256:fc1f5fac3d737354de8831cbba3eb04f79dd649d8f3afb4c5b114925e662a796"},
|
||||
{file = "aioitertools-0.12.0.tar.gz", hash = "sha256:c2a9055b4fbb7705f561b9d86053e8af5d10cc845d22c32008c43490b2d8dd6b"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
dev = ["attribution (==1.8.0)", "black (==24.8.0)", "build (>=1.2)", "coverage (==7.6.1)", "flake8 (==7.1.1)", "flit (==3.9.0)", "mypy (==1.11.2)", "ufmt (==2.7.1)", "usort (==1.0.8.post1)"]
|
||||
docs = ["sphinx (==8.0.2)", "sphinx-mdinclude (==0.6.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "aiolimiter"
|
||||
version = "1.2.1"
|
||||
@ -400,7 +462,7 @@ description = "LTS Port of Python audioop"
|
||||
optional = false
|
||||
python-versions = ">=3.13"
|
||||
groups = ["main"]
|
||||
markers = "python_version >= \"3.13\""
|
||||
markers = "python_version == \"3.13\""
|
||||
files = [
|
||||
{file = "audioop_lts-0.2.1-cp313-abi3-macosx_10_13_universal2.whl", hash = "sha256:fd1345ae99e17e6910f47ce7d52673c6a1a70820d78b67de1b7abb3af29c426a"},
|
||||
{file = "audioop_lts-0.2.1-cp313-abi3-macosx_10_13_x86_64.whl", hash = "sha256:e175350da05d2087e12cea8e72a70a1a8b14a17e92ed2022952a4419689ede5e"},
|
||||
@ -581,20 +643,20 @@ files = [
|
||||
|
||||
[[package]]
|
||||
name = "boto3"
|
||||
version = "1.38.36"
|
||||
version = "1.37.3"
|
||||
description = "The AWS SDK for Python"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
python-versions = ">=3.8"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "boto3-1.38.36-py3-none-any.whl", hash = "sha256:34c27d7317cadb62c0e9856e5d5aa0271ef47202d340584831048bc7ac904136"},
|
||||
{file = "boto3-1.38.36.tar.gz", hash = "sha256:efe0aaa060f8fedd76e5c942055f051aee0432fc722d79d8830a9fd9db83593e"},
|
||||
{file = "boto3-1.37.3-py3-none-any.whl", hash = "sha256:2063b40af99fd02f6228ff52397b552ff3353831edaf8d25cc04801827ab9794"},
|
||||
{file = "boto3-1.37.3.tar.gz", hash = "sha256:21f3ce0ef111297e63a6eb998a25197b8c10982970c320d4c6e8db08be2157be"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
botocore = ">=1.38.36,<1.39.0"
|
||||
botocore = ">=1.37.3,<1.38.0"
|
||||
jmespath = ">=0.7.1,<2.0.0"
|
||||
s3transfer = ">=0.13.0,<0.14.0"
|
||||
s3transfer = ">=0.11.0,<0.12.0"
|
||||
|
||||
[package.extras]
|
||||
crt = ["botocore[crt] (>=1.21.0,<2.0a0)"]
|
||||
@ -1028,14 +1090,14 @@ xray = ["mypy-boto3-xray (>=1.38.0,<1.39.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "botocore"
|
||||
version = "1.38.36"
|
||||
version = "1.37.3"
|
||||
description = "Low-level, data-driven core of boto 3."
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
python-versions = ">=3.8"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "botocore-1.38.36-py3-none-any.whl", hash = "sha256:b6a50b853f6d23af9edfed89a59800c6bc1687a947cdd3492879f7d64e002d30"},
|
||||
{file = "botocore-1.38.36.tar.gz", hash = "sha256:4a1ced1a4218bdff0ed5b46abb54570d473154ddefafa5d121a8d96e4b76ebc1"},
|
||||
{file = "botocore-1.37.3-py3-none-any.whl", hash = "sha256:d01bd3bf4c80e61fa88d636ad9f5c9f60a551d71549b481386c6b4efe0bb2b2e"},
|
||||
{file = "botocore-1.37.3.tar.gz", hash = "sha256:fe8403eb55a88faf9b0f9da6615e5bee7be056d75e17af66c3c8f0a3b0648da4"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -1580,7 +1642,7 @@ files = [
|
||||
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
|
||||
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
||||
]
|
||||
markers = {main = "platform_system == \"Windows\" or sys_platform == \"win32\" or os_name == \"nt\"", dev = "os_name == \"nt\" or sys_platform == \"win32\"", runtime = "sys_platform == \"win32\"", test = "platform_system == \"Windows\" or sys_platform == \"win32\""}
|
||||
markers = {main = "platform_system == \"Windows\" or os_name == \"nt\" or sys_platform == \"win32\"", dev = "os_name == \"nt\" or sys_platform == \"win32\"", runtime = "sys_platform == \"win32\"", test = "platform_system == \"Windows\" or sys_platform == \"win32\""}
|
||||
|
||||
[[package]]
|
||||
name = "comm"
|
||||
@ -1932,16 +1994,48 @@ tests-numpy2 = ["Pillow (>=9.4.0)", "absl-py", "decorator", "elasticsearch (<8.0
|
||||
torch = ["torch"]
|
||||
vision = ["Pillow (>=9.4.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "daytona"
|
||||
version = "0.21.1"
|
||||
description = "Python SDK for Daytona"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "daytona-0.21.1-py3-none-any.whl", hash = "sha256:1ce6b352f52ef92e667098b7bdaa60c22ffbfb8e686a8cbd12418bf7698ac834"},
|
||||
{file = "daytona-0.21.1.tar.gz", hash = "sha256:01d83dd2b627f87e82491fb97f41845768d75c33f0767eaa44f6e8378bd58e60"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
aioboto3 = ">=14.0.0,<15.0.0"
|
||||
aiofiles = ">=24.1.0,<24.2.0"
|
||||
aiohttp = ">=3.12.0,<4.0.0"
|
||||
aiohttp_retry = ">=2.9.0,<3.0.0"
|
||||
boto3 = ">=1.0.0,<2.0.0"
|
||||
daytona_api_client = ">=0.21.0,<0.22.0"
|
||||
daytona_api_client_async = ">=0.21.0,<0.22.0"
|
||||
Deprecated = ">=1.2.18,<2.0.0"
|
||||
environs = ">=9.5.0,<10.0.0"
|
||||
httpx = ">=0.28.0,<0.29.0"
|
||||
marshmallow = ">=3.19.0,<4.0.0"
|
||||
pydantic = ">=2.4.2,<3.0.0"
|
||||
python-dateutil = ">=2.8.2,<3.0.0"
|
||||
toml = ">=0.10.0,<0.11.0"
|
||||
urllib3 = ">=2.0.7,<3.0.0"
|
||||
|
||||
[package.extras]
|
||||
dev = ["black[jupyter] (>=23.1.0,<24.0.0)", "build (>=1.0.3)", "isort (>=5.10.0,<6.0.0)", "matplotlib (>=3.10.0,<3.11.0)", "nbqa (>=1.9.1,<2.0.0)", "pydoc-markdown (>=4.8.2)", "pylint (>=3.3.4,<4.0.0)", "setuptools (>=68.0.0)", "twine (>=4.0.2)", "unasync (>=0.6.0,<0.7.0)", "wheel (>=0.41.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "daytona-api-client"
|
||||
version = "0.20.1"
|
||||
version = "0.21.0"
|
||||
description = "Daytona"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "daytona_api_client-0.20.1-py3-none-any.whl", hash = "sha256:4d5023108013365eba76bd0bd4704f30dee54c13e2ac5b62e8c88bcd4af5db92"},
|
||||
{file = "daytona_api_client-0.20.1.tar.gz", hash = "sha256:ff2061f7e7dc9c935a9087216600be277cb9cf6b8c1eecdfe333ef30d6b208fd"},
|
||||
{file = "daytona_api_client-0.21.0-py3-none-any.whl", hash = "sha256:a8ff1f0fb397368dbd6ddb224c28d679e599c657eab2ec5821cf0c972a60229a"},
|
||||
{file = "daytona_api_client-0.21.0.tar.gz", hash = "sha256:92d591c5a1750a827b5850425ce483441609b72b05d35a618d5353fbbba50bca"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -1952,14 +2046,14 @@ urllib3 = ">=1.25.3,<3.0.0"
|
||||
|
||||
[[package]]
|
||||
name = "daytona-api-client-async"
|
||||
version = "0.20.1"
|
||||
version = "0.21.0"
|
||||
description = "Daytona"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "daytona_api_client_async-0.20.1-py3-none-any.whl", hash = "sha256:f24e06e3ab6e554214ed064f1b4c8723356c76c14c69de9a73a6cad60a386127"},
|
||||
{file = "daytona_api_client_async-0.20.1.tar.gz", hash = "sha256:043045cb173b0b53416c19a9e276124a5c4fe14209f409a8572ef1975240e53f"},
|
||||
{file = "daytona_api_client_async-0.21.0-py3-none-any.whl", hash = "sha256:f5731963d0dd6c1e207b92bdc7f5b59952d3365444bc9dc8b013d77a4dddf377"},
|
||||
{file = "daytona_api_client_async-0.21.0.tar.gz", hash = "sha256:08a22c0d1616f82efa8d157d7be6c432554fd43d75560725c4e0cef0228607d6"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -1970,35 +2064,6 @@ python-dateutil = ">=2.8.2"
|
||||
typing-extensions = ">=4.7.1"
|
||||
urllib3 = ">=1.25.3,<3.0.0"
|
||||
|
||||
[[package]]
|
||||
name = "daytona-sdk"
|
||||
version = "0.20.0"
|
||||
description = "Python SDK for Daytona"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "daytona_sdk-0.20.0-py3-none-any.whl", hash = "sha256:7919acfff21c072a0ea826a3b250c0d9c5765e58c054d2bd5b91ea76f0df4709"},
|
||||
{file = "daytona_sdk-0.20.0.tar.gz", hash = "sha256:b5c13b999fcce1e6460974dbbb0dd336d8ca1e96d6a25afe705f476fba4e6f11"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
aiofiles = ">=24.1.0,<24.2.0"
|
||||
aiohttp = ">=3.12.0,<4.0.0"
|
||||
aiohttp_retry = ">=2.9.0,<3.0.0"
|
||||
daytona_api_client = ">=0.20.0,<0.21.0"
|
||||
daytona_api_client_async = ">=0.20.0,<0.21.0"
|
||||
Deprecated = ">=1.2.18,<2.0.0"
|
||||
environs = ">=9.5.0,<10.0.0"
|
||||
httpx = ">=0.28.0,<0.29.0"
|
||||
marshmallow = ">=3.19.0,<4.0.0"
|
||||
pydantic = ">=2.4.2,<3.0.0"
|
||||
python-dateutil = ">=2.8.2,<3.0.0"
|
||||
urllib3 = ">=2.0.7,<3.0.0"
|
||||
|
||||
[package.extras]
|
||||
dev = ["black[jupyter] (>=23.1.0,<24.0.0)", "build (>=1.0.3)", "isort (>=5.10.0,<6.0.0)", "matplotlib (>=3.10.0,<3.11.0)", "nbqa (>=1.9.1,<2.0.0)", "pydoc-markdown (>=4.8.2)", "pylint (>=3.3.4,<4.0.0)", "setuptools (>=68.0.0)", "twine (>=4.0.2)", "unasync (>=0.6.0,<0.7.0)", "wheel (>=0.41.2)"]
|
||||
|
||||
[[package]]
|
||||
name = "debugpy"
|
||||
version = "1.8.14"
|
||||
@ -2974,8 +3039,8 @@ files = [
|
||||
google-api-core = {version = ">=1.34.1,<2.0.dev0 || >=2.11.dev0,<3.0.0dev", extras = ["grpc"]}
|
||||
google-auth = ">=2.14.1,<2.24.0 || >2.24.0,<2.25.0 || >2.25.0,<3.0.0dev"
|
||||
proto-plus = [
|
||||
{version = ">=1.22.3,<2.0.0dev"},
|
||||
{version = ">=1.25.0,<2.0.0dev", markers = "python_version >= \"3.13\""},
|
||||
{version = ">=1.22.3,<2.0.0dev"},
|
||||
]
|
||||
protobuf = ">=3.20.2,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<6.0.0dev"
|
||||
|
||||
@ -2997,8 +3062,8 @@ googleapis-common-protos = ">=1.56.2,<2.0.0"
|
||||
grpcio = {version = ">=1.49.1,<2.0.0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}
|
||||
grpcio-status = {version = ">=1.49.1,<2.0.0", optional = true, markers = "python_version >= \"3.11\" and extra == \"grpc\""}
|
||||
proto-plus = [
|
||||
{version = ">=1.22.3,<2.0.0"},
|
||||
{version = ">=1.25.0,<2.0.0", markers = "python_version >= \"3.13\""},
|
||||
{version = ">=1.22.3,<2.0.0"},
|
||||
]
|
||||
protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<7.0.0"
|
||||
requests = ">=2.18.0,<3.0.0"
|
||||
@ -3216,8 +3281,8 @@ google-api-core = {version = ">=1.34.1,<2.0.dev0 || >=2.11.dev0,<3.0.0", extras
|
||||
google-auth = ">=2.14.1,<2.24.0 || >2.24.0,<2.25.0 || >2.25.0,<3.0.0"
|
||||
grpc-google-iam-v1 = ">=0.14.0,<1.0.0"
|
||||
proto-plus = [
|
||||
{version = ">=1.22.3,<2.0.0"},
|
||||
{version = ">=1.25.0,<2.0.0", markers = "python_version >= \"3.13\""},
|
||||
{version = ">=1.22.3,<2.0.0"},
|
||||
]
|
||||
protobuf = ">=3.20.2,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<7.0.0"
|
||||
|
||||
@ -6479,8 +6544,8 @@ files = [
|
||||
[package.dependencies]
|
||||
googleapis-common-protos = ">=1.52,<2.0"
|
||||
grpcio = [
|
||||
{version = ">=1.63.2,<2.0.0", markers = "python_version < \"3.13\""},
|
||||
{version = ">=1.66.2,<2.0.0", markers = "python_version >= \"3.13\""},
|
||||
{version = ">=1.63.2,<2.0.0", markers = "python_version < \"3.13\""},
|
||||
]
|
||||
opentelemetry-api = ">=1.15,<2.0"
|
||||
opentelemetry-exporter-otlp-proto-common = "1.34.1"
|
||||
@ -8967,21 +9032,21 @@ typing-extensions = ">=4.10,<5"
|
||||
|
||||
[[package]]
|
||||
name = "s3transfer"
|
||||
version = "0.13.0"
|
||||
version = "0.11.3"
|
||||
description = "An Amazon S3 Transfer Manager"
|
||||
optional = false
|
||||
python-versions = ">=3.9"
|
||||
python-versions = ">=3.8"
|
||||
groups = ["main"]
|
||||
files = [
|
||||
{file = "s3transfer-0.13.0-py3-none-any.whl", hash = "sha256:0148ef34d6dd964d0d8cf4311b2b21c474693e57c2e069ec708ce043d2b527be"},
|
||||
{file = "s3transfer-0.13.0.tar.gz", hash = "sha256:f5e6db74eb7776a37208001113ea7aa97695368242b364d73e91c981ac522177"},
|
||||
{file = "s3transfer-0.11.3-py3-none-any.whl", hash = "sha256:ca855bdeb885174b5ffa95b9913622459d4ad8e331fc98eb01e6d5eb6a30655d"},
|
||||
{file = "s3transfer-0.11.3.tar.gz", hash = "sha256:edae4977e3a122445660c7c114bba949f9d191bae3b34a096f18a1c8c354527a"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
botocore = ">=1.37.4,<2.0a.0"
|
||||
botocore = ">=1.36.0,<2.0a.0"
|
||||
|
||||
[package.extras]
|
||||
crt = ["botocore[crt] (>=1.37.4,<2.0a.0)"]
|
||||
crt = ["botocore[crt] (>=1.36.0,<2.0a.0)"]
|
||||
|
||||
[[package]]
|
||||
name = "sacrebleu"
|
||||
@ -9243,7 +9308,6 @@ files = [
|
||||
{file = "setuptools-80.9.0-py3-none-any.whl", hash = "sha256:062d34222ad13e0cc312a4c02d73f059e86a4acbfbdea8f8f76b28c99f306922"},
|
||||
{file = "setuptools-80.9.0.tar.gz", hash = "sha256:f36b47402ecde768dbfafc46e8e4207b4360c654f1f3bb84475f0a28628fb19c"},
|
||||
]
|
||||
markers = {evaluation = "platform_system == \"Linux\" and platform_machine == \"x86_64\""}
|
||||
|
||||
[package.extras]
|
||||
check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\"", "ruff (>=0.8.0) ; sys_platform != \"cygwin\""]
|
||||
@ -9486,7 +9550,7 @@ description = "Standard library aifc redistribution. \"dead battery\"."
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
groups = ["main"]
|
||||
markers = "python_version >= \"3.13\""
|
||||
markers = "python_version == \"3.13\""
|
||||
files = [
|
||||
{file = "standard_aifc-3.13.0-py3-none-any.whl", hash = "sha256:f7ae09cc57de1224a0dd8e3eb8f73830be7c3d0bc485de4c1f82b4a7f645ac66"},
|
||||
{file = "standard_aifc-3.13.0.tar.gz", hash = "sha256:64e249c7cb4b3daf2fdba4e95721f811bde8bdfc43ad9f936589b7bb2fae2e43"},
|
||||
@ -9503,7 +9567,7 @@ description = "Standard library chunk redistribution. \"dead battery\"."
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
groups = ["main"]
|
||||
markers = "python_version >= \"3.13\""
|
||||
markers = "python_version == \"3.13\""
|
||||
files = [
|
||||
{file = "standard_chunk-3.13.0-py3-none-any.whl", hash = "sha256:17880a26c285189c644bd5bd8f8ed2bdb795d216e3293e6dbe55bbd848e2982c"},
|
||||
{file = "standard_chunk-3.13.0.tar.gz", hash = "sha256:4ac345d37d7e686d2755e01836b8d98eda0d1a3ee90375e597ae43aaf064d654"},
|
||||
@ -11665,4 +11729,4 @@ cffi = ["cffi (>=1.11)"]
|
||||
[metadata]
|
||||
lock-version = "2.1"
|
||||
python-versions = "^3.12,<3.14"
|
||||
content-hash = "47df4fc76b97147ff31169028edafaf35c1f4e661c7ab74bad48cb0ceea06aba"
|
||||
content-hash = "df8217d9808a5a1f5886e0328cbeb5032b20c28a677154888bd010f7bc945cb2"
|
||||
|
||||
@ -80,7 +80,7 @@ bashlex = "^0.18"
|
||||
# TODO: These are integrations that should probably be optional
|
||||
redis = ">=5.2,<7.0"
|
||||
minio = "^7.2.8"
|
||||
daytona-sdk = "0.20.0"
|
||||
daytona = "0.21.1"
|
||||
stripe = ">=11.5,<13.0"
|
||||
google-cloud-aiplatform = "*"
|
||||
anthropic = { extras = [ "vertex" ], version = "*" }
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user