cua-computer 0.4.6__tar.gz → 0.4.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {cua_computer-0.4.6 → cua_computer-0.4.8}/PKG-INFO +1 -1
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/computer.py +51 -25
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/providers/docker/provider.py +28 -8
- {cua_computer-0.4.6 → cua_computer-0.4.8}/pyproject.toml +3 -3
- {cua_computer-0.4.6 → cua_computer-0.4.8}/README.md +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/__init__.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/diorama_computer.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/helpers.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/interface/__init__.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/interface/base.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/interface/factory.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/interface/generic.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/interface/linux.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/interface/macos.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/interface/models.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/interface/windows.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/logger.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/models.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/providers/__init__.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/providers/base.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/providers/cloud/__init__.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/providers/cloud/provider.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/providers/docker/__init__.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/providers/factory.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/providers/lume/__init__.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/providers/lume/provider.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/providers/lume_api.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/providers/lumier/__init__.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/providers/lumier/provider.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/providers/winsandbox/__init__.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/providers/winsandbox/provider.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/providers/winsandbox/setup_script.ps1 +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/ui/__init__.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/ui/__main__.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/ui/gradio/__init__.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/ui/gradio/app.py +0 -0
- {cua_computer-0.4.6 → cua_computer-0.4.8}/computer/utils.py +0 -0
@@ -794,19 +794,33 @@ class Computer:
|
|
794
794
|
Tuple of (stdout, stderr) from the installation command
|
795
795
|
"""
|
796
796
|
requirements = requirements or []
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
|
797
|
+
# Windows vs POSIX handling
|
798
|
+
if self.os_type == "windows":
|
799
|
+
# Use %USERPROFILE% for home directory and cmd.exe semantics
|
800
|
+
venv_path = f"%USERPROFILE%\\.venvs\\{venv_name}"
|
801
|
+
ensure_dir_cmd = "if not exist \"%USERPROFILE%\\.venvs\" mkdir \"%USERPROFILE%\\.venvs\""
|
802
|
+
create_cmd = f"if not exist \"{venv_path}\" python -m venv \"{venv_path}\""
|
803
|
+
requirements_str = " ".join(requirements)
|
804
|
+
# Activate via activate.bat and install
|
805
|
+
install_cmd = f"call \"{venv_path}\\Scripts\\activate.bat\" && pip install {requirements_str}" if requirements_str else f"echo No requirements to install"
|
806
|
+
await self.interface.run_command(ensure_dir_cmd)
|
807
|
+
await self.interface.run_command(create_cmd)
|
808
|
+
return await self.interface.run_command(install_cmd)
|
809
|
+
else:
|
810
|
+
# POSIX (macOS/Linux)
|
811
|
+
venv_path = f"$HOME/.venvs/{venv_name}"
|
812
|
+
create_cmd = f"mkdir -p \"$HOME/.venvs\" && python3 -m venv \"{venv_path}\""
|
813
|
+
# Check if venv exists, if not create it
|
814
|
+
check_cmd = f"test -d \"{venv_path}\" || ({create_cmd})"
|
815
|
+
_ = await self.interface.run_command(check_cmd)
|
816
|
+
# Install packages
|
817
|
+
requirements_str = " ".join(requirements)
|
818
|
+
install_cmd = (
|
819
|
+
f". \"{venv_path}/bin/activate\" && pip install {requirements_str}"
|
820
|
+
if requirements_str
|
821
|
+
else "echo No requirements to install"
|
822
|
+
)
|
823
|
+
return await self.interface.run_command(install_cmd)
|
810
824
|
|
811
825
|
async def venv_cmd(self, venv_name: str, command: str):
|
812
826
|
"""Execute a shell command in a virtual environment.
|
@@ -818,18 +832,30 @@ class Computer:
|
|
818
832
|
Returns:
|
819
833
|
Tuple of (stdout, stderr) from the command execution
|
820
834
|
"""
|
821
|
-
|
822
|
-
|
823
|
-
|
824
|
-
|
825
|
-
|
826
|
-
|
827
|
-
|
828
|
-
|
829
|
-
|
830
|
-
|
831
|
-
|
832
|
-
|
835
|
+
if self.os_type == "windows":
|
836
|
+
# Windows (cmd.exe)
|
837
|
+
venv_path = f"%USERPROFILE%\\.venvs\\{venv_name}"
|
838
|
+
# Check existence and signal if missing
|
839
|
+
check_cmd = f"if not exist \"{venv_path}\" (echo VENV_NOT_FOUND) else (echo VENV_FOUND)"
|
840
|
+
result = await self.interface.run_command(check_cmd)
|
841
|
+
if "VENV_NOT_FOUND" in getattr(result, "stdout", ""):
|
842
|
+
# Auto-create the venv with no requirements
|
843
|
+
await self.venv_install(venv_name, [])
|
844
|
+
# Activate and run the command
|
845
|
+
full_command = f"call \"{venv_path}\\Scripts\\activate.bat\" && {command}"
|
846
|
+
return await self.interface.run_command(full_command)
|
847
|
+
else:
|
848
|
+
# POSIX (macOS/Linux)
|
849
|
+
venv_path = f"$HOME/.venvs/{venv_name}"
|
850
|
+
# Check if virtual environment exists
|
851
|
+
check_cmd = f"test -d \"{venv_path}\""
|
852
|
+
result = await self.interface.run_command(check_cmd)
|
853
|
+
if result.stderr or "test:" in result.stdout: # venv doesn't exist
|
854
|
+
# Auto-create the venv with no requirements
|
855
|
+
await self.venv_install(venv_name, [])
|
856
|
+
# Activate virtual environment and run command
|
857
|
+
full_command = f". \"{venv_path}/bin/activate\" && {command}"
|
858
|
+
return await self.interface.run_command(full_command)
|
833
859
|
|
834
860
|
async def venv_exec(self, venv_name: str, python_func, *args, **kwargs):
|
835
861
|
"""Execute Python function in a virtual environment using source code extraction.
|
@@ -36,7 +36,7 @@ class DockerProvider(BaseVMProvider):
|
|
36
36
|
"""
|
37
37
|
|
38
38
|
def __init__(
|
39
|
-
self,
|
39
|
+
self,
|
40
40
|
port: Optional[int] = 8000,
|
41
41
|
host: str = "localhost",
|
42
42
|
storage: Optional[str] = None,
|
@@ -47,13 +47,16 @@ class DockerProvider(BaseVMProvider):
|
|
47
47
|
vnc_port: Optional[int] = 6901,
|
48
48
|
):
|
49
49
|
"""Initialize the Docker VM Provider.
|
50
|
-
|
50
|
+
|
51
51
|
Args:
|
52
52
|
port: Currently unused (VM provider port)
|
53
53
|
host: Hostname for the API server (default: localhost)
|
54
54
|
storage: Path for persistent VM storage
|
55
55
|
shared_path: Path for shared folder between host and container
|
56
56
|
image: Docker image to use (default: "trycua/cua-ubuntu:latest")
|
57
|
+
Supported images:
|
58
|
+
- "trycua/cua-ubuntu:latest" (Kasm-based)
|
59
|
+
- "trycua/cua-docker-xfce:latest" (vanilla XFCE)
|
57
60
|
verbose: Enable verbose logging
|
58
61
|
ephemeral: Use ephemeral (temporary) storage
|
59
62
|
vnc_port: Port for VNC interface (default: 6901)
|
@@ -62,19 +65,35 @@ class DockerProvider(BaseVMProvider):
|
|
62
65
|
self.api_port = 8000
|
63
66
|
self.vnc_port = vnc_port
|
64
67
|
self.ephemeral = ephemeral
|
65
|
-
|
68
|
+
|
66
69
|
# Handle ephemeral storage (temporary directory)
|
67
70
|
if ephemeral:
|
68
71
|
self.storage = "ephemeral"
|
69
72
|
else:
|
70
73
|
self.storage = storage
|
71
|
-
|
74
|
+
|
72
75
|
self.shared_path = shared_path
|
73
76
|
self.image = image
|
74
77
|
self.verbose = verbose
|
75
78
|
self._container_id = None
|
76
79
|
self._running_containers = {} # Track running containers by name
|
80
|
+
|
81
|
+
# Detect image type and configure user directory accordingly
|
82
|
+
self._detect_image_config()
|
77
83
|
|
84
|
+
def _detect_image_config(self):
|
85
|
+
"""Detect image type and configure paths accordingly."""
|
86
|
+
# Detect if this is a docker-xfce image or Kasm image
|
87
|
+
if "docker-xfce" in self.image.lower() or "xfce" in self.image.lower():
|
88
|
+
self._home_dir = "/home/cua"
|
89
|
+
self._image_type = "docker-xfce"
|
90
|
+
logger.info(f"Detected docker-xfce image: using {self._home_dir}")
|
91
|
+
else:
|
92
|
+
# Default to Kasm configuration
|
93
|
+
self._home_dir = "/home/kasm-user"
|
94
|
+
self._image_type = "kasm"
|
95
|
+
logger.info(f"Detected Kasm image: using {self._home_dir}")
|
96
|
+
|
78
97
|
@property
|
79
98
|
def provider_type(self) -> VMProviderType:
|
80
99
|
"""Return the provider type."""
|
@@ -277,12 +296,13 @@ class DockerProvider(BaseVMProvider):
|
|
277
296
|
# Add volume mounts if storage is specified
|
278
297
|
storage_path = storage or self.storage
|
279
298
|
if storage_path and storage_path != "ephemeral":
|
280
|
-
# Mount storage directory
|
281
|
-
cmd.extend(["-v", f"{storage_path}
|
282
|
-
|
299
|
+
# Mount storage directory using detected home directory
|
300
|
+
cmd.extend(["-v", f"{storage_path}:{self._home_dir}/storage"])
|
301
|
+
|
283
302
|
# Add shared path if specified
|
284
303
|
if self.shared_path:
|
285
|
-
|
304
|
+
# Mount shared directory using detected home directory
|
305
|
+
cmd.extend(["-v", f"{self.shared_path}:{self._home_dir}/shared"])
|
286
306
|
|
287
307
|
# Add environment variables
|
288
308
|
cmd.extend(["-e", "VNC_PW=password"]) # Set VNC password
|
@@ -6,7 +6,7 @@ build-backend = "pdm.backend"
|
|
6
6
|
|
7
7
|
[project]
|
8
8
|
name = "cua-computer"
|
9
|
-
version = "0.4.
|
9
|
+
version = "0.4.8"
|
10
10
|
description = "Computer-Use Interface (CUI) framework powering Cua"
|
11
11
|
readme = "README.md"
|
12
12
|
authors = [
|
@@ -57,7 +57,7 @@ target-version = [
|
|
57
57
|
|
58
58
|
[tool.ruff]
|
59
59
|
line-length = 100
|
60
|
-
target-version = "
|
60
|
+
target-version = "py311"
|
61
61
|
select = [
|
62
62
|
"E",
|
63
63
|
"F",
|
@@ -71,7 +71,7 @@ docstring-code-format = true
|
|
71
71
|
|
72
72
|
[tool.mypy]
|
73
73
|
strict = true
|
74
|
-
python_version = "
|
74
|
+
python_version = "3.11"
|
75
75
|
ignore_missing_imports = true
|
76
76
|
disallow_untyped_defs = true
|
77
77
|
check_untyped_defs = true
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|