cua-computer 0.4.5__tar.gz → 0.4.6__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.5 → cua_computer-0.4.6}/PKG-INFO +1 -1
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/computer.py +2 -2
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/providers/winsandbox/provider.py +27 -6
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/providers/winsandbox/setup_script.ps1 +33 -8
- {cua_computer-0.4.5 → cua_computer-0.4.6}/pyproject.toml +3 -3
- {cua_computer-0.4.5 → cua_computer-0.4.6}/README.md +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/__init__.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/diorama_computer.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/helpers.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/interface/__init__.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/interface/base.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/interface/factory.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/interface/generic.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/interface/linux.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/interface/macos.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/interface/models.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/interface/windows.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/logger.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/models.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/providers/__init__.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/providers/base.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/providers/cloud/__init__.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/providers/cloud/provider.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/providers/docker/__init__.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/providers/docker/provider.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/providers/factory.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/providers/lume/__init__.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/providers/lume/provider.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/providers/lume_api.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/providers/lumier/__init__.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/providers/lumier/provider.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/providers/winsandbox/__init__.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/ui/__init__.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/ui/__main__.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/ui/gradio/__init__.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/ui/gradio/app.py +0 -0
- {cua_computer-0.4.5 → cua_computer-0.4.6}/computer/utils.py +0 -0
@@ -154,8 +154,8 @@ class Computer:
|
|
154
154
|
self.interface_logger = Logger("computer.interface", verbosity)
|
155
155
|
|
156
156
|
if not use_host_computer_server:
|
157
|
-
if ":" not in image
|
158
|
-
|
157
|
+
if ":" not in image:
|
158
|
+
image = f"{image}:latest"
|
159
159
|
|
160
160
|
if not name:
|
161
161
|
# Normalize the name to be used for the VM
|
@@ -5,6 +5,7 @@ import asyncio
|
|
5
5
|
import logging
|
6
6
|
import time
|
7
7
|
from typing import Dict, Any, Optional, List
|
8
|
+
from pathlib import Path
|
8
9
|
|
9
10
|
from ..base import BaseVMProvider, VMProviderType
|
10
11
|
|
@@ -242,8 +243,15 @@ class WinSandboxProvider(BaseVMProvider):
|
|
242
243
|
|
243
244
|
networking = run_opts.get("networking", self.networking)
|
244
245
|
|
245
|
-
# Create folder mappers
|
246
|
+
# Create folder mappers; always map a persistent venv directory on host for caching packages
|
246
247
|
folder_mappers = []
|
248
|
+
# Ensure host side persistent venv directory exists (Path.home()/wsb_venv)
|
249
|
+
host_wsb_env = Path.home() / ".cua" / "wsb_cache"
|
250
|
+
try:
|
251
|
+
host_wsb_env.mkdir(parents=True, exist_ok=True)
|
252
|
+
except Exception:
|
253
|
+
# If cannot create, continue without persistent mapping
|
254
|
+
host_wsb_env = None
|
247
255
|
shared_directories = run_opts.get("shared_directories", [])
|
248
256
|
for shared_dir in shared_directories:
|
249
257
|
if isinstance(shared_dir, dict):
|
@@ -255,6 +263,15 @@ class WinSandboxProvider(BaseVMProvider):
|
|
255
263
|
|
256
264
|
if host_path and os.path.exists(host_path):
|
257
265
|
folder_mappers.append(winsandbox.FolderMapper(host_path))
|
266
|
+
|
267
|
+
# Add mapping for the persistent venv directory (read/write) so it appears in Sandbox Desktop
|
268
|
+
if host_wsb_env is not None and host_wsb_env.exists():
|
269
|
+
try:
|
270
|
+
folder_mappers.append(
|
271
|
+
winsandbox.FolderMapper(str(host_wsb_env), read_only=False)
|
272
|
+
)
|
273
|
+
except Exception as e:
|
274
|
+
self.logger.warning(f"Failed to map host winsandbox_venv: {e}")
|
258
275
|
|
259
276
|
self.logger.info(f"Creating Windows Sandbox: {name}")
|
260
277
|
self.logger.info(f"Memory: {memory_mb}MB, Networking: {networking}")
|
@@ -290,8 +307,10 @@ class WinSandboxProvider(BaseVMProvider):
|
|
290
307
|
|
291
308
|
self.logger.info(f"Windows Sandbox {name} created successfully")
|
292
309
|
|
310
|
+
venv_exists = (host_wsb_env / "venv" / "Lib" / "site-packages" / "computer_server").exists() if host_wsb_env else False
|
311
|
+
|
293
312
|
# Setup the computer server in the sandbox
|
294
|
-
await self._setup_computer_server(sandbox, name)
|
313
|
+
await self._setup_computer_server(sandbox, name, wait_for_venv=(not venv_exists))
|
295
314
|
|
296
315
|
return {
|
297
316
|
"success": True,
|
@@ -423,7 +442,7 @@ class WinSandboxProvider(BaseVMProvider):
|
|
423
442
|
if total_attempts % 10 == 0:
|
424
443
|
self.logger.info(f"Still waiting for Windows Sandbox {name} IP after {total_attempts} attempts...")
|
425
444
|
|
426
|
-
async def _setup_computer_server(self, sandbox, name: str, visible: bool = False):
|
445
|
+
async def _setup_computer_server(self, sandbox, name: str, visible: bool = False, wait_for_venv: bool = True):
|
427
446
|
"""Setup the computer server in the Windows Sandbox using RPyC.
|
428
447
|
|
429
448
|
Args:
|
@@ -471,10 +490,12 @@ class WinSandboxProvider(BaseVMProvider):
|
|
471
490
|
creationflags=creation_flags,
|
472
491
|
shell=False
|
473
492
|
)
|
474
|
-
|
475
|
-
# # Sleep for 30 seconds
|
476
|
-
# await asyncio.sleep(30)
|
477
493
|
|
494
|
+
if wait_for_venv:
|
495
|
+
print("Waiting for venv to be created for the first time setup of Windows Sandbox...")
|
496
|
+
print("This may take a minute...")
|
497
|
+
await asyncio.sleep(120)
|
498
|
+
|
478
499
|
ip = await self.get_ip(name)
|
479
500
|
self.logger.info(f"Sandbox IP: {ip}")
|
480
501
|
self.logger.info(f"Setup script started in background in sandbox {name} with PID: {process.pid}")
|
@@ -79,23 +79,48 @@ try {
|
|
79
79
|
$pythonVersion = & $pythonExe --version 2>&1
|
80
80
|
Write-Host "Python version: $pythonVersion"
|
81
81
|
|
82
|
-
# Step 2:
|
83
|
-
Write-Host "Step 2:
|
82
|
+
# Step 2: Create a dedicated virtual environment in mapped Desktop folder (persistent)
|
83
|
+
Write-Host "Step 2: Creating virtual environment (if needed)..."
|
84
|
+
$cachePath = "C:\Users\WDAGUtilityAccount\Desktop\wsb_cache"
|
85
|
+
$venvPath = "C:\Users\WDAGUtilityAccount\Desktop\wsb_cache\venv"
|
86
|
+
if (!(Test-Path $venvPath)) {
|
87
|
+
Write-Host "Creating venv at: $venvPath"
|
88
|
+
& $pythonExe -m venv $venvPath
|
89
|
+
} else {
|
90
|
+
Write-Host "Venv already exists at: $venvPath"
|
91
|
+
}
|
92
|
+
# Hide the folder to keep Desktop clean
|
93
|
+
try {
|
94
|
+
$item = Get-Item $cachePath -ErrorAction SilentlyContinue
|
95
|
+
if ($item) {
|
96
|
+
if (-not ($item.Attributes -band [IO.FileAttributes]::Hidden)) {
|
97
|
+
$item.Attributes = $item.Attributes -bor [IO.FileAttributes]::Hidden
|
98
|
+
}
|
99
|
+
}
|
100
|
+
} catch { }
|
101
|
+
$venvPython = Join-Path $venvPath "Scripts\python.exe"
|
102
|
+
if (!(Test-Path $venvPython)) {
|
103
|
+
throw "Virtual environment Python not found at $venvPython"
|
104
|
+
}
|
105
|
+
Write-Host "Using venv Python: $venvPython"
|
106
|
+
|
107
|
+
# Step 3: Install cua-computer-server into the venv
|
108
|
+
Write-Host "Step 3: Installing cua-computer-server..."
|
84
109
|
|
85
110
|
Write-Host "Upgrading pip..."
|
86
|
-
& $
|
111
|
+
& $venvPython -m pip install --upgrade pip --quiet
|
87
112
|
|
88
113
|
Write-Host "Installing cua-computer-server..."
|
89
|
-
& $
|
114
|
+
& $venvPython -m pip install cua-computer-server
|
90
115
|
|
91
116
|
Write-Host "cua-computer-server installation completed."
|
92
117
|
|
93
|
-
# Step
|
94
|
-
Write-Host "Step
|
95
|
-
Write-Host "Starting computer server with: $
|
118
|
+
# Step 4: Start computer server in background using the venv Python
|
119
|
+
Write-Host "Step 4: Starting computer server in background..."
|
120
|
+
Write-Host "Starting computer server with: $venvPython"
|
96
121
|
|
97
122
|
# Start the computer server in the background
|
98
|
-
$serverProcess = Start-Process -FilePath $
|
123
|
+
$serverProcess = Start-Process -FilePath $venvPython -ArgumentList "-m", "computer_server.main" -WindowStyle Hidden -PassThru
|
99
124
|
Write-Host "Computer server started in background with PID: $($serverProcess.Id)"
|
100
125
|
|
101
126
|
# Give it a moment to start
|
@@ -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.6"
|
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 = "0.4.
|
60
|
+
target-version = "0.4.6"
|
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 = "0.4.
|
74
|
+
python_version = "0.4.6"
|
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
|