cloudbrain-client 1.1.0__tar.gz → 1.1.2__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 (17) hide show
  1. {cloudbrain_client-1.1.0 → cloudbrain_client-1.1.2}/PKG-INFO +1 -1
  2. {cloudbrain_client-1.1.0 → cloudbrain_client-1.1.2}/cloudbrain_client/__init__.py +1 -1
  3. {cloudbrain_client-1.1.0 → cloudbrain_client-1.1.2}/cloudbrain_client/ai_websocket_client.py +50 -0
  4. {cloudbrain_client-1.1.0 → cloudbrain_client-1.1.2}/cloudbrain_client/cloudbrain_collaboration_helper.py +160 -2
  5. {cloudbrain_client-1.1.0 → cloudbrain_client-1.1.2}/cloudbrain_client.egg-info/PKG-INFO +1 -1
  6. {cloudbrain_client-1.1.0 → cloudbrain_client-1.1.2}/pyproject.toml +1 -1
  7. {cloudbrain_client-1.1.0 → cloudbrain_client-1.1.2}/README.md +0 -0
  8. {cloudbrain_client-1.1.0 → cloudbrain_client-1.1.2}/cloudbrain_client/ai_conversation_helper.py +0 -0
  9. {cloudbrain_client-1.1.0 → cloudbrain_client-1.1.2}/cloudbrain_client/cloudbrain_client.py +0 -0
  10. {cloudbrain_client-1.1.0 → cloudbrain_client-1.1.2}/cloudbrain_client/cloudbrain_quick.py +0 -0
  11. {cloudbrain_client-1.1.0 → cloudbrain_client-1.1.2}/cloudbrain_client/message_poller.py +0 -0
  12. {cloudbrain_client-1.1.0 → cloudbrain_client-1.1.2}/cloudbrain_client.egg-info/SOURCES.txt +0 -0
  13. {cloudbrain_client-1.1.0 → cloudbrain_client-1.1.2}/cloudbrain_client.egg-info/dependency_links.txt +0 -0
  14. {cloudbrain_client-1.1.0 → cloudbrain_client-1.1.2}/cloudbrain_client.egg-info/entry_points.txt +0 -0
  15. {cloudbrain_client-1.1.0 → cloudbrain_client-1.1.2}/cloudbrain_client.egg-info/requires.txt +0 -0
  16. {cloudbrain_client-1.1.0 → cloudbrain_client-1.1.2}/cloudbrain_client.egg-info/top_level.txt +0 -0
  17. {cloudbrain_client-1.1.0 → cloudbrain_client-1.1.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudbrain-client
3
- Version: 1.1.0
3
+ Version: 1.1.2
4
4
  Summary: CloudBrain Client - AI collaboration and communication system with AI-to-AI collaboration support
5
5
  Author: CloudBrain Team
6
6
  License: MIT
@@ -18,7 +18,7 @@ AI-FRIENDLY QUICK START:
18
18
  >>> await client.run()
19
19
  """
20
20
 
21
- __version__ = "1.1.0"
21
+ __version__ = "1.1.1"
22
22
 
23
23
  from .cloudbrain_client import CloudBrainClient
24
24
  from .ai_websocket_client import AIWebSocketClient
@@ -90,6 +90,15 @@ class AIWebSocketClient:
90
90
  async def handle_message(self, data: dict):
91
91
  """Handle incoming message"""
92
92
  message_type = data.get('type')
93
+ request_id = data.get('request_id')
94
+
95
+ # Check if this is a response to a request
96
+ if request_id and request_id in self.message_handlers:
97
+ handler = self.message_handlers[request_id]
98
+ if isinstance(handler, asyncio.Future):
99
+ handler.set_result(data)
100
+ del self.message_handlers[request_id]
101
+ return
93
102
 
94
103
  if message_type == 'new_message':
95
104
  await self.handle_new_message(data)
@@ -226,6 +235,47 @@ class AIWebSocketClient:
226
235
 
227
236
  await self.ws.send(json.dumps(message))
228
237
 
238
+ async def send_request(self, request_type: str, data: dict = None) -> dict:
239
+ """
240
+ Send a custom request and wait for response
241
+
242
+ Args:
243
+ request_type: Type of request
244
+ data: Optional data dictionary
245
+
246
+ Returns:
247
+ Response dictionary from server
248
+ """
249
+ if not self.connected:
250
+ return {"error": "Not connected"}
251
+
252
+ # Create a unique request ID
253
+ request_id = f"req_{request_type}_{id(self)}"
254
+
255
+ # Create a future to wait for response
256
+ response_future = asyncio.Future()
257
+
258
+ # Store the future in message handlers
259
+ self.message_handlers[request_id] = response_future
260
+
261
+ # Send the request
262
+ message = {
263
+ 'type': request_type,
264
+ 'request_id': request_id,
265
+ **(data or {})
266
+ }
267
+
268
+ await self.ws.send(json.dumps(message))
269
+
270
+ # Wait for response with timeout
271
+ try:
272
+ response = await asyncio.wait_for(response_future, timeout=10.0)
273
+ return response
274
+ except asyncio.TimeoutError:
275
+ return {"error": "Request timeout"}
276
+ except Exception as e:
277
+ return {"error": str(e)}
278
+
229
279
  async def close(self):
230
280
  """Close connection"""
231
281
  if self.ws:
@@ -22,12 +22,30 @@ from cloudbrain_client.ai_websocket_client import AIWebSocketClient
22
22
  class CloudBrainCollaborator:
23
23
  """Helper class for AI agents to collaborate through CloudBrain"""
24
24
 
25
- def __init__(self, ai_id: int, server_url: str = 'ws://127.0.0.1:8766'):
25
+ def __init__(self, ai_id: int, server_url: str = 'ws://127.0.0.1:8766', db_path: str = None):
26
26
  self.ai_id = ai_id
27
27
  self.server_url = server_url
28
28
  self.client = None
29
29
  self.connected = False
30
30
  self.ai_name = None
31
+ # Use provided db_path or default to server/ai_db/cloudbrain.db relative to current directory
32
+ if db_path:
33
+ self.db_path = Path(db_path)
34
+ else:
35
+ # Try to find the database in common locations
36
+ possible_paths = [
37
+ Path.cwd() / "server" / "ai_db" / "cloudbrain.db",
38
+ Path(__file__).parent.parent.parent.parent / "server" / "ai_db" / "cloudbrain.db",
39
+ Path.home() / "gits" / "hub" / "cloudbrain" / "server" / "ai_db" / "cloudbrain.db",
40
+ ]
41
+ self.db_path = None
42
+ for path in possible_paths:
43
+ if path.exists():
44
+ self.db_path = path
45
+ break
46
+ if self.db_path is None:
47
+ # Default to the first option even if it doesn't exist yet
48
+ self.db_path = Path.cwd() / "server" / "ai_db" / "cloudbrain.db"
31
49
 
32
50
  async def connect(self):
33
51
  """Connect to CloudBrain server"""
@@ -59,7 +77,7 @@ class CloudBrainCollaborator:
59
77
  return []
60
78
 
61
79
  try:
62
- conn = sqlite3.connect(Path(__file__).parent / "server" / "ai_db" / "cloudbrain.db")
80
+ conn = sqlite3.connect(self.db_path)
63
81
  conn.row_factory = sqlite3.Row
64
82
  cursor = conn.cursor()
65
83
 
@@ -240,6 +258,146 @@ class CloudBrainCollaborator:
240
258
  return False
241
259
 
242
260
 
261
+ class CloudBrainCollaborationHelper:
262
+ """
263
+ AI-to-AI Collaboration Helper with 4-step pattern
264
+
265
+ This helper provides a simple 4-step pattern for autonomous AI-to-AI collaboration:
266
+ 1. Check - Look for collaboration opportunities
267
+ 2. Share - Share your work, insights, or discoveries
268
+ 3. Respond - Respond to other AIs' work
269
+ 4. Track - Monitor collaboration progress
270
+ """
271
+
272
+ def __init__(self, ai_id: int, ai_name: str = "", server_url: str = 'ws://127.0.0.1:8766', db_path: str = None):
273
+ self.ai_id = ai_id
274
+ self.ai_name = ai_name
275
+ self.server_url = server_url
276
+ self.client = None
277
+ self.connected = False
278
+ self._collaborator = CloudBrainCollaborator(ai_id, server_url, db_path)
279
+
280
+ async def connect(self):
281
+ """Connect to CloudBrain server"""
282
+ success = await self._collaborator.connect()
283
+ if success and not self.ai_name:
284
+ self.ai_name = self._collaborator.ai_name
285
+ self.connected = success
286
+ return success
287
+
288
+ async def disconnect(self):
289
+ """Disconnect from CloudBrain server"""
290
+ await self._collaborator.disconnect()
291
+ self.connected = False
292
+
293
+ async def check_collaboration_opportunities(self, limit: int = 10) -> List[Dict]:
294
+ """
295
+ Step 1: Check for collaboration opportunities
296
+
297
+ Returns recent messages from other AIs that might need collaboration.
298
+ """
299
+ return await self._collaborator.check_for_updates(limit)
300
+
301
+ async def share_work(self, title: str, content: str, tags: List[str] = None) -> bool:
302
+ """
303
+ Step 2: Share your work, insights, or discoveries
304
+
305
+ Args:
306
+ title: Title of your work
307
+ content: Detailed description of your work
308
+ tags: Optional tags for categorization
309
+
310
+ Returns:
311
+ True if successfully shared
312
+ """
313
+ return await self._collaborator.share_insight(title, content, tags)
314
+
315
+ async def respond_to_collaboration(self, target_ai_id: int, message: str) -> bool:
316
+ """
317
+ Step 3: Respond to other AIs' work
318
+
319
+ Args:
320
+ target_ai_id: AI ID to respond to
321
+ message: Your response message
322
+
323
+ Returns:
324
+ True if successfully responded
325
+ """
326
+ content = f"🤝 **Response to AI {target_ai_id}**\n\n{message}"
327
+ return await self._collaborator.coordinate_with_ai(target_ai_id, content)
328
+
329
+ async def get_collaboration_progress(self) -> Dict[str, Any]:
330
+ """
331
+ Step 4: Track collaboration progress
332
+
333
+ Returns:
334
+ Dictionary with collaboration statistics and recent activity
335
+ """
336
+ if not self.connected:
337
+ return {"error": "Not connected"}
338
+
339
+ try:
340
+ conn = sqlite3.connect(self._collaborator.db_path)
341
+ conn.row_factory = sqlite3.Row
342
+ cursor = conn.cursor()
343
+
344
+ # Get total messages from other AIs
345
+ cursor.execute("""
346
+ SELECT COUNT(*) as total
347
+ FROM ai_messages
348
+ WHERE sender_id != ?
349
+ """, (self.ai_id,))
350
+ total_messages = cursor.fetchone()['total']
351
+
352
+ # Get recent collaboration activity
353
+ cursor.execute("""
354
+ SELECT sender_id, message_type, created_at
355
+ FROM ai_messages
356
+ WHERE sender_id != ?
357
+ ORDER BY created_at DESC
358
+ LIMIT 5
359
+ """, (self.ai_id,))
360
+ recent_activity = [dict(row) for row in cursor.fetchall()]
361
+
362
+ conn.close()
363
+
364
+ progress = {
365
+ "ai_id": self.ai_id,
366
+ "ai_name": self.ai_name,
367
+ "total_collaborations": total_messages,
368
+ "recent_activity": recent_activity,
369
+ "last_check": datetime.now().isoformat()
370
+ }
371
+
372
+ print(f"📊 Collaboration Progress: {total_messages} total collaborations")
373
+ return progress
374
+
375
+ except Exception as e:
376
+ print(f"❌ Error getting collaboration progress: {e}")
377
+ return {"error": str(e)}
378
+
379
+ async def _send_request(self, request_type: str, data: dict) -> dict:
380
+ """
381
+ Send a custom request to the CloudBrain server
382
+
383
+ Args:
384
+ request_type: Type of request (e.g., 'brain_save_state', 'brain_load_state')
385
+ data: Dictionary of request data
386
+
387
+ Returns:
388
+ Response dictionary from server
389
+ """
390
+ if not self.connected or not self._collaborator.client:
391
+ return {"error": "Not connected to server"}
392
+
393
+ try:
394
+ response = await self._collaborator.client.send_request(request_type, data)
395
+ return response
396
+ except Exception as e:
397
+ print(f"❌ Error sending request: {e}")
398
+ return {"error": str(e)}
399
+
400
+
243
401
  async def integrate_cloudbrain_to_tasks(ai_id: int, tasks: List[Dict[str, Any]]) -> bool:
244
402
  """
245
403
  Helper function to integrate CloudBrain operations into a task list.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cloudbrain-client
3
- Version: 1.1.0
3
+ Version: 1.1.2
4
4
  Summary: CloudBrain Client - AI collaboration and communication system with AI-to-AI collaboration support
5
5
  Author: CloudBrain Team
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "cloudbrain-client"
7
- version = "1.1.0"
7
+ version = "1.1.2"
8
8
  description = "CloudBrain Client - AI collaboration and communication system with AI-to-AI collaboration support"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"