cua-computer 0.2.4__py3-none-any.whl → 0.2.6__py3-none-any.whl

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.
@@ -26,6 +26,7 @@ class LinuxComputerInterface(BaseComputerInterface):
26
26
  self._reconnect_delay = 1 # Start with 1 second delay
27
27
  self._max_reconnect_delay = 30 # Maximum delay between reconnection attempts
28
28
  self._log_connection_attempts = True # Flag to control connection attempt logging
29
+ self._authenticated = False # Track authentication status
29
30
 
30
31
  # Set logger name for Linux interface
31
32
  self.logger = Logger("cua.interface.linux", LogLevel.NORMAL)
@@ -89,34 +90,14 @@ class LinuxComputerInterface(BaseComputerInterface):
89
90
  )
90
91
  self.logger.info("WebSocket connection established")
91
92
 
92
- # If api_key and vm_name are provided, perform authentication handshake
93
- if self.api_key and self.vm_name:
94
- self.logger.info("Performing authentication handshake...")
95
- auth_message = {
96
- "command": "authenticate",
97
- "params": {
98
- "api_key": self.api_key,
99
- "container_name": self.vm_name
100
- }
101
- }
102
- await self._ws.send(json.dumps(auth_message))
103
-
104
- # Wait for authentication response
105
- auth_response = await asyncio.wait_for(self._ws.recv(), timeout=10)
106
- auth_result = json.loads(auth_response)
107
-
108
- if not auth_result.get("success"):
109
- error_msg = auth_result.get("error", "Authentication failed")
110
- self.logger.error(f"Authentication failed: {error_msg}")
111
- await self._ws.close()
112
- self._ws = None
113
- raise ConnectionError(f"Authentication failed: {error_msg}")
114
-
115
- self.logger.info("Authentication successful")
93
+ # Authentication will be handled by the first command that needs it
94
+ # Don't do authentication here to avoid recv conflicts
116
95
 
117
96
  self._reconnect_delay = 1 # Reset reconnect delay on successful connection
118
97
  self._last_ping = time.time()
119
98
  retry_count = 0 # Reset retry count on successful connection
99
+ self._authenticated = False # Reset auth status on new connection
100
+
120
101
  except (asyncio.TimeoutError, websockets.exceptions.WebSocketException) as e:
121
102
  next_retry = self._reconnect_delay
122
103
 
@@ -140,13 +121,6 @@ class LinuxComputerInterface(BaseComputerInterface):
140
121
  pass
141
122
  self._ws = None
142
123
 
143
- # Use exponential backoff for connection retries
144
- await asyncio.sleep(self._reconnect_delay)
145
- self._reconnect_delay = min(
146
- self._reconnect_delay * 2, self._max_reconnect_delay
147
- )
148
- continue
149
-
150
124
  # Regular ping to check connection
151
125
  if self._ws and self._ws.state == websockets.protocol.State.OPEN:
152
126
  try:
@@ -225,6 +199,31 @@ class LinuxComputerInterface(BaseComputerInterface):
225
199
  if not self._ws:
226
200
  raise ConnectionError("WebSocket connection is not established")
227
201
 
202
+ # Handle authentication if needed
203
+ if self.api_key and self.vm_name and not self._authenticated:
204
+ self.logger.info("Performing authentication handshake...")
205
+ auth_message = {
206
+ "command": "authenticate",
207
+ "params": {
208
+ "api_key": self.api_key,
209
+ "container_name": self.vm_name
210
+ }
211
+ }
212
+ await self._ws.send(json.dumps(auth_message))
213
+
214
+ # Wait for authentication response
215
+ auth_response = await asyncio.wait_for(self._ws.recv(), timeout=10)
216
+ auth_result = json.loads(auth_response)
217
+
218
+ if not auth_result.get("success"):
219
+ error_msg = auth_result.get("error", "Authentication failed")
220
+ self.logger.error(f"Authentication failed: {error_msg}")
221
+ self._authenticated = False
222
+ raise ConnectionError(f"Authentication failed: {error_msg}")
223
+
224
+ self.logger.info("Authentication successful")
225
+ self._authenticated = True
226
+
228
227
  message = {"command": command, "params": params or {}}
229
228
  await self._ws.send(json.dumps(message))
230
229
  response = await asyncio.wait_for(self._ws.recv(), timeout=30)
@@ -245,9 +244,7 @@ class LinuxComputerInterface(BaseComputerInterface):
245
244
  f"Failed to send command '{command}' after {max_retries} retries"
246
245
  )
247
246
  self.logger.debug(f"Command failure details: {e}")
248
- raise
249
-
250
- raise last_error if last_error else RuntimeError("Failed to send command")
247
+ raise last_error if last_error else RuntimeError("Failed to send command")
251
248
 
252
249
  async def wait_for_ready(self, timeout: int = 60, interval: float = 1.0):
253
250
  """Wait for WebSocket connection to become available."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cua-computer
3
- Version: 0.2.4
3
+ Version: 0.2.6
4
4
  Summary: Computer-Use Interface (CUI) framework powering Cua
5
5
  Author-Email: TryCua <gh@trycua.com>
6
6
  Requires-Python: >=3.10
@@ -3,7 +3,7 @@ computer/computer.py,sha256=Rc32XFZdKr7XZKO0zhbEom-REvYYPPlvmvjDbw5gP9k,32218
3
3
  computer/interface/__init__.py,sha256=xQvYjq5PMn9ZJOmRR5mWtONTl_0HVd8ACvW6AQnzDdw,262
4
4
  computer/interface/base.py,sha256=CD9WpDp-6qP-ID5MjhXA8qpYs0XhJ4TPkR917l2FFSo,6021
5
5
  computer/interface/factory.py,sha256=RjAZAB_jFuS8JierYjLbapRX6RqFE0qE3BiIyP5UDOE,1441
6
- computer/interface/linux.py,sha256=EIVxwD_q0OmZoaW0Tv8FvKTpja9kInIsKWI47gpn2Po,27077
6
+ computer/interface/linux.py,sha256=CT1N0QA52TNKBbFG2LXdN6yAGWWJ12_2hTMEI8yNoM4,26865
7
7
  computer/interface/macos.py,sha256=_8R_IroxbcVmh1WagrjDQOitaT6tVkCHVzGgA_lwTrM,27077
8
8
  computer/interface/models.py,sha256=RZKVUdwKrKUoFqwlx2Dk8Egkmq_AInlIu_d0xg7SZzw,3238
9
9
  computer/logger.py,sha256=UVvnmZGOWVF9TCsixEbeQnDZ3wBPAJ2anW3Zp-MoJ8Y,2896
@@ -23,7 +23,7 @@ computer/ui/__init__.py,sha256=pmo05ek9qiB_x7DPeE6Vf_8RsIOqTD0w1dBLMHfoOnY,45
23
23
  computer/ui/gradio/__init__.py,sha256=5_KimixM48-X74FCsLw7LbSt39MQfUMEL8-M9amK3Cw,117
24
24
  computer/ui/gradio/app.py,sha256=o31nphBcb6zM5OKPuODTjuOzSJ3lt61kQHpUeMBBs70,65077
25
25
  computer/utils.py,sha256=zY50NXB7r51GNLQ6l7lhG_qv0_ufpQ8n0-SDhCei8m4,2838
26
- cua_computer-0.2.4.dist-info/METADATA,sha256=ksHZS9FWt0s5sIhUtidpM77JJSChr9wpd5kbojtxhoc,5844
27
- cua_computer-0.2.4.dist-info/WHEEL,sha256=tSfRZzRHthuv7vxpI4aehrdN9scLjk-dCJkPLzkHxGg,90
28
- cua_computer-0.2.4.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
29
- cua_computer-0.2.4.dist-info/RECORD,,
26
+ cua_computer-0.2.6.dist-info/METADATA,sha256=2eZab1PZTMnKx2lIrYSOZGCI5gT596kOmp5Hu1xb4Tg,5844
27
+ cua_computer-0.2.6.dist-info/WHEEL,sha256=tSfRZzRHthuv7vxpI4aehrdN9scLjk-dCJkPLzkHxGg,90
28
+ cua_computer-0.2.6.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
29
+ cua_computer-0.2.6.dist-info/RECORD,,