praisonaiagents 0.0.77__py3-none-any.whl → 0.0.79__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.
@@ -22,6 +22,13 @@ import inspect
22
22
  import uuid
23
23
  from dataclasses import dataclass
24
24
 
25
+ # Global variables for API server
26
+ _server_started = False
27
+ _registered_agents = {}
28
+ _shared_app = None
29
+
30
+ # Don't import FastAPI dependencies here - use lazy loading instead
31
+
25
32
  if TYPE_CHECKING:
26
33
  from ..task.task import Task
27
34
 
@@ -1399,4 +1406,183 @@ Your Goal: {self.goal}
1399
1406
 
1400
1407
  except Exception as e:
1401
1408
  logging.error(f"Error in execute_tool_async: {str(e)}", exc_info=True)
1402
- return {"error": f"Error in execute_tool_async: {str(e)}"}
1409
+ return {"error": f"Error in execute_tool_async: {str(e)}"}
1410
+
1411
+ def launch(self, path: str = '/', port: int = 8000, host: str = '0.0.0.0', debug: bool = False):
1412
+ """
1413
+ Launch the agent as an HTTP API endpoint.
1414
+
1415
+ Args:
1416
+ path: API endpoint path (default: '/')
1417
+ port: Server port (default: 8000)
1418
+ host: Server host (default: '0.0.0.0')
1419
+ debug: Enable debug mode for uvicorn (default: False)
1420
+
1421
+ Returns:
1422
+ None
1423
+ """
1424
+ global _server_started, _registered_agents, _shared_app
1425
+
1426
+ # Try to import FastAPI dependencies - lazy loading
1427
+ try:
1428
+ import uvicorn
1429
+ from fastapi import FastAPI, HTTPException, Request
1430
+ from fastapi.responses import JSONResponse
1431
+ from pydantic import BaseModel
1432
+ import threading
1433
+ import time
1434
+
1435
+ # Define the request model here since we need pydantic
1436
+ class AgentQuery(BaseModel):
1437
+ query: str
1438
+
1439
+ except ImportError as e:
1440
+ # Check which specific module is missing
1441
+ missing_module = str(e).split("No module named '")[-1].rstrip("'")
1442
+ display_error(f"Missing dependency: {missing_module}. Required for launch() method.")
1443
+ logging.error(f"Missing dependency: {missing_module}. Required for launch() method.")
1444
+ print(f"\nTo add API capabilities, install the required dependencies:")
1445
+ print(f"pip install {missing_module}")
1446
+ print("\nOr install all API dependencies with:")
1447
+ print("pip install 'praisonaiagents[api]'")
1448
+ return None
1449
+
1450
+ # Initialize shared FastAPI app if not already created
1451
+ if _shared_app is None:
1452
+ _shared_app = FastAPI(
1453
+ title="PraisonAI Agents API",
1454
+ description="API for interacting with PraisonAI Agents"
1455
+ )
1456
+
1457
+ # Add a root endpoint with a welcome message
1458
+ @_shared_app.get("/")
1459
+ async def root():
1460
+ return {"message": "Welcome to PraisonAI Agents API. See /docs for usage."}
1461
+
1462
+ # Add healthcheck endpoint
1463
+ @_shared_app.get("/health")
1464
+ async def healthcheck():
1465
+ return {"status": "ok", "agents": list(_registered_agents.keys())}
1466
+
1467
+ # Normalize path to ensure it starts with /
1468
+ if not path.startswith('/'):
1469
+ path = f'/{path}'
1470
+
1471
+ # Check if path is already registered by another agent
1472
+ if path in _registered_agents and _registered_agents[path] != self.agent_id:
1473
+ existing_agent = _registered_agents[path]
1474
+ logging.warning(f"Path '{path}' is already registered by another agent. Please use a different path.")
1475
+ print(f"⚠️ Warning: Path '{path}' is already registered by another agent.")
1476
+ # Use a modified path to avoid conflicts
1477
+ original_path = path
1478
+ path = f"{path}_{self.agent_id[:6]}"
1479
+ logging.warning(f"Using '{path}' instead of '{original_path}'")
1480
+ print(f"🔄 Using '{path}' instead")
1481
+
1482
+ # Register the agent to this path
1483
+ _registered_agents[path] = self.agent_id
1484
+
1485
+ # Define the endpoint handler
1486
+ @_shared_app.post(path)
1487
+ async def handle_agent_query(request: Request, query_data: Optional[AgentQuery] = None):
1488
+ # Handle both direct JSON with query field and form data
1489
+ if query_data is None:
1490
+ try:
1491
+ request_data = await request.json()
1492
+ if "query" not in request_data:
1493
+ raise HTTPException(status_code=400, detail="Missing 'query' field in request")
1494
+ query = request_data["query"]
1495
+ except:
1496
+ # Fallback to form data or query params
1497
+ form_data = await request.form()
1498
+ if "query" in form_data:
1499
+ query = form_data["query"]
1500
+ else:
1501
+ raise HTTPException(status_code=400, detail="Missing 'query' field in request")
1502
+ else:
1503
+ query = query_data.query
1504
+
1505
+ try:
1506
+ # Use async version if available, otherwise use sync version
1507
+ if asyncio.iscoroutinefunction(self.chat):
1508
+ response = await self.achat(query)
1509
+ else:
1510
+ # Run sync function in a thread to avoid blocking
1511
+ loop = asyncio.get_event_loop()
1512
+ response = await loop.run_in_executor(None, lambda: self.chat(query))
1513
+
1514
+ return {"response": response}
1515
+ except Exception as e:
1516
+ logging.error(f"Error processing query: {str(e)}", exc_info=True)
1517
+ return JSONResponse(
1518
+ status_code=500,
1519
+ content={"error": f"Error processing query: {str(e)}"}
1520
+ )
1521
+
1522
+ print(f"🚀 Agent '{self.name}' available at http://{host}:{port}{path}")
1523
+
1524
+ # Start the server if it's not already running
1525
+ if not _server_started:
1526
+ _server_started = True
1527
+
1528
+ # Start the server in a separate thread
1529
+ def run_server():
1530
+ try:
1531
+ print(f"✅ FastAPI server started at http://{host}:{port}")
1532
+ print(f"📚 API documentation available at http://{host}:{port}/docs")
1533
+ print(f"🔌 Available endpoints: {', '.join(list(_registered_agents.keys()))}")
1534
+ uvicorn.run(_shared_app, host=host, port=port, log_level="debug" if debug else "info")
1535
+ except Exception as e:
1536
+ logging.error(f"Error starting server: {str(e)}", exc_info=True)
1537
+ print(f"❌ Error starting server: {str(e)}")
1538
+
1539
+ # Run server in a background thread
1540
+ server_thread = threading.Thread(target=run_server, daemon=True)
1541
+ server_thread.start()
1542
+
1543
+ # Wait for a moment to allow the server to start and register endpoints
1544
+ time.sleep(0.5)
1545
+ else:
1546
+ # If server is already running, wait a moment to make sure the endpoint is registered
1547
+ time.sleep(0.1)
1548
+ print(f"🔌 Available endpoints: {', '.join(list(_registered_agents.keys()))}")
1549
+
1550
+ # Get the stack frame to check if this is the last launch() call in the script
1551
+ import inspect
1552
+ stack = inspect.stack()
1553
+
1554
+ # If this is called from a Python script (not interactive), try to detect if it's the last launch call
1555
+ if len(stack) > 1 and stack[1].filename.endswith('.py'):
1556
+ caller_frame = stack[1]
1557
+ caller_line = caller_frame.lineno
1558
+
1559
+ try:
1560
+ # Read the file to check if there are more launch calls after this one
1561
+ with open(caller_frame.filename, 'r') as f:
1562
+ lines = f.readlines()
1563
+
1564
+ # Check if there are more launch() calls after the current line
1565
+ has_more_launches = False
1566
+ for line in lines[caller_line:]:
1567
+ if '.launch(' in line and not line.strip().startswith('#'):
1568
+ has_more_launches = True
1569
+ break
1570
+
1571
+ # If this is the last launch call, block the main thread
1572
+ if not has_more_launches:
1573
+ try:
1574
+ print("\nAll agents registered. Press Ctrl+C to stop the server.")
1575
+ while True:
1576
+ time.sleep(1)
1577
+ except KeyboardInterrupt:
1578
+ print("\nServer stopped")
1579
+ except Exception as e:
1580
+ # If something goes wrong with detection, block anyway to be safe
1581
+ logging.error(f"Error in launch detection: {e}")
1582
+ try:
1583
+ while True:
1584
+ time.sleep(1)
1585
+ except KeyboardInterrupt:
1586
+ print("\nServer stopped")
1587
+
1588
+ return None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: praisonaiagents
3
- Version: 0.0.77
3
+ Version: 0.0.79
4
4
  Summary: Praison AI agents for completing complex tasks with Self Reflection Agents
5
5
  Author: Mervin Praison
6
6
  Requires-Dist: pydantic
@@ -19,8 +19,12 @@ Requires-Dist: chonkie>=1.0.2; extra == "knowledge"
19
19
  Provides-Extra: llm
20
20
  Requires-Dist: litellm>=1.50.0; extra == "llm"
21
21
  Requires-Dist: pydantic>=2.4.2; extra == "llm"
22
+ Provides-Extra: api
23
+ Requires-Dist: fastapi>=0.115.0; extra == "api"
24
+ Requires-Dist: uvicorn>=0.34.0; extra == "api"
22
25
  Provides-Extra: all
23
26
  Requires-Dist: praisonaiagents[memory]; extra == "all"
24
27
  Requires-Dist: praisonaiagents[knowledge]; extra == "all"
25
28
  Requires-Dist: praisonaiagents[llm]; extra == "all"
26
29
  Requires-Dist: praisonaiagents[mcp]; extra == "all"
30
+ Requires-Dist: praisonaiagents[api]; extra == "all"
@@ -1,7 +1,7 @@
1
1
  praisonaiagents/__init__.py,sha256=Z2_rSA6mYozz0r3ioUgKzl3QV8uWRDS_QaqPg2oGjqg,1324
2
2
  praisonaiagents/main.py,sha256=l29nGEbV2ReBi4szURbnH0Fk0w2F_QZTmECysyZjYcA,15066
3
3
  praisonaiagents/agent/__init__.py,sha256=j0T19TVNbfZcClvpbZDDinQxZ0oORgsMrMqx16jZ-bA,128
4
- praisonaiagents/agent/agent.py,sha256=ZQOLF8tRr_TddhNRBFnna1AMrxeXwp1igw9I3KrngDk,66617
4
+ praisonaiagents/agent/agent.py,sha256=OOP_05mOMoHNkeElQWqH9jKOFUivlIjZ_vZJWLhIkSc,75089
5
5
  praisonaiagents/agent/image_agent.py,sha256=-5MXG594HVwSpFMcidt16YBp7udtik-Cp7eXlzLE1fY,8696
6
6
  praisonaiagents/agents/__init__.py,sha256=_1d6Pqyk9EoBSo7E68sKyd1jDRlN1vxvVIRpoMc0Jcw,168
7
7
  praisonaiagents/agents/agents.py,sha256=uAOHyn77noFvg3sYVFRhQUuc1LDpCMpfLND8CKOXAd4,37971
@@ -40,7 +40,7 @@ praisonaiagents/tools/xml_tools.py,sha256=iYTMBEk5l3L3ryQ1fkUnNVYK-Nnua2Kx2S0dxN
40
40
  praisonaiagents/tools/yaml_tools.py,sha256=uogAZrhXV9O7xvspAtcTfpKSQYL2nlOTvCQXN94-G9A,14215
41
41
  praisonaiagents/tools/yfinance_tools.py,sha256=s2PBj_1v7oQnOobo2fDbQBACEHl61ftG4beG6Z979ZE,8529
42
42
  praisonaiagents/tools/train/data/generatecot.py,sha256=H6bNh-E2hqL5MW6kX3hqZ05g9ETKN2-kudSjiuU_SD8,19403
43
- praisonaiagents-0.0.77.dist-info/METADATA,sha256=idfF7xXDr8DOx84tV0RSFL9sGzB_AncqVUauMEIBvD4,982
44
- praisonaiagents-0.0.77.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
45
- praisonaiagents-0.0.77.dist-info/top_level.txt,sha256=_HsRddrJ23iDx5TTqVUVvXG2HeHBL5voshncAMDGjtA,16
46
- praisonaiagents-0.0.77.dist-info/RECORD,,
43
+ praisonaiagents-0.0.79.dist-info/METADATA,sha256=kfbFrfIzL7AMat_CvuzqwaLAakTuDZ3IspnIW4T5Mwo,1149
44
+ praisonaiagents-0.0.79.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
45
+ praisonaiagents-0.0.79.dist-info/top_level.txt,sha256=_HsRddrJ23iDx5TTqVUVvXG2HeHBL5voshncAMDGjtA,16
46
+ praisonaiagents-0.0.79.dist-info/RECORD,,