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.
Files changed (36) hide show
  1. {cua_computer-0.3.6 → cua_computer-0.4.0}/PKG-INFO +1 -1
  2. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/interface/generic.py +33 -32
  3. {cua_computer-0.3.6 → cua_computer-0.4.0}/pyproject.toml +3 -3
  4. {cua_computer-0.3.6 → cua_computer-0.4.0}/README.md +0 -0
  5. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/__init__.py +0 -0
  6. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/computer.py +0 -0
  7. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/diorama_computer.py +0 -0
  8. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/helpers.py +0 -0
  9. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/interface/__init__.py +0 -0
  10. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/interface/base.py +0 -0
  11. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/interface/factory.py +0 -0
  12. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/interface/linux.py +0 -0
  13. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/interface/macos.py +0 -0
  14. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/interface/models.py +0 -0
  15. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/interface/windows.py +0 -0
  16. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/logger.py +0 -0
  17. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/models.py +0 -0
  18. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/__init__.py +0 -0
  19. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/base.py +0 -0
  20. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/cloud/__init__.py +0 -0
  21. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/cloud/provider.py +0 -0
  22. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/factory.py +0 -0
  23. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/lume/__init__.py +0 -0
  24. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/lume/provider.py +0 -0
  25. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/lume_api.py +0 -0
  26. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/lumier/__init__.py +0 -0
  27. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/lumier/provider.py +0 -0
  28. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/winsandbox/__init__.py +0 -0
  29. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/winsandbox/provider.py +0 -0
  30. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/providers/winsandbox/setup_script.ps1 +0 -0
  31. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/telemetry.py +0 -0
  32. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/ui/__init__.py +0 -0
  33. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/ui/__main__.py +0 -0
  34. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/ui/gradio/__init__.py +0 -0
  35. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/ui/gradio/app.py +0 -0
  36. {cua_computer-0.3.6 → cua_computer-0.4.0}/computer/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cua-computer
3
- Version: 0.3.6
3
+ Version: 0.4.0
4
4
  Summary: Computer-Use Interface (CUI) framework powering Cua
5
5
  Author-Email: TryCua <gh@trycua.com>
6
6
  Requires-Python: >=3.11
@@ -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._command_lock = asyncio.Lock() # Lock to ensure only one command at a time
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
- auth_response = await asyncio.wait_for(self._ws.recv(), timeout=10)
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
- async with self._command_lock:
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")
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
- message = {"command": command, "params": params or {}}
708
- await self._ws.send(json.dumps(message))
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
- self.logger.debug(f"Completed command: {command}")
711
- return json.loads(response)
712
- except Exception as e:
713
- last_error = e
714
- retry_count += 1
715
- if retry_count < max_retries:
716
- # Only log at debug level for intermediate retries
717
- self.logger.debug(
718
- f"Command '{command}' failed (attempt {retry_count}/{max_retries}): {e}"
719
- )
720
- await asyncio.sleep(1)
721
- continue
722
- else:
723
- # Only log at error level for the final failure
724
- self.logger.error(
725
- f"Failed to send command '{command}' after {max_retries} retries"
726
- )
727
- self.logger.debug(f"Command failure details: {e}")
728
- raise
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
- raise last_error if last_error else RuntimeError("Failed to send command")
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.3.6"
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.3.6"
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.3.6"
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