cua-computer 0.3.6__tar.gz → 0.4.0__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.3.6 → cua_computer-0.4.0}/PKG-INFO +1 -1
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/interface/generic.py +33 -32
- {cua_computer-0.3.6 → cua_computer-0.4.0}/pyproject.toml +3 -3
- {cua_computer-0.3.6 → cua_computer-0.4.0}/README.md +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/__init__.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/computer.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/diorama_computer.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/helpers.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/interface/__init__.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/interface/base.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/interface/factory.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/interface/linux.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/interface/macos.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/interface/models.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/interface/windows.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/logger.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/models.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/__init__.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/base.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/cloud/__init__.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/cloud/provider.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/factory.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/lume/__init__.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/lume/provider.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/lume_api.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/lumier/__init__.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/lumier/provider.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/winsandbox/__init__.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/winsandbox/provider.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/winsandbox/setup_script.ps1 +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/telemetry.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/ui/__init__.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/ui/__main__.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/ui/gradio/__init__.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/ui/gradio/app.py +0 -0
- {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/utils.py +0 -0
@@ -28,7 +28,7 @@ class GenericComputerInterface(BaseComputerInterface):
|
|
28
28
|
self._max_reconnect_delay = 30 # Maximum delay between reconnection attempts
|
29
29
|
self._log_connection_attempts = True # Flag to control connection attempt logging
|
30
30
|
self._authenticated = False # Track authentication status
|
31
|
-
self.
|
31
|
+
self._recv_lock = asyncio.Lock() # Lock to ensure only one recv at a time
|
32
32
|
|
33
33
|
# Set logger name for the interface
|
34
34
|
self.logger = Logger(logger_name, LogLevel.NORMAL)
|
@@ -245,7 +245,7 @@ class GenericComputerInterface(BaseComputerInterface):
|
|
245
245
|
"""
|
246
246
|
result = await self._send_command("screenshot")
|
247
247
|
if not result.get("image_data"):
|
248
|
-
raise RuntimeError("Failed to take screenshot")
|
248
|
+
raise RuntimeError("Failed to take screenshot, no image data received from server")
|
249
249
|
|
250
250
|
screenshot = decode_base64_image(result["image_data"])
|
251
251
|
|
@@ -578,7 +578,8 @@ class GenericComputerInterface(BaseComputerInterface):
|
|
578
578
|
await self._ws.send(json.dumps(auth_message))
|
579
579
|
|
580
580
|
# Wait for authentication response
|
581
|
-
|
581
|
+
async with self._recv_lock:
|
582
|
+
auth_response = await asyncio.wait_for(self._ws.recv(), timeout=10)
|
582
583
|
auth_result = json.loads(auth_response)
|
583
584
|
|
584
585
|
if not auth_result.get("success"):
|
@@ -696,38 +697,38 @@ class GenericComputerInterface(BaseComputerInterface):
|
|
696
697
|
last_error = None
|
697
698
|
|
698
699
|
# Acquire lock to ensure only one command is processed at a time
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
raise ConnectionError("WebSocket connection is not established")
|
700
|
+
self.logger.debug(f"Acquired lock for command: {command}")
|
701
|
+
while retry_count < max_retries:
|
702
|
+
try:
|
703
|
+
await self._ensure_connection()
|
704
|
+
if not self._ws:
|
705
|
+
raise ConnectionError("WebSocket connection is not established")
|
706
706
|
|
707
|
-
|
708
|
-
|
707
|
+
message = {"command": command, "params": params or {}}
|
708
|
+
await self._ws.send(json.dumps(message))
|
709
|
+
async with self._recv_lock:
|
709
710
|
response = await asyncio.wait_for(self._ws.recv(), timeout=120)
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
711
|
+
self.logger.debug(f"Completed command: {command}")
|
712
|
+
return json.loads(response)
|
713
|
+
except Exception as e:
|
714
|
+
last_error = e
|
715
|
+
retry_count += 1
|
716
|
+
if retry_count < max_retries:
|
717
|
+
# Only log at debug level for intermediate retries
|
718
|
+
self.logger.debug(
|
719
|
+
f"Command '{command}' failed (attempt {retry_count}/{max_retries}): {e}"
|
720
|
+
)
|
721
|
+
await asyncio.sleep(1)
|
722
|
+
continue
|
723
|
+
else:
|
724
|
+
# Only log at error level for the final failure
|
725
|
+
self.logger.error(
|
726
|
+
f"Failed to send command '{command}' after {max_retries} retries"
|
727
|
+
)
|
728
|
+
self.logger.debug(f"Command failure details: {e}")
|
729
|
+
raise
|
729
730
|
|
730
|
-
|
731
|
+
raise last_error if last_error else RuntimeError("Failed to send command")
|
731
732
|
|
732
733
|
async def _send_command_rest(self, command: str, params: Optional[Dict] = None) -> Dict[str, Any]:
|
733
734
|
"""Send command through REST API without retries or connection management."""
|
@@ -6,7 +6,7 @@ build-backend = "pdm.backend"
|
|
6
6
|
|
7
7
|
[project]
|
8
8
|
name = "cua-computer"
|
9
|
-
version = "0.
|
9
|
+
version = "0.4.0"
|
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.
|
60
|
+
target-version = "0.4.0"
|
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.
|
74
|
+
python_version = "0.4.0"
|
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
|