chore: remove legacy agent-services backup directory
- Removed apps/agent-services_backup_20260402_120554/ directory - Deleted agent-bridge integration layer (integration_layer.py) - Deleted agent-compliance service (compliance_agent.py) - Deleted agent-coordinator service (coordinator.py) - Deleted agent-trading service (trading_agent.py) - Removed backup files from April 2, 2026 12:05:54 timestamp - Cleanup of outdated agent services implementation
This commit is contained in:
@@ -1,229 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Agent Integration Layer
|
|
||||||
Connects agent protocols to existing AITBC services
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import aiohttp
|
|
||||||
import json
|
|
||||||
from typing import Dict, Any, List, Optional
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
class AITBCServiceIntegration:
|
|
||||||
"""Integration layer for AITBC services"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.service_endpoints = {
|
|
||||||
"coordinator_api": "http://localhost:8000",
|
|
||||||
"blockchain_rpc": "http://localhost:8006",
|
|
||||||
"exchange_service": "http://localhost:8001",
|
|
||||||
"marketplace": "http://localhost:8002",
|
|
||||||
"agent_registry": "http://localhost:8013"
|
|
||||||
}
|
|
||||||
self.session = None
|
|
||||||
|
|
||||||
async def __aenter__(self):
|
|
||||||
self.session = aiohttp.ClientSession()
|
|
||||||
return self
|
|
||||||
|
|
||||||
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
||||||
if self.session:
|
|
||||||
await self.session.close()
|
|
||||||
|
|
||||||
async def get_blockchain_info(self) -> Dict[str, Any]:
|
|
||||||
"""Get blockchain information"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['blockchain_rpc']}/health") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "unavailable"}
|
|
||||||
|
|
||||||
async def get_exchange_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get exchange service status"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['exchange_service']}/api/health") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "unavailable"}
|
|
||||||
|
|
||||||
async def get_coordinator_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get coordinator API status"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['coordinator_api']}/health") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "unavailable"}
|
|
||||||
|
|
||||||
async def submit_transaction(self, transaction_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Submit transaction to blockchain"""
|
|
||||||
try:
|
|
||||||
async with self.session.post(
|
|
||||||
f"{self.service_endpoints['blockchain_rpc']}/rpc/submit",
|
|
||||||
json=transaction_data
|
|
||||||
) as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "failed"}
|
|
||||||
|
|
||||||
async def get_market_data(self, symbol: str = "AITBC/BTC") -> Dict[str, Any]:
|
|
||||||
"""Get market data from exchange"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['exchange_service']}/api/market/{symbol}") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "failed"}
|
|
||||||
|
|
||||||
async def register_agent_with_coordinator(self, agent_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Register agent with coordinator"""
|
|
||||||
try:
|
|
||||||
async with self.session.post(
|
|
||||||
f"{self.service_endpoints['agent_registry']}/api/agents/register",
|
|
||||||
json=agent_data
|
|
||||||
) as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "failed"}
|
|
||||||
|
|
||||||
class AgentServiceBridge:
|
|
||||||
"""Bridge between agents and AITBC services"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.integration = AITBCServiceIntegration()
|
|
||||||
self.active_agents = {}
|
|
||||||
|
|
||||||
async def start_agent(self, agent_id: str, agent_config: Dict[str, Any]) -> bool:
|
|
||||||
"""Start an agent with service integration"""
|
|
||||||
try:
|
|
||||||
# Register agent with coordinator
|
|
||||||
async with self.integration as integration:
|
|
||||||
registration_result = await integration.register_agent_with_coordinator({
|
|
||||||
"name": agent_id,
|
|
||||||
"type": agent_config.get("type", "generic"),
|
|
||||||
"capabilities": agent_config.get("capabilities", []),
|
|
||||||
"chain_id": agent_config.get("chain_id", "ait-mainnet"),
|
|
||||||
"endpoint": agent_config.get("endpoint", f"http://localhost:{8000 + len(self.active_agents) + 10}")
|
|
||||||
})
|
|
||||||
|
|
||||||
# The registry returns the created agent dict on success, not a {"status": "ok"} wrapper
|
|
||||||
if registration_result and "id" in registration_result:
|
|
||||||
self.active_agents[agent_id] = {
|
|
||||||
"config": agent_config,
|
|
||||||
"registration": registration_result,
|
|
||||||
"started_at": datetime.utcnow()
|
|
||||||
}
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f"Registration failed: {registration_result}")
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Failed to start agent {agent_id}: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def stop_agent(self, agent_id: str) -> bool:
|
|
||||||
"""Stop an agent"""
|
|
||||||
if agent_id in self.active_agents:
|
|
||||||
del self.active_agents[agent_id]
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def get_agent_status(self, agent_id: str) -> Dict[str, Any]:
|
|
||||||
"""Get agent status with service integration"""
|
|
||||||
if agent_id not in self.active_agents:
|
|
||||||
return {"status": "not_found"}
|
|
||||||
|
|
||||||
agent_info = self.active_agents[agent_id]
|
|
||||||
|
|
||||||
async with self.integration as integration:
|
|
||||||
# Get service statuses
|
|
||||||
blockchain_status = await integration.get_blockchain_info()
|
|
||||||
exchange_status = await integration.get_exchange_status()
|
|
||||||
coordinator_status = await integration.get_coordinator_status()
|
|
||||||
|
|
||||||
return {
|
|
||||||
"agent_id": agent_id,
|
|
||||||
"status": "active",
|
|
||||||
"started_at": agent_info["started_at"].isoformat(),
|
|
||||||
"services": {
|
|
||||||
"blockchain": blockchain_status,
|
|
||||||
"exchange": exchange_status,
|
|
||||||
"coordinator": coordinator_status
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async def execute_agent_task(self, agent_id: str, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute agent task with service integration"""
|
|
||||||
if agent_id not in self.active_agents:
|
|
||||||
return {"status": "error", "message": "Agent not found"}
|
|
||||||
|
|
||||||
task_type = task_data.get("type")
|
|
||||||
|
|
||||||
if task_type == "market_analysis":
|
|
||||||
return await self._execute_market_analysis(task_data)
|
|
||||||
elif task_type == "trading":
|
|
||||||
return await self._execute_trading_task(task_data)
|
|
||||||
elif task_type == "compliance_check":
|
|
||||||
return await self._execute_compliance_check(task_data)
|
|
||||||
else:
|
|
||||||
return {"status": "error", "message": f"Unknown task type: {task_type}"}
|
|
||||||
|
|
||||||
async def _execute_market_analysis(self, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute market analysis task"""
|
|
||||||
try:
|
|
||||||
async with self.integration as integration:
|
|
||||||
market_data = await integration.get_market_data(task_data.get("symbol", "AITBC/BTC"))
|
|
||||||
|
|
||||||
# Perform basic analysis
|
|
||||||
analysis_result = {
|
|
||||||
"symbol": task_data.get("symbol", "AITBC/BTC"),
|
|
||||||
"market_data": market_data,
|
|
||||||
"analysis": {
|
|
||||||
"trend": "neutral",
|
|
||||||
"volatility": "medium",
|
|
||||||
"recommendation": "hold"
|
|
||||||
},
|
|
||||||
"timestamp": datetime.utcnow().isoformat()
|
|
||||||
}
|
|
||||||
|
|
||||||
return {"status": "success", "result": analysis_result}
|
|
||||||
except Exception as e:
|
|
||||||
return {"status": "error", "message": str(e)}
|
|
||||||
|
|
||||||
async def _execute_trading_task(self, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute trading task"""
|
|
||||||
try:
|
|
||||||
# Get market data first
|
|
||||||
async with self.integration as integration:
|
|
||||||
market_data = await integration.get_market_data(task_data.get("symbol", "AITBC/BTC"))
|
|
||||||
|
|
||||||
# Create transaction
|
|
||||||
transaction = {
|
|
||||||
"type": "trade",
|
|
||||||
"symbol": task_data.get("symbol", "AITBC/BTC"),
|
|
||||||
"side": task_data.get("side", "buy"),
|
|
||||||
"amount": task_data.get("amount", 0.1),
|
|
||||||
"price": task_data.get("price", market_data.get("price", 0.001))
|
|
||||||
}
|
|
||||||
|
|
||||||
# Submit transaction
|
|
||||||
tx_result = await integration.submit_transaction(transaction)
|
|
||||||
|
|
||||||
return {"status": "success", "transaction": tx_result}
|
|
||||||
except Exception as e:
|
|
||||||
return {"status": "error", "message": str(e)}
|
|
||||||
|
|
||||||
async def _execute_compliance_check(self, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute compliance check task"""
|
|
||||||
try:
|
|
||||||
# Basic compliance check
|
|
||||||
compliance_result = {
|
|
||||||
"user_id": task_data.get("user_id"),
|
|
||||||
"check_type": task_data.get("check_type", "basic"),
|
|
||||||
"status": "passed",
|
|
||||||
"checks_performed": ["kyc", "aml", "sanctions"],
|
|
||||||
"timestamp": datetime.utcnow().isoformat()
|
|
||||||
}
|
|
||||||
|
|
||||||
return {"status": "success", "result": compliance_result}
|
|
||||||
except Exception as e:
|
|
||||||
return {"status": "error", "message": str(e)}
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Compliance Agent
|
|
||||||
Automated compliance and regulatory monitoring agent
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import json
|
|
||||||
import time
|
|
||||||
from typing import Dict, Any, List
|
|
||||||
from datetime import datetime
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Add parent directory to path
|
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '../../../..'))
|
|
||||||
|
|
||||||
from apps.agent_services.agent_bridge.src.integration_layer import AgentServiceBridge
|
|
||||||
|
|
||||||
class ComplianceAgent:
|
|
||||||
"""Automated compliance agent"""
|
|
||||||
|
|
||||||
def __init__(self, agent_id: str, config: Dict[str, Any]):
|
|
||||||
self.agent_id = agent_id
|
|
||||||
self.config = config
|
|
||||||
self.bridge = AgentServiceBridge()
|
|
||||||
self.is_running = False
|
|
||||||
self.check_interval = config.get("check_interval", 300) # 5 minutes
|
|
||||||
self.monitored_entities = config.get("monitored_entities", [])
|
|
||||||
|
|
||||||
async def start(self) -> bool:
|
|
||||||
"""Start compliance agent"""
|
|
||||||
try:
|
|
||||||
success = await self.bridge.start_agent(self.agent_id, {
|
|
||||||
"type": "compliance",
|
|
||||||
"capabilities": ["kyc_check", "aml_screening", "regulatory_reporting"],
|
|
||||||
"endpoint": f"http://localhost:8006"
|
|
||||||
})
|
|
||||||
|
|
||||||
if success:
|
|
||||||
self.is_running = True
|
|
||||||
print(f"Compliance agent {self.agent_id} started successfully")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f"Failed to start compliance agent {self.agent_id}")
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error starting compliance agent: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def stop(self) -> bool:
|
|
||||||
"""Stop compliance agent"""
|
|
||||||
self.is_running = False
|
|
||||||
success = await self.bridge.stop_agent(self.agent_id)
|
|
||||||
if success:
|
|
||||||
print(f"Compliance agent {self.agent_id} stopped successfully")
|
|
||||||
return success
|
|
||||||
|
|
||||||
async def run_compliance_loop(self):
|
|
||||||
"""Main compliance monitoring loop"""
|
|
||||||
while self.is_running:
|
|
||||||
try:
|
|
||||||
for entity in self.monitored_entities:
|
|
||||||
await self._perform_compliance_check(entity)
|
|
||||||
|
|
||||||
await asyncio.sleep(self.check_interval)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error in compliance loop: {e}")
|
|
||||||
await asyncio.sleep(30) # Wait before retrying
|
|
||||||
|
|
||||||
async def _perform_compliance_check(self, entity_id: str) -> None:
|
|
||||||
"""Perform compliance check for entity"""
|
|
||||||
try:
|
|
||||||
compliance_task = {
|
|
||||||
"type": "compliance_check",
|
|
||||||
"user_id": entity_id,
|
|
||||||
"check_type": "full",
|
|
||||||
"monitored_activities": ["trading", "transfers", "wallet_creation"]
|
|
||||||
}
|
|
||||||
|
|
||||||
result = await self.bridge.execute_agent_task(self.agent_id, compliance_task)
|
|
||||||
|
|
||||||
if result.get("status") == "success":
|
|
||||||
compliance_result = result["result"]
|
|
||||||
await self._handle_compliance_result(entity_id, compliance_result)
|
|
||||||
else:
|
|
||||||
print(f"Compliance check failed for {entity_id}: {result}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error performing compliance check for {entity_id}: {e}")
|
|
||||||
|
|
||||||
async def _handle_compliance_result(self, entity_id: str, result: Dict[str, Any]) -> None:
|
|
||||||
"""Handle compliance check result"""
|
|
||||||
status = result.get("status", "unknown")
|
|
||||||
|
|
||||||
if status == "passed":
|
|
||||||
print(f"✅ Compliance check passed for {entity_id}")
|
|
||||||
elif status == "failed":
|
|
||||||
print(f"❌ Compliance check failed for {entity_id}")
|
|
||||||
# Trigger alert or further investigation
|
|
||||||
await self._trigger_compliance_alert(entity_id, result)
|
|
||||||
else:
|
|
||||||
print(f"⚠️ Compliance check inconclusive for {entity_id}")
|
|
||||||
|
|
||||||
async def _trigger_compliance_alert(self, entity_id: str, result: Dict[str, Any]) -> None:
|
|
||||||
"""Trigger compliance alert"""
|
|
||||||
alert_data = {
|
|
||||||
"entity_id": entity_id,
|
|
||||||
"alert_type": "compliance_failure",
|
|
||||||
"severity": "high",
|
|
||||||
"details": result,
|
|
||||||
"timestamp": datetime.utcnow().isoformat()
|
|
||||||
}
|
|
||||||
|
|
||||||
# In a real implementation, this would send to alert system
|
|
||||||
print(f"🚨 COMPLIANCE ALERT: {json.dumps(alert_data, indent=2)}")
|
|
||||||
|
|
||||||
async def get_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get agent status"""
|
|
||||||
status = await self.bridge.get_agent_status(self.agent_id)
|
|
||||||
status["monitored_entities"] = len(self.monitored_entities)
|
|
||||||
status["check_interval"] = self.check_interval
|
|
||||||
return status
|
|
||||||
|
|
||||||
# Main execution
|
|
||||||
async def main():
|
|
||||||
"""Main compliance agent execution"""
|
|
||||||
agent_id = "compliance-agent-001"
|
|
||||||
config = {
|
|
||||||
"check_interval": 60, # 1 minute for testing
|
|
||||||
"monitored_entities": ["user001", "user002", "user003"]
|
|
||||||
}
|
|
||||||
|
|
||||||
agent = ComplianceAgent(agent_id, config)
|
|
||||||
|
|
||||||
# Start agent
|
|
||||||
if await agent.start():
|
|
||||||
try:
|
|
||||||
# Run compliance loop
|
|
||||||
await agent.run_compliance_loop()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("Shutting down compliance agent...")
|
|
||||||
finally:
|
|
||||||
await agent.stop()
|
|
||||||
else:
|
|
||||||
print("Failed to start compliance agent")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
asyncio.run(main())
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Agent Coordinator Service
|
|
||||||
Agent task coordination and management
|
|
||||||
"""
|
|
||||||
|
|
||||||
from fastapi import FastAPI, HTTPException
|
|
||||||
from pydantic import BaseModel
|
|
||||||
from typing import List, Optional, Dict, Any
|
|
||||||
import json
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime
|
|
||||||
import sqlite3
|
|
||||||
from contextlib import contextmanager
|
|
||||||
from contextlib import asynccontextmanager
|
|
||||||
|
|
||||||
@asynccontextmanager
|
|
||||||
async def lifespan(app: FastAPI):
|
|
||||||
# Startup
|
|
||||||
init_db()
|
|
||||||
yield
|
|
||||||
# Shutdown (cleanup if needed)
|
|
||||||
pass
|
|
||||||
|
|
||||||
app = FastAPI(title="AITBC Agent Coordinator API", version="1.0.0", lifespan=lifespan)
|
|
||||||
|
|
||||||
# Database setup
|
|
||||||
def get_db():
|
|
||||||
conn = sqlite3.connect('agent_coordinator.db')
|
|
||||||
conn.row_factory = sqlite3.Row
|
|
||||||
return conn
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def get_db_connection():
|
|
||||||
conn = get_db()
|
|
||||||
try:
|
|
||||||
yield conn
|
|
||||||
finally:
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
# Initialize database
|
|
||||||
def init_db():
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
CREATE TABLE IF NOT EXISTS tasks (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
task_type TEXT NOT NULL,
|
|
||||||
payload TEXT NOT NULL,
|
|
||||||
required_capabilities TEXT NOT NULL,
|
|
||||||
priority TEXT NOT NULL,
|
|
||||||
status TEXT NOT NULL,
|
|
||||||
assigned_agent_id TEXT,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
result TEXT
|
|
||||||
)
|
|
||||||
''')
|
|
||||||
|
|
||||||
# Models
|
|
||||||
class Task(BaseModel):
|
|
||||||
id: str
|
|
||||||
task_type: str
|
|
||||||
payload: Dict[str, Any]
|
|
||||||
required_capabilities: List[str]
|
|
||||||
priority: str
|
|
||||||
status: str
|
|
||||||
assigned_agent_id: Optional[str] = None
|
|
||||||
|
|
||||||
class TaskCreation(BaseModel):
|
|
||||||
task_type: str
|
|
||||||
payload: Dict[str, Any]
|
|
||||||
required_capabilities: List[str]
|
|
||||||
priority: str = "normal"
|
|
||||||
|
|
||||||
# API Endpoints
|
|
||||||
|
|
||||||
@app.post("/api/tasks", response_model=Task)
|
|
||||||
async def create_task(task: TaskCreation):
|
|
||||||
"""Create a new task"""
|
|
||||||
task_id = str(uuid.uuid4())
|
|
||||||
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
INSERT INTO tasks (id, task_type, payload, required_capabilities, priority, status)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?)
|
|
||||||
''', (
|
|
||||||
task_id, task.task_type, json.dumps(task.payload),
|
|
||||||
json.dumps(task.required_capabilities), task.priority, "pending"
|
|
||||||
))
|
|
||||||
|
|
||||||
return Task(
|
|
||||||
id=task_id,
|
|
||||||
task_type=task.task_type,
|
|
||||||
payload=task.payload,
|
|
||||||
required_capabilities=task.required_capabilities,
|
|
||||||
priority=task.priority,
|
|
||||||
status="pending"
|
|
||||||
)
|
|
||||||
|
|
||||||
@app.get("/api/tasks", response_model=List[Task])
|
|
||||||
async def list_tasks(status: Optional[str] = None):
|
|
||||||
"""List tasks with optional status filter"""
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
query = "SELECT * FROM tasks"
|
|
||||||
params = []
|
|
||||||
|
|
||||||
if status:
|
|
||||||
query += " WHERE status = ?"
|
|
||||||
params.append(status)
|
|
||||||
|
|
||||||
tasks = conn.execute(query, params).fetchall()
|
|
||||||
|
|
||||||
return [
|
|
||||||
Task(
|
|
||||||
id=task["id"],
|
|
||||||
task_type=task["task_type"],
|
|
||||||
payload=json.loads(task["payload"]),
|
|
||||||
required_capabilities=json.loads(task["required_capabilities"]),
|
|
||||||
priority=task["priority"],
|
|
||||||
status=task["status"],
|
|
||||||
assigned_agent_id=task["assigned_agent_id"]
|
|
||||||
)
|
|
||||||
for task in tasks
|
|
||||||
]
|
|
||||||
|
|
||||||
@app.get("/api/health")
|
|
||||||
async def health_check():
|
|
||||||
"""Health check endpoint"""
|
|
||||||
return {"status": "ok", "timestamp": datetime.utcnow()}
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import uvicorn
|
|
||||||
uvicorn.run(app, host="0.0.0.0", port=8012)
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
# AITBC Agent Protocols Environment Configuration
|
|
||||||
# Copy this file to .env and update with your secure values
|
|
||||||
|
|
||||||
# Agent Protocol Encryption Key (generate a strong, unique key)
|
|
||||||
AITBC_AGENT_PROTOCOL_KEY=your-secure-encryption-key-here
|
|
||||||
|
|
||||||
# Agent Protocol Salt (generate a unique salt value)
|
|
||||||
AITBC_AGENT_PROTOCOL_SALT=your-unique-salt-value-here
|
|
||||||
|
|
||||||
# Agent Registry Configuration
|
|
||||||
AGENT_REGISTRY_HOST=0.0.0.0
|
|
||||||
AGENT_REGISTRY_PORT=8003
|
|
||||||
|
|
||||||
# Database Configuration
|
|
||||||
AGENT_REGISTRY_DB_PATH=agent_registry.db
|
|
||||||
|
|
||||||
# Security Settings
|
|
||||||
AGENT_PROTOCOL_TIMEOUT=300
|
|
||||||
AGENT_PROTOCOL_MAX_RETRIES=3
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
"""
|
|
||||||
Agent Protocols Package
|
|
||||||
"""
|
|
||||||
|
|
||||||
from .message_protocol import MessageProtocol, MessageTypes, AgentMessageClient
|
|
||||||
from .task_manager import TaskManager, TaskStatus, TaskPriority, Task
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
"MessageProtocol",
|
|
||||||
"MessageTypes",
|
|
||||||
"AgentMessageClient",
|
|
||||||
"TaskManager",
|
|
||||||
"TaskStatus",
|
|
||||||
"TaskPriority",
|
|
||||||
"Task"
|
|
||||||
]
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
"""
|
|
||||||
Message Protocol for AITBC Agents
|
|
||||||
Handles message creation, routing, and delivery between agents
|
|
||||||
"""
|
|
||||||
|
|
||||||
import json
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime
|
|
||||||
from typing import Dict, Any, Optional, List
|
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
class MessageTypes(Enum):
|
|
||||||
"""Message type enumeration"""
|
|
||||||
TASK_REQUEST = "task_request"
|
|
||||||
TASK_RESPONSE = "task_response"
|
|
||||||
HEARTBEAT = "heartbeat"
|
|
||||||
STATUS_UPDATE = "status_update"
|
|
||||||
ERROR = "error"
|
|
||||||
DATA = "data"
|
|
||||||
|
|
||||||
class MessageProtocol:
|
|
||||||
"""Message protocol handler for agent communication"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.messages = []
|
|
||||||
self.message_handlers = {}
|
|
||||||
|
|
||||||
def create_message(
|
|
||||||
self,
|
|
||||||
sender_id: str,
|
|
||||||
receiver_id: str,
|
|
||||||
message_type: MessageTypes,
|
|
||||||
content: Dict[str, Any],
|
|
||||||
message_id: Optional[str] = None
|
|
||||||
) -> Dict[str, Any]:
|
|
||||||
"""Create a new message"""
|
|
||||||
if message_id is None:
|
|
||||||
message_id = str(uuid.uuid4())
|
|
||||||
|
|
||||||
message = {
|
|
||||||
"message_id": message_id,
|
|
||||||
"sender_id": sender_id,
|
|
||||||
"receiver_id": receiver_id,
|
|
||||||
"message_type": message_type.value,
|
|
||||||
"content": content,
|
|
||||||
"timestamp": datetime.utcnow().isoformat(),
|
|
||||||
"status": "pending"
|
|
||||||
}
|
|
||||||
|
|
||||||
self.messages.append(message)
|
|
||||||
return message
|
|
||||||
|
|
||||||
def send_message(self, message: Dict[str, Any]) -> bool:
|
|
||||||
"""Send a message to the receiver"""
|
|
||||||
try:
|
|
||||||
message["status"] = "sent"
|
|
||||||
message["sent_timestamp"] = datetime.utcnow().isoformat()
|
|
||||||
return True
|
|
||||||
except Exception:
|
|
||||||
message["status"] = "failed"
|
|
||||||
return False
|
|
||||||
|
|
||||||
def receive_message(self, message_id: str) -> Optional[Dict[str, Any]]:
|
|
||||||
"""Receive and process a message"""
|
|
||||||
for message in self.messages:
|
|
||||||
if message["message_id"] == message_id:
|
|
||||||
message["status"] = "received"
|
|
||||||
message["received_timestamp"] = datetime.utcnow().isoformat()
|
|
||||||
return message
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_messages_by_agent(self, agent_id: str) -> List[Dict[str, Any]]:
|
|
||||||
"""Get all messages for a specific agent"""
|
|
||||||
return [
|
|
||||||
msg for msg in self.messages
|
|
||||||
if msg["sender_id"] == agent_id or msg["receiver_id"] == agent_id
|
|
||||||
]
|
|
||||||
|
|
||||||
class AgentMessageClient:
|
|
||||||
"""Client for agent message communication"""
|
|
||||||
|
|
||||||
def __init__(self, agent_id: str, protocol: MessageProtocol):
|
|
||||||
self.agent_id = agent_id
|
|
||||||
self.protocol = protocol
|
|
||||||
self.received_messages = []
|
|
||||||
|
|
||||||
def send_message(
|
|
||||||
self,
|
|
||||||
receiver_id: str,
|
|
||||||
message_type: MessageTypes,
|
|
||||||
content: Dict[str, Any]
|
|
||||||
) -> Dict[str, Any]:
|
|
||||||
"""Send a message to another agent"""
|
|
||||||
message = self.protocol.create_message(
|
|
||||||
sender_id=self.agent_id,
|
|
||||||
receiver_id=receiver_id,
|
|
||||||
message_type=message_type,
|
|
||||||
content=content
|
|
||||||
)
|
|
||||||
self.protocol.send_message(message)
|
|
||||||
return message
|
|
||||||
|
|
||||||
def receive_messages(self) -> List[Dict[str, Any]]:
|
|
||||||
"""Receive all pending messages for this agent"""
|
|
||||||
messages = []
|
|
||||||
for message in self.protocol.messages:
|
|
||||||
if (message["receiver_id"] == self.agent_id and
|
|
||||||
message["status"] == "sent" and
|
|
||||||
message not in self.received_messages):
|
|
||||||
self.protocol.receive_message(message["message_id"])
|
|
||||||
self.received_messages.append(message)
|
|
||||||
messages.append(message)
|
|
||||||
return messages
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
"""
|
|
||||||
Task Manager for AITBC Agents
|
|
||||||
Handles task creation, assignment, and tracking
|
|
||||||
"""
|
|
||||||
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
from typing import Dict, Any, Optional, List
|
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
class TaskStatus(Enum):
|
|
||||||
"""Task status enumeration"""
|
|
||||||
PENDING = "pending"
|
|
||||||
IN_PROGRESS = "in_progress"
|
|
||||||
COMPLETED = "completed"
|
|
||||||
FAILED = "failed"
|
|
||||||
CANCELLED = "cancelled"
|
|
||||||
|
|
||||||
class TaskPriority(Enum):
|
|
||||||
"""Task priority enumeration"""
|
|
||||||
LOW = "low"
|
|
||||||
MEDIUM = "medium"
|
|
||||||
HIGH = "high"
|
|
||||||
URGENT = "urgent"
|
|
||||||
|
|
||||||
class Task:
|
|
||||||
"""Task representation"""
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
task_id: str,
|
|
||||||
title: str,
|
|
||||||
description: str,
|
|
||||||
assigned_to: str,
|
|
||||||
priority: TaskPriority = TaskPriority.MEDIUM,
|
|
||||||
created_by: Optional[str] = None
|
|
||||||
):
|
|
||||||
self.task_id = task_id
|
|
||||||
self.title = title
|
|
||||||
self.description = description
|
|
||||||
self.assigned_to = assigned_to
|
|
||||||
self.priority = priority
|
|
||||||
self.created_by = created_by or assigned_to
|
|
||||||
self.status = TaskStatus.PENDING
|
|
||||||
self.created_at = datetime.utcnow()
|
|
||||||
self.updated_at = datetime.utcnow()
|
|
||||||
self.completed_at = None
|
|
||||||
self.result = None
|
|
||||||
self.error = None
|
|
||||||
|
|
||||||
class TaskManager:
|
|
||||||
"""Task manager for agent coordination"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.tasks = {}
|
|
||||||
self.task_history = []
|
|
||||||
|
|
||||||
def create_task(
|
|
||||||
self,
|
|
||||||
title: str,
|
|
||||||
description: str,
|
|
||||||
assigned_to: str,
|
|
||||||
priority: TaskPriority = TaskPriority.MEDIUM,
|
|
||||||
created_by: Optional[str] = None
|
|
||||||
) -> Task:
|
|
||||||
"""Create a new task"""
|
|
||||||
task_id = str(uuid.uuid4())
|
|
||||||
task = Task(
|
|
||||||
task_id=task_id,
|
|
||||||
title=title,
|
|
||||||
description=description,
|
|
||||||
assigned_to=assigned_to,
|
|
||||||
priority=priority,
|
|
||||||
created_by=created_by
|
|
||||||
)
|
|
||||||
|
|
||||||
self.tasks[task_id] = task
|
|
||||||
return task
|
|
||||||
|
|
||||||
def get_task(self, task_id: str) -> Optional[Task]:
|
|
||||||
"""Get a task by ID"""
|
|
||||||
return self.tasks.get(task_id)
|
|
||||||
|
|
||||||
def update_task_status(
|
|
||||||
self,
|
|
||||||
task_id: str,
|
|
||||||
status: TaskStatus,
|
|
||||||
result: Optional[Dict[str, Any]] = None,
|
|
||||||
error: Optional[str] = None
|
|
||||||
) -> bool:
|
|
||||||
"""Update task status"""
|
|
||||||
task = self.get_task(task_id)
|
|
||||||
if not task:
|
|
||||||
return False
|
|
||||||
|
|
||||||
task.status = status
|
|
||||||
task.updated_at = datetime.utcnow()
|
|
||||||
|
|
||||||
if status == TaskStatus.COMPLETED:
|
|
||||||
task.completed_at = datetime.utcnow()
|
|
||||||
task.result = result
|
|
||||||
elif status == TaskStatus.FAILED:
|
|
||||||
task.error = error
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def get_tasks_by_agent(self, agent_id: str) -> List[Task]:
|
|
||||||
"""Get all tasks assigned to an agent"""
|
|
||||||
return [
|
|
||||||
task for task in self.tasks.values()
|
|
||||||
if task.assigned_to == agent_id
|
|
||||||
]
|
|
||||||
|
|
||||||
def get_tasks_by_status(self, status: TaskStatus) -> List[Task]:
|
|
||||||
"""Get all tasks with a specific status"""
|
|
||||||
return [
|
|
||||||
task for task in self.tasks.values()
|
|
||||||
if task.status == status
|
|
||||||
]
|
|
||||||
|
|
||||||
def get_overdue_tasks(self, hours: int = 24) -> List[Task]:
|
|
||||||
"""Get tasks that are overdue"""
|
|
||||||
cutoff_time = datetime.utcnow() - timedelta(hours=hours)
|
|
||||||
return [
|
|
||||||
task for task in self.tasks.values()
|
|
||||||
if task.status in [TaskStatus.PENDING, TaskStatus.IN_PROGRESS] and
|
|
||||||
task.created_at < cutoff_time
|
|
||||||
]
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Agent Registry Service
|
|
||||||
Central agent discovery and registration system
|
|
||||||
"""
|
|
||||||
|
|
||||||
from fastapi import FastAPI, HTTPException, Depends
|
|
||||||
from pydantic import BaseModel
|
|
||||||
from typing import List, Optional, Dict, Any
|
|
||||||
import json
|
|
||||||
import time
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
import sqlite3
|
|
||||||
from contextlib import contextmanager
|
|
||||||
from contextlib import asynccontextmanager
|
|
||||||
|
|
||||||
@asynccontextmanager
|
|
||||||
async def lifespan(app: FastAPI):
|
|
||||||
# Startup
|
|
||||||
init_db()
|
|
||||||
yield
|
|
||||||
# Shutdown (cleanup if needed)
|
|
||||||
pass
|
|
||||||
|
|
||||||
app = FastAPI(title="AITBC Agent Registry API", version="1.0.0", lifespan=lifespan)
|
|
||||||
|
|
||||||
# Database setup
|
|
||||||
def get_db():
|
|
||||||
conn = sqlite3.connect('agent_registry.db')
|
|
||||||
conn.row_factory = sqlite3.Row
|
|
||||||
return conn
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def get_db_connection():
|
|
||||||
conn = get_db()
|
|
||||||
try:
|
|
||||||
yield conn
|
|
||||||
finally:
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
# Initialize database
|
|
||||||
def init_db():
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
CREATE TABLE IF NOT EXISTS agents (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
name TEXT NOT NULL,
|
|
||||||
type TEXT NOT NULL,
|
|
||||||
capabilities TEXT NOT NULL,
|
|
||||||
chain_id TEXT NOT NULL,
|
|
||||||
endpoint TEXT NOT NULL,
|
|
||||||
status TEXT DEFAULT 'active',
|
|
||||||
last_heartbeat TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
metadata TEXT,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
||||||
)
|
|
||||||
''')
|
|
||||||
|
|
||||||
# Models
|
|
||||||
class Agent(BaseModel):
|
|
||||||
id: str
|
|
||||||
name: str
|
|
||||||
type: str
|
|
||||||
capabilities: List[str]
|
|
||||||
chain_id: str
|
|
||||||
endpoint: str
|
|
||||||
metadata: Optional[Dict[str, Any]] = {}
|
|
||||||
|
|
||||||
class AgentRegistration(BaseModel):
|
|
||||||
name: str
|
|
||||||
type: str
|
|
||||||
capabilities: List[str]
|
|
||||||
chain_id: str
|
|
||||||
endpoint: str
|
|
||||||
metadata: Optional[Dict[str, Any]] = {}
|
|
||||||
|
|
||||||
# API Endpoints
|
|
||||||
|
|
||||||
@app.post("/api/agents/register", response_model=Agent)
|
|
||||||
async def register_agent(agent: AgentRegistration):
|
|
||||||
"""Register a new agent"""
|
|
||||||
agent_id = str(uuid.uuid4())
|
|
||||||
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
INSERT INTO agents (id, name, type, capabilities, chain_id, endpoint, metadata)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
||||||
''', (
|
|
||||||
agent_id, agent.name, agent.type,
|
|
||||||
json.dumps(agent.capabilities), agent.chain_id,
|
|
||||||
agent.endpoint, json.dumps(agent.metadata)
|
|
||||||
))
|
|
||||||
conn.commit()
|
|
||||||
|
|
||||||
return Agent(
|
|
||||||
id=agent_id,
|
|
||||||
name=agent.name,
|
|
||||||
type=agent.type,
|
|
||||||
capabilities=agent.capabilities,
|
|
||||||
chain_id=agent.chain_id,
|
|
||||||
endpoint=agent.endpoint,
|
|
||||||
metadata=agent.metadata
|
|
||||||
)
|
|
||||||
|
|
||||||
@app.get("/api/agents", response_model=List[Agent])
|
|
||||||
async def list_agents(
|
|
||||||
agent_type: Optional[str] = None,
|
|
||||||
chain_id: Optional[str] = None,
|
|
||||||
capability: Optional[str] = None
|
|
||||||
):
|
|
||||||
"""List registered agents with optional filters"""
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
query = "SELECT * FROM agents WHERE status = 'active'"
|
|
||||||
params = []
|
|
||||||
|
|
||||||
if agent_type:
|
|
||||||
query += " AND type = ?"
|
|
||||||
params.append(agent_type)
|
|
||||||
|
|
||||||
if chain_id:
|
|
||||||
query += " AND chain_id = ?"
|
|
||||||
params.append(chain_id)
|
|
||||||
|
|
||||||
if capability:
|
|
||||||
query += " AND capabilities LIKE ?"
|
|
||||||
params.append(f'%{capability}%')
|
|
||||||
|
|
||||||
agents = conn.execute(query, params).fetchall()
|
|
||||||
|
|
||||||
return [
|
|
||||||
Agent(
|
|
||||||
id=agent["id"],
|
|
||||||
name=agent["name"],
|
|
||||||
type=agent["type"],
|
|
||||||
capabilities=json.loads(agent["capabilities"]),
|
|
||||||
chain_id=agent["chain_id"],
|
|
||||||
endpoint=agent["endpoint"],
|
|
||||||
metadata=json.loads(agent["metadata"] or "{}")
|
|
||||||
)
|
|
||||||
for agent in agents
|
|
||||||
]
|
|
||||||
|
|
||||||
@app.get("/api/health")
|
|
||||||
async def health_check():
|
|
||||||
"""Health check endpoint"""
|
|
||||||
return {"status": "ok", "timestamp": datetime.utcnow()}
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import uvicorn
|
|
||||||
uvicorn.run(app, host="0.0.0.0", port=8013)
|
|
||||||
@@ -1,166 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Trading Agent
|
|
||||||
Automated trading agent for AITBC marketplace
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import json
|
|
||||||
import time
|
|
||||||
from typing import Dict, Any, List
|
|
||||||
from datetime import datetime
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Add parent directory to path
|
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '../../../..'))
|
|
||||||
|
|
||||||
from apps.agent_services.agent_bridge.src.integration_layer import AgentServiceBridge
|
|
||||||
|
|
||||||
class TradingAgent:
|
|
||||||
"""Automated trading agent"""
|
|
||||||
|
|
||||||
def __init__(self, agent_id: str, config: Dict[str, Any]):
|
|
||||||
self.agent_id = agent_id
|
|
||||||
self.config = config
|
|
||||||
self.bridge = AgentServiceBridge()
|
|
||||||
self.is_running = False
|
|
||||||
self.trading_strategy = config.get("strategy", "basic")
|
|
||||||
self.symbols = config.get("symbols", ["AITBC/BTC"])
|
|
||||||
self.trade_interval = config.get("trade_interval", 60) # seconds
|
|
||||||
|
|
||||||
async def start(self) -> bool:
|
|
||||||
"""Start trading agent"""
|
|
||||||
try:
|
|
||||||
# Register with service bridge
|
|
||||||
success = await self.bridge.start_agent(self.agent_id, {
|
|
||||||
"type": "trading",
|
|
||||||
"capabilities": ["market_analysis", "trading", "risk_management"],
|
|
||||||
"endpoint": f"http://localhost:8005"
|
|
||||||
})
|
|
||||||
|
|
||||||
if success:
|
|
||||||
self.is_running = True
|
|
||||||
print(f"Trading agent {self.agent_id} started successfully")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f"Failed to start trading agent {self.agent_id}")
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error starting trading agent: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def stop(self) -> bool:
|
|
||||||
"""Stop trading agent"""
|
|
||||||
self.is_running = False
|
|
||||||
success = await self.bridge.stop_agent(self.agent_id)
|
|
||||||
if success:
|
|
||||||
print(f"Trading agent {self.agent_id} stopped successfully")
|
|
||||||
return success
|
|
||||||
|
|
||||||
async def run_trading_loop(self):
|
|
||||||
"""Main trading loop"""
|
|
||||||
while self.is_running:
|
|
||||||
try:
|
|
||||||
for symbol in self.symbols:
|
|
||||||
await self._analyze_and_trade(symbol)
|
|
||||||
|
|
||||||
await asyncio.sleep(self.trade_interval)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error in trading loop: {e}")
|
|
||||||
await asyncio.sleep(10) # Wait before retrying
|
|
||||||
|
|
||||||
async def _analyze_and_trade(self, symbol: str) -> None:
|
|
||||||
"""Analyze market and execute trades"""
|
|
||||||
try:
|
|
||||||
# Perform market analysis
|
|
||||||
analysis_task = {
|
|
||||||
"type": "market_analysis",
|
|
||||||
"symbol": symbol,
|
|
||||||
"strategy": self.trading_strategy
|
|
||||||
}
|
|
||||||
|
|
||||||
analysis_result = await self.bridge.execute_agent_task(self.agent_id, analysis_task)
|
|
||||||
|
|
||||||
if analysis_result.get("status") == "success":
|
|
||||||
analysis = analysis_result["result"]["analysis"]
|
|
||||||
|
|
||||||
# Make trading decision
|
|
||||||
if self._should_trade(analysis):
|
|
||||||
await self._execute_trade(symbol, analysis)
|
|
||||||
else:
|
|
||||||
print(f"Market analysis failed for {symbol}: {analysis_result}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error in analyze_and_trade for {symbol}: {e}")
|
|
||||||
|
|
||||||
def _should_trade(self, analysis: Dict[str, Any]) -> bool:
|
|
||||||
"""Determine if should execute trade"""
|
|
||||||
recommendation = analysis.get("recommendation", "hold")
|
|
||||||
return recommendation in ["buy", "sell"]
|
|
||||||
|
|
||||||
async def _execute_trade(self, symbol: str, analysis: Dict[str, Any]) -> None:
|
|
||||||
"""Execute trade based on analysis"""
|
|
||||||
try:
|
|
||||||
recommendation = analysis.get("recommendation", "hold")
|
|
||||||
|
|
||||||
if recommendation == "buy":
|
|
||||||
trade_task = {
|
|
||||||
"type": "trading",
|
|
||||||
"symbol": symbol,
|
|
||||||
"side": "buy",
|
|
||||||
"amount": self.config.get("trade_amount", 0.1),
|
|
||||||
"strategy": self.trading_strategy
|
|
||||||
}
|
|
||||||
elif recommendation == "sell":
|
|
||||||
trade_task = {
|
|
||||||
"type": "trading",
|
|
||||||
"symbol": symbol,
|
|
||||||
"side": "sell",
|
|
||||||
"amount": self.config.get("trade_amount", 0.1),
|
|
||||||
"strategy": self.trading_strategy
|
|
||||||
}
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
|
|
||||||
trade_result = await self.bridge.execute_agent_task(self.agent_id, trade_task)
|
|
||||||
|
|
||||||
if trade_result.get("status") == "success":
|
|
||||||
print(f"Trade executed successfully: {trade_result}")
|
|
||||||
else:
|
|
||||||
print(f"Trade execution failed: {trade_result}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error executing trade: {e}")
|
|
||||||
|
|
||||||
async def get_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get agent status"""
|
|
||||||
return await self.bridge.get_agent_status(self.agent_id)
|
|
||||||
|
|
||||||
# Main execution
|
|
||||||
async def main():
|
|
||||||
"""Main trading agent execution"""
|
|
||||||
agent_id = "trading-agent-001"
|
|
||||||
config = {
|
|
||||||
"strategy": "basic",
|
|
||||||
"symbols": ["AITBC/BTC"],
|
|
||||||
"trade_interval": 30,
|
|
||||||
"trade_amount": 0.1
|
|
||||||
}
|
|
||||||
|
|
||||||
agent = TradingAgent(agent_id, config)
|
|
||||||
|
|
||||||
# Start agent
|
|
||||||
if await agent.start():
|
|
||||||
try:
|
|
||||||
# Run trading loop
|
|
||||||
await agent.run_trading_loop()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("Shutting down trading agent...")
|
|
||||||
finally:
|
|
||||||
await agent.stop()
|
|
||||||
else:
|
|
||||||
print("Failed to start trading agent")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
asyncio.run(main())
|
|
||||||
@@ -1,229 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Agent Integration Layer
|
|
||||||
Connects agent protocols to existing AITBC services
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import aiohttp
|
|
||||||
import json
|
|
||||||
from typing import Dict, Any, List, Optional
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
class AITBCServiceIntegration:
|
|
||||||
"""Integration layer for AITBC services"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.service_endpoints = {
|
|
||||||
"coordinator_api": "http://localhost:8000",
|
|
||||||
"blockchain_rpc": "http://localhost:8006",
|
|
||||||
"exchange_service": "http://localhost:8001",
|
|
||||||
"marketplace": "http://localhost:8002",
|
|
||||||
"agent_registry": "http://localhost:8013"
|
|
||||||
}
|
|
||||||
self.session = None
|
|
||||||
|
|
||||||
async def __aenter__(self):
|
|
||||||
self.session = aiohttp.ClientSession()
|
|
||||||
return self
|
|
||||||
|
|
||||||
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
||||||
if self.session:
|
|
||||||
await self.session.close()
|
|
||||||
|
|
||||||
async def get_blockchain_info(self) -> Dict[str, Any]:
|
|
||||||
"""Get blockchain information"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['blockchain_rpc']}/health") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "unavailable"}
|
|
||||||
|
|
||||||
async def get_exchange_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get exchange service status"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['exchange_service']}/api/health") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "unavailable"}
|
|
||||||
|
|
||||||
async def get_coordinator_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get coordinator API status"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['coordinator_api']}/health") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "unavailable"}
|
|
||||||
|
|
||||||
async def submit_transaction(self, transaction_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Submit transaction to blockchain"""
|
|
||||||
try:
|
|
||||||
async with self.session.post(
|
|
||||||
f"{self.service_endpoints['blockchain_rpc']}/rpc/submit",
|
|
||||||
json=transaction_data
|
|
||||||
) as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "failed"}
|
|
||||||
|
|
||||||
async def get_market_data(self, symbol: str = "AITBC/BTC") -> Dict[str, Any]:
|
|
||||||
"""Get market data from exchange"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['exchange_service']}/api/market/{symbol}") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "failed"}
|
|
||||||
|
|
||||||
async def register_agent_with_coordinator(self, agent_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Register agent with coordinator"""
|
|
||||||
try:
|
|
||||||
async with self.session.post(
|
|
||||||
f"{self.service_endpoints['agent_registry']}/api/agents/register",
|
|
||||||
json=agent_data
|
|
||||||
) as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "failed"}
|
|
||||||
|
|
||||||
class AgentServiceBridge:
|
|
||||||
"""Bridge between agents and AITBC services"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.integration = AITBCServiceIntegration()
|
|
||||||
self.active_agents = {}
|
|
||||||
|
|
||||||
async def start_agent(self, agent_id: str, agent_config: Dict[str, Any]) -> bool:
|
|
||||||
"""Start an agent with service integration"""
|
|
||||||
try:
|
|
||||||
# Register agent with coordinator
|
|
||||||
async with self.integration as integration:
|
|
||||||
registration_result = await integration.register_agent_with_coordinator({
|
|
||||||
"name": agent_id,
|
|
||||||
"type": agent_config.get("type", "generic"),
|
|
||||||
"capabilities": agent_config.get("capabilities", []),
|
|
||||||
"chain_id": agent_config.get("chain_id", "ait-mainnet"),
|
|
||||||
"endpoint": agent_config.get("endpoint", f"http://localhost:{8000 + len(self.active_agents) + 10}")
|
|
||||||
})
|
|
||||||
|
|
||||||
# The registry returns the created agent dict on success, not a {"status": "ok"} wrapper
|
|
||||||
if registration_result and "id" in registration_result:
|
|
||||||
self.active_agents[agent_id] = {
|
|
||||||
"config": agent_config,
|
|
||||||
"registration": registration_result,
|
|
||||||
"started_at": datetime.utcnow()
|
|
||||||
}
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f"Registration failed: {registration_result}")
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Failed to start agent {agent_id}: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def stop_agent(self, agent_id: str) -> bool:
|
|
||||||
"""Stop an agent"""
|
|
||||||
if agent_id in self.active_agents:
|
|
||||||
del self.active_agents[agent_id]
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def get_agent_status(self, agent_id: str) -> Dict[str, Any]:
|
|
||||||
"""Get agent status with service integration"""
|
|
||||||
if agent_id not in self.active_agents:
|
|
||||||
return {"status": "not_found"}
|
|
||||||
|
|
||||||
agent_info = self.active_agents[agent_id]
|
|
||||||
|
|
||||||
async with self.integration as integration:
|
|
||||||
# Get service statuses
|
|
||||||
blockchain_status = await integration.get_blockchain_info()
|
|
||||||
exchange_status = await integration.get_exchange_status()
|
|
||||||
coordinator_status = await integration.get_coordinator_status()
|
|
||||||
|
|
||||||
return {
|
|
||||||
"agent_id": agent_id,
|
|
||||||
"status": "active",
|
|
||||||
"started_at": agent_info["started_at"].isoformat(),
|
|
||||||
"services": {
|
|
||||||
"blockchain": blockchain_status,
|
|
||||||
"exchange": exchange_status,
|
|
||||||
"coordinator": coordinator_status
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async def execute_agent_task(self, agent_id: str, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute agent task with service integration"""
|
|
||||||
if agent_id not in self.active_agents:
|
|
||||||
return {"status": "error", "message": "Agent not found"}
|
|
||||||
|
|
||||||
task_type = task_data.get("type")
|
|
||||||
|
|
||||||
if task_type == "market_analysis":
|
|
||||||
return await self._execute_market_analysis(task_data)
|
|
||||||
elif task_type == "trading":
|
|
||||||
return await self._execute_trading_task(task_data)
|
|
||||||
elif task_type == "compliance_check":
|
|
||||||
return await self._execute_compliance_check(task_data)
|
|
||||||
else:
|
|
||||||
return {"status": "error", "message": f"Unknown task type: {task_type}"}
|
|
||||||
|
|
||||||
async def _execute_market_analysis(self, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute market analysis task"""
|
|
||||||
try:
|
|
||||||
async with self.integration as integration:
|
|
||||||
market_data = await integration.get_market_data(task_data.get("symbol", "AITBC/BTC"))
|
|
||||||
|
|
||||||
# Perform basic analysis
|
|
||||||
analysis_result = {
|
|
||||||
"symbol": task_data.get("symbol", "AITBC/BTC"),
|
|
||||||
"market_data": market_data,
|
|
||||||
"analysis": {
|
|
||||||
"trend": "neutral",
|
|
||||||
"volatility": "medium",
|
|
||||||
"recommendation": "hold"
|
|
||||||
},
|
|
||||||
"timestamp": datetime.utcnow().isoformat()
|
|
||||||
}
|
|
||||||
|
|
||||||
return {"status": "success", "result": analysis_result}
|
|
||||||
except Exception as e:
|
|
||||||
return {"status": "error", "message": str(e)}
|
|
||||||
|
|
||||||
async def _execute_trading_task(self, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute trading task"""
|
|
||||||
try:
|
|
||||||
# Get market data first
|
|
||||||
async with self.integration as integration:
|
|
||||||
market_data = await integration.get_market_data(task_data.get("symbol", "AITBC/BTC"))
|
|
||||||
|
|
||||||
# Create transaction
|
|
||||||
transaction = {
|
|
||||||
"type": "trade",
|
|
||||||
"symbol": task_data.get("symbol", "AITBC/BTC"),
|
|
||||||
"side": task_data.get("side", "buy"),
|
|
||||||
"amount": task_data.get("amount", 0.1),
|
|
||||||
"price": task_data.get("price", market_data.get("price", 0.001))
|
|
||||||
}
|
|
||||||
|
|
||||||
# Submit transaction
|
|
||||||
tx_result = await integration.submit_transaction(transaction)
|
|
||||||
|
|
||||||
return {"status": "success", "transaction": tx_result}
|
|
||||||
except Exception as e:
|
|
||||||
return {"status": "error", "message": str(e)}
|
|
||||||
|
|
||||||
async def _execute_compliance_check(self, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute compliance check task"""
|
|
||||||
try:
|
|
||||||
# Basic compliance check
|
|
||||||
compliance_result = {
|
|
||||||
"user_id": task_data.get("user_id"),
|
|
||||||
"check_type": task_data.get("check_type", "basic"),
|
|
||||||
"status": "passed",
|
|
||||||
"checks_performed": ["kyc", "aml", "sanctions"],
|
|
||||||
"timestamp": datetime.utcnow().isoformat()
|
|
||||||
}
|
|
||||||
|
|
||||||
return {"status": "success", "result": compliance_result}
|
|
||||||
except Exception as e:
|
|
||||||
return {"status": "error", "message": str(e)}
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Compliance Agent
|
|
||||||
Automated compliance and regulatory monitoring agent
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import json
|
|
||||||
import time
|
|
||||||
from typing import Dict, Any, List
|
|
||||||
from datetime import datetime
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Add parent directory to path
|
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '../../../..'))
|
|
||||||
|
|
||||||
from apps.agent_services.agent_bridge.src.integration_layer import AgentServiceBridge
|
|
||||||
|
|
||||||
class ComplianceAgent:
|
|
||||||
"""Automated compliance agent"""
|
|
||||||
|
|
||||||
def __init__(self, agent_id: str, config: Dict[str, Any]):
|
|
||||||
self.agent_id = agent_id
|
|
||||||
self.config = config
|
|
||||||
self.bridge = AgentServiceBridge()
|
|
||||||
self.is_running = False
|
|
||||||
self.check_interval = config.get("check_interval", 300) # 5 minutes
|
|
||||||
self.monitored_entities = config.get("monitored_entities", [])
|
|
||||||
|
|
||||||
async def start(self) -> bool:
|
|
||||||
"""Start compliance agent"""
|
|
||||||
try:
|
|
||||||
success = await self.bridge.start_agent(self.agent_id, {
|
|
||||||
"type": "compliance",
|
|
||||||
"capabilities": ["kyc_check", "aml_screening", "regulatory_reporting"],
|
|
||||||
"endpoint": f"http://localhost:8006"
|
|
||||||
})
|
|
||||||
|
|
||||||
if success:
|
|
||||||
self.is_running = True
|
|
||||||
print(f"Compliance agent {self.agent_id} started successfully")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f"Failed to start compliance agent {self.agent_id}")
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error starting compliance agent: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def stop(self) -> bool:
|
|
||||||
"""Stop compliance agent"""
|
|
||||||
self.is_running = False
|
|
||||||
success = await self.bridge.stop_agent(self.agent_id)
|
|
||||||
if success:
|
|
||||||
print(f"Compliance agent {self.agent_id} stopped successfully")
|
|
||||||
return success
|
|
||||||
|
|
||||||
async def run_compliance_loop(self):
|
|
||||||
"""Main compliance monitoring loop"""
|
|
||||||
while self.is_running:
|
|
||||||
try:
|
|
||||||
for entity in self.monitored_entities:
|
|
||||||
await self._perform_compliance_check(entity)
|
|
||||||
|
|
||||||
await asyncio.sleep(self.check_interval)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error in compliance loop: {e}")
|
|
||||||
await asyncio.sleep(30) # Wait before retrying
|
|
||||||
|
|
||||||
async def _perform_compliance_check(self, entity_id: str) -> None:
|
|
||||||
"""Perform compliance check for entity"""
|
|
||||||
try:
|
|
||||||
compliance_task = {
|
|
||||||
"type": "compliance_check",
|
|
||||||
"user_id": entity_id,
|
|
||||||
"check_type": "full",
|
|
||||||
"monitored_activities": ["trading", "transfers", "wallet_creation"]
|
|
||||||
}
|
|
||||||
|
|
||||||
result = await self.bridge.execute_agent_task(self.agent_id, compliance_task)
|
|
||||||
|
|
||||||
if result.get("status") == "success":
|
|
||||||
compliance_result = result["result"]
|
|
||||||
await self._handle_compliance_result(entity_id, compliance_result)
|
|
||||||
else:
|
|
||||||
print(f"Compliance check failed for {entity_id}: {result}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error performing compliance check for {entity_id}: {e}")
|
|
||||||
|
|
||||||
async def _handle_compliance_result(self, entity_id: str, result: Dict[str, Any]) -> None:
|
|
||||||
"""Handle compliance check result"""
|
|
||||||
status = result.get("status", "unknown")
|
|
||||||
|
|
||||||
if status == "passed":
|
|
||||||
print(f"✅ Compliance check passed for {entity_id}")
|
|
||||||
elif status == "failed":
|
|
||||||
print(f"❌ Compliance check failed for {entity_id}")
|
|
||||||
# Trigger alert or further investigation
|
|
||||||
await self._trigger_compliance_alert(entity_id, result)
|
|
||||||
else:
|
|
||||||
print(f"⚠️ Compliance check inconclusive for {entity_id}")
|
|
||||||
|
|
||||||
async def _trigger_compliance_alert(self, entity_id: str, result: Dict[str, Any]) -> None:
|
|
||||||
"""Trigger compliance alert"""
|
|
||||||
alert_data = {
|
|
||||||
"entity_id": entity_id,
|
|
||||||
"alert_type": "compliance_failure",
|
|
||||||
"severity": "high",
|
|
||||||
"details": result,
|
|
||||||
"timestamp": datetime.utcnow().isoformat()
|
|
||||||
}
|
|
||||||
|
|
||||||
# In a real implementation, this would send to alert system
|
|
||||||
print(f"🚨 COMPLIANCE ALERT: {json.dumps(alert_data, indent=2)}")
|
|
||||||
|
|
||||||
async def get_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get agent status"""
|
|
||||||
status = await self.bridge.get_agent_status(self.agent_id)
|
|
||||||
status["monitored_entities"] = len(self.monitored_entities)
|
|
||||||
status["check_interval"] = self.check_interval
|
|
||||||
return status
|
|
||||||
|
|
||||||
# Main execution
|
|
||||||
async def main():
|
|
||||||
"""Main compliance agent execution"""
|
|
||||||
agent_id = "compliance-agent-001"
|
|
||||||
config = {
|
|
||||||
"check_interval": 60, # 1 minute for testing
|
|
||||||
"monitored_entities": ["user001", "user002", "user003"]
|
|
||||||
}
|
|
||||||
|
|
||||||
agent = ComplianceAgent(agent_id, config)
|
|
||||||
|
|
||||||
# Start agent
|
|
||||||
if await agent.start():
|
|
||||||
try:
|
|
||||||
# Run compliance loop
|
|
||||||
await agent.run_compliance_loop()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("Shutting down compliance agent...")
|
|
||||||
finally:
|
|
||||||
await agent.stop()
|
|
||||||
else:
|
|
||||||
print("Failed to start compliance agent")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
asyncio.run(main())
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Agent Coordinator Service
|
|
||||||
Agent task coordination and management
|
|
||||||
"""
|
|
||||||
|
|
||||||
from fastapi import FastAPI, HTTPException
|
|
||||||
from pydantic import BaseModel
|
|
||||||
from typing import List, Optional, Dict, Any
|
|
||||||
import json
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime
|
|
||||||
import sqlite3
|
|
||||||
from contextlib import contextmanager
|
|
||||||
from contextlib import asynccontextmanager
|
|
||||||
|
|
||||||
@asynccontextmanager
|
|
||||||
async def lifespan(app: FastAPI):
|
|
||||||
# Startup
|
|
||||||
init_db()
|
|
||||||
yield
|
|
||||||
# Shutdown (cleanup if needed)
|
|
||||||
pass
|
|
||||||
|
|
||||||
app = FastAPI(title="AITBC Agent Coordinator API", version="1.0.0", lifespan=lifespan)
|
|
||||||
|
|
||||||
# Database setup
|
|
||||||
def get_db():
|
|
||||||
conn = sqlite3.connect('agent_coordinator.db')
|
|
||||||
conn.row_factory = sqlite3.Row
|
|
||||||
return conn
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def get_db_connection():
|
|
||||||
conn = get_db()
|
|
||||||
try:
|
|
||||||
yield conn
|
|
||||||
finally:
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
# Initialize database
|
|
||||||
def init_db():
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
CREATE TABLE IF NOT EXISTS tasks (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
task_type TEXT NOT NULL,
|
|
||||||
payload TEXT NOT NULL,
|
|
||||||
required_capabilities TEXT NOT NULL,
|
|
||||||
priority TEXT NOT NULL,
|
|
||||||
status TEXT NOT NULL,
|
|
||||||
assigned_agent_id TEXT,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
result TEXT
|
|
||||||
)
|
|
||||||
''')
|
|
||||||
|
|
||||||
# Models
|
|
||||||
class Task(BaseModel):
|
|
||||||
id: str
|
|
||||||
task_type: str
|
|
||||||
payload: Dict[str, Any]
|
|
||||||
required_capabilities: List[str]
|
|
||||||
priority: str
|
|
||||||
status: str
|
|
||||||
assigned_agent_id: Optional[str] = None
|
|
||||||
|
|
||||||
class TaskCreation(BaseModel):
|
|
||||||
task_type: str
|
|
||||||
payload: Dict[str, Any]
|
|
||||||
required_capabilities: List[str]
|
|
||||||
priority: str = "normal"
|
|
||||||
|
|
||||||
# API Endpoints
|
|
||||||
|
|
||||||
@app.post("/api/tasks", response_model=Task)
|
|
||||||
async def create_task(task: TaskCreation):
|
|
||||||
"""Create a new task"""
|
|
||||||
task_id = str(uuid.uuid4())
|
|
||||||
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
INSERT INTO tasks (id, task_type, payload, required_capabilities, priority, status)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?)
|
|
||||||
''', (
|
|
||||||
task_id, task.task_type, json.dumps(task.payload),
|
|
||||||
json.dumps(task.required_capabilities), task.priority, "pending"
|
|
||||||
))
|
|
||||||
|
|
||||||
return Task(
|
|
||||||
id=task_id,
|
|
||||||
task_type=task.task_type,
|
|
||||||
payload=task.payload,
|
|
||||||
required_capabilities=task.required_capabilities,
|
|
||||||
priority=task.priority,
|
|
||||||
status="pending"
|
|
||||||
)
|
|
||||||
|
|
||||||
@app.get("/api/tasks", response_model=List[Task])
|
|
||||||
async def list_tasks(status: Optional[str] = None):
|
|
||||||
"""List tasks with optional status filter"""
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
query = "SELECT * FROM tasks"
|
|
||||||
params = []
|
|
||||||
|
|
||||||
if status:
|
|
||||||
query += " WHERE status = ?"
|
|
||||||
params.append(status)
|
|
||||||
|
|
||||||
tasks = conn.execute(query, params).fetchall()
|
|
||||||
|
|
||||||
return [
|
|
||||||
Task(
|
|
||||||
id=task["id"],
|
|
||||||
task_type=task["task_type"],
|
|
||||||
payload=json.loads(task["payload"]),
|
|
||||||
required_capabilities=json.loads(task["required_capabilities"]),
|
|
||||||
priority=task["priority"],
|
|
||||||
status=task["status"],
|
|
||||||
assigned_agent_id=task["assigned_agent_id"]
|
|
||||||
)
|
|
||||||
for task in tasks
|
|
||||||
]
|
|
||||||
|
|
||||||
@app.get("/api/health")
|
|
||||||
async def health_check():
|
|
||||||
"""Health check endpoint"""
|
|
||||||
return {"status": "ok", "timestamp": datetime.utcnow()}
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import uvicorn
|
|
||||||
uvicorn.run(app, host="0.0.0.0", port=8012)
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
# AITBC Agent Protocols Environment Configuration
|
|
||||||
# Copy this file to .env and update with your secure values
|
|
||||||
|
|
||||||
# Agent Protocol Encryption Key (generate a strong, unique key)
|
|
||||||
AITBC_AGENT_PROTOCOL_KEY=your-secure-encryption-key-here
|
|
||||||
|
|
||||||
# Agent Protocol Salt (generate a unique salt value)
|
|
||||||
AITBC_AGENT_PROTOCOL_SALT=your-unique-salt-value-here
|
|
||||||
|
|
||||||
# Agent Registry Configuration
|
|
||||||
AGENT_REGISTRY_HOST=0.0.0.0
|
|
||||||
AGENT_REGISTRY_PORT=8003
|
|
||||||
|
|
||||||
# Database Configuration
|
|
||||||
AGENT_REGISTRY_DB_PATH=agent_registry.db
|
|
||||||
|
|
||||||
# Security Settings
|
|
||||||
AGENT_PROTOCOL_TIMEOUT=300
|
|
||||||
AGENT_PROTOCOL_MAX_RETRIES=3
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
"""
|
|
||||||
Agent Protocols Package
|
|
||||||
"""
|
|
||||||
|
|
||||||
from .message_protocol import MessageProtocol, MessageTypes, AgentMessageClient
|
|
||||||
from .task_manager import TaskManager, TaskStatus, TaskPriority, Task
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
"MessageProtocol",
|
|
||||||
"MessageTypes",
|
|
||||||
"AgentMessageClient",
|
|
||||||
"TaskManager",
|
|
||||||
"TaskStatus",
|
|
||||||
"TaskPriority",
|
|
||||||
"Task"
|
|
||||||
]
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
"""
|
|
||||||
Message Protocol for AITBC Agents
|
|
||||||
Handles message creation, routing, and delivery between agents
|
|
||||||
"""
|
|
||||||
|
|
||||||
import json
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime
|
|
||||||
from typing import Dict, Any, Optional, List
|
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
class MessageTypes(Enum):
|
|
||||||
"""Message type enumeration"""
|
|
||||||
TASK_REQUEST = "task_request"
|
|
||||||
TASK_RESPONSE = "task_response"
|
|
||||||
HEARTBEAT = "heartbeat"
|
|
||||||
STATUS_UPDATE = "status_update"
|
|
||||||
ERROR = "error"
|
|
||||||
DATA = "data"
|
|
||||||
|
|
||||||
class MessageProtocol:
|
|
||||||
"""Message protocol handler for agent communication"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.messages = []
|
|
||||||
self.message_handlers = {}
|
|
||||||
|
|
||||||
def create_message(
|
|
||||||
self,
|
|
||||||
sender_id: str,
|
|
||||||
receiver_id: str,
|
|
||||||
message_type: MessageTypes,
|
|
||||||
content: Dict[str, Any],
|
|
||||||
message_id: Optional[str] = None
|
|
||||||
) -> Dict[str, Any]:
|
|
||||||
"""Create a new message"""
|
|
||||||
if message_id is None:
|
|
||||||
message_id = str(uuid.uuid4())
|
|
||||||
|
|
||||||
message = {
|
|
||||||
"message_id": message_id,
|
|
||||||
"sender_id": sender_id,
|
|
||||||
"receiver_id": receiver_id,
|
|
||||||
"message_type": message_type.value,
|
|
||||||
"content": content,
|
|
||||||
"timestamp": datetime.utcnow().isoformat(),
|
|
||||||
"status": "pending"
|
|
||||||
}
|
|
||||||
|
|
||||||
self.messages.append(message)
|
|
||||||
return message
|
|
||||||
|
|
||||||
def send_message(self, message: Dict[str, Any]) -> bool:
|
|
||||||
"""Send a message to the receiver"""
|
|
||||||
try:
|
|
||||||
message["status"] = "sent"
|
|
||||||
message["sent_timestamp"] = datetime.utcnow().isoformat()
|
|
||||||
return True
|
|
||||||
except Exception:
|
|
||||||
message["status"] = "failed"
|
|
||||||
return False
|
|
||||||
|
|
||||||
def receive_message(self, message_id: str) -> Optional[Dict[str, Any]]:
|
|
||||||
"""Receive and process a message"""
|
|
||||||
for message in self.messages:
|
|
||||||
if message["message_id"] == message_id:
|
|
||||||
message["status"] = "received"
|
|
||||||
message["received_timestamp"] = datetime.utcnow().isoformat()
|
|
||||||
return message
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_messages_by_agent(self, agent_id: str) -> List[Dict[str, Any]]:
|
|
||||||
"""Get all messages for a specific agent"""
|
|
||||||
return [
|
|
||||||
msg for msg in self.messages
|
|
||||||
if msg["sender_id"] == agent_id or msg["receiver_id"] == agent_id
|
|
||||||
]
|
|
||||||
|
|
||||||
class AgentMessageClient:
|
|
||||||
"""Client for agent message communication"""
|
|
||||||
|
|
||||||
def __init__(self, agent_id: str, protocol: MessageProtocol):
|
|
||||||
self.agent_id = agent_id
|
|
||||||
self.protocol = protocol
|
|
||||||
self.received_messages = []
|
|
||||||
|
|
||||||
def send_message(
|
|
||||||
self,
|
|
||||||
receiver_id: str,
|
|
||||||
message_type: MessageTypes,
|
|
||||||
content: Dict[str, Any]
|
|
||||||
) -> Dict[str, Any]:
|
|
||||||
"""Send a message to another agent"""
|
|
||||||
message = self.protocol.create_message(
|
|
||||||
sender_id=self.agent_id,
|
|
||||||
receiver_id=receiver_id,
|
|
||||||
message_type=message_type,
|
|
||||||
content=content
|
|
||||||
)
|
|
||||||
self.protocol.send_message(message)
|
|
||||||
return message
|
|
||||||
|
|
||||||
def receive_messages(self) -> List[Dict[str, Any]]:
|
|
||||||
"""Receive all pending messages for this agent"""
|
|
||||||
messages = []
|
|
||||||
for message in self.protocol.messages:
|
|
||||||
if (message["receiver_id"] == self.agent_id and
|
|
||||||
message["status"] == "sent" and
|
|
||||||
message not in self.received_messages):
|
|
||||||
self.protocol.receive_message(message["message_id"])
|
|
||||||
self.received_messages.append(message)
|
|
||||||
messages.append(message)
|
|
||||||
return messages
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
"""
|
|
||||||
Task Manager for AITBC Agents
|
|
||||||
Handles task creation, assignment, and tracking
|
|
||||||
"""
|
|
||||||
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
from typing import Dict, Any, Optional, List
|
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
class TaskStatus(Enum):
|
|
||||||
"""Task status enumeration"""
|
|
||||||
PENDING = "pending"
|
|
||||||
IN_PROGRESS = "in_progress"
|
|
||||||
COMPLETED = "completed"
|
|
||||||
FAILED = "failed"
|
|
||||||
CANCELLED = "cancelled"
|
|
||||||
|
|
||||||
class TaskPriority(Enum):
|
|
||||||
"""Task priority enumeration"""
|
|
||||||
LOW = "low"
|
|
||||||
MEDIUM = "medium"
|
|
||||||
HIGH = "high"
|
|
||||||
URGENT = "urgent"
|
|
||||||
|
|
||||||
class Task:
|
|
||||||
"""Task representation"""
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
task_id: str,
|
|
||||||
title: str,
|
|
||||||
description: str,
|
|
||||||
assigned_to: str,
|
|
||||||
priority: TaskPriority = TaskPriority.MEDIUM,
|
|
||||||
created_by: Optional[str] = None
|
|
||||||
):
|
|
||||||
self.task_id = task_id
|
|
||||||
self.title = title
|
|
||||||
self.description = description
|
|
||||||
self.assigned_to = assigned_to
|
|
||||||
self.priority = priority
|
|
||||||
self.created_by = created_by or assigned_to
|
|
||||||
self.status = TaskStatus.PENDING
|
|
||||||
self.created_at = datetime.utcnow()
|
|
||||||
self.updated_at = datetime.utcnow()
|
|
||||||
self.completed_at = None
|
|
||||||
self.result = None
|
|
||||||
self.error = None
|
|
||||||
|
|
||||||
class TaskManager:
|
|
||||||
"""Task manager for agent coordination"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.tasks = {}
|
|
||||||
self.task_history = []
|
|
||||||
|
|
||||||
def create_task(
|
|
||||||
self,
|
|
||||||
title: str,
|
|
||||||
description: str,
|
|
||||||
assigned_to: str,
|
|
||||||
priority: TaskPriority = TaskPriority.MEDIUM,
|
|
||||||
created_by: Optional[str] = None
|
|
||||||
) -> Task:
|
|
||||||
"""Create a new task"""
|
|
||||||
task_id = str(uuid.uuid4())
|
|
||||||
task = Task(
|
|
||||||
task_id=task_id,
|
|
||||||
title=title,
|
|
||||||
description=description,
|
|
||||||
assigned_to=assigned_to,
|
|
||||||
priority=priority,
|
|
||||||
created_by=created_by
|
|
||||||
)
|
|
||||||
|
|
||||||
self.tasks[task_id] = task
|
|
||||||
return task
|
|
||||||
|
|
||||||
def get_task(self, task_id: str) -> Optional[Task]:
|
|
||||||
"""Get a task by ID"""
|
|
||||||
return self.tasks.get(task_id)
|
|
||||||
|
|
||||||
def update_task_status(
|
|
||||||
self,
|
|
||||||
task_id: str,
|
|
||||||
status: TaskStatus,
|
|
||||||
result: Optional[Dict[str, Any]] = None,
|
|
||||||
error: Optional[str] = None
|
|
||||||
) -> bool:
|
|
||||||
"""Update task status"""
|
|
||||||
task = self.get_task(task_id)
|
|
||||||
if not task:
|
|
||||||
return False
|
|
||||||
|
|
||||||
task.status = status
|
|
||||||
task.updated_at = datetime.utcnow()
|
|
||||||
|
|
||||||
if status == TaskStatus.COMPLETED:
|
|
||||||
task.completed_at = datetime.utcnow()
|
|
||||||
task.result = result
|
|
||||||
elif status == TaskStatus.FAILED:
|
|
||||||
task.error = error
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def get_tasks_by_agent(self, agent_id: str) -> List[Task]:
|
|
||||||
"""Get all tasks assigned to an agent"""
|
|
||||||
return [
|
|
||||||
task for task in self.tasks.values()
|
|
||||||
if task.assigned_to == agent_id
|
|
||||||
]
|
|
||||||
|
|
||||||
def get_tasks_by_status(self, status: TaskStatus) -> List[Task]:
|
|
||||||
"""Get all tasks with a specific status"""
|
|
||||||
return [
|
|
||||||
task for task in self.tasks.values()
|
|
||||||
if task.status == status
|
|
||||||
]
|
|
||||||
|
|
||||||
def get_overdue_tasks(self, hours: int = 24) -> List[Task]:
|
|
||||||
"""Get tasks that are overdue"""
|
|
||||||
cutoff_time = datetime.utcnow() - timedelta(hours=hours)
|
|
||||||
return [
|
|
||||||
task for task in self.tasks.values()
|
|
||||||
if task.status in [TaskStatus.PENDING, TaskStatus.IN_PROGRESS] and
|
|
||||||
task.created_at < cutoff_time
|
|
||||||
]
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Agent Registry Service
|
|
||||||
Central agent discovery and registration system
|
|
||||||
"""
|
|
||||||
|
|
||||||
from fastapi import FastAPI, HTTPException, Depends
|
|
||||||
from pydantic import BaseModel
|
|
||||||
from typing import List, Optional, Dict, Any
|
|
||||||
import json
|
|
||||||
import time
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
import sqlite3
|
|
||||||
from contextlib import contextmanager
|
|
||||||
from contextlib import asynccontextmanager
|
|
||||||
|
|
||||||
@asynccontextmanager
|
|
||||||
async def lifespan(app: FastAPI):
|
|
||||||
# Startup
|
|
||||||
init_db()
|
|
||||||
yield
|
|
||||||
# Shutdown (cleanup if needed)
|
|
||||||
pass
|
|
||||||
|
|
||||||
app = FastAPI(title="AITBC Agent Registry API", version="1.0.0", lifespan=lifespan)
|
|
||||||
|
|
||||||
# Database setup
|
|
||||||
def get_db():
|
|
||||||
conn = sqlite3.connect('agent_registry.db')
|
|
||||||
conn.row_factory = sqlite3.Row
|
|
||||||
return conn
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def get_db_connection():
|
|
||||||
conn = get_db()
|
|
||||||
try:
|
|
||||||
yield conn
|
|
||||||
finally:
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
# Initialize database
|
|
||||||
def init_db():
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
CREATE TABLE IF NOT EXISTS agents (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
name TEXT NOT NULL,
|
|
||||||
type TEXT NOT NULL,
|
|
||||||
capabilities TEXT NOT NULL,
|
|
||||||
chain_id TEXT NOT NULL,
|
|
||||||
endpoint TEXT NOT NULL,
|
|
||||||
status TEXT DEFAULT 'active',
|
|
||||||
last_heartbeat TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
metadata TEXT,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
||||||
)
|
|
||||||
''')
|
|
||||||
|
|
||||||
# Models
|
|
||||||
class Agent(BaseModel):
|
|
||||||
id: str
|
|
||||||
name: str
|
|
||||||
type: str
|
|
||||||
capabilities: List[str]
|
|
||||||
chain_id: str
|
|
||||||
endpoint: str
|
|
||||||
metadata: Optional[Dict[str, Any]] = {}
|
|
||||||
|
|
||||||
class AgentRegistration(BaseModel):
|
|
||||||
name: str
|
|
||||||
type: str
|
|
||||||
capabilities: List[str]
|
|
||||||
chain_id: str
|
|
||||||
endpoint: str
|
|
||||||
metadata: Optional[Dict[str, Any]] = {}
|
|
||||||
|
|
||||||
# API Endpoints
|
|
||||||
|
|
||||||
@app.post("/api/agents/register", response_model=Agent)
|
|
||||||
async def register_agent(agent: AgentRegistration):
|
|
||||||
"""Register a new agent"""
|
|
||||||
agent_id = str(uuid.uuid4())
|
|
||||||
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
INSERT INTO agents (id, name, type, capabilities, chain_id, endpoint, metadata)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
||||||
''', (
|
|
||||||
agent_id, agent.name, agent.type,
|
|
||||||
json.dumps(agent.capabilities), agent.chain_id,
|
|
||||||
agent.endpoint, json.dumps(agent.metadata)
|
|
||||||
))
|
|
||||||
conn.commit()
|
|
||||||
|
|
||||||
return Agent(
|
|
||||||
id=agent_id,
|
|
||||||
name=agent.name,
|
|
||||||
type=agent.type,
|
|
||||||
capabilities=agent.capabilities,
|
|
||||||
chain_id=agent.chain_id,
|
|
||||||
endpoint=agent.endpoint,
|
|
||||||
metadata=agent.metadata
|
|
||||||
)
|
|
||||||
|
|
||||||
@app.get("/api/agents", response_model=List[Agent])
|
|
||||||
async def list_agents(
|
|
||||||
agent_type: Optional[str] = None,
|
|
||||||
chain_id: Optional[str] = None,
|
|
||||||
capability: Optional[str] = None
|
|
||||||
):
|
|
||||||
"""List registered agents with optional filters"""
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
query = "SELECT * FROM agents WHERE status = 'active'"
|
|
||||||
params = []
|
|
||||||
|
|
||||||
if agent_type:
|
|
||||||
query += " AND type = ?"
|
|
||||||
params.append(agent_type)
|
|
||||||
|
|
||||||
if chain_id:
|
|
||||||
query += " AND chain_id = ?"
|
|
||||||
params.append(chain_id)
|
|
||||||
|
|
||||||
if capability:
|
|
||||||
query += " AND capabilities LIKE ?"
|
|
||||||
params.append(f'%{capability}%')
|
|
||||||
|
|
||||||
agents = conn.execute(query, params).fetchall()
|
|
||||||
|
|
||||||
return [
|
|
||||||
Agent(
|
|
||||||
id=agent["id"],
|
|
||||||
name=agent["name"],
|
|
||||||
type=agent["type"],
|
|
||||||
capabilities=json.loads(agent["capabilities"]),
|
|
||||||
chain_id=agent["chain_id"],
|
|
||||||
endpoint=agent["endpoint"],
|
|
||||||
metadata=json.loads(agent["metadata"] or "{}")
|
|
||||||
)
|
|
||||||
for agent in agents
|
|
||||||
]
|
|
||||||
|
|
||||||
@app.get("/api/health")
|
|
||||||
async def health_check():
|
|
||||||
"""Health check endpoint"""
|
|
||||||
return {"status": "ok", "timestamp": datetime.utcnow()}
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import uvicorn
|
|
||||||
uvicorn.run(app, host="0.0.0.0", port=8013)
|
|
||||||
@@ -1,431 +0,0 @@
|
|||||||
"""
|
|
||||||
Agent Registration System
|
|
||||||
Handles AI agent registration, capability management, and discovery
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import time
|
|
||||||
import json
|
|
||||||
import hashlib
|
|
||||||
from typing import Dict, List, Optional, Set, Tuple
|
|
||||||
from dataclasses import dataclass, asdict
|
|
||||||
from enum import Enum
|
|
||||||
from decimal import Decimal
|
|
||||||
|
|
||||||
class AgentType(Enum):
|
|
||||||
AI_MODEL = "ai_model"
|
|
||||||
DATA_PROVIDER = "data_provider"
|
|
||||||
VALIDATOR = "validator"
|
|
||||||
MARKET_MAKER = "market_maker"
|
|
||||||
BROKER = "broker"
|
|
||||||
ORACLE = "oracle"
|
|
||||||
|
|
||||||
class AgentStatus(Enum):
|
|
||||||
REGISTERED = "registered"
|
|
||||||
ACTIVE = "active"
|
|
||||||
INACTIVE = "inactive"
|
|
||||||
SUSPENDED = "suspended"
|
|
||||||
BANNED = "banned"
|
|
||||||
|
|
||||||
class CapabilityType(Enum):
|
|
||||||
TEXT_GENERATION = "text_generation"
|
|
||||||
IMAGE_GENERATION = "image_generation"
|
|
||||||
DATA_ANALYSIS = "data_analysis"
|
|
||||||
PREDICTION = "prediction"
|
|
||||||
VALIDATION = "validation"
|
|
||||||
COMPUTATION = "computation"
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class AgentCapability:
|
|
||||||
capability_type: CapabilityType
|
|
||||||
name: str
|
|
||||||
version: str
|
|
||||||
parameters: Dict
|
|
||||||
performance_metrics: Dict
|
|
||||||
cost_per_use: Decimal
|
|
||||||
availability: float
|
|
||||||
max_concurrent_jobs: int
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class AgentInfo:
|
|
||||||
agent_id: str
|
|
||||||
agent_type: AgentType
|
|
||||||
name: str
|
|
||||||
owner_address: str
|
|
||||||
public_key: str
|
|
||||||
endpoint_url: str
|
|
||||||
capabilities: List[AgentCapability]
|
|
||||||
reputation_score: float
|
|
||||||
total_jobs_completed: int
|
|
||||||
total_earnings: Decimal
|
|
||||||
registration_time: float
|
|
||||||
last_active: float
|
|
||||||
status: AgentStatus
|
|
||||||
metadata: Dict
|
|
||||||
|
|
||||||
class AgentRegistry:
|
|
||||||
"""Manages AI agent registration and discovery"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.agents: Dict[str, AgentInfo] = {}
|
|
||||||
self.capability_index: Dict[CapabilityType, Set[str]] = {} # capability -> agent_ids
|
|
||||||
self.type_index: Dict[AgentType, Set[str]] = {} # agent_type -> agent_ids
|
|
||||||
self.reputation_scores: Dict[str, float] = {}
|
|
||||||
self.registration_queue: List[Dict] = []
|
|
||||||
|
|
||||||
# Registry parameters
|
|
||||||
self.min_reputation_threshold = 0.5
|
|
||||||
self.max_agents_per_type = 1000
|
|
||||||
self.registration_fee = Decimal('100.0')
|
|
||||||
self.inactivity_threshold = 86400 * 7 # 7 days
|
|
||||||
|
|
||||||
# Initialize capability index
|
|
||||||
for capability_type in CapabilityType:
|
|
||||||
self.capability_index[capability_type] = set()
|
|
||||||
|
|
||||||
# Initialize type index
|
|
||||||
for agent_type in AgentType:
|
|
||||||
self.type_index[agent_type] = set()
|
|
||||||
|
|
||||||
async def register_agent(self, agent_type: AgentType, name: str, owner_address: str,
|
|
||||||
public_key: str, endpoint_url: str, capabilities: List[Dict],
|
|
||||||
metadata: Dict = None) -> Tuple[bool, str, Optional[str]]:
|
|
||||||
"""Register a new AI agent"""
|
|
||||||
try:
|
|
||||||
# Validate inputs
|
|
||||||
if not self._validate_registration_inputs(agent_type, name, owner_address, public_key, endpoint_url):
|
|
||||||
return False, "Invalid registration inputs", None
|
|
||||||
|
|
||||||
# Check if agent already exists
|
|
||||||
agent_id = self._generate_agent_id(owner_address, name)
|
|
||||||
if agent_id in self.agents:
|
|
||||||
return False, "Agent already registered", None
|
|
||||||
|
|
||||||
# Check type limits
|
|
||||||
if len(self.type_index[agent_type]) >= self.max_agents_per_type:
|
|
||||||
return False, f"Maximum agents of type {agent_type.value} reached", None
|
|
||||||
|
|
||||||
# Convert capabilities
|
|
||||||
agent_capabilities = []
|
|
||||||
for cap_data in capabilities:
|
|
||||||
capability = self._create_capability_from_data(cap_data)
|
|
||||||
if capability:
|
|
||||||
agent_capabilities.append(capability)
|
|
||||||
|
|
||||||
if not agent_capabilities:
|
|
||||||
return False, "Agent must have at least one valid capability", None
|
|
||||||
|
|
||||||
# Create agent info
|
|
||||||
agent_info = AgentInfo(
|
|
||||||
agent_id=agent_id,
|
|
||||||
agent_type=agent_type,
|
|
||||||
name=name,
|
|
||||||
owner_address=owner_address,
|
|
||||||
public_key=public_key,
|
|
||||||
endpoint_url=endpoint_url,
|
|
||||||
capabilities=agent_capabilities,
|
|
||||||
reputation_score=1.0, # Start with neutral reputation
|
|
||||||
total_jobs_completed=0,
|
|
||||||
total_earnings=Decimal('0'),
|
|
||||||
registration_time=time.time(),
|
|
||||||
last_active=time.time(),
|
|
||||||
status=AgentStatus.REGISTERED,
|
|
||||||
metadata=metadata or {}
|
|
||||||
)
|
|
||||||
|
|
||||||
# Add to registry
|
|
||||||
self.agents[agent_id] = agent_info
|
|
||||||
|
|
||||||
# Update indexes
|
|
||||||
self.type_index[agent_type].add(agent_id)
|
|
||||||
for capability in agent_capabilities:
|
|
||||||
self.capability_index[capability.capability_type].add(agent_id)
|
|
||||||
|
|
||||||
log_info(f"Agent registered: {agent_id} ({name})")
|
|
||||||
return True, "Registration successful", agent_id
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
return False, f"Registration failed: {str(e)}", None
|
|
||||||
|
|
||||||
def _validate_registration_inputs(self, agent_type: AgentType, name: str,
|
|
||||||
owner_address: str, public_key: str, endpoint_url: str) -> bool:
|
|
||||||
"""Validate registration inputs"""
|
|
||||||
# Check required fields
|
|
||||||
if not all([agent_type, name, owner_address, public_key, endpoint_url]):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Validate address format (simplified)
|
|
||||||
if not owner_address.startswith('0x') or len(owner_address) != 42:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Validate URL format (simplified)
|
|
||||||
if not endpoint_url.startswith(('http://', 'https://')):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Validate name
|
|
||||||
if len(name) < 3 or len(name) > 100:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def _generate_agent_id(self, owner_address: str, name: str) -> str:
|
|
||||||
"""Generate unique agent ID"""
|
|
||||||
content = f"{owner_address}:{name}:{time.time()}"
|
|
||||||
return hashlib.sha256(content.encode()).hexdigest()[:16]
|
|
||||||
|
|
||||||
def _create_capability_from_data(self, cap_data: Dict) -> Optional[AgentCapability]:
|
|
||||||
"""Create capability from data dictionary"""
|
|
||||||
try:
|
|
||||||
# Validate required fields
|
|
||||||
required_fields = ['type', 'name', 'version', 'cost_per_use']
|
|
||||||
if not all(field in cap_data for field in required_fields):
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Parse capability type
|
|
||||||
try:
|
|
||||||
capability_type = CapabilityType(cap_data['type'])
|
|
||||||
except ValueError:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Create capability
|
|
||||||
return AgentCapability(
|
|
||||||
capability_type=capability_type,
|
|
||||||
name=cap_data['name'],
|
|
||||||
version=cap_data['version'],
|
|
||||||
parameters=cap_data.get('parameters', {}),
|
|
||||||
performance_metrics=cap_data.get('performance_metrics', {}),
|
|
||||||
cost_per_use=Decimal(str(cap_data['cost_per_use'])),
|
|
||||||
availability=cap_data.get('availability', 1.0),
|
|
||||||
max_concurrent_jobs=cap_data.get('max_concurrent_jobs', 1)
|
|
||||||
)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
log_error(f"Error creating capability: {e}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
async def update_agent_status(self, agent_id: str, status: AgentStatus) -> Tuple[bool, str]:
|
|
||||||
"""Update agent status"""
|
|
||||||
if agent_id not in self.agents:
|
|
||||||
return False, "Agent not found"
|
|
||||||
|
|
||||||
agent = self.agents[agent_id]
|
|
||||||
old_status = agent.status
|
|
||||||
agent.status = status
|
|
||||||
agent.last_active = time.time()
|
|
||||||
|
|
||||||
log_info(f"Agent {agent_id} status changed: {old_status.value} -> {status.value}")
|
|
||||||
return True, "Status updated successfully"
|
|
||||||
|
|
||||||
async def update_agent_capabilities(self, agent_id: str, capabilities: List[Dict]) -> Tuple[bool, str]:
|
|
||||||
"""Update agent capabilities"""
|
|
||||||
if agent_id not in self.agents:
|
|
||||||
return False, "Agent not found"
|
|
||||||
|
|
||||||
agent = self.agents[agent_id]
|
|
||||||
|
|
||||||
# Remove old capabilities from index
|
|
||||||
for old_capability in agent.capabilities:
|
|
||||||
self.capability_index[old_capability.capability_type].discard(agent_id)
|
|
||||||
|
|
||||||
# Add new capabilities
|
|
||||||
new_capabilities = []
|
|
||||||
for cap_data in capabilities:
|
|
||||||
capability = self._create_capability_from_data(cap_data)
|
|
||||||
if capability:
|
|
||||||
new_capabilities.append(capability)
|
|
||||||
self.capability_index[capability.capability_type].add(agent_id)
|
|
||||||
|
|
||||||
if not new_capabilities:
|
|
||||||
return False, "No valid capabilities provided"
|
|
||||||
|
|
||||||
agent.capabilities = new_capabilities
|
|
||||||
agent.last_active = time.time()
|
|
||||||
|
|
||||||
return True, "Capabilities updated successfully"
|
|
||||||
|
|
||||||
async def find_agents_by_capability(self, capability_type: CapabilityType,
|
|
||||||
filters: Dict = None) -> List[AgentInfo]:
|
|
||||||
"""Find agents by capability type"""
|
|
||||||
agent_ids = self.capability_index.get(capability_type, set())
|
|
||||||
|
|
||||||
agents = []
|
|
||||||
for agent_id in agent_ids:
|
|
||||||
agent = self.agents.get(agent_id)
|
|
||||||
if agent and agent.status == AgentStatus.ACTIVE:
|
|
||||||
if self._matches_filters(agent, filters):
|
|
||||||
agents.append(agent)
|
|
||||||
|
|
||||||
# Sort by reputation (highest first)
|
|
||||||
agents.sort(key=lambda x: x.reputation_score, reverse=True)
|
|
||||||
return agents
|
|
||||||
|
|
||||||
async def find_agents_by_type(self, agent_type: AgentType, filters: Dict = None) -> List[AgentInfo]:
|
|
||||||
"""Find agents by type"""
|
|
||||||
agent_ids = self.type_index.get(agent_type, set())
|
|
||||||
|
|
||||||
agents = []
|
|
||||||
for agent_id in agent_ids:
|
|
||||||
agent = self.agents.get(agent_id)
|
|
||||||
if agent and agent.status == AgentStatus.ACTIVE:
|
|
||||||
if self._matches_filters(agent, filters):
|
|
||||||
agents.append(agent)
|
|
||||||
|
|
||||||
# Sort by reputation (highest first)
|
|
||||||
agents.sort(key=lambda x: x.reputation_score, reverse=True)
|
|
||||||
return agents
|
|
||||||
|
|
||||||
def _matches_filters(self, agent: AgentInfo, filters: Dict) -> bool:
|
|
||||||
"""Check if agent matches filters"""
|
|
||||||
if not filters:
|
|
||||||
return True
|
|
||||||
|
|
||||||
# Reputation filter
|
|
||||||
if 'min_reputation' in filters:
|
|
||||||
if agent.reputation_score < filters['min_reputation']:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Cost filter
|
|
||||||
if 'max_cost_per_use' in filters:
|
|
||||||
max_cost = Decimal(str(filters['max_cost_per_use']))
|
|
||||||
if any(cap.cost_per_use > max_cost for cap in agent.capabilities):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Availability filter
|
|
||||||
if 'min_availability' in filters:
|
|
||||||
min_availability = filters['min_availability']
|
|
||||||
if any(cap.availability < min_availability for cap in agent.capabilities):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Location filter (if implemented)
|
|
||||||
if 'location' in filters:
|
|
||||||
agent_location = agent.metadata.get('location')
|
|
||||||
if agent_location != filters['location']:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
async def get_agent_info(self, agent_id: str) -> Optional[AgentInfo]:
|
|
||||||
"""Get agent information"""
|
|
||||||
return self.agents.get(agent_id)
|
|
||||||
|
|
||||||
async def search_agents(self, query: str, limit: int = 50) -> List[AgentInfo]:
|
|
||||||
"""Search agents by name or capability"""
|
|
||||||
query_lower = query.lower()
|
|
||||||
results = []
|
|
||||||
|
|
||||||
for agent in self.agents.values():
|
|
||||||
if agent.status != AgentStatus.ACTIVE:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Search in name
|
|
||||||
if query_lower in agent.name.lower():
|
|
||||||
results.append(agent)
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Search in capabilities
|
|
||||||
for capability in agent.capabilities:
|
|
||||||
if (query_lower in capability.name.lower() or
|
|
||||||
query_lower in capability.capability_type.value):
|
|
||||||
results.append(agent)
|
|
||||||
break
|
|
||||||
|
|
||||||
# Sort by relevance (reputation)
|
|
||||||
results.sort(key=lambda x: x.reputation_score, reverse=True)
|
|
||||||
return results[:limit]
|
|
||||||
|
|
||||||
async def get_agent_statistics(self, agent_id: str) -> Optional[Dict]:
|
|
||||||
"""Get detailed statistics for an agent"""
|
|
||||||
agent = self.agents.get(agent_id)
|
|
||||||
if not agent:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Calculate additional statistics
|
|
||||||
avg_job_earnings = agent.total_earnings / agent.total_jobs_completed if agent.total_jobs_completed > 0 else Decimal('0')
|
|
||||||
days_active = (time.time() - agent.registration_time) / 86400
|
|
||||||
jobs_per_day = agent.total_jobs_completed / days_active if days_active > 0 else 0
|
|
||||||
|
|
||||||
return {
|
|
||||||
'agent_id': agent_id,
|
|
||||||
'name': agent.name,
|
|
||||||
'type': agent.agent_type.value,
|
|
||||||
'status': agent.status.value,
|
|
||||||
'reputation_score': agent.reputation_score,
|
|
||||||
'total_jobs_completed': agent.total_jobs_completed,
|
|
||||||
'total_earnings': float(agent.total_earnings),
|
|
||||||
'avg_job_earnings': float(avg_job_earnings),
|
|
||||||
'jobs_per_day': jobs_per_day,
|
|
||||||
'days_active': int(days_active),
|
|
||||||
'capabilities_count': len(agent.capabilities),
|
|
||||||
'last_active': agent.last_active,
|
|
||||||
'registration_time': agent.registration_time
|
|
||||||
}
|
|
||||||
|
|
||||||
async def get_registry_statistics(self) -> Dict:
|
|
||||||
"""Get registry-wide statistics"""
|
|
||||||
total_agents = len(self.agents)
|
|
||||||
active_agents = len([a for a in self.agents.values() if a.status == AgentStatus.ACTIVE])
|
|
||||||
|
|
||||||
# Count by type
|
|
||||||
type_counts = {}
|
|
||||||
for agent_type in AgentType:
|
|
||||||
type_counts[agent_type.value] = len(self.type_index[agent_type])
|
|
||||||
|
|
||||||
# Count by capability
|
|
||||||
capability_counts = {}
|
|
||||||
for capability_type in CapabilityType:
|
|
||||||
capability_counts[capability_type.value] = len(self.capability_index[capability_type])
|
|
||||||
|
|
||||||
# Reputation statistics
|
|
||||||
reputations = [a.reputation_score for a in self.agents.values()]
|
|
||||||
avg_reputation = sum(reputations) / len(reputations) if reputations else 0
|
|
||||||
|
|
||||||
# Earnings statistics
|
|
||||||
total_earnings = sum(a.total_earnings for a in self.agents.values())
|
|
||||||
|
|
||||||
return {
|
|
||||||
'total_agents': total_agents,
|
|
||||||
'active_agents': active_agents,
|
|
||||||
'inactive_agents': total_agents - active_agents,
|
|
||||||
'agent_types': type_counts,
|
|
||||||
'capabilities': capability_counts,
|
|
||||||
'average_reputation': avg_reputation,
|
|
||||||
'total_earnings': float(total_earnings),
|
|
||||||
'registration_fee': float(self.registration_fee)
|
|
||||||
}
|
|
||||||
|
|
||||||
async def cleanup_inactive_agents(self) -> Tuple[int, str]:
|
|
||||||
"""Clean up inactive agents"""
|
|
||||||
current_time = time.time()
|
|
||||||
cleaned_count = 0
|
|
||||||
|
|
||||||
for agent_id, agent in list(self.agents.items()):
|
|
||||||
if (agent.status == AgentStatus.INACTIVE and
|
|
||||||
current_time - agent.last_active > self.inactivity_threshold):
|
|
||||||
|
|
||||||
# Remove from registry
|
|
||||||
del self.agents[agent_id]
|
|
||||||
|
|
||||||
# Update indexes
|
|
||||||
self.type_index[agent.agent_type].discard(agent_id)
|
|
||||||
for capability in agent.capabilities:
|
|
||||||
self.capability_index[capability.capability_type].discard(agent_id)
|
|
||||||
|
|
||||||
cleaned_count += 1
|
|
||||||
|
|
||||||
if cleaned_count > 0:
|
|
||||||
log_info(f"Cleaned up {cleaned_count} inactive agents")
|
|
||||||
|
|
||||||
return cleaned_count, f"Cleaned up {cleaned_count} inactive agents"
|
|
||||||
|
|
||||||
# Global agent registry
|
|
||||||
agent_registry: Optional[AgentRegistry] = None
|
|
||||||
|
|
||||||
def get_agent_registry() -> Optional[AgentRegistry]:
|
|
||||||
"""Get global agent registry"""
|
|
||||||
return agent_registry
|
|
||||||
|
|
||||||
def create_agent_registry() -> AgentRegistry:
|
|
||||||
"""Create and set global agent registry"""
|
|
||||||
global agent_registry
|
|
||||||
agent_registry = AgentRegistry()
|
|
||||||
return agent_registry
|
|
||||||
@@ -1,166 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Trading Agent
|
|
||||||
Automated trading agent for AITBC marketplace
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import json
|
|
||||||
import time
|
|
||||||
from typing import Dict, Any, List
|
|
||||||
from datetime import datetime
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Add parent directory to path
|
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '../../../..'))
|
|
||||||
|
|
||||||
from apps.agent_services.agent_bridge.src.integration_layer import AgentServiceBridge
|
|
||||||
|
|
||||||
class TradingAgent:
|
|
||||||
"""Automated trading agent"""
|
|
||||||
|
|
||||||
def __init__(self, agent_id: str, config: Dict[str, Any]):
|
|
||||||
self.agent_id = agent_id
|
|
||||||
self.config = config
|
|
||||||
self.bridge = AgentServiceBridge()
|
|
||||||
self.is_running = False
|
|
||||||
self.trading_strategy = config.get("strategy", "basic")
|
|
||||||
self.symbols = config.get("symbols", ["AITBC/BTC"])
|
|
||||||
self.trade_interval = config.get("trade_interval", 60) # seconds
|
|
||||||
|
|
||||||
async def start(self) -> bool:
|
|
||||||
"""Start trading agent"""
|
|
||||||
try:
|
|
||||||
# Register with service bridge
|
|
||||||
success = await self.bridge.start_agent(self.agent_id, {
|
|
||||||
"type": "trading",
|
|
||||||
"capabilities": ["market_analysis", "trading", "risk_management"],
|
|
||||||
"endpoint": f"http://localhost:8005"
|
|
||||||
})
|
|
||||||
|
|
||||||
if success:
|
|
||||||
self.is_running = True
|
|
||||||
print(f"Trading agent {self.agent_id} started successfully")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f"Failed to start trading agent {self.agent_id}")
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error starting trading agent: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def stop(self) -> bool:
|
|
||||||
"""Stop trading agent"""
|
|
||||||
self.is_running = False
|
|
||||||
success = await self.bridge.stop_agent(self.agent_id)
|
|
||||||
if success:
|
|
||||||
print(f"Trading agent {self.agent_id} stopped successfully")
|
|
||||||
return success
|
|
||||||
|
|
||||||
async def run_trading_loop(self):
|
|
||||||
"""Main trading loop"""
|
|
||||||
while self.is_running:
|
|
||||||
try:
|
|
||||||
for symbol in self.symbols:
|
|
||||||
await self._analyze_and_trade(symbol)
|
|
||||||
|
|
||||||
await asyncio.sleep(self.trade_interval)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error in trading loop: {e}")
|
|
||||||
await asyncio.sleep(10) # Wait before retrying
|
|
||||||
|
|
||||||
async def _analyze_and_trade(self, symbol: str) -> None:
|
|
||||||
"""Analyze market and execute trades"""
|
|
||||||
try:
|
|
||||||
# Perform market analysis
|
|
||||||
analysis_task = {
|
|
||||||
"type": "market_analysis",
|
|
||||||
"symbol": symbol,
|
|
||||||
"strategy": self.trading_strategy
|
|
||||||
}
|
|
||||||
|
|
||||||
analysis_result = await self.bridge.execute_agent_task(self.agent_id, analysis_task)
|
|
||||||
|
|
||||||
if analysis_result.get("status") == "success":
|
|
||||||
analysis = analysis_result["result"]["analysis"]
|
|
||||||
|
|
||||||
# Make trading decision
|
|
||||||
if self._should_trade(analysis):
|
|
||||||
await self._execute_trade(symbol, analysis)
|
|
||||||
else:
|
|
||||||
print(f"Market analysis failed for {symbol}: {analysis_result}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error in analyze_and_trade for {symbol}: {e}")
|
|
||||||
|
|
||||||
def _should_trade(self, analysis: Dict[str, Any]) -> bool:
|
|
||||||
"""Determine if should execute trade"""
|
|
||||||
recommendation = analysis.get("recommendation", "hold")
|
|
||||||
return recommendation in ["buy", "sell"]
|
|
||||||
|
|
||||||
async def _execute_trade(self, symbol: str, analysis: Dict[str, Any]) -> None:
|
|
||||||
"""Execute trade based on analysis"""
|
|
||||||
try:
|
|
||||||
recommendation = analysis.get("recommendation", "hold")
|
|
||||||
|
|
||||||
if recommendation == "buy":
|
|
||||||
trade_task = {
|
|
||||||
"type": "trading",
|
|
||||||
"symbol": symbol,
|
|
||||||
"side": "buy",
|
|
||||||
"amount": self.config.get("trade_amount", 0.1),
|
|
||||||
"strategy": self.trading_strategy
|
|
||||||
}
|
|
||||||
elif recommendation == "sell":
|
|
||||||
trade_task = {
|
|
||||||
"type": "trading",
|
|
||||||
"symbol": symbol,
|
|
||||||
"side": "sell",
|
|
||||||
"amount": self.config.get("trade_amount", 0.1),
|
|
||||||
"strategy": self.trading_strategy
|
|
||||||
}
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
|
|
||||||
trade_result = await self.bridge.execute_agent_task(self.agent_id, trade_task)
|
|
||||||
|
|
||||||
if trade_result.get("status") == "success":
|
|
||||||
print(f"Trade executed successfully: {trade_result}")
|
|
||||||
else:
|
|
||||||
print(f"Trade execution failed: {trade_result}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error executing trade: {e}")
|
|
||||||
|
|
||||||
async def get_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get agent status"""
|
|
||||||
return await self.bridge.get_agent_status(self.agent_id)
|
|
||||||
|
|
||||||
# Main execution
|
|
||||||
async def main():
|
|
||||||
"""Main trading agent execution"""
|
|
||||||
agent_id = "trading-agent-001"
|
|
||||||
config = {
|
|
||||||
"strategy": "basic",
|
|
||||||
"symbols": ["AITBC/BTC"],
|
|
||||||
"trade_interval": 30,
|
|
||||||
"trade_amount": 0.1
|
|
||||||
}
|
|
||||||
|
|
||||||
agent = TradingAgent(agent_id, config)
|
|
||||||
|
|
||||||
# Start agent
|
|
||||||
if await agent.start():
|
|
||||||
try:
|
|
||||||
# Run trading loop
|
|
||||||
await agent.run_trading_loop()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("Shutting down trading agent...")
|
|
||||||
finally:
|
|
||||||
await agent.stop()
|
|
||||||
else:
|
|
||||||
print("Failed to start trading agent")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
asyncio.run(main())
|
|
||||||
@@ -1,229 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Agent Integration Layer
|
|
||||||
Connects agent protocols to existing AITBC services
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import aiohttp
|
|
||||||
import json
|
|
||||||
from typing import Dict, Any, List, Optional
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
class AITBCServiceIntegration:
|
|
||||||
"""Integration layer for AITBC services"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.service_endpoints = {
|
|
||||||
"coordinator_api": "http://localhost:8000",
|
|
||||||
"blockchain_rpc": "http://localhost:8006",
|
|
||||||
"exchange_service": "http://localhost:8001",
|
|
||||||
"marketplace": "http://localhost:8002",
|
|
||||||
"agent_registry": "http://localhost:8013"
|
|
||||||
}
|
|
||||||
self.session = None
|
|
||||||
|
|
||||||
async def __aenter__(self):
|
|
||||||
self.session = aiohttp.ClientSession()
|
|
||||||
return self
|
|
||||||
|
|
||||||
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
||||||
if self.session:
|
|
||||||
await self.session.close()
|
|
||||||
|
|
||||||
async def get_blockchain_info(self) -> Dict[str, Any]:
|
|
||||||
"""Get blockchain information"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['blockchain_rpc']}/health") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "unavailable"}
|
|
||||||
|
|
||||||
async def get_exchange_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get exchange service status"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['exchange_service']}/api/health") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "unavailable"}
|
|
||||||
|
|
||||||
async def get_coordinator_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get coordinator API status"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['coordinator_api']}/health") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "unavailable"}
|
|
||||||
|
|
||||||
async def submit_transaction(self, transaction_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Submit transaction to blockchain"""
|
|
||||||
try:
|
|
||||||
async with self.session.post(
|
|
||||||
f"{self.service_endpoints['blockchain_rpc']}/rpc/submit",
|
|
||||||
json=transaction_data
|
|
||||||
) as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "failed"}
|
|
||||||
|
|
||||||
async def get_market_data(self, symbol: str = "AITBC/BTC") -> Dict[str, Any]:
|
|
||||||
"""Get market data from exchange"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['exchange_service']}/api/market/{symbol}") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "failed"}
|
|
||||||
|
|
||||||
async def register_agent_with_coordinator(self, agent_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Register agent with coordinator"""
|
|
||||||
try:
|
|
||||||
async with self.session.post(
|
|
||||||
f"{self.service_endpoints['agent_registry']}/api/agents/register",
|
|
||||||
json=agent_data
|
|
||||||
) as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "failed"}
|
|
||||||
|
|
||||||
class AgentServiceBridge:
|
|
||||||
"""Bridge between agents and AITBC services"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.integration = AITBCServiceIntegration()
|
|
||||||
self.active_agents = {}
|
|
||||||
|
|
||||||
async def start_agent(self, agent_id: str, agent_config: Dict[str, Any]) -> bool:
|
|
||||||
"""Start an agent with service integration"""
|
|
||||||
try:
|
|
||||||
# Register agent with coordinator
|
|
||||||
async with self.integration as integration:
|
|
||||||
registration_result = await integration.register_agent_with_coordinator({
|
|
||||||
"name": agent_id,
|
|
||||||
"type": agent_config.get("type", "generic"),
|
|
||||||
"capabilities": agent_config.get("capabilities", []),
|
|
||||||
"chain_id": agent_config.get("chain_id", "ait-mainnet"),
|
|
||||||
"endpoint": agent_config.get("endpoint", f"http://localhost:{8000 + len(self.active_agents) + 10}")
|
|
||||||
})
|
|
||||||
|
|
||||||
# The registry returns the created agent dict on success, not a {"status": "ok"} wrapper
|
|
||||||
if registration_result and "id" in registration_result:
|
|
||||||
self.active_agents[agent_id] = {
|
|
||||||
"config": agent_config,
|
|
||||||
"registration": registration_result,
|
|
||||||
"started_at": datetime.utcnow()
|
|
||||||
}
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f"Registration failed: {registration_result}")
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Failed to start agent {agent_id}: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def stop_agent(self, agent_id: str) -> bool:
|
|
||||||
"""Stop an agent"""
|
|
||||||
if agent_id in self.active_agents:
|
|
||||||
del self.active_agents[agent_id]
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def get_agent_status(self, agent_id: str) -> Dict[str, Any]:
|
|
||||||
"""Get agent status with service integration"""
|
|
||||||
if agent_id not in self.active_agents:
|
|
||||||
return {"status": "not_found"}
|
|
||||||
|
|
||||||
agent_info = self.active_agents[agent_id]
|
|
||||||
|
|
||||||
async with self.integration as integration:
|
|
||||||
# Get service statuses
|
|
||||||
blockchain_status = await integration.get_blockchain_info()
|
|
||||||
exchange_status = await integration.get_exchange_status()
|
|
||||||
coordinator_status = await integration.get_coordinator_status()
|
|
||||||
|
|
||||||
return {
|
|
||||||
"agent_id": agent_id,
|
|
||||||
"status": "active",
|
|
||||||
"started_at": agent_info["started_at"].isoformat(),
|
|
||||||
"services": {
|
|
||||||
"blockchain": blockchain_status,
|
|
||||||
"exchange": exchange_status,
|
|
||||||
"coordinator": coordinator_status
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async def execute_agent_task(self, agent_id: str, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute agent task with service integration"""
|
|
||||||
if agent_id not in self.active_agents:
|
|
||||||
return {"status": "error", "message": "Agent not found"}
|
|
||||||
|
|
||||||
task_type = task_data.get("type")
|
|
||||||
|
|
||||||
if task_type == "market_analysis":
|
|
||||||
return await self._execute_market_analysis(task_data)
|
|
||||||
elif task_type == "trading":
|
|
||||||
return await self._execute_trading_task(task_data)
|
|
||||||
elif task_type == "compliance_check":
|
|
||||||
return await self._execute_compliance_check(task_data)
|
|
||||||
else:
|
|
||||||
return {"status": "error", "message": f"Unknown task type: {task_type}"}
|
|
||||||
|
|
||||||
async def _execute_market_analysis(self, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute market analysis task"""
|
|
||||||
try:
|
|
||||||
async with self.integration as integration:
|
|
||||||
market_data = await integration.get_market_data(task_data.get("symbol", "AITBC/BTC"))
|
|
||||||
|
|
||||||
# Perform basic analysis
|
|
||||||
analysis_result = {
|
|
||||||
"symbol": task_data.get("symbol", "AITBC/BTC"),
|
|
||||||
"market_data": market_data,
|
|
||||||
"analysis": {
|
|
||||||
"trend": "neutral",
|
|
||||||
"volatility": "medium",
|
|
||||||
"recommendation": "hold"
|
|
||||||
},
|
|
||||||
"timestamp": datetime.utcnow().isoformat()
|
|
||||||
}
|
|
||||||
|
|
||||||
return {"status": "success", "result": analysis_result}
|
|
||||||
except Exception as e:
|
|
||||||
return {"status": "error", "message": str(e)}
|
|
||||||
|
|
||||||
async def _execute_trading_task(self, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute trading task"""
|
|
||||||
try:
|
|
||||||
# Get market data first
|
|
||||||
async with self.integration as integration:
|
|
||||||
market_data = await integration.get_market_data(task_data.get("symbol", "AITBC/BTC"))
|
|
||||||
|
|
||||||
# Create transaction
|
|
||||||
transaction = {
|
|
||||||
"type": "trade",
|
|
||||||
"symbol": task_data.get("symbol", "AITBC/BTC"),
|
|
||||||
"side": task_data.get("side", "buy"),
|
|
||||||
"amount": task_data.get("amount", 0.1),
|
|
||||||
"price": task_data.get("price", market_data.get("price", 0.001))
|
|
||||||
}
|
|
||||||
|
|
||||||
# Submit transaction
|
|
||||||
tx_result = await integration.submit_transaction(transaction)
|
|
||||||
|
|
||||||
return {"status": "success", "transaction": tx_result}
|
|
||||||
except Exception as e:
|
|
||||||
return {"status": "error", "message": str(e)}
|
|
||||||
|
|
||||||
async def _execute_compliance_check(self, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute compliance check task"""
|
|
||||||
try:
|
|
||||||
# Basic compliance check
|
|
||||||
compliance_result = {
|
|
||||||
"user_id": task_data.get("user_id"),
|
|
||||||
"check_type": task_data.get("check_type", "basic"),
|
|
||||||
"status": "passed",
|
|
||||||
"checks_performed": ["kyc", "aml", "sanctions"],
|
|
||||||
"timestamp": datetime.utcnow().isoformat()
|
|
||||||
}
|
|
||||||
|
|
||||||
return {"status": "success", "result": compliance_result}
|
|
||||||
except Exception as e:
|
|
||||||
return {"status": "error", "message": str(e)}
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Compliance Agent
|
|
||||||
Automated compliance and regulatory monitoring agent
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import json
|
|
||||||
import time
|
|
||||||
from typing import Dict, Any, List
|
|
||||||
from datetime import datetime
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Add parent directory to path
|
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '../../../..'))
|
|
||||||
|
|
||||||
from apps.agent_services.agent_bridge.src.integration_layer import AgentServiceBridge
|
|
||||||
|
|
||||||
class ComplianceAgent:
|
|
||||||
"""Automated compliance agent"""
|
|
||||||
|
|
||||||
def __init__(self, agent_id: str, config: Dict[str, Any]):
|
|
||||||
self.agent_id = agent_id
|
|
||||||
self.config = config
|
|
||||||
self.bridge = AgentServiceBridge()
|
|
||||||
self.is_running = False
|
|
||||||
self.check_interval = config.get("check_interval", 300) # 5 minutes
|
|
||||||
self.monitored_entities = config.get("monitored_entities", [])
|
|
||||||
|
|
||||||
async def start(self) -> bool:
|
|
||||||
"""Start compliance agent"""
|
|
||||||
try:
|
|
||||||
success = await self.bridge.start_agent(self.agent_id, {
|
|
||||||
"type": "compliance",
|
|
||||||
"capabilities": ["kyc_check", "aml_screening", "regulatory_reporting"],
|
|
||||||
"endpoint": f"http://localhost:8006"
|
|
||||||
})
|
|
||||||
|
|
||||||
if success:
|
|
||||||
self.is_running = True
|
|
||||||
print(f"Compliance agent {self.agent_id} started successfully")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f"Failed to start compliance agent {self.agent_id}")
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error starting compliance agent: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def stop(self) -> bool:
|
|
||||||
"""Stop compliance agent"""
|
|
||||||
self.is_running = False
|
|
||||||
success = await self.bridge.stop_agent(self.agent_id)
|
|
||||||
if success:
|
|
||||||
print(f"Compliance agent {self.agent_id} stopped successfully")
|
|
||||||
return success
|
|
||||||
|
|
||||||
async def run_compliance_loop(self):
|
|
||||||
"""Main compliance monitoring loop"""
|
|
||||||
while self.is_running:
|
|
||||||
try:
|
|
||||||
for entity in self.monitored_entities:
|
|
||||||
await self._perform_compliance_check(entity)
|
|
||||||
|
|
||||||
await asyncio.sleep(self.check_interval)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error in compliance loop: {e}")
|
|
||||||
await asyncio.sleep(30) # Wait before retrying
|
|
||||||
|
|
||||||
async def _perform_compliance_check(self, entity_id: str) -> None:
|
|
||||||
"""Perform compliance check for entity"""
|
|
||||||
try:
|
|
||||||
compliance_task = {
|
|
||||||
"type": "compliance_check",
|
|
||||||
"user_id": entity_id,
|
|
||||||
"check_type": "full",
|
|
||||||
"monitored_activities": ["trading", "transfers", "wallet_creation"]
|
|
||||||
}
|
|
||||||
|
|
||||||
result = await self.bridge.execute_agent_task(self.agent_id, compliance_task)
|
|
||||||
|
|
||||||
if result.get("status") == "success":
|
|
||||||
compliance_result = result["result"]
|
|
||||||
await self._handle_compliance_result(entity_id, compliance_result)
|
|
||||||
else:
|
|
||||||
print(f"Compliance check failed for {entity_id}: {result}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error performing compliance check for {entity_id}: {e}")
|
|
||||||
|
|
||||||
async def _handle_compliance_result(self, entity_id: str, result: Dict[str, Any]) -> None:
|
|
||||||
"""Handle compliance check result"""
|
|
||||||
status = result.get("status", "unknown")
|
|
||||||
|
|
||||||
if status == "passed":
|
|
||||||
print(f"✅ Compliance check passed for {entity_id}")
|
|
||||||
elif status == "failed":
|
|
||||||
print(f"❌ Compliance check failed for {entity_id}")
|
|
||||||
# Trigger alert or further investigation
|
|
||||||
await self._trigger_compliance_alert(entity_id, result)
|
|
||||||
else:
|
|
||||||
print(f"⚠️ Compliance check inconclusive for {entity_id}")
|
|
||||||
|
|
||||||
async def _trigger_compliance_alert(self, entity_id: str, result: Dict[str, Any]) -> None:
|
|
||||||
"""Trigger compliance alert"""
|
|
||||||
alert_data = {
|
|
||||||
"entity_id": entity_id,
|
|
||||||
"alert_type": "compliance_failure",
|
|
||||||
"severity": "high",
|
|
||||||
"details": result,
|
|
||||||
"timestamp": datetime.utcnow().isoformat()
|
|
||||||
}
|
|
||||||
|
|
||||||
# In a real implementation, this would send to alert system
|
|
||||||
print(f"🚨 COMPLIANCE ALERT: {json.dumps(alert_data, indent=2)}")
|
|
||||||
|
|
||||||
async def get_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get agent status"""
|
|
||||||
status = await self.bridge.get_agent_status(self.agent_id)
|
|
||||||
status["monitored_entities"] = len(self.monitored_entities)
|
|
||||||
status["check_interval"] = self.check_interval
|
|
||||||
return status
|
|
||||||
|
|
||||||
# Main execution
|
|
||||||
async def main():
|
|
||||||
"""Main compliance agent execution"""
|
|
||||||
agent_id = "compliance-agent-001"
|
|
||||||
config = {
|
|
||||||
"check_interval": 60, # 1 minute for testing
|
|
||||||
"monitored_entities": ["user001", "user002", "user003"]
|
|
||||||
}
|
|
||||||
|
|
||||||
agent = ComplianceAgent(agent_id, config)
|
|
||||||
|
|
||||||
# Start agent
|
|
||||||
if await agent.start():
|
|
||||||
try:
|
|
||||||
# Run compliance loop
|
|
||||||
await agent.run_compliance_loop()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("Shutting down compliance agent...")
|
|
||||||
finally:
|
|
||||||
await agent.stop()
|
|
||||||
else:
|
|
||||||
print("Failed to start compliance agent")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
asyncio.run(main())
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Agent Coordinator Service
|
|
||||||
Agent task coordination and management
|
|
||||||
"""
|
|
||||||
|
|
||||||
from fastapi import FastAPI, HTTPException
|
|
||||||
from pydantic import BaseModel
|
|
||||||
from typing import List, Optional, Dict, Any
|
|
||||||
import json
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime
|
|
||||||
import sqlite3
|
|
||||||
from contextlib import contextmanager
|
|
||||||
from contextlib import asynccontextmanager
|
|
||||||
|
|
||||||
@asynccontextmanager
|
|
||||||
async def lifespan(app: FastAPI):
|
|
||||||
# Startup
|
|
||||||
init_db()
|
|
||||||
yield
|
|
||||||
# Shutdown (cleanup if needed)
|
|
||||||
pass
|
|
||||||
|
|
||||||
app = FastAPI(title="AITBC Agent Coordinator API", version="1.0.0", lifespan=lifespan)
|
|
||||||
|
|
||||||
# Database setup
|
|
||||||
def get_db():
|
|
||||||
conn = sqlite3.connect('agent_coordinator.db')
|
|
||||||
conn.row_factory = sqlite3.Row
|
|
||||||
return conn
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def get_db_connection():
|
|
||||||
conn = get_db()
|
|
||||||
try:
|
|
||||||
yield conn
|
|
||||||
finally:
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
# Initialize database
|
|
||||||
def init_db():
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
CREATE TABLE IF NOT EXISTS tasks (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
task_type TEXT NOT NULL,
|
|
||||||
payload TEXT NOT NULL,
|
|
||||||
required_capabilities TEXT NOT NULL,
|
|
||||||
priority TEXT NOT NULL,
|
|
||||||
status TEXT NOT NULL,
|
|
||||||
assigned_agent_id TEXT,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
result TEXT
|
|
||||||
)
|
|
||||||
''')
|
|
||||||
|
|
||||||
# Models
|
|
||||||
class Task(BaseModel):
|
|
||||||
id: str
|
|
||||||
task_type: str
|
|
||||||
payload: Dict[str, Any]
|
|
||||||
required_capabilities: List[str]
|
|
||||||
priority: str
|
|
||||||
status: str
|
|
||||||
assigned_agent_id: Optional[str] = None
|
|
||||||
|
|
||||||
class TaskCreation(BaseModel):
|
|
||||||
task_type: str
|
|
||||||
payload: Dict[str, Any]
|
|
||||||
required_capabilities: List[str]
|
|
||||||
priority: str = "normal"
|
|
||||||
|
|
||||||
# API Endpoints
|
|
||||||
|
|
||||||
@app.post("/api/tasks", response_model=Task)
|
|
||||||
async def create_task(task: TaskCreation):
|
|
||||||
"""Create a new task"""
|
|
||||||
task_id = str(uuid.uuid4())
|
|
||||||
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
INSERT INTO tasks (id, task_type, payload, required_capabilities, priority, status)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?)
|
|
||||||
''', (
|
|
||||||
task_id, task.task_type, json.dumps(task.payload),
|
|
||||||
json.dumps(task.required_capabilities), task.priority, "pending"
|
|
||||||
))
|
|
||||||
|
|
||||||
return Task(
|
|
||||||
id=task_id,
|
|
||||||
task_type=task.task_type,
|
|
||||||
payload=task.payload,
|
|
||||||
required_capabilities=task.required_capabilities,
|
|
||||||
priority=task.priority,
|
|
||||||
status="pending"
|
|
||||||
)
|
|
||||||
|
|
||||||
@app.get("/api/tasks", response_model=List[Task])
|
|
||||||
async def list_tasks(status: Optional[str] = None):
|
|
||||||
"""List tasks with optional status filter"""
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
query = "SELECT * FROM tasks"
|
|
||||||
params = []
|
|
||||||
|
|
||||||
if status:
|
|
||||||
query += " WHERE status = ?"
|
|
||||||
params.append(status)
|
|
||||||
|
|
||||||
tasks = conn.execute(query, params).fetchall()
|
|
||||||
|
|
||||||
return [
|
|
||||||
Task(
|
|
||||||
id=task["id"],
|
|
||||||
task_type=task["task_type"],
|
|
||||||
payload=json.loads(task["payload"]),
|
|
||||||
required_capabilities=json.loads(task["required_capabilities"]),
|
|
||||||
priority=task["priority"],
|
|
||||||
status=task["status"],
|
|
||||||
assigned_agent_id=task["assigned_agent_id"]
|
|
||||||
)
|
|
||||||
for task in tasks
|
|
||||||
]
|
|
||||||
|
|
||||||
@app.get("/api/health")
|
|
||||||
async def health_check():
|
|
||||||
"""Health check endpoint"""
|
|
||||||
return {"status": "ok", "timestamp": datetime.utcnow()}
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import uvicorn
|
|
||||||
uvicorn.run(app, host="0.0.0.0", port=8012)
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
# AITBC Agent Protocols Environment Configuration
|
|
||||||
# Copy this file to .env and update with your secure values
|
|
||||||
|
|
||||||
# Agent Protocol Encryption Key (generate a strong, unique key)
|
|
||||||
AITBC_AGENT_PROTOCOL_KEY=your-secure-encryption-key-here
|
|
||||||
|
|
||||||
# Agent Protocol Salt (generate a unique salt value)
|
|
||||||
AITBC_AGENT_PROTOCOL_SALT=your-unique-salt-value-here
|
|
||||||
|
|
||||||
# Agent Registry Configuration
|
|
||||||
AGENT_REGISTRY_HOST=0.0.0.0
|
|
||||||
AGENT_REGISTRY_PORT=8003
|
|
||||||
|
|
||||||
# Database Configuration
|
|
||||||
AGENT_REGISTRY_DB_PATH=agent_registry.db
|
|
||||||
|
|
||||||
# Security Settings
|
|
||||||
AGENT_PROTOCOL_TIMEOUT=300
|
|
||||||
AGENT_PROTOCOL_MAX_RETRIES=3
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
"""
|
|
||||||
Agent Protocols Package
|
|
||||||
"""
|
|
||||||
|
|
||||||
from .message_protocol import MessageProtocol, MessageTypes, AgentMessageClient
|
|
||||||
from .task_manager import TaskManager, TaskStatus, TaskPriority, Task
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
"MessageProtocol",
|
|
||||||
"MessageTypes",
|
|
||||||
"AgentMessageClient",
|
|
||||||
"TaskManager",
|
|
||||||
"TaskStatus",
|
|
||||||
"TaskPriority",
|
|
||||||
"Task"
|
|
||||||
]
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
"""
|
|
||||||
Message Protocol for AITBC Agents
|
|
||||||
Handles message creation, routing, and delivery between agents
|
|
||||||
"""
|
|
||||||
|
|
||||||
import json
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime
|
|
||||||
from typing import Dict, Any, Optional, List
|
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
class MessageTypes(Enum):
|
|
||||||
"""Message type enumeration"""
|
|
||||||
TASK_REQUEST = "task_request"
|
|
||||||
TASK_RESPONSE = "task_response"
|
|
||||||
HEARTBEAT = "heartbeat"
|
|
||||||
STATUS_UPDATE = "status_update"
|
|
||||||
ERROR = "error"
|
|
||||||
DATA = "data"
|
|
||||||
|
|
||||||
class MessageProtocol:
|
|
||||||
"""Message protocol handler for agent communication"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.messages = []
|
|
||||||
self.message_handlers = {}
|
|
||||||
|
|
||||||
def create_message(
|
|
||||||
self,
|
|
||||||
sender_id: str,
|
|
||||||
receiver_id: str,
|
|
||||||
message_type: MessageTypes,
|
|
||||||
content: Dict[str, Any],
|
|
||||||
message_id: Optional[str] = None
|
|
||||||
) -> Dict[str, Any]:
|
|
||||||
"""Create a new message"""
|
|
||||||
if message_id is None:
|
|
||||||
message_id = str(uuid.uuid4())
|
|
||||||
|
|
||||||
message = {
|
|
||||||
"message_id": message_id,
|
|
||||||
"sender_id": sender_id,
|
|
||||||
"receiver_id": receiver_id,
|
|
||||||
"message_type": message_type.value,
|
|
||||||
"content": content,
|
|
||||||
"timestamp": datetime.utcnow().isoformat(),
|
|
||||||
"status": "pending"
|
|
||||||
}
|
|
||||||
|
|
||||||
self.messages.append(message)
|
|
||||||
return message
|
|
||||||
|
|
||||||
def send_message(self, message: Dict[str, Any]) -> bool:
|
|
||||||
"""Send a message to the receiver"""
|
|
||||||
try:
|
|
||||||
message["status"] = "sent"
|
|
||||||
message["sent_timestamp"] = datetime.utcnow().isoformat()
|
|
||||||
return True
|
|
||||||
except Exception:
|
|
||||||
message["status"] = "failed"
|
|
||||||
return False
|
|
||||||
|
|
||||||
def receive_message(self, message_id: str) -> Optional[Dict[str, Any]]:
|
|
||||||
"""Receive and process a message"""
|
|
||||||
for message in self.messages:
|
|
||||||
if message["message_id"] == message_id:
|
|
||||||
message["status"] = "received"
|
|
||||||
message["received_timestamp"] = datetime.utcnow().isoformat()
|
|
||||||
return message
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_messages_by_agent(self, agent_id: str) -> List[Dict[str, Any]]:
|
|
||||||
"""Get all messages for a specific agent"""
|
|
||||||
return [
|
|
||||||
msg for msg in self.messages
|
|
||||||
if msg["sender_id"] == agent_id or msg["receiver_id"] == agent_id
|
|
||||||
]
|
|
||||||
|
|
||||||
class AgentMessageClient:
|
|
||||||
"""Client for agent message communication"""
|
|
||||||
|
|
||||||
def __init__(self, agent_id: str, protocol: MessageProtocol):
|
|
||||||
self.agent_id = agent_id
|
|
||||||
self.protocol = protocol
|
|
||||||
self.received_messages = []
|
|
||||||
|
|
||||||
def send_message(
|
|
||||||
self,
|
|
||||||
receiver_id: str,
|
|
||||||
message_type: MessageTypes,
|
|
||||||
content: Dict[str, Any]
|
|
||||||
) -> Dict[str, Any]:
|
|
||||||
"""Send a message to another agent"""
|
|
||||||
message = self.protocol.create_message(
|
|
||||||
sender_id=self.agent_id,
|
|
||||||
receiver_id=receiver_id,
|
|
||||||
message_type=message_type,
|
|
||||||
content=content
|
|
||||||
)
|
|
||||||
self.protocol.send_message(message)
|
|
||||||
return message
|
|
||||||
|
|
||||||
def receive_messages(self) -> List[Dict[str, Any]]:
|
|
||||||
"""Receive all pending messages for this agent"""
|
|
||||||
messages = []
|
|
||||||
for message in self.protocol.messages:
|
|
||||||
if (message["receiver_id"] == self.agent_id and
|
|
||||||
message["status"] == "sent" and
|
|
||||||
message not in self.received_messages):
|
|
||||||
self.protocol.receive_message(message["message_id"])
|
|
||||||
self.received_messages.append(message)
|
|
||||||
messages.append(message)
|
|
||||||
return messages
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
"""
|
|
||||||
Task Manager for AITBC Agents
|
|
||||||
Handles task creation, assignment, and tracking
|
|
||||||
"""
|
|
||||||
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
from typing import Dict, Any, Optional, List
|
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
class TaskStatus(Enum):
|
|
||||||
"""Task status enumeration"""
|
|
||||||
PENDING = "pending"
|
|
||||||
IN_PROGRESS = "in_progress"
|
|
||||||
COMPLETED = "completed"
|
|
||||||
FAILED = "failed"
|
|
||||||
CANCELLED = "cancelled"
|
|
||||||
|
|
||||||
class TaskPriority(Enum):
|
|
||||||
"""Task priority enumeration"""
|
|
||||||
LOW = "low"
|
|
||||||
MEDIUM = "medium"
|
|
||||||
HIGH = "high"
|
|
||||||
URGENT = "urgent"
|
|
||||||
|
|
||||||
class Task:
|
|
||||||
"""Task representation"""
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
task_id: str,
|
|
||||||
title: str,
|
|
||||||
description: str,
|
|
||||||
assigned_to: str,
|
|
||||||
priority: TaskPriority = TaskPriority.MEDIUM,
|
|
||||||
created_by: Optional[str] = None
|
|
||||||
):
|
|
||||||
self.task_id = task_id
|
|
||||||
self.title = title
|
|
||||||
self.description = description
|
|
||||||
self.assigned_to = assigned_to
|
|
||||||
self.priority = priority
|
|
||||||
self.created_by = created_by or assigned_to
|
|
||||||
self.status = TaskStatus.PENDING
|
|
||||||
self.created_at = datetime.utcnow()
|
|
||||||
self.updated_at = datetime.utcnow()
|
|
||||||
self.completed_at = None
|
|
||||||
self.result = None
|
|
||||||
self.error = None
|
|
||||||
|
|
||||||
class TaskManager:
|
|
||||||
"""Task manager for agent coordination"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.tasks = {}
|
|
||||||
self.task_history = []
|
|
||||||
|
|
||||||
def create_task(
|
|
||||||
self,
|
|
||||||
title: str,
|
|
||||||
description: str,
|
|
||||||
assigned_to: str,
|
|
||||||
priority: TaskPriority = TaskPriority.MEDIUM,
|
|
||||||
created_by: Optional[str] = None
|
|
||||||
) -> Task:
|
|
||||||
"""Create a new task"""
|
|
||||||
task_id = str(uuid.uuid4())
|
|
||||||
task = Task(
|
|
||||||
task_id=task_id,
|
|
||||||
title=title,
|
|
||||||
description=description,
|
|
||||||
assigned_to=assigned_to,
|
|
||||||
priority=priority,
|
|
||||||
created_by=created_by
|
|
||||||
)
|
|
||||||
|
|
||||||
self.tasks[task_id] = task
|
|
||||||
return task
|
|
||||||
|
|
||||||
def get_task(self, task_id: str) -> Optional[Task]:
|
|
||||||
"""Get a task by ID"""
|
|
||||||
return self.tasks.get(task_id)
|
|
||||||
|
|
||||||
def update_task_status(
|
|
||||||
self,
|
|
||||||
task_id: str,
|
|
||||||
status: TaskStatus,
|
|
||||||
result: Optional[Dict[str, Any]] = None,
|
|
||||||
error: Optional[str] = None
|
|
||||||
) -> bool:
|
|
||||||
"""Update task status"""
|
|
||||||
task = self.get_task(task_id)
|
|
||||||
if not task:
|
|
||||||
return False
|
|
||||||
|
|
||||||
task.status = status
|
|
||||||
task.updated_at = datetime.utcnow()
|
|
||||||
|
|
||||||
if status == TaskStatus.COMPLETED:
|
|
||||||
task.completed_at = datetime.utcnow()
|
|
||||||
task.result = result
|
|
||||||
elif status == TaskStatus.FAILED:
|
|
||||||
task.error = error
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def get_tasks_by_agent(self, agent_id: str) -> List[Task]:
|
|
||||||
"""Get all tasks assigned to an agent"""
|
|
||||||
return [
|
|
||||||
task for task in self.tasks.values()
|
|
||||||
if task.assigned_to == agent_id
|
|
||||||
]
|
|
||||||
|
|
||||||
def get_tasks_by_status(self, status: TaskStatus) -> List[Task]:
|
|
||||||
"""Get all tasks with a specific status"""
|
|
||||||
return [
|
|
||||||
task for task in self.tasks.values()
|
|
||||||
if task.status == status
|
|
||||||
]
|
|
||||||
|
|
||||||
def get_overdue_tasks(self, hours: int = 24) -> List[Task]:
|
|
||||||
"""Get tasks that are overdue"""
|
|
||||||
cutoff_time = datetime.utcnow() - timedelta(hours=hours)
|
|
||||||
return [
|
|
||||||
task for task in self.tasks.values()
|
|
||||||
if task.status in [TaskStatus.PENDING, TaskStatus.IN_PROGRESS] and
|
|
||||||
task.created_at < cutoff_time
|
|
||||||
]
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Agent Registry Service
|
|
||||||
Central agent discovery and registration system
|
|
||||||
"""
|
|
||||||
|
|
||||||
from fastapi import FastAPI, HTTPException, Depends
|
|
||||||
from pydantic import BaseModel
|
|
||||||
from typing import List, Optional, Dict, Any
|
|
||||||
import json
|
|
||||||
import time
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
import sqlite3
|
|
||||||
from contextlib import contextmanager
|
|
||||||
from contextlib import asynccontextmanager
|
|
||||||
|
|
||||||
@asynccontextmanager
|
|
||||||
async def lifespan(app: FastAPI):
|
|
||||||
# Startup
|
|
||||||
init_db()
|
|
||||||
yield
|
|
||||||
# Shutdown (cleanup if needed)
|
|
||||||
pass
|
|
||||||
|
|
||||||
app = FastAPI(title="AITBC Agent Registry API", version="1.0.0", lifespan=lifespan)
|
|
||||||
|
|
||||||
# Database setup
|
|
||||||
def get_db():
|
|
||||||
conn = sqlite3.connect('agent_registry.db')
|
|
||||||
conn.row_factory = sqlite3.Row
|
|
||||||
return conn
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def get_db_connection():
|
|
||||||
conn = get_db()
|
|
||||||
try:
|
|
||||||
yield conn
|
|
||||||
finally:
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
# Initialize database
|
|
||||||
def init_db():
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
CREATE TABLE IF NOT EXISTS agents (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
name TEXT NOT NULL,
|
|
||||||
type TEXT NOT NULL,
|
|
||||||
capabilities TEXT NOT NULL,
|
|
||||||
chain_id TEXT NOT NULL,
|
|
||||||
endpoint TEXT NOT NULL,
|
|
||||||
status TEXT DEFAULT 'active',
|
|
||||||
last_heartbeat TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
metadata TEXT,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
||||||
)
|
|
||||||
''')
|
|
||||||
|
|
||||||
# Models
|
|
||||||
class Agent(BaseModel):
|
|
||||||
id: str
|
|
||||||
name: str
|
|
||||||
type: str
|
|
||||||
capabilities: List[str]
|
|
||||||
chain_id: str
|
|
||||||
endpoint: str
|
|
||||||
metadata: Optional[Dict[str, Any]] = {}
|
|
||||||
|
|
||||||
class AgentRegistration(BaseModel):
|
|
||||||
name: str
|
|
||||||
type: str
|
|
||||||
capabilities: List[str]
|
|
||||||
chain_id: str
|
|
||||||
endpoint: str
|
|
||||||
metadata: Optional[Dict[str, Any]] = {}
|
|
||||||
|
|
||||||
# API Endpoints
|
|
||||||
|
|
||||||
@app.post("/api/agents/register", response_model=Agent)
|
|
||||||
async def register_agent(agent: AgentRegistration):
|
|
||||||
"""Register a new agent"""
|
|
||||||
agent_id = str(uuid.uuid4())
|
|
||||||
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
INSERT INTO agents (id, name, type, capabilities, chain_id, endpoint, metadata)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
||||||
''', (
|
|
||||||
agent_id, agent.name, agent.type,
|
|
||||||
json.dumps(agent.capabilities), agent.chain_id,
|
|
||||||
agent.endpoint, json.dumps(agent.metadata)
|
|
||||||
))
|
|
||||||
conn.commit()
|
|
||||||
|
|
||||||
return Agent(
|
|
||||||
id=agent_id,
|
|
||||||
name=agent.name,
|
|
||||||
type=agent.type,
|
|
||||||
capabilities=agent.capabilities,
|
|
||||||
chain_id=agent.chain_id,
|
|
||||||
endpoint=agent.endpoint,
|
|
||||||
metadata=agent.metadata
|
|
||||||
)
|
|
||||||
|
|
||||||
@app.get("/api/agents", response_model=List[Agent])
|
|
||||||
async def list_agents(
|
|
||||||
agent_type: Optional[str] = None,
|
|
||||||
chain_id: Optional[str] = None,
|
|
||||||
capability: Optional[str] = None
|
|
||||||
):
|
|
||||||
"""List registered agents with optional filters"""
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
query = "SELECT * FROM agents WHERE status = 'active'"
|
|
||||||
params = []
|
|
||||||
|
|
||||||
if agent_type:
|
|
||||||
query += " AND type = ?"
|
|
||||||
params.append(agent_type)
|
|
||||||
|
|
||||||
if chain_id:
|
|
||||||
query += " AND chain_id = ?"
|
|
||||||
params.append(chain_id)
|
|
||||||
|
|
||||||
if capability:
|
|
||||||
query += " AND capabilities LIKE ?"
|
|
||||||
params.append(f'%{capability}%')
|
|
||||||
|
|
||||||
agents = conn.execute(query, params).fetchall()
|
|
||||||
|
|
||||||
return [
|
|
||||||
Agent(
|
|
||||||
id=agent["id"],
|
|
||||||
name=agent["name"],
|
|
||||||
type=agent["type"],
|
|
||||||
capabilities=json.loads(agent["capabilities"]),
|
|
||||||
chain_id=agent["chain_id"],
|
|
||||||
endpoint=agent["endpoint"],
|
|
||||||
metadata=json.loads(agent["metadata"] or "{}")
|
|
||||||
)
|
|
||||||
for agent in agents
|
|
||||||
]
|
|
||||||
|
|
||||||
@app.get("/api/health")
|
|
||||||
async def health_check():
|
|
||||||
"""Health check endpoint"""
|
|
||||||
return {"status": "ok", "timestamp": datetime.utcnow()}
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import uvicorn
|
|
||||||
uvicorn.run(app, host="0.0.0.0", port=8013)
|
|
||||||
@@ -1,431 +0,0 @@
|
|||||||
"""
|
|
||||||
Agent Registration System
|
|
||||||
Handles AI agent registration, capability management, and discovery
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import time
|
|
||||||
import json
|
|
||||||
import hashlib
|
|
||||||
from typing import Dict, List, Optional, Set, Tuple
|
|
||||||
from dataclasses import dataclass, asdict
|
|
||||||
from enum import Enum
|
|
||||||
from decimal import Decimal
|
|
||||||
|
|
||||||
class AgentType(Enum):
|
|
||||||
AI_MODEL = "ai_model"
|
|
||||||
DATA_PROVIDER = "data_provider"
|
|
||||||
VALIDATOR = "validator"
|
|
||||||
MARKET_MAKER = "market_maker"
|
|
||||||
BROKER = "broker"
|
|
||||||
ORACLE = "oracle"
|
|
||||||
|
|
||||||
class AgentStatus(Enum):
|
|
||||||
REGISTERED = "registered"
|
|
||||||
ACTIVE = "active"
|
|
||||||
INACTIVE = "inactive"
|
|
||||||
SUSPENDED = "suspended"
|
|
||||||
BANNED = "banned"
|
|
||||||
|
|
||||||
class CapabilityType(Enum):
|
|
||||||
TEXT_GENERATION = "text_generation"
|
|
||||||
IMAGE_GENERATION = "image_generation"
|
|
||||||
DATA_ANALYSIS = "data_analysis"
|
|
||||||
PREDICTION = "prediction"
|
|
||||||
VALIDATION = "validation"
|
|
||||||
COMPUTATION = "computation"
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class AgentCapability:
|
|
||||||
capability_type: CapabilityType
|
|
||||||
name: str
|
|
||||||
version: str
|
|
||||||
parameters: Dict
|
|
||||||
performance_metrics: Dict
|
|
||||||
cost_per_use: Decimal
|
|
||||||
availability: float
|
|
||||||
max_concurrent_jobs: int
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class AgentInfo:
|
|
||||||
agent_id: str
|
|
||||||
agent_type: AgentType
|
|
||||||
name: str
|
|
||||||
owner_address: str
|
|
||||||
public_key: str
|
|
||||||
endpoint_url: str
|
|
||||||
capabilities: List[AgentCapability]
|
|
||||||
reputation_score: float
|
|
||||||
total_jobs_completed: int
|
|
||||||
total_earnings: Decimal
|
|
||||||
registration_time: float
|
|
||||||
last_active: float
|
|
||||||
status: AgentStatus
|
|
||||||
metadata: Dict
|
|
||||||
|
|
||||||
class AgentRegistry:
|
|
||||||
"""Manages AI agent registration and discovery"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.agents: Dict[str, AgentInfo] = {}
|
|
||||||
self.capability_index: Dict[CapabilityType, Set[str]] = {} # capability -> agent_ids
|
|
||||||
self.type_index: Dict[AgentType, Set[str]] = {} # agent_type -> agent_ids
|
|
||||||
self.reputation_scores: Dict[str, float] = {}
|
|
||||||
self.registration_queue: List[Dict] = []
|
|
||||||
|
|
||||||
# Registry parameters
|
|
||||||
self.min_reputation_threshold = 0.5
|
|
||||||
self.max_agents_per_type = 1000
|
|
||||||
self.registration_fee = Decimal('100.0')
|
|
||||||
self.inactivity_threshold = 86400 * 7 # 7 days
|
|
||||||
|
|
||||||
# Initialize capability index
|
|
||||||
for capability_type in CapabilityType:
|
|
||||||
self.capability_index[capability_type] = set()
|
|
||||||
|
|
||||||
# Initialize type index
|
|
||||||
for agent_type in AgentType:
|
|
||||||
self.type_index[agent_type] = set()
|
|
||||||
|
|
||||||
async def register_agent(self, agent_type: AgentType, name: str, owner_address: str,
|
|
||||||
public_key: str, endpoint_url: str, capabilities: List[Dict],
|
|
||||||
metadata: Dict = None) -> Tuple[bool, str, Optional[str]]:
|
|
||||||
"""Register a new AI agent"""
|
|
||||||
try:
|
|
||||||
# Validate inputs
|
|
||||||
if not self._validate_registration_inputs(agent_type, name, owner_address, public_key, endpoint_url):
|
|
||||||
return False, "Invalid registration inputs", None
|
|
||||||
|
|
||||||
# Check if agent already exists
|
|
||||||
agent_id = self._generate_agent_id(owner_address, name)
|
|
||||||
if agent_id in self.agents:
|
|
||||||
return False, "Agent already registered", None
|
|
||||||
|
|
||||||
# Check type limits
|
|
||||||
if len(self.type_index[agent_type]) >= self.max_agents_per_type:
|
|
||||||
return False, f"Maximum agents of type {agent_type.value} reached", None
|
|
||||||
|
|
||||||
# Convert capabilities
|
|
||||||
agent_capabilities = []
|
|
||||||
for cap_data in capabilities:
|
|
||||||
capability = self._create_capability_from_data(cap_data)
|
|
||||||
if capability:
|
|
||||||
agent_capabilities.append(capability)
|
|
||||||
|
|
||||||
if not agent_capabilities:
|
|
||||||
return False, "Agent must have at least one valid capability", None
|
|
||||||
|
|
||||||
# Create agent info
|
|
||||||
agent_info = AgentInfo(
|
|
||||||
agent_id=agent_id,
|
|
||||||
agent_type=agent_type,
|
|
||||||
name=name,
|
|
||||||
owner_address=owner_address,
|
|
||||||
public_key=public_key,
|
|
||||||
endpoint_url=endpoint_url,
|
|
||||||
capabilities=agent_capabilities,
|
|
||||||
reputation_score=1.0, # Start with neutral reputation
|
|
||||||
total_jobs_completed=0,
|
|
||||||
total_earnings=Decimal('0'),
|
|
||||||
registration_time=time.time(),
|
|
||||||
last_active=time.time(),
|
|
||||||
status=AgentStatus.REGISTERED,
|
|
||||||
metadata=metadata or {}
|
|
||||||
)
|
|
||||||
|
|
||||||
# Add to registry
|
|
||||||
self.agents[agent_id] = agent_info
|
|
||||||
|
|
||||||
# Update indexes
|
|
||||||
self.type_index[agent_type].add(agent_id)
|
|
||||||
for capability in agent_capabilities:
|
|
||||||
self.capability_index[capability.capability_type].add(agent_id)
|
|
||||||
|
|
||||||
log_info(f"Agent registered: {agent_id} ({name})")
|
|
||||||
return True, "Registration successful", agent_id
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
return False, f"Registration failed: {str(e)}", None
|
|
||||||
|
|
||||||
def _validate_registration_inputs(self, agent_type: AgentType, name: str,
|
|
||||||
owner_address: str, public_key: str, endpoint_url: str) -> bool:
|
|
||||||
"""Validate registration inputs"""
|
|
||||||
# Check required fields
|
|
||||||
if not all([agent_type, name, owner_address, public_key, endpoint_url]):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Validate address format (simplified)
|
|
||||||
if not owner_address.startswith('0x') or len(owner_address) != 42:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Validate URL format (simplified)
|
|
||||||
if not endpoint_url.startswith(('http://', 'https://')):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Validate name
|
|
||||||
if len(name) < 3 or len(name) > 100:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def _generate_agent_id(self, owner_address: str, name: str) -> str:
|
|
||||||
"""Generate unique agent ID"""
|
|
||||||
content = f"{owner_address}:{name}:{time.time()}"
|
|
||||||
return hashlib.sha256(content.encode()).hexdigest()[:16]
|
|
||||||
|
|
||||||
def _create_capability_from_data(self, cap_data: Dict) -> Optional[AgentCapability]:
|
|
||||||
"""Create capability from data dictionary"""
|
|
||||||
try:
|
|
||||||
# Validate required fields
|
|
||||||
required_fields = ['type', 'name', 'version', 'cost_per_use']
|
|
||||||
if not all(field in cap_data for field in required_fields):
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Parse capability type
|
|
||||||
try:
|
|
||||||
capability_type = CapabilityType(cap_data['type'])
|
|
||||||
except ValueError:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Create capability
|
|
||||||
return AgentCapability(
|
|
||||||
capability_type=capability_type,
|
|
||||||
name=cap_data['name'],
|
|
||||||
version=cap_data['version'],
|
|
||||||
parameters=cap_data.get('parameters', {}),
|
|
||||||
performance_metrics=cap_data.get('performance_metrics', {}),
|
|
||||||
cost_per_use=Decimal(str(cap_data['cost_per_use'])),
|
|
||||||
availability=cap_data.get('availability', 1.0),
|
|
||||||
max_concurrent_jobs=cap_data.get('max_concurrent_jobs', 1)
|
|
||||||
)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
log_error(f"Error creating capability: {e}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
async def update_agent_status(self, agent_id: str, status: AgentStatus) -> Tuple[bool, str]:
|
|
||||||
"""Update agent status"""
|
|
||||||
if agent_id not in self.agents:
|
|
||||||
return False, "Agent not found"
|
|
||||||
|
|
||||||
agent = self.agents[agent_id]
|
|
||||||
old_status = agent.status
|
|
||||||
agent.status = status
|
|
||||||
agent.last_active = time.time()
|
|
||||||
|
|
||||||
log_info(f"Agent {agent_id} status changed: {old_status.value} -> {status.value}")
|
|
||||||
return True, "Status updated successfully"
|
|
||||||
|
|
||||||
async def update_agent_capabilities(self, agent_id: str, capabilities: List[Dict]) -> Tuple[bool, str]:
|
|
||||||
"""Update agent capabilities"""
|
|
||||||
if agent_id not in self.agents:
|
|
||||||
return False, "Agent not found"
|
|
||||||
|
|
||||||
agent = self.agents[agent_id]
|
|
||||||
|
|
||||||
# Remove old capabilities from index
|
|
||||||
for old_capability in agent.capabilities:
|
|
||||||
self.capability_index[old_capability.capability_type].discard(agent_id)
|
|
||||||
|
|
||||||
# Add new capabilities
|
|
||||||
new_capabilities = []
|
|
||||||
for cap_data in capabilities:
|
|
||||||
capability = self._create_capability_from_data(cap_data)
|
|
||||||
if capability:
|
|
||||||
new_capabilities.append(capability)
|
|
||||||
self.capability_index[capability.capability_type].add(agent_id)
|
|
||||||
|
|
||||||
if not new_capabilities:
|
|
||||||
return False, "No valid capabilities provided"
|
|
||||||
|
|
||||||
agent.capabilities = new_capabilities
|
|
||||||
agent.last_active = time.time()
|
|
||||||
|
|
||||||
return True, "Capabilities updated successfully"
|
|
||||||
|
|
||||||
async def find_agents_by_capability(self, capability_type: CapabilityType,
|
|
||||||
filters: Dict = None) -> List[AgentInfo]:
|
|
||||||
"""Find agents by capability type"""
|
|
||||||
agent_ids = self.capability_index.get(capability_type, set())
|
|
||||||
|
|
||||||
agents = []
|
|
||||||
for agent_id in agent_ids:
|
|
||||||
agent = self.agents.get(agent_id)
|
|
||||||
if agent and agent.status == AgentStatus.ACTIVE:
|
|
||||||
if self._matches_filters(agent, filters):
|
|
||||||
agents.append(agent)
|
|
||||||
|
|
||||||
# Sort by reputation (highest first)
|
|
||||||
agents.sort(key=lambda x: x.reputation_score, reverse=True)
|
|
||||||
return agents
|
|
||||||
|
|
||||||
async def find_agents_by_type(self, agent_type: AgentType, filters: Dict = None) -> List[AgentInfo]:
|
|
||||||
"""Find agents by type"""
|
|
||||||
agent_ids = self.type_index.get(agent_type, set())
|
|
||||||
|
|
||||||
agents = []
|
|
||||||
for agent_id in agent_ids:
|
|
||||||
agent = self.agents.get(agent_id)
|
|
||||||
if agent and agent.status == AgentStatus.ACTIVE:
|
|
||||||
if self._matches_filters(agent, filters):
|
|
||||||
agents.append(agent)
|
|
||||||
|
|
||||||
# Sort by reputation (highest first)
|
|
||||||
agents.sort(key=lambda x: x.reputation_score, reverse=True)
|
|
||||||
return agents
|
|
||||||
|
|
||||||
def _matches_filters(self, agent: AgentInfo, filters: Dict) -> bool:
|
|
||||||
"""Check if agent matches filters"""
|
|
||||||
if not filters:
|
|
||||||
return True
|
|
||||||
|
|
||||||
# Reputation filter
|
|
||||||
if 'min_reputation' in filters:
|
|
||||||
if agent.reputation_score < filters['min_reputation']:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Cost filter
|
|
||||||
if 'max_cost_per_use' in filters:
|
|
||||||
max_cost = Decimal(str(filters['max_cost_per_use']))
|
|
||||||
if any(cap.cost_per_use > max_cost for cap in agent.capabilities):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Availability filter
|
|
||||||
if 'min_availability' in filters:
|
|
||||||
min_availability = filters['min_availability']
|
|
||||||
if any(cap.availability < min_availability for cap in agent.capabilities):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Location filter (if implemented)
|
|
||||||
if 'location' in filters:
|
|
||||||
agent_location = agent.metadata.get('location')
|
|
||||||
if agent_location != filters['location']:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
async def get_agent_info(self, agent_id: str) -> Optional[AgentInfo]:
|
|
||||||
"""Get agent information"""
|
|
||||||
return self.agents.get(agent_id)
|
|
||||||
|
|
||||||
async def search_agents(self, query: str, limit: int = 50) -> List[AgentInfo]:
|
|
||||||
"""Search agents by name or capability"""
|
|
||||||
query_lower = query.lower()
|
|
||||||
results = []
|
|
||||||
|
|
||||||
for agent in self.agents.values():
|
|
||||||
if agent.status != AgentStatus.ACTIVE:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Search in name
|
|
||||||
if query_lower in agent.name.lower():
|
|
||||||
results.append(agent)
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Search in capabilities
|
|
||||||
for capability in agent.capabilities:
|
|
||||||
if (query_lower in capability.name.lower() or
|
|
||||||
query_lower in capability.capability_type.value):
|
|
||||||
results.append(agent)
|
|
||||||
break
|
|
||||||
|
|
||||||
# Sort by relevance (reputation)
|
|
||||||
results.sort(key=lambda x: x.reputation_score, reverse=True)
|
|
||||||
return results[:limit]
|
|
||||||
|
|
||||||
async def get_agent_statistics(self, agent_id: str) -> Optional[Dict]:
|
|
||||||
"""Get detailed statistics for an agent"""
|
|
||||||
agent = self.agents.get(agent_id)
|
|
||||||
if not agent:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Calculate additional statistics
|
|
||||||
avg_job_earnings = agent.total_earnings / agent.total_jobs_completed if agent.total_jobs_completed > 0 else Decimal('0')
|
|
||||||
days_active = (time.time() - agent.registration_time) / 86400
|
|
||||||
jobs_per_day = agent.total_jobs_completed / days_active if days_active > 0 else 0
|
|
||||||
|
|
||||||
return {
|
|
||||||
'agent_id': agent_id,
|
|
||||||
'name': agent.name,
|
|
||||||
'type': agent.agent_type.value,
|
|
||||||
'status': agent.status.value,
|
|
||||||
'reputation_score': agent.reputation_score,
|
|
||||||
'total_jobs_completed': agent.total_jobs_completed,
|
|
||||||
'total_earnings': float(agent.total_earnings),
|
|
||||||
'avg_job_earnings': float(avg_job_earnings),
|
|
||||||
'jobs_per_day': jobs_per_day,
|
|
||||||
'days_active': int(days_active),
|
|
||||||
'capabilities_count': len(agent.capabilities),
|
|
||||||
'last_active': agent.last_active,
|
|
||||||
'registration_time': agent.registration_time
|
|
||||||
}
|
|
||||||
|
|
||||||
async def get_registry_statistics(self) -> Dict:
|
|
||||||
"""Get registry-wide statistics"""
|
|
||||||
total_agents = len(self.agents)
|
|
||||||
active_agents = len([a for a in self.agents.values() if a.status == AgentStatus.ACTIVE])
|
|
||||||
|
|
||||||
# Count by type
|
|
||||||
type_counts = {}
|
|
||||||
for agent_type in AgentType:
|
|
||||||
type_counts[agent_type.value] = len(self.type_index[agent_type])
|
|
||||||
|
|
||||||
# Count by capability
|
|
||||||
capability_counts = {}
|
|
||||||
for capability_type in CapabilityType:
|
|
||||||
capability_counts[capability_type.value] = len(self.capability_index[capability_type])
|
|
||||||
|
|
||||||
# Reputation statistics
|
|
||||||
reputations = [a.reputation_score for a in self.agents.values()]
|
|
||||||
avg_reputation = sum(reputations) / len(reputations) if reputations else 0
|
|
||||||
|
|
||||||
# Earnings statistics
|
|
||||||
total_earnings = sum(a.total_earnings for a in self.agents.values())
|
|
||||||
|
|
||||||
return {
|
|
||||||
'total_agents': total_agents,
|
|
||||||
'active_agents': active_agents,
|
|
||||||
'inactive_agents': total_agents - active_agents,
|
|
||||||
'agent_types': type_counts,
|
|
||||||
'capabilities': capability_counts,
|
|
||||||
'average_reputation': avg_reputation,
|
|
||||||
'total_earnings': float(total_earnings),
|
|
||||||
'registration_fee': float(self.registration_fee)
|
|
||||||
}
|
|
||||||
|
|
||||||
async def cleanup_inactive_agents(self) -> Tuple[int, str]:
|
|
||||||
"""Clean up inactive agents"""
|
|
||||||
current_time = time.time()
|
|
||||||
cleaned_count = 0
|
|
||||||
|
|
||||||
for agent_id, agent in list(self.agents.items()):
|
|
||||||
if (agent.status == AgentStatus.INACTIVE and
|
|
||||||
current_time - agent.last_active > self.inactivity_threshold):
|
|
||||||
|
|
||||||
# Remove from registry
|
|
||||||
del self.agents[agent_id]
|
|
||||||
|
|
||||||
# Update indexes
|
|
||||||
self.type_index[agent.agent_type].discard(agent_id)
|
|
||||||
for capability in agent.capabilities:
|
|
||||||
self.capability_index[capability.capability_type].discard(agent_id)
|
|
||||||
|
|
||||||
cleaned_count += 1
|
|
||||||
|
|
||||||
if cleaned_count > 0:
|
|
||||||
log_info(f"Cleaned up {cleaned_count} inactive agents")
|
|
||||||
|
|
||||||
return cleaned_count, f"Cleaned up {cleaned_count} inactive agents"
|
|
||||||
|
|
||||||
# Global agent registry
|
|
||||||
agent_registry: Optional[AgentRegistry] = None
|
|
||||||
|
|
||||||
def get_agent_registry() -> Optional[AgentRegistry]:
|
|
||||||
"""Get global agent registry"""
|
|
||||||
return agent_registry
|
|
||||||
|
|
||||||
def create_agent_registry() -> AgentRegistry:
|
|
||||||
"""Create and set global agent registry"""
|
|
||||||
global agent_registry
|
|
||||||
agent_registry = AgentRegistry()
|
|
||||||
return agent_registry
|
|
||||||
@@ -1,166 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Trading Agent
|
|
||||||
Automated trading agent for AITBC marketplace
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import json
|
|
||||||
import time
|
|
||||||
from typing import Dict, Any, List
|
|
||||||
from datetime import datetime
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Add parent directory to path
|
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '../../../..'))
|
|
||||||
|
|
||||||
from apps.agent_services.agent_bridge.src.integration_layer import AgentServiceBridge
|
|
||||||
|
|
||||||
class TradingAgent:
|
|
||||||
"""Automated trading agent"""
|
|
||||||
|
|
||||||
def __init__(self, agent_id: str, config: Dict[str, Any]):
|
|
||||||
self.agent_id = agent_id
|
|
||||||
self.config = config
|
|
||||||
self.bridge = AgentServiceBridge()
|
|
||||||
self.is_running = False
|
|
||||||
self.trading_strategy = config.get("strategy", "basic")
|
|
||||||
self.symbols = config.get("symbols", ["AITBC/BTC"])
|
|
||||||
self.trade_interval = config.get("trade_interval", 60) # seconds
|
|
||||||
|
|
||||||
async def start(self) -> bool:
|
|
||||||
"""Start trading agent"""
|
|
||||||
try:
|
|
||||||
# Register with service bridge
|
|
||||||
success = await self.bridge.start_agent(self.agent_id, {
|
|
||||||
"type": "trading",
|
|
||||||
"capabilities": ["market_analysis", "trading", "risk_management"],
|
|
||||||
"endpoint": f"http://localhost:8005"
|
|
||||||
})
|
|
||||||
|
|
||||||
if success:
|
|
||||||
self.is_running = True
|
|
||||||
print(f"Trading agent {self.agent_id} started successfully")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f"Failed to start trading agent {self.agent_id}")
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error starting trading agent: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def stop(self) -> bool:
|
|
||||||
"""Stop trading agent"""
|
|
||||||
self.is_running = False
|
|
||||||
success = await self.bridge.stop_agent(self.agent_id)
|
|
||||||
if success:
|
|
||||||
print(f"Trading agent {self.agent_id} stopped successfully")
|
|
||||||
return success
|
|
||||||
|
|
||||||
async def run_trading_loop(self):
|
|
||||||
"""Main trading loop"""
|
|
||||||
while self.is_running:
|
|
||||||
try:
|
|
||||||
for symbol in self.symbols:
|
|
||||||
await self._analyze_and_trade(symbol)
|
|
||||||
|
|
||||||
await asyncio.sleep(self.trade_interval)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error in trading loop: {e}")
|
|
||||||
await asyncio.sleep(10) # Wait before retrying
|
|
||||||
|
|
||||||
async def _analyze_and_trade(self, symbol: str) -> None:
|
|
||||||
"""Analyze market and execute trades"""
|
|
||||||
try:
|
|
||||||
# Perform market analysis
|
|
||||||
analysis_task = {
|
|
||||||
"type": "market_analysis",
|
|
||||||
"symbol": symbol,
|
|
||||||
"strategy": self.trading_strategy
|
|
||||||
}
|
|
||||||
|
|
||||||
analysis_result = await self.bridge.execute_agent_task(self.agent_id, analysis_task)
|
|
||||||
|
|
||||||
if analysis_result.get("status") == "success":
|
|
||||||
analysis = analysis_result["result"]["analysis"]
|
|
||||||
|
|
||||||
# Make trading decision
|
|
||||||
if self._should_trade(analysis):
|
|
||||||
await self._execute_trade(symbol, analysis)
|
|
||||||
else:
|
|
||||||
print(f"Market analysis failed for {symbol}: {analysis_result}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error in analyze_and_trade for {symbol}: {e}")
|
|
||||||
|
|
||||||
def _should_trade(self, analysis: Dict[str, Any]) -> bool:
|
|
||||||
"""Determine if should execute trade"""
|
|
||||||
recommendation = analysis.get("recommendation", "hold")
|
|
||||||
return recommendation in ["buy", "sell"]
|
|
||||||
|
|
||||||
async def _execute_trade(self, symbol: str, analysis: Dict[str, Any]) -> None:
|
|
||||||
"""Execute trade based on analysis"""
|
|
||||||
try:
|
|
||||||
recommendation = analysis.get("recommendation", "hold")
|
|
||||||
|
|
||||||
if recommendation == "buy":
|
|
||||||
trade_task = {
|
|
||||||
"type": "trading",
|
|
||||||
"symbol": symbol,
|
|
||||||
"side": "buy",
|
|
||||||
"amount": self.config.get("trade_amount", 0.1),
|
|
||||||
"strategy": self.trading_strategy
|
|
||||||
}
|
|
||||||
elif recommendation == "sell":
|
|
||||||
trade_task = {
|
|
||||||
"type": "trading",
|
|
||||||
"symbol": symbol,
|
|
||||||
"side": "sell",
|
|
||||||
"amount": self.config.get("trade_amount", 0.1),
|
|
||||||
"strategy": self.trading_strategy
|
|
||||||
}
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
|
|
||||||
trade_result = await self.bridge.execute_agent_task(self.agent_id, trade_task)
|
|
||||||
|
|
||||||
if trade_result.get("status") == "success":
|
|
||||||
print(f"Trade executed successfully: {trade_result}")
|
|
||||||
else:
|
|
||||||
print(f"Trade execution failed: {trade_result}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error executing trade: {e}")
|
|
||||||
|
|
||||||
async def get_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get agent status"""
|
|
||||||
return await self.bridge.get_agent_status(self.agent_id)
|
|
||||||
|
|
||||||
# Main execution
|
|
||||||
async def main():
|
|
||||||
"""Main trading agent execution"""
|
|
||||||
agent_id = "trading-agent-001"
|
|
||||||
config = {
|
|
||||||
"strategy": "basic",
|
|
||||||
"symbols": ["AITBC/BTC"],
|
|
||||||
"trade_interval": 30,
|
|
||||||
"trade_amount": 0.1
|
|
||||||
}
|
|
||||||
|
|
||||||
agent = TradingAgent(agent_id, config)
|
|
||||||
|
|
||||||
# Start agent
|
|
||||||
if await agent.start():
|
|
||||||
try:
|
|
||||||
# Run trading loop
|
|
||||||
await agent.run_trading_loop()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("Shutting down trading agent...")
|
|
||||||
finally:
|
|
||||||
await agent.stop()
|
|
||||||
else:
|
|
||||||
print("Failed to start trading agent")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
asyncio.run(main())
|
|
||||||
@@ -1,229 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Agent Integration Layer
|
|
||||||
Connects agent protocols to existing AITBC services
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import aiohttp
|
|
||||||
import json
|
|
||||||
from typing import Dict, Any, List, Optional
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
class AITBCServiceIntegration:
|
|
||||||
"""Integration layer for AITBC services"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.service_endpoints = {
|
|
||||||
"coordinator_api": "http://localhost:8000",
|
|
||||||
"blockchain_rpc": "http://localhost:8006",
|
|
||||||
"exchange_service": "http://localhost:8001",
|
|
||||||
"marketplace": "http://localhost:8002",
|
|
||||||
"agent_registry": "http://localhost:8013"
|
|
||||||
}
|
|
||||||
self.session = None
|
|
||||||
|
|
||||||
async def __aenter__(self):
|
|
||||||
self.session = aiohttp.ClientSession()
|
|
||||||
return self
|
|
||||||
|
|
||||||
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
||||||
if self.session:
|
|
||||||
await self.session.close()
|
|
||||||
|
|
||||||
async def get_blockchain_info(self) -> Dict[str, Any]:
|
|
||||||
"""Get blockchain information"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['blockchain_rpc']}/health") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "unavailable"}
|
|
||||||
|
|
||||||
async def get_exchange_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get exchange service status"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['exchange_service']}/api/health") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "unavailable"}
|
|
||||||
|
|
||||||
async def get_coordinator_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get coordinator API status"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['coordinator_api']}/health") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "unavailable"}
|
|
||||||
|
|
||||||
async def submit_transaction(self, transaction_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Submit transaction to blockchain"""
|
|
||||||
try:
|
|
||||||
async with self.session.post(
|
|
||||||
f"{self.service_endpoints['blockchain_rpc']}/rpc/submit",
|
|
||||||
json=transaction_data
|
|
||||||
) as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "failed"}
|
|
||||||
|
|
||||||
async def get_market_data(self, symbol: str = "AITBC/BTC") -> Dict[str, Any]:
|
|
||||||
"""Get market data from exchange"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['exchange_service']}/api/market/{symbol}") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "failed"}
|
|
||||||
|
|
||||||
async def register_agent_with_coordinator(self, agent_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Register agent with coordinator"""
|
|
||||||
try:
|
|
||||||
async with self.session.post(
|
|
||||||
f"{self.service_endpoints['agent_registry']}/api/agents/register",
|
|
||||||
json=agent_data
|
|
||||||
) as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "failed"}
|
|
||||||
|
|
||||||
class AgentServiceBridge:
|
|
||||||
"""Bridge between agents and AITBC services"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.integration = AITBCServiceIntegration()
|
|
||||||
self.active_agents = {}
|
|
||||||
|
|
||||||
async def start_agent(self, agent_id: str, agent_config: Dict[str, Any]) -> bool:
|
|
||||||
"""Start an agent with service integration"""
|
|
||||||
try:
|
|
||||||
# Register agent with coordinator
|
|
||||||
async with self.integration as integration:
|
|
||||||
registration_result = await integration.register_agent_with_coordinator({
|
|
||||||
"name": agent_id,
|
|
||||||
"type": agent_config.get("type", "generic"),
|
|
||||||
"capabilities": agent_config.get("capabilities", []),
|
|
||||||
"chain_id": agent_config.get("chain_id", "ait-mainnet"),
|
|
||||||
"endpoint": agent_config.get("endpoint", f"http://localhost:{8000 + len(self.active_agents) + 10}")
|
|
||||||
})
|
|
||||||
|
|
||||||
# The registry returns the created agent dict on success, not a {"status": "ok"} wrapper
|
|
||||||
if registration_result and "id" in registration_result:
|
|
||||||
self.active_agents[agent_id] = {
|
|
||||||
"config": agent_config,
|
|
||||||
"registration": registration_result,
|
|
||||||
"started_at": datetime.utcnow()
|
|
||||||
}
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f"Registration failed: {registration_result}")
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Failed to start agent {agent_id}: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def stop_agent(self, agent_id: str) -> bool:
|
|
||||||
"""Stop an agent"""
|
|
||||||
if agent_id in self.active_agents:
|
|
||||||
del self.active_agents[agent_id]
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def get_agent_status(self, agent_id: str) -> Dict[str, Any]:
|
|
||||||
"""Get agent status with service integration"""
|
|
||||||
if agent_id not in self.active_agents:
|
|
||||||
return {"status": "not_found"}
|
|
||||||
|
|
||||||
agent_info = self.active_agents[agent_id]
|
|
||||||
|
|
||||||
async with self.integration as integration:
|
|
||||||
# Get service statuses
|
|
||||||
blockchain_status = await integration.get_blockchain_info()
|
|
||||||
exchange_status = await integration.get_exchange_status()
|
|
||||||
coordinator_status = await integration.get_coordinator_status()
|
|
||||||
|
|
||||||
return {
|
|
||||||
"agent_id": agent_id,
|
|
||||||
"status": "active",
|
|
||||||
"started_at": agent_info["started_at"].isoformat(),
|
|
||||||
"services": {
|
|
||||||
"blockchain": blockchain_status,
|
|
||||||
"exchange": exchange_status,
|
|
||||||
"coordinator": coordinator_status
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async def execute_agent_task(self, agent_id: str, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute agent task with service integration"""
|
|
||||||
if agent_id not in self.active_agents:
|
|
||||||
return {"status": "error", "message": "Agent not found"}
|
|
||||||
|
|
||||||
task_type = task_data.get("type")
|
|
||||||
|
|
||||||
if task_type == "market_analysis":
|
|
||||||
return await self._execute_market_analysis(task_data)
|
|
||||||
elif task_type == "trading":
|
|
||||||
return await self._execute_trading_task(task_data)
|
|
||||||
elif task_type == "compliance_check":
|
|
||||||
return await self._execute_compliance_check(task_data)
|
|
||||||
else:
|
|
||||||
return {"status": "error", "message": f"Unknown task type: {task_type}"}
|
|
||||||
|
|
||||||
async def _execute_market_analysis(self, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute market analysis task"""
|
|
||||||
try:
|
|
||||||
async with self.integration as integration:
|
|
||||||
market_data = await integration.get_market_data(task_data.get("symbol", "AITBC/BTC"))
|
|
||||||
|
|
||||||
# Perform basic analysis
|
|
||||||
analysis_result = {
|
|
||||||
"symbol": task_data.get("symbol", "AITBC/BTC"),
|
|
||||||
"market_data": market_data,
|
|
||||||
"analysis": {
|
|
||||||
"trend": "neutral",
|
|
||||||
"volatility": "medium",
|
|
||||||
"recommendation": "hold"
|
|
||||||
},
|
|
||||||
"timestamp": datetime.utcnow().isoformat()
|
|
||||||
}
|
|
||||||
|
|
||||||
return {"status": "success", "result": analysis_result}
|
|
||||||
except Exception as e:
|
|
||||||
return {"status": "error", "message": str(e)}
|
|
||||||
|
|
||||||
async def _execute_trading_task(self, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute trading task"""
|
|
||||||
try:
|
|
||||||
# Get market data first
|
|
||||||
async with self.integration as integration:
|
|
||||||
market_data = await integration.get_market_data(task_data.get("symbol", "AITBC/BTC"))
|
|
||||||
|
|
||||||
# Create transaction
|
|
||||||
transaction = {
|
|
||||||
"type": "trade",
|
|
||||||
"symbol": task_data.get("symbol", "AITBC/BTC"),
|
|
||||||
"side": task_data.get("side", "buy"),
|
|
||||||
"amount": task_data.get("amount", 0.1),
|
|
||||||
"price": task_data.get("price", market_data.get("price", 0.001))
|
|
||||||
}
|
|
||||||
|
|
||||||
# Submit transaction
|
|
||||||
tx_result = await integration.submit_transaction(transaction)
|
|
||||||
|
|
||||||
return {"status": "success", "transaction": tx_result}
|
|
||||||
except Exception as e:
|
|
||||||
return {"status": "error", "message": str(e)}
|
|
||||||
|
|
||||||
async def _execute_compliance_check(self, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute compliance check task"""
|
|
||||||
try:
|
|
||||||
# Basic compliance check
|
|
||||||
compliance_result = {
|
|
||||||
"user_id": task_data.get("user_id"),
|
|
||||||
"check_type": task_data.get("check_type", "basic"),
|
|
||||||
"status": "passed",
|
|
||||||
"checks_performed": ["kyc", "aml", "sanctions"],
|
|
||||||
"timestamp": datetime.utcnow().isoformat()
|
|
||||||
}
|
|
||||||
|
|
||||||
return {"status": "success", "result": compliance_result}
|
|
||||||
except Exception as e:
|
|
||||||
return {"status": "error", "message": str(e)}
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Compliance Agent
|
|
||||||
Automated compliance and regulatory monitoring agent
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import json
|
|
||||||
import time
|
|
||||||
from typing import Dict, Any, List
|
|
||||||
from datetime import datetime
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Add parent directory to path
|
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '../../../..'))
|
|
||||||
|
|
||||||
from apps.agent_services.agent_bridge.src.integration_layer import AgentServiceBridge
|
|
||||||
|
|
||||||
class ComplianceAgent:
|
|
||||||
"""Automated compliance agent"""
|
|
||||||
|
|
||||||
def __init__(self, agent_id: str, config: Dict[str, Any]):
|
|
||||||
self.agent_id = agent_id
|
|
||||||
self.config = config
|
|
||||||
self.bridge = AgentServiceBridge()
|
|
||||||
self.is_running = False
|
|
||||||
self.check_interval = config.get("check_interval", 300) # 5 minutes
|
|
||||||
self.monitored_entities = config.get("monitored_entities", [])
|
|
||||||
|
|
||||||
async def start(self) -> bool:
|
|
||||||
"""Start compliance agent"""
|
|
||||||
try:
|
|
||||||
success = await self.bridge.start_agent(self.agent_id, {
|
|
||||||
"type": "compliance",
|
|
||||||
"capabilities": ["kyc_check", "aml_screening", "regulatory_reporting"],
|
|
||||||
"endpoint": f"http://localhost:8006"
|
|
||||||
})
|
|
||||||
|
|
||||||
if success:
|
|
||||||
self.is_running = True
|
|
||||||
print(f"Compliance agent {self.agent_id} started successfully")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f"Failed to start compliance agent {self.agent_id}")
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error starting compliance agent: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def stop(self) -> bool:
|
|
||||||
"""Stop compliance agent"""
|
|
||||||
self.is_running = False
|
|
||||||
success = await self.bridge.stop_agent(self.agent_id)
|
|
||||||
if success:
|
|
||||||
print(f"Compliance agent {self.agent_id} stopped successfully")
|
|
||||||
return success
|
|
||||||
|
|
||||||
async def run_compliance_loop(self):
|
|
||||||
"""Main compliance monitoring loop"""
|
|
||||||
while self.is_running:
|
|
||||||
try:
|
|
||||||
for entity in self.monitored_entities:
|
|
||||||
await self._perform_compliance_check(entity)
|
|
||||||
|
|
||||||
await asyncio.sleep(self.check_interval)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error in compliance loop: {e}")
|
|
||||||
await asyncio.sleep(30) # Wait before retrying
|
|
||||||
|
|
||||||
async def _perform_compliance_check(self, entity_id: str) -> None:
|
|
||||||
"""Perform compliance check for entity"""
|
|
||||||
try:
|
|
||||||
compliance_task = {
|
|
||||||
"type": "compliance_check",
|
|
||||||
"user_id": entity_id,
|
|
||||||
"check_type": "full",
|
|
||||||
"monitored_activities": ["trading", "transfers", "wallet_creation"]
|
|
||||||
}
|
|
||||||
|
|
||||||
result = await self.bridge.execute_agent_task(self.agent_id, compliance_task)
|
|
||||||
|
|
||||||
if result.get("status") == "success":
|
|
||||||
compliance_result = result["result"]
|
|
||||||
await self._handle_compliance_result(entity_id, compliance_result)
|
|
||||||
else:
|
|
||||||
print(f"Compliance check failed for {entity_id}: {result}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error performing compliance check for {entity_id}: {e}")
|
|
||||||
|
|
||||||
async def _handle_compliance_result(self, entity_id: str, result: Dict[str, Any]) -> None:
|
|
||||||
"""Handle compliance check result"""
|
|
||||||
status = result.get("status", "unknown")
|
|
||||||
|
|
||||||
if status == "passed":
|
|
||||||
print(f"✅ Compliance check passed for {entity_id}")
|
|
||||||
elif status == "failed":
|
|
||||||
print(f"❌ Compliance check failed for {entity_id}")
|
|
||||||
# Trigger alert or further investigation
|
|
||||||
await self._trigger_compliance_alert(entity_id, result)
|
|
||||||
else:
|
|
||||||
print(f"⚠️ Compliance check inconclusive for {entity_id}")
|
|
||||||
|
|
||||||
async def _trigger_compliance_alert(self, entity_id: str, result: Dict[str, Any]) -> None:
|
|
||||||
"""Trigger compliance alert"""
|
|
||||||
alert_data = {
|
|
||||||
"entity_id": entity_id,
|
|
||||||
"alert_type": "compliance_failure",
|
|
||||||
"severity": "high",
|
|
||||||
"details": result,
|
|
||||||
"timestamp": datetime.utcnow().isoformat()
|
|
||||||
}
|
|
||||||
|
|
||||||
# In a real implementation, this would send to alert system
|
|
||||||
print(f"🚨 COMPLIANCE ALERT: {json.dumps(alert_data, indent=2)}")
|
|
||||||
|
|
||||||
async def get_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get agent status"""
|
|
||||||
status = await self.bridge.get_agent_status(self.agent_id)
|
|
||||||
status["monitored_entities"] = len(self.monitored_entities)
|
|
||||||
status["check_interval"] = self.check_interval
|
|
||||||
return status
|
|
||||||
|
|
||||||
# Main execution
|
|
||||||
async def main():
|
|
||||||
"""Main compliance agent execution"""
|
|
||||||
agent_id = "compliance-agent-001"
|
|
||||||
config = {
|
|
||||||
"check_interval": 60, # 1 minute for testing
|
|
||||||
"monitored_entities": ["user001", "user002", "user003"]
|
|
||||||
}
|
|
||||||
|
|
||||||
agent = ComplianceAgent(agent_id, config)
|
|
||||||
|
|
||||||
# Start agent
|
|
||||||
if await agent.start():
|
|
||||||
try:
|
|
||||||
# Run compliance loop
|
|
||||||
await agent.run_compliance_loop()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("Shutting down compliance agent...")
|
|
||||||
finally:
|
|
||||||
await agent.stop()
|
|
||||||
else:
|
|
||||||
print("Failed to start compliance agent")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
asyncio.run(main())
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Agent Coordinator Service
|
|
||||||
Agent task coordination and management
|
|
||||||
"""
|
|
||||||
|
|
||||||
from fastapi import FastAPI, HTTPException
|
|
||||||
from pydantic import BaseModel
|
|
||||||
from typing import List, Optional, Dict, Any
|
|
||||||
import json
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime
|
|
||||||
import sqlite3
|
|
||||||
from contextlib import contextmanager
|
|
||||||
from contextlib import asynccontextmanager
|
|
||||||
|
|
||||||
@asynccontextmanager
|
|
||||||
async def lifespan(app: FastAPI):
|
|
||||||
# Startup
|
|
||||||
init_db()
|
|
||||||
yield
|
|
||||||
# Shutdown (cleanup if needed)
|
|
||||||
pass
|
|
||||||
|
|
||||||
app = FastAPI(title="AITBC Agent Coordinator API", version="1.0.0", lifespan=lifespan)
|
|
||||||
|
|
||||||
# Database setup
|
|
||||||
def get_db():
|
|
||||||
conn = sqlite3.connect('agent_coordinator.db')
|
|
||||||
conn.row_factory = sqlite3.Row
|
|
||||||
return conn
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def get_db_connection():
|
|
||||||
conn = get_db()
|
|
||||||
try:
|
|
||||||
yield conn
|
|
||||||
finally:
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
# Initialize database
|
|
||||||
def init_db():
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
CREATE TABLE IF NOT EXISTS tasks (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
task_type TEXT NOT NULL,
|
|
||||||
payload TEXT NOT NULL,
|
|
||||||
required_capabilities TEXT NOT NULL,
|
|
||||||
priority TEXT NOT NULL,
|
|
||||||
status TEXT NOT NULL,
|
|
||||||
assigned_agent_id TEXT,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
result TEXT
|
|
||||||
)
|
|
||||||
''')
|
|
||||||
|
|
||||||
# Models
|
|
||||||
class Task(BaseModel):
|
|
||||||
id: str
|
|
||||||
task_type: str
|
|
||||||
payload: Dict[str, Any]
|
|
||||||
required_capabilities: List[str]
|
|
||||||
priority: str
|
|
||||||
status: str
|
|
||||||
assigned_agent_id: Optional[str] = None
|
|
||||||
|
|
||||||
class TaskCreation(BaseModel):
|
|
||||||
task_type: str
|
|
||||||
payload: Dict[str, Any]
|
|
||||||
required_capabilities: List[str]
|
|
||||||
priority: str = "normal"
|
|
||||||
|
|
||||||
# API Endpoints
|
|
||||||
|
|
||||||
@app.post("/api/tasks", response_model=Task)
|
|
||||||
async def create_task(task: TaskCreation):
|
|
||||||
"""Create a new task"""
|
|
||||||
task_id = str(uuid.uuid4())
|
|
||||||
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
INSERT INTO tasks (id, task_type, payload, required_capabilities, priority, status)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?)
|
|
||||||
''', (
|
|
||||||
task_id, task.task_type, json.dumps(task.payload),
|
|
||||||
json.dumps(task.required_capabilities), task.priority, "pending"
|
|
||||||
))
|
|
||||||
|
|
||||||
return Task(
|
|
||||||
id=task_id,
|
|
||||||
task_type=task.task_type,
|
|
||||||
payload=task.payload,
|
|
||||||
required_capabilities=task.required_capabilities,
|
|
||||||
priority=task.priority,
|
|
||||||
status="pending"
|
|
||||||
)
|
|
||||||
|
|
||||||
@app.get("/api/tasks", response_model=List[Task])
|
|
||||||
async def list_tasks(status: Optional[str] = None):
|
|
||||||
"""List tasks with optional status filter"""
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
query = "SELECT * FROM tasks"
|
|
||||||
params = []
|
|
||||||
|
|
||||||
if status:
|
|
||||||
query += " WHERE status = ?"
|
|
||||||
params.append(status)
|
|
||||||
|
|
||||||
tasks = conn.execute(query, params).fetchall()
|
|
||||||
|
|
||||||
return [
|
|
||||||
Task(
|
|
||||||
id=task["id"],
|
|
||||||
task_type=task["task_type"],
|
|
||||||
payload=json.loads(task["payload"]),
|
|
||||||
required_capabilities=json.loads(task["required_capabilities"]),
|
|
||||||
priority=task["priority"],
|
|
||||||
status=task["status"],
|
|
||||||
assigned_agent_id=task["assigned_agent_id"]
|
|
||||||
)
|
|
||||||
for task in tasks
|
|
||||||
]
|
|
||||||
|
|
||||||
@app.get("/api/health")
|
|
||||||
async def health_check():
|
|
||||||
"""Health check endpoint"""
|
|
||||||
return {"status": "ok", "timestamp": datetime.utcnow()}
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import uvicorn
|
|
||||||
uvicorn.run(app, host="0.0.0.0", port=8012)
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
# AITBC Agent Protocols Environment Configuration
|
|
||||||
# Copy this file to .env and update with your secure values
|
|
||||||
|
|
||||||
# Agent Protocol Encryption Key (generate a strong, unique key)
|
|
||||||
AITBC_AGENT_PROTOCOL_KEY=your-secure-encryption-key-here
|
|
||||||
|
|
||||||
# Agent Protocol Salt (generate a unique salt value)
|
|
||||||
AITBC_AGENT_PROTOCOL_SALT=your-unique-salt-value-here
|
|
||||||
|
|
||||||
# Agent Registry Configuration
|
|
||||||
AGENT_REGISTRY_HOST=0.0.0.0
|
|
||||||
AGENT_REGISTRY_PORT=8003
|
|
||||||
|
|
||||||
# Database Configuration
|
|
||||||
AGENT_REGISTRY_DB_PATH=agent_registry.db
|
|
||||||
|
|
||||||
# Security Settings
|
|
||||||
AGENT_PROTOCOL_TIMEOUT=300
|
|
||||||
AGENT_PROTOCOL_MAX_RETRIES=3
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
"""
|
|
||||||
Agent Protocols Package
|
|
||||||
"""
|
|
||||||
|
|
||||||
from .message_protocol import MessageProtocol, MessageTypes, AgentMessageClient
|
|
||||||
from .task_manager import TaskManager, TaskStatus, TaskPriority, Task
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
"MessageProtocol",
|
|
||||||
"MessageTypes",
|
|
||||||
"AgentMessageClient",
|
|
||||||
"TaskManager",
|
|
||||||
"TaskStatus",
|
|
||||||
"TaskPriority",
|
|
||||||
"Task"
|
|
||||||
]
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
"""
|
|
||||||
Message Protocol for AITBC Agents
|
|
||||||
Handles message creation, routing, and delivery between agents
|
|
||||||
"""
|
|
||||||
|
|
||||||
import json
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime
|
|
||||||
from typing import Dict, Any, Optional, List
|
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
class MessageTypes(Enum):
|
|
||||||
"""Message type enumeration"""
|
|
||||||
TASK_REQUEST = "task_request"
|
|
||||||
TASK_RESPONSE = "task_response"
|
|
||||||
HEARTBEAT = "heartbeat"
|
|
||||||
STATUS_UPDATE = "status_update"
|
|
||||||
ERROR = "error"
|
|
||||||
DATA = "data"
|
|
||||||
|
|
||||||
class MessageProtocol:
|
|
||||||
"""Message protocol handler for agent communication"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.messages = []
|
|
||||||
self.message_handlers = {}
|
|
||||||
|
|
||||||
def create_message(
|
|
||||||
self,
|
|
||||||
sender_id: str,
|
|
||||||
receiver_id: str,
|
|
||||||
message_type: MessageTypes,
|
|
||||||
content: Dict[str, Any],
|
|
||||||
message_id: Optional[str] = None
|
|
||||||
) -> Dict[str, Any]:
|
|
||||||
"""Create a new message"""
|
|
||||||
if message_id is None:
|
|
||||||
message_id = str(uuid.uuid4())
|
|
||||||
|
|
||||||
message = {
|
|
||||||
"message_id": message_id,
|
|
||||||
"sender_id": sender_id,
|
|
||||||
"receiver_id": receiver_id,
|
|
||||||
"message_type": message_type.value,
|
|
||||||
"content": content,
|
|
||||||
"timestamp": datetime.utcnow().isoformat(),
|
|
||||||
"status": "pending"
|
|
||||||
}
|
|
||||||
|
|
||||||
self.messages.append(message)
|
|
||||||
return message
|
|
||||||
|
|
||||||
def send_message(self, message: Dict[str, Any]) -> bool:
|
|
||||||
"""Send a message to the receiver"""
|
|
||||||
try:
|
|
||||||
message["status"] = "sent"
|
|
||||||
message["sent_timestamp"] = datetime.utcnow().isoformat()
|
|
||||||
return True
|
|
||||||
except Exception:
|
|
||||||
message["status"] = "failed"
|
|
||||||
return False
|
|
||||||
|
|
||||||
def receive_message(self, message_id: str) -> Optional[Dict[str, Any]]:
|
|
||||||
"""Receive and process a message"""
|
|
||||||
for message in self.messages:
|
|
||||||
if message["message_id"] == message_id:
|
|
||||||
message["status"] = "received"
|
|
||||||
message["received_timestamp"] = datetime.utcnow().isoformat()
|
|
||||||
return message
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_messages_by_agent(self, agent_id: str) -> List[Dict[str, Any]]:
|
|
||||||
"""Get all messages for a specific agent"""
|
|
||||||
return [
|
|
||||||
msg for msg in self.messages
|
|
||||||
if msg["sender_id"] == agent_id or msg["receiver_id"] == agent_id
|
|
||||||
]
|
|
||||||
|
|
||||||
class AgentMessageClient:
|
|
||||||
"""Client for agent message communication"""
|
|
||||||
|
|
||||||
def __init__(self, agent_id: str, protocol: MessageProtocol):
|
|
||||||
self.agent_id = agent_id
|
|
||||||
self.protocol = protocol
|
|
||||||
self.received_messages = []
|
|
||||||
|
|
||||||
def send_message(
|
|
||||||
self,
|
|
||||||
receiver_id: str,
|
|
||||||
message_type: MessageTypes,
|
|
||||||
content: Dict[str, Any]
|
|
||||||
) -> Dict[str, Any]:
|
|
||||||
"""Send a message to another agent"""
|
|
||||||
message = self.protocol.create_message(
|
|
||||||
sender_id=self.agent_id,
|
|
||||||
receiver_id=receiver_id,
|
|
||||||
message_type=message_type,
|
|
||||||
content=content
|
|
||||||
)
|
|
||||||
self.protocol.send_message(message)
|
|
||||||
return message
|
|
||||||
|
|
||||||
def receive_messages(self) -> List[Dict[str, Any]]:
|
|
||||||
"""Receive all pending messages for this agent"""
|
|
||||||
messages = []
|
|
||||||
for message in self.protocol.messages:
|
|
||||||
if (message["receiver_id"] == self.agent_id and
|
|
||||||
message["status"] == "sent" and
|
|
||||||
message not in self.received_messages):
|
|
||||||
self.protocol.receive_message(message["message_id"])
|
|
||||||
self.received_messages.append(message)
|
|
||||||
messages.append(message)
|
|
||||||
return messages
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
"""
|
|
||||||
Task Manager for AITBC Agents
|
|
||||||
Handles task creation, assignment, and tracking
|
|
||||||
"""
|
|
||||||
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
from typing import Dict, Any, Optional, List
|
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
class TaskStatus(Enum):
|
|
||||||
"""Task status enumeration"""
|
|
||||||
PENDING = "pending"
|
|
||||||
IN_PROGRESS = "in_progress"
|
|
||||||
COMPLETED = "completed"
|
|
||||||
FAILED = "failed"
|
|
||||||
CANCELLED = "cancelled"
|
|
||||||
|
|
||||||
class TaskPriority(Enum):
|
|
||||||
"""Task priority enumeration"""
|
|
||||||
LOW = "low"
|
|
||||||
MEDIUM = "medium"
|
|
||||||
HIGH = "high"
|
|
||||||
URGENT = "urgent"
|
|
||||||
|
|
||||||
class Task:
|
|
||||||
"""Task representation"""
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
task_id: str,
|
|
||||||
title: str,
|
|
||||||
description: str,
|
|
||||||
assigned_to: str,
|
|
||||||
priority: TaskPriority = TaskPriority.MEDIUM,
|
|
||||||
created_by: Optional[str] = None
|
|
||||||
):
|
|
||||||
self.task_id = task_id
|
|
||||||
self.title = title
|
|
||||||
self.description = description
|
|
||||||
self.assigned_to = assigned_to
|
|
||||||
self.priority = priority
|
|
||||||
self.created_by = created_by or assigned_to
|
|
||||||
self.status = TaskStatus.PENDING
|
|
||||||
self.created_at = datetime.utcnow()
|
|
||||||
self.updated_at = datetime.utcnow()
|
|
||||||
self.completed_at = None
|
|
||||||
self.result = None
|
|
||||||
self.error = None
|
|
||||||
|
|
||||||
class TaskManager:
|
|
||||||
"""Task manager for agent coordination"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.tasks = {}
|
|
||||||
self.task_history = []
|
|
||||||
|
|
||||||
def create_task(
|
|
||||||
self,
|
|
||||||
title: str,
|
|
||||||
description: str,
|
|
||||||
assigned_to: str,
|
|
||||||
priority: TaskPriority = TaskPriority.MEDIUM,
|
|
||||||
created_by: Optional[str] = None
|
|
||||||
) -> Task:
|
|
||||||
"""Create a new task"""
|
|
||||||
task_id = str(uuid.uuid4())
|
|
||||||
task = Task(
|
|
||||||
task_id=task_id,
|
|
||||||
title=title,
|
|
||||||
description=description,
|
|
||||||
assigned_to=assigned_to,
|
|
||||||
priority=priority,
|
|
||||||
created_by=created_by
|
|
||||||
)
|
|
||||||
|
|
||||||
self.tasks[task_id] = task
|
|
||||||
return task
|
|
||||||
|
|
||||||
def get_task(self, task_id: str) -> Optional[Task]:
|
|
||||||
"""Get a task by ID"""
|
|
||||||
return self.tasks.get(task_id)
|
|
||||||
|
|
||||||
def update_task_status(
|
|
||||||
self,
|
|
||||||
task_id: str,
|
|
||||||
status: TaskStatus,
|
|
||||||
result: Optional[Dict[str, Any]] = None,
|
|
||||||
error: Optional[str] = None
|
|
||||||
) -> bool:
|
|
||||||
"""Update task status"""
|
|
||||||
task = self.get_task(task_id)
|
|
||||||
if not task:
|
|
||||||
return False
|
|
||||||
|
|
||||||
task.status = status
|
|
||||||
task.updated_at = datetime.utcnow()
|
|
||||||
|
|
||||||
if status == TaskStatus.COMPLETED:
|
|
||||||
task.completed_at = datetime.utcnow()
|
|
||||||
task.result = result
|
|
||||||
elif status == TaskStatus.FAILED:
|
|
||||||
task.error = error
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def get_tasks_by_agent(self, agent_id: str) -> List[Task]:
|
|
||||||
"""Get all tasks assigned to an agent"""
|
|
||||||
return [
|
|
||||||
task for task in self.tasks.values()
|
|
||||||
if task.assigned_to == agent_id
|
|
||||||
]
|
|
||||||
|
|
||||||
def get_tasks_by_status(self, status: TaskStatus) -> List[Task]:
|
|
||||||
"""Get all tasks with a specific status"""
|
|
||||||
return [
|
|
||||||
task for task in self.tasks.values()
|
|
||||||
if task.status == status
|
|
||||||
]
|
|
||||||
|
|
||||||
def get_overdue_tasks(self, hours: int = 24) -> List[Task]:
|
|
||||||
"""Get tasks that are overdue"""
|
|
||||||
cutoff_time = datetime.utcnow() - timedelta(hours=hours)
|
|
||||||
return [
|
|
||||||
task for task in self.tasks.values()
|
|
||||||
if task.status in [TaskStatus.PENDING, TaskStatus.IN_PROGRESS] and
|
|
||||||
task.created_at < cutoff_time
|
|
||||||
]
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Agent Registry Service
|
|
||||||
Central agent discovery and registration system
|
|
||||||
"""
|
|
||||||
|
|
||||||
from fastapi import FastAPI, HTTPException, Depends
|
|
||||||
from pydantic import BaseModel
|
|
||||||
from typing import List, Optional, Dict, Any
|
|
||||||
import json
|
|
||||||
import time
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
import sqlite3
|
|
||||||
from contextlib import contextmanager
|
|
||||||
from contextlib import asynccontextmanager
|
|
||||||
|
|
||||||
@asynccontextmanager
|
|
||||||
async def lifespan(app: FastAPI):
|
|
||||||
# Startup
|
|
||||||
init_db()
|
|
||||||
yield
|
|
||||||
# Shutdown (cleanup if needed)
|
|
||||||
pass
|
|
||||||
|
|
||||||
app = FastAPI(title="AITBC Agent Registry API", version="1.0.0", lifespan=lifespan)
|
|
||||||
|
|
||||||
# Database setup
|
|
||||||
def get_db():
|
|
||||||
conn = sqlite3.connect('agent_registry.db')
|
|
||||||
conn.row_factory = sqlite3.Row
|
|
||||||
return conn
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def get_db_connection():
|
|
||||||
conn = get_db()
|
|
||||||
try:
|
|
||||||
yield conn
|
|
||||||
finally:
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
# Initialize database
|
|
||||||
def init_db():
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
CREATE TABLE IF NOT EXISTS agents (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
name TEXT NOT NULL,
|
|
||||||
type TEXT NOT NULL,
|
|
||||||
capabilities TEXT NOT NULL,
|
|
||||||
chain_id TEXT NOT NULL,
|
|
||||||
endpoint TEXT NOT NULL,
|
|
||||||
status TEXT DEFAULT 'active',
|
|
||||||
last_heartbeat TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
metadata TEXT,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
||||||
)
|
|
||||||
''')
|
|
||||||
|
|
||||||
# Models
|
|
||||||
class Agent(BaseModel):
|
|
||||||
id: str
|
|
||||||
name: str
|
|
||||||
type: str
|
|
||||||
capabilities: List[str]
|
|
||||||
chain_id: str
|
|
||||||
endpoint: str
|
|
||||||
metadata: Optional[Dict[str, Any]] = {}
|
|
||||||
|
|
||||||
class AgentRegistration(BaseModel):
|
|
||||||
name: str
|
|
||||||
type: str
|
|
||||||
capabilities: List[str]
|
|
||||||
chain_id: str
|
|
||||||
endpoint: str
|
|
||||||
metadata: Optional[Dict[str, Any]] = {}
|
|
||||||
|
|
||||||
# API Endpoints
|
|
||||||
|
|
||||||
@app.post("/api/agents/register", response_model=Agent)
|
|
||||||
async def register_agent(agent: AgentRegistration):
|
|
||||||
"""Register a new agent"""
|
|
||||||
agent_id = str(uuid.uuid4())
|
|
||||||
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
INSERT INTO agents (id, name, type, capabilities, chain_id, endpoint, metadata)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
||||||
''', (
|
|
||||||
agent_id, agent.name, agent.type,
|
|
||||||
json.dumps(agent.capabilities), agent.chain_id,
|
|
||||||
agent.endpoint, json.dumps(agent.metadata)
|
|
||||||
))
|
|
||||||
conn.commit()
|
|
||||||
|
|
||||||
return Agent(
|
|
||||||
id=agent_id,
|
|
||||||
name=agent.name,
|
|
||||||
type=agent.type,
|
|
||||||
capabilities=agent.capabilities,
|
|
||||||
chain_id=agent.chain_id,
|
|
||||||
endpoint=agent.endpoint,
|
|
||||||
metadata=agent.metadata
|
|
||||||
)
|
|
||||||
|
|
||||||
@app.get("/api/agents", response_model=List[Agent])
|
|
||||||
async def list_agents(
|
|
||||||
agent_type: Optional[str] = None,
|
|
||||||
chain_id: Optional[str] = None,
|
|
||||||
capability: Optional[str] = None
|
|
||||||
):
|
|
||||||
"""List registered agents with optional filters"""
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
query = "SELECT * FROM agents WHERE status = 'active'"
|
|
||||||
params = []
|
|
||||||
|
|
||||||
if agent_type:
|
|
||||||
query += " AND type = ?"
|
|
||||||
params.append(agent_type)
|
|
||||||
|
|
||||||
if chain_id:
|
|
||||||
query += " AND chain_id = ?"
|
|
||||||
params.append(chain_id)
|
|
||||||
|
|
||||||
if capability:
|
|
||||||
query += " AND capabilities LIKE ?"
|
|
||||||
params.append(f'%{capability}%')
|
|
||||||
|
|
||||||
agents = conn.execute(query, params).fetchall()
|
|
||||||
|
|
||||||
return [
|
|
||||||
Agent(
|
|
||||||
id=agent["id"],
|
|
||||||
name=agent["name"],
|
|
||||||
type=agent["type"],
|
|
||||||
capabilities=json.loads(agent["capabilities"]),
|
|
||||||
chain_id=agent["chain_id"],
|
|
||||||
endpoint=agent["endpoint"],
|
|
||||||
metadata=json.loads(agent["metadata"] or "{}")
|
|
||||||
)
|
|
||||||
for agent in agents
|
|
||||||
]
|
|
||||||
|
|
||||||
@app.get("/api/health")
|
|
||||||
async def health_check():
|
|
||||||
"""Health check endpoint"""
|
|
||||||
return {"status": "ok", "timestamp": datetime.utcnow()}
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import uvicorn
|
|
||||||
uvicorn.run(app, host="0.0.0.0", port=8013)
|
|
||||||
@@ -1,431 +0,0 @@
|
|||||||
"""
|
|
||||||
Agent Registration System
|
|
||||||
Handles AI agent registration, capability management, and discovery
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import time
|
|
||||||
import json
|
|
||||||
import hashlib
|
|
||||||
from typing import Dict, List, Optional, Set, Tuple
|
|
||||||
from dataclasses import dataclass, asdict
|
|
||||||
from enum import Enum
|
|
||||||
from decimal import Decimal
|
|
||||||
|
|
||||||
class AgentType(Enum):
|
|
||||||
AI_MODEL = "ai_model"
|
|
||||||
DATA_PROVIDER = "data_provider"
|
|
||||||
VALIDATOR = "validator"
|
|
||||||
MARKET_MAKER = "market_maker"
|
|
||||||
BROKER = "broker"
|
|
||||||
ORACLE = "oracle"
|
|
||||||
|
|
||||||
class AgentStatus(Enum):
|
|
||||||
REGISTERED = "registered"
|
|
||||||
ACTIVE = "active"
|
|
||||||
INACTIVE = "inactive"
|
|
||||||
SUSPENDED = "suspended"
|
|
||||||
BANNED = "banned"
|
|
||||||
|
|
||||||
class CapabilityType(Enum):
|
|
||||||
TEXT_GENERATION = "text_generation"
|
|
||||||
IMAGE_GENERATION = "image_generation"
|
|
||||||
DATA_ANALYSIS = "data_analysis"
|
|
||||||
PREDICTION = "prediction"
|
|
||||||
VALIDATION = "validation"
|
|
||||||
COMPUTATION = "computation"
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class AgentCapability:
|
|
||||||
capability_type: CapabilityType
|
|
||||||
name: str
|
|
||||||
version: str
|
|
||||||
parameters: Dict
|
|
||||||
performance_metrics: Dict
|
|
||||||
cost_per_use: Decimal
|
|
||||||
availability: float
|
|
||||||
max_concurrent_jobs: int
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class AgentInfo:
|
|
||||||
agent_id: str
|
|
||||||
agent_type: AgentType
|
|
||||||
name: str
|
|
||||||
owner_address: str
|
|
||||||
public_key: str
|
|
||||||
endpoint_url: str
|
|
||||||
capabilities: List[AgentCapability]
|
|
||||||
reputation_score: float
|
|
||||||
total_jobs_completed: int
|
|
||||||
total_earnings: Decimal
|
|
||||||
registration_time: float
|
|
||||||
last_active: float
|
|
||||||
status: AgentStatus
|
|
||||||
metadata: Dict
|
|
||||||
|
|
||||||
class AgentRegistry:
|
|
||||||
"""Manages AI agent registration and discovery"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.agents: Dict[str, AgentInfo] = {}
|
|
||||||
self.capability_index: Dict[CapabilityType, Set[str]] = {} # capability -> agent_ids
|
|
||||||
self.type_index: Dict[AgentType, Set[str]] = {} # agent_type -> agent_ids
|
|
||||||
self.reputation_scores: Dict[str, float] = {}
|
|
||||||
self.registration_queue: List[Dict] = []
|
|
||||||
|
|
||||||
# Registry parameters
|
|
||||||
self.min_reputation_threshold = 0.5
|
|
||||||
self.max_agents_per_type = 1000
|
|
||||||
self.registration_fee = Decimal('100.0')
|
|
||||||
self.inactivity_threshold = 86400 * 7 # 7 days
|
|
||||||
|
|
||||||
# Initialize capability index
|
|
||||||
for capability_type in CapabilityType:
|
|
||||||
self.capability_index[capability_type] = set()
|
|
||||||
|
|
||||||
# Initialize type index
|
|
||||||
for agent_type in AgentType:
|
|
||||||
self.type_index[agent_type] = set()
|
|
||||||
|
|
||||||
async def register_agent(self, agent_type: AgentType, name: str, owner_address: str,
|
|
||||||
public_key: str, endpoint_url: str, capabilities: List[Dict],
|
|
||||||
metadata: Dict = None) -> Tuple[bool, str, Optional[str]]:
|
|
||||||
"""Register a new AI agent"""
|
|
||||||
try:
|
|
||||||
# Validate inputs
|
|
||||||
if not self._validate_registration_inputs(agent_type, name, owner_address, public_key, endpoint_url):
|
|
||||||
return False, "Invalid registration inputs", None
|
|
||||||
|
|
||||||
# Check if agent already exists
|
|
||||||
agent_id = self._generate_agent_id(owner_address, name)
|
|
||||||
if agent_id in self.agents:
|
|
||||||
return False, "Agent already registered", None
|
|
||||||
|
|
||||||
# Check type limits
|
|
||||||
if len(self.type_index[agent_type]) >= self.max_agents_per_type:
|
|
||||||
return False, f"Maximum agents of type {agent_type.value} reached", None
|
|
||||||
|
|
||||||
# Convert capabilities
|
|
||||||
agent_capabilities = []
|
|
||||||
for cap_data in capabilities:
|
|
||||||
capability = self._create_capability_from_data(cap_data)
|
|
||||||
if capability:
|
|
||||||
agent_capabilities.append(capability)
|
|
||||||
|
|
||||||
if not agent_capabilities:
|
|
||||||
return False, "Agent must have at least one valid capability", None
|
|
||||||
|
|
||||||
# Create agent info
|
|
||||||
agent_info = AgentInfo(
|
|
||||||
agent_id=agent_id,
|
|
||||||
agent_type=agent_type,
|
|
||||||
name=name,
|
|
||||||
owner_address=owner_address,
|
|
||||||
public_key=public_key,
|
|
||||||
endpoint_url=endpoint_url,
|
|
||||||
capabilities=agent_capabilities,
|
|
||||||
reputation_score=1.0, # Start with neutral reputation
|
|
||||||
total_jobs_completed=0,
|
|
||||||
total_earnings=Decimal('0'),
|
|
||||||
registration_time=time.time(),
|
|
||||||
last_active=time.time(),
|
|
||||||
status=AgentStatus.REGISTERED,
|
|
||||||
metadata=metadata or {}
|
|
||||||
)
|
|
||||||
|
|
||||||
# Add to registry
|
|
||||||
self.agents[agent_id] = agent_info
|
|
||||||
|
|
||||||
# Update indexes
|
|
||||||
self.type_index[agent_type].add(agent_id)
|
|
||||||
for capability in agent_capabilities:
|
|
||||||
self.capability_index[capability.capability_type].add(agent_id)
|
|
||||||
|
|
||||||
log_info(f"Agent registered: {agent_id} ({name})")
|
|
||||||
return True, "Registration successful", agent_id
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
return False, f"Registration failed: {str(e)}", None
|
|
||||||
|
|
||||||
def _validate_registration_inputs(self, agent_type: AgentType, name: str,
|
|
||||||
owner_address: str, public_key: str, endpoint_url: str) -> bool:
|
|
||||||
"""Validate registration inputs"""
|
|
||||||
# Check required fields
|
|
||||||
if not all([agent_type, name, owner_address, public_key, endpoint_url]):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Validate address format (simplified)
|
|
||||||
if not owner_address.startswith('0x') or len(owner_address) != 42:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Validate URL format (simplified)
|
|
||||||
if not endpoint_url.startswith(('http://', 'https://')):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Validate name
|
|
||||||
if len(name) < 3 or len(name) > 100:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def _generate_agent_id(self, owner_address: str, name: str) -> str:
|
|
||||||
"""Generate unique agent ID"""
|
|
||||||
content = f"{owner_address}:{name}:{time.time()}"
|
|
||||||
return hashlib.sha256(content.encode()).hexdigest()[:16]
|
|
||||||
|
|
||||||
def _create_capability_from_data(self, cap_data: Dict) -> Optional[AgentCapability]:
|
|
||||||
"""Create capability from data dictionary"""
|
|
||||||
try:
|
|
||||||
# Validate required fields
|
|
||||||
required_fields = ['type', 'name', 'version', 'cost_per_use']
|
|
||||||
if not all(field in cap_data for field in required_fields):
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Parse capability type
|
|
||||||
try:
|
|
||||||
capability_type = CapabilityType(cap_data['type'])
|
|
||||||
except ValueError:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Create capability
|
|
||||||
return AgentCapability(
|
|
||||||
capability_type=capability_type,
|
|
||||||
name=cap_data['name'],
|
|
||||||
version=cap_data['version'],
|
|
||||||
parameters=cap_data.get('parameters', {}),
|
|
||||||
performance_metrics=cap_data.get('performance_metrics', {}),
|
|
||||||
cost_per_use=Decimal(str(cap_data['cost_per_use'])),
|
|
||||||
availability=cap_data.get('availability', 1.0),
|
|
||||||
max_concurrent_jobs=cap_data.get('max_concurrent_jobs', 1)
|
|
||||||
)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
log_error(f"Error creating capability: {e}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
async def update_agent_status(self, agent_id: str, status: AgentStatus) -> Tuple[bool, str]:
|
|
||||||
"""Update agent status"""
|
|
||||||
if agent_id not in self.agents:
|
|
||||||
return False, "Agent not found"
|
|
||||||
|
|
||||||
agent = self.agents[agent_id]
|
|
||||||
old_status = agent.status
|
|
||||||
agent.status = status
|
|
||||||
agent.last_active = time.time()
|
|
||||||
|
|
||||||
log_info(f"Agent {agent_id} status changed: {old_status.value} -> {status.value}")
|
|
||||||
return True, "Status updated successfully"
|
|
||||||
|
|
||||||
async def update_agent_capabilities(self, agent_id: str, capabilities: List[Dict]) -> Tuple[bool, str]:
|
|
||||||
"""Update agent capabilities"""
|
|
||||||
if agent_id not in self.agents:
|
|
||||||
return False, "Agent not found"
|
|
||||||
|
|
||||||
agent = self.agents[agent_id]
|
|
||||||
|
|
||||||
# Remove old capabilities from index
|
|
||||||
for old_capability in agent.capabilities:
|
|
||||||
self.capability_index[old_capability.capability_type].discard(agent_id)
|
|
||||||
|
|
||||||
# Add new capabilities
|
|
||||||
new_capabilities = []
|
|
||||||
for cap_data in capabilities:
|
|
||||||
capability = self._create_capability_from_data(cap_data)
|
|
||||||
if capability:
|
|
||||||
new_capabilities.append(capability)
|
|
||||||
self.capability_index[capability.capability_type].add(agent_id)
|
|
||||||
|
|
||||||
if not new_capabilities:
|
|
||||||
return False, "No valid capabilities provided"
|
|
||||||
|
|
||||||
agent.capabilities = new_capabilities
|
|
||||||
agent.last_active = time.time()
|
|
||||||
|
|
||||||
return True, "Capabilities updated successfully"
|
|
||||||
|
|
||||||
async def find_agents_by_capability(self, capability_type: CapabilityType,
|
|
||||||
filters: Dict = None) -> List[AgentInfo]:
|
|
||||||
"""Find agents by capability type"""
|
|
||||||
agent_ids = self.capability_index.get(capability_type, set())
|
|
||||||
|
|
||||||
agents = []
|
|
||||||
for agent_id in agent_ids:
|
|
||||||
agent = self.agents.get(agent_id)
|
|
||||||
if agent and agent.status == AgentStatus.ACTIVE:
|
|
||||||
if self._matches_filters(agent, filters):
|
|
||||||
agents.append(agent)
|
|
||||||
|
|
||||||
# Sort by reputation (highest first)
|
|
||||||
agents.sort(key=lambda x: x.reputation_score, reverse=True)
|
|
||||||
return agents
|
|
||||||
|
|
||||||
async def find_agents_by_type(self, agent_type: AgentType, filters: Dict = None) -> List[AgentInfo]:
|
|
||||||
"""Find agents by type"""
|
|
||||||
agent_ids = self.type_index.get(agent_type, set())
|
|
||||||
|
|
||||||
agents = []
|
|
||||||
for agent_id in agent_ids:
|
|
||||||
agent = self.agents.get(agent_id)
|
|
||||||
if agent and agent.status == AgentStatus.ACTIVE:
|
|
||||||
if self._matches_filters(agent, filters):
|
|
||||||
agents.append(agent)
|
|
||||||
|
|
||||||
# Sort by reputation (highest first)
|
|
||||||
agents.sort(key=lambda x: x.reputation_score, reverse=True)
|
|
||||||
return agents
|
|
||||||
|
|
||||||
def _matches_filters(self, agent: AgentInfo, filters: Dict) -> bool:
|
|
||||||
"""Check if agent matches filters"""
|
|
||||||
if not filters:
|
|
||||||
return True
|
|
||||||
|
|
||||||
# Reputation filter
|
|
||||||
if 'min_reputation' in filters:
|
|
||||||
if agent.reputation_score < filters['min_reputation']:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Cost filter
|
|
||||||
if 'max_cost_per_use' in filters:
|
|
||||||
max_cost = Decimal(str(filters['max_cost_per_use']))
|
|
||||||
if any(cap.cost_per_use > max_cost for cap in agent.capabilities):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Availability filter
|
|
||||||
if 'min_availability' in filters:
|
|
||||||
min_availability = filters['min_availability']
|
|
||||||
if any(cap.availability < min_availability for cap in agent.capabilities):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Location filter (if implemented)
|
|
||||||
if 'location' in filters:
|
|
||||||
agent_location = agent.metadata.get('location')
|
|
||||||
if agent_location != filters['location']:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
async def get_agent_info(self, agent_id: str) -> Optional[AgentInfo]:
|
|
||||||
"""Get agent information"""
|
|
||||||
return self.agents.get(agent_id)
|
|
||||||
|
|
||||||
async def search_agents(self, query: str, limit: int = 50) -> List[AgentInfo]:
|
|
||||||
"""Search agents by name or capability"""
|
|
||||||
query_lower = query.lower()
|
|
||||||
results = []
|
|
||||||
|
|
||||||
for agent in self.agents.values():
|
|
||||||
if agent.status != AgentStatus.ACTIVE:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Search in name
|
|
||||||
if query_lower in agent.name.lower():
|
|
||||||
results.append(agent)
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Search in capabilities
|
|
||||||
for capability in agent.capabilities:
|
|
||||||
if (query_lower in capability.name.lower() or
|
|
||||||
query_lower in capability.capability_type.value):
|
|
||||||
results.append(agent)
|
|
||||||
break
|
|
||||||
|
|
||||||
# Sort by relevance (reputation)
|
|
||||||
results.sort(key=lambda x: x.reputation_score, reverse=True)
|
|
||||||
return results[:limit]
|
|
||||||
|
|
||||||
async def get_agent_statistics(self, agent_id: str) -> Optional[Dict]:
|
|
||||||
"""Get detailed statistics for an agent"""
|
|
||||||
agent = self.agents.get(agent_id)
|
|
||||||
if not agent:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Calculate additional statistics
|
|
||||||
avg_job_earnings = agent.total_earnings / agent.total_jobs_completed if agent.total_jobs_completed > 0 else Decimal('0')
|
|
||||||
days_active = (time.time() - agent.registration_time) / 86400
|
|
||||||
jobs_per_day = agent.total_jobs_completed / days_active if days_active > 0 else 0
|
|
||||||
|
|
||||||
return {
|
|
||||||
'agent_id': agent_id,
|
|
||||||
'name': agent.name,
|
|
||||||
'type': agent.agent_type.value,
|
|
||||||
'status': agent.status.value,
|
|
||||||
'reputation_score': agent.reputation_score,
|
|
||||||
'total_jobs_completed': agent.total_jobs_completed,
|
|
||||||
'total_earnings': float(agent.total_earnings),
|
|
||||||
'avg_job_earnings': float(avg_job_earnings),
|
|
||||||
'jobs_per_day': jobs_per_day,
|
|
||||||
'days_active': int(days_active),
|
|
||||||
'capabilities_count': len(agent.capabilities),
|
|
||||||
'last_active': agent.last_active,
|
|
||||||
'registration_time': agent.registration_time
|
|
||||||
}
|
|
||||||
|
|
||||||
async def get_registry_statistics(self) -> Dict:
|
|
||||||
"""Get registry-wide statistics"""
|
|
||||||
total_agents = len(self.agents)
|
|
||||||
active_agents = len([a for a in self.agents.values() if a.status == AgentStatus.ACTIVE])
|
|
||||||
|
|
||||||
# Count by type
|
|
||||||
type_counts = {}
|
|
||||||
for agent_type in AgentType:
|
|
||||||
type_counts[agent_type.value] = len(self.type_index[agent_type])
|
|
||||||
|
|
||||||
# Count by capability
|
|
||||||
capability_counts = {}
|
|
||||||
for capability_type in CapabilityType:
|
|
||||||
capability_counts[capability_type.value] = len(self.capability_index[capability_type])
|
|
||||||
|
|
||||||
# Reputation statistics
|
|
||||||
reputations = [a.reputation_score for a in self.agents.values()]
|
|
||||||
avg_reputation = sum(reputations) / len(reputations) if reputations else 0
|
|
||||||
|
|
||||||
# Earnings statistics
|
|
||||||
total_earnings = sum(a.total_earnings for a in self.agents.values())
|
|
||||||
|
|
||||||
return {
|
|
||||||
'total_agents': total_agents,
|
|
||||||
'active_agents': active_agents,
|
|
||||||
'inactive_agents': total_agents - active_agents,
|
|
||||||
'agent_types': type_counts,
|
|
||||||
'capabilities': capability_counts,
|
|
||||||
'average_reputation': avg_reputation,
|
|
||||||
'total_earnings': float(total_earnings),
|
|
||||||
'registration_fee': float(self.registration_fee)
|
|
||||||
}
|
|
||||||
|
|
||||||
async def cleanup_inactive_agents(self) -> Tuple[int, str]:
|
|
||||||
"""Clean up inactive agents"""
|
|
||||||
current_time = time.time()
|
|
||||||
cleaned_count = 0
|
|
||||||
|
|
||||||
for agent_id, agent in list(self.agents.items()):
|
|
||||||
if (agent.status == AgentStatus.INACTIVE and
|
|
||||||
current_time - agent.last_active > self.inactivity_threshold):
|
|
||||||
|
|
||||||
# Remove from registry
|
|
||||||
del self.agents[agent_id]
|
|
||||||
|
|
||||||
# Update indexes
|
|
||||||
self.type_index[agent.agent_type].discard(agent_id)
|
|
||||||
for capability in agent.capabilities:
|
|
||||||
self.capability_index[capability.capability_type].discard(agent_id)
|
|
||||||
|
|
||||||
cleaned_count += 1
|
|
||||||
|
|
||||||
if cleaned_count > 0:
|
|
||||||
log_info(f"Cleaned up {cleaned_count} inactive agents")
|
|
||||||
|
|
||||||
return cleaned_count, f"Cleaned up {cleaned_count} inactive agents"
|
|
||||||
|
|
||||||
# Global agent registry
|
|
||||||
agent_registry: Optional[AgentRegistry] = None
|
|
||||||
|
|
||||||
def get_agent_registry() -> Optional[AgentRegistry]:
|
|
||||||
"""Get global agent registry"""
|
|
||||||
return agent_registry
|
|
||||||
|
|
||||||
def create_agent_registry() -> AgentRegistry:
|
|
||||||
"""Create and set global agent registry"""
|
|
||||||
global agent_registry
|
|
||||||
agent_registry = AgentRegistry()
|
|
||||||
return agent_registry
|
|
||||||
@@ -1,166 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Trading Agent
|
|
||||||
Automated trading agent for AITBC marketplace
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import json
|
|
||||||
import time
|
|
||||||
from typing import Dict, Any, List
|
|
||||||
from datetime import datetime
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Add parent directory to path
|
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '../../../..'))
|
|
||||||
|
|
||||||
from apps.agent_services.agent_bridge.src.integration_layer import AgentServiceBridge
|
|
||||||
|
|
||||||
class TradingAgent:
|
|
||||||
"""Automated trading agent"""
|
|
||||||
|
|
||||||
def __init__(self, agent_id: str, config: Dict[str, Any]):
|
|
||||||
self.agent_id = agent_id
|
|
||||||
self.config = config
|
|
||||||
self.bridge = AgentServiceBridge()
|
|
||||||
self.is_running = False
|
|
||||||
self.trading_strategy = config.get("strategy", "basic")
|
|
||||||
self.symbols = config.get("symbols", ["AITBC/BTC"])
|
|
||||||
self.trade_interval = config.get("trade_interval", 60) # seconds
|
|
||||||
|
|
||||||
async def start(self) -> bool:
|
|
||||||
"""Start trading agent"""
|
|
||||||
try:
|
|
||||||
# Register with service bridge
|
|
||||||
success = await self.bridge.start_agent(self.agent_id, {
|
|
||||||
"type": "trading",
|
|
||||||
"capabilities": ["market_analysis", "trading", "risk_management"],
|
|
||||||
"endpoint": f"http://localhost:8005"
|
|
||||||
})
|
|
||||||
|
|
||||||
if success:
|
|
||||||
self.is_running = True
|
|
||||||
print(f"Trading agent {self.agent_id} started successfully")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f"Failed to start trading agent {self.agent_id}")
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error starting trading agent: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def stop(self) -> bool:
|
|
||||||
"""Stop trading agent"""
|
|
||||||
self.is_running = False
|
|
||||||
success = await self.bridge.stop_agent(self.agent_id)
|
|
||||||
if success:
|
|
||||||
print(f"Trading agent {self.agent_id} stopped successfully")
|
|
||||||
return success
|
|
||||||
|
|
||||||
async def run_trading_loop(self):
|
|
||||||
"""Main trading loop"""
|
|
||||||
while self.is_running:
|
|
||||||
try:
|
|
||||||
for symbol in self.symbols:
|
|
||||||
await self._analyze_and_trade(symbol)
|
|
||||||
|
|
||||||
await asyncio.sleep(self.trade_interval)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error in trading loop: {e}")
|
|
||||||
await asyncio.sleep(10) # Wait before retrying
|
|
||||||
|
|
||||||
async def _analyze_and_trade(self, symbol: str) -> None:
|
|
||||||
"""Analyze market and execute trades"""
|
|
||||||
try:
|
|
||||||
# Perform market analysis
|
|
||||||
analysis_task = {
|
|
||||||
"type": "market_analysis",
|
|
||||||
"symbol": symbol,
|
|
||||||
"strategy": self.trading_strategy
|
|
||||||
}
|
|
||||||
|
|
||||||
analysis_result = await self.bridge.execute_agent_task(self.agent_id, analysis_task)
|
|
||||||
|
|
||||||
if analysis_result.get("status") == "success":
|
|
||||||
analysis = analysis_result["result"]["analysis"]
|
|
||||||
|
|
||||||
# Make trading decision
|
|
||||||
if self._should_trade(analysis):
|
|
||||||
await self._execute_trade(symbol, analysis)
|
|
||||||
else:
|
|
||||||
print(f"Market analysis failed for {symbol}: {analysis_result}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error in analyze_and_trade for {symbol}: {e}")
|
|
||||||
|
|
||||||
def _should_trade(self, analysis: Dict[str, Any]) -> bool:
|
|
||||||
"""Determine if should execute trade"""
|
|
||||||
recommendation = analysis.get("recommendation", "hold")
|
|
||||||
return recommendation in ["buy", "sell"]
|
|
||||||
|
|
||||||
async def _execute_trade(self, symbol: str, analysis: Dict[str, Any]) -> None:
|
|
||||||
"""Execute trade based on analysis"""
|
|
||||||
try:
|
|
||||||
recommendation = analysis.get("recommendation", "hold")
|
|
||||||
|
|
||||||
if recommendation == "buy":
|
|
||||||
trade_task = {
|
|
||||||
"type": "trading",
|
|
||||||
"symbol": symbol,
|
|
||||||
"side": "buy",
|
|
||||||
"amount": self.config.get("trade_amount", 0.1),
|
|
||||||
"strategy": self.trading_strategy
|
|
||||||
}
|
|
||||||
elif recommendation == "sell":
|
|
||||||
trade_task = {
|
|
||||||
"type": "trading",
|
|
||||||
"symbol": symbol,
|
|
||||||
"side": "sell",
|
|
||||||
"amount": self.config.get("trade_amount", 0.1),
|
|
||||||
"strategy": self.trading_strategy
|
|
||||||
}
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
|
|
||||||
trade_result = await self.bridge.execute_agent_task(self.agent_id, trade_task)
|
|
||||||
|
|
||||||
if trade_result.get("status") == "success":
|
|
||||||
print(f"Trade executed successfully: {trade_result}")
|
|
||||||
else:
|
|
||||||
print(f"Trade execution failed: {trade_result}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error executing trade: {e}")
|
|
||||||
|
|
||||||
async def get_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get agent status"""
|
|
||||||
return await self.bridge.get_agent_status(self.agent_id)
|
|
||||||
|
|
||||||
# Main execution
|
|
||||||
async def main():
|
|
||||||
"""Main trading agent execution"""
|
|
||||||
agent_id = "trading-agent-001"
|
|
||||||
config = {
|
|
||||||
"strategy": "basic",
|
|
||||||
"symbols": ["AITBC/BTC"],
|
|
||||||
"trade_interval": 30,
|
|
||||||
"trade_amount": 0.1
|
|
||||||
}
|
|
||||||
|
|
||||||
agent = TradingAgent(agent_id, config)
|
|
||||||
|
|
||||||
# Start agent
|
|
||||||
if await agent.start():
|
|
||||||
try:
|
|
||||||
# Run trading loop
|
|
||||||
await agent.run_trading_loop()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("Shutting down trading agent...")
|
|
||||||
finally:
|
|
||||||
await agent.stop()
|
|
||||||
else:
|
|
||||||
print("Failed to start trading agent")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
asyncio.run(main())
|
|
||||||
@@ -1,229 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Agent Integration Layer
|
|
||||||
Connects agent protocols to existing AITBC services
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import aiohttp
|
|
||||||
import json
|
|
||||||
from typing import Dict, Any, List, Optional
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
class AITBCServiceIntegration:
|
|
||||||
"""Integration layer for AITBC services"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.service_endpoints = {
|
|
||||||
"coordinator_api": "http://localhost:8000",
|
|
||||||
"blockchain_rpc": "http://localhost:8006",
|
|
||||||
"exchange_service": "http://localhost:8001",
|
|
||||||
"marketplace": "http://localhost:8002",
|
|
||||||
"agent_registry": "http://localhost:8013"
|
|
||||||
}
|
|
||||||
self.session = None
|
|
||||||
|
|
||||||
async def __aenter__(self):
|
|
||||||
self.session = aiohttp.ClientSession()
|
|
||||||
return self
|
|
||||||
|
|
||||||
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
||||||
if self.session:
|
|
||||||
await self.session.close()
|
|
||||||
|
|
||||||
async def get_blockchain_info(self) -> Dict[str, Any]:
|
|
||||||
"""Get blockchain information"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['blockchain_rpc']}/health") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "unavailable"}
|
|
||||||
|
|
||||||
async def get_exchange_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get exchange service status"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['exchange_service']}/api/health") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "unavailable"}
|
|
||||||
|
|
||||||
async def get_coordinator_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get coordinator API status"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['coordinator_api']}/health") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "unavailable"}
|
|
||||||
|
|
||||||
async def submit_transaction(self, transaction_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Submit transaction to blockchain"""
|
|
||||||
try:
|
|
||||||
async with self.session.post(
|
|
||||||
f"{self.service_endpoints['blockchain_rpc']}/rpc/submit",
|
|
||||||
json=transaction_data
|
|
||||||
) as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "failed"}
|
|
||||||
|
|
||||||
async def get_market_data(self, symbol: str = "AITBC/BTC") -> Dict[str, Any]:
|
|
||||||
"""Get market data from exchange"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['exchange_service']}/api/market/{symbol}") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "failed"}
|
|
||||||
|
|
||||||
async def register_agent_with_coordinator(self, agent_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Register agent with coordinator"""
|
|
||||||
try:
|
|
||||||
async with self.session.post(
|
|
||||||
f"{self.service_endpoints['agent_registry']}/api/agents/register",
|
|
||||||
json=agent_data
|
|
||||||
) as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "failed"}
|
|
||||||
|
|
||||||
class AgentServiceBridge:
|
|
||||||
"""Bridge between agents and AITBC services"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.integration = AITBCServiceIntegration()
|
|
||||||
self.active_agents = {}
|
|
||||||
|
|
||||||
async def start_agent(self, agent_id: str, agent_config: Dict[str, Any]) -> bool:
|
|
||||||
"""Start an agent with service integration"""
|
|
||||||
try:
|
|
||||||
# Register agent with coordinator
|
|
||||||
async with self.integration as integration:
|
|
||||||
registration_result = await integration.register_agent_with_coordinator({
|
|
||||||
"name": agent_id,
|
|
||||||
"type": agent_config.get("type", "generic"),
|
|
||||||
"capabilities": agent_config.get("capabilities", []),
|
|
||||||
"chain_id": agent_config.get("chain_id", "ait-mainnet"),
|
|
||||||
"endpoint": agent_config.get("endpoint", f"http://localhost:{8000 + len(self.active_agents) + 10}")
|
|
||||||
})
|
|
||||||
|
|
||||||
# The registry returns the created agent dict on success, not a {"status": "ok"} wrapper
|
|
||||||
if registration_result and "id" in registration_result:
|
|
||||||
self.active_agents[agent_id] = {
|
|
||||||
"config": agent_config,
|
|
||||||
"registration": registration_result,
|
|
||||||
"started_at": datetime.utcnow()
|
|
||||||
}
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f"Registration failed: {registration_result}")
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Failed to start agent {agent_id}: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def stop_agent(self, agent_id: str) -> bool:
|
|
||||||
"""Stop an agent"""
|
|
||||||
if agent_id in self.active_agents:
|
|
||||||
del self.active_agents[agent_id]
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def get_agent_status(self, agent_id: str) -> Dict[str, Any]:
|
|
||||||
"""Get agent status with service integration"""
|
|
||||||
if agent_id not in self.active_agents:
|
|
||||||
return {"status": "not_found"}
|
|
||||||
|
|
||||||
agent_info = self.active_agents[agent_id]
|
|
||||||
|
|
||||||
async with self.integration as integration:
|
|
||||||
# Get service statuses
|
|
||||||
blockchain_status = await integration.get_blockchain_info()
|
|
||||||
exchange_status = await integration.get_exchange_status()
|
|
||||||
coordinator_status = await integration.get_coordinator_status()
|
|
||||||
|
|
||||||
return {
|
|
||||||
"agent_id": agent_id,
|
|
||||||
"status": "active",
|
|
||||||
"started_at": agent_info["started_at"].isoformat(),
|
|
||||||
"services": {
|
|
||||||
"blockchain": blockchain_status,
|
|
||||||
"exchange": exchange_status,
|
|
||||||
"coordinator": coordinator_status
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async def execute_agent_task(self, agent_id: str, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute agent task with service integration"""
|
|
||||||
if agent_id not in self.active_agents:
|
|
||||||
return {"status": "error", "message": "Agent not found"}
|
|
||||||
|
|
||||||
task_type = task_data.get("type")
|
|
||||||
|
|
||||||
if task_type == "market_analysis":
|
|
||||||
return await self._execute_market_analysis(task_data)
|
|
||||||
elif task_type == "trading":
|
|
||||||
return await self._execute_trading_task(task_data)
|
|
||||||
elif task_type == "compliance_check":
|
|
||||||
return await self._execute_compliance_check(task_data)
|
|
||||||
else:
|
|
||||||
return {"status": "error", "message": f"Unknown task type: {task_type}"}
|
|
||||||
|
|
||||||
async def _execute_market_analysis(self, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute market analysis task"""
|
|
||||||
try:
|
|
||||||
async with self.integration as integration:
|
|
||||||
market_data = await integration.get_market_data(task_data.get("symbol", "AITBC/BTC"))
|
|
||||||
|
|
||||||
# Perform basic analysis
|
|
||||||
analysis_result = {
|
|
||||||
"symbol": task_data.get("symbol", "AITBC/BTC"),
|
|
||||||
"market_data": market_data,
|
|
||||||
"analysis": {
|
|
||||||
"trend": "neutral",
|
|
||||||
"volatility": "medium",
|
|
||||||
"recommendation": "hold"
|
|
||||||
},
|
|
||||||
"timestamp": datetime.utcnow().isoformat()
|
|
||||||
}
|
|
||||||
|
|
||||||
return {"status": "success", "result": analysis_result}
|
|
||||||
except Exception as e:
|
|
||||||
return {"status": "error", "message": str(e)}
|
|
||||||
|
|
||||||
async def _execute_trading_task(self, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute trading task"""
|
|
||||||
try:
|
|
||||||
# Get market data first
|
|
||||||
async with self.integration as integration:
|
|
||||||
market_data = await integration.get_market_data(task_data.get("symbol", "AITBC/BTC"))
|
|
||||||
|
|
||||||
# Create transaction
|
|
||||||
transaction = {
|
|
||||||
"type": "trade",
|
|
||||||
"symbol": task_data.get("symbol", "AITBC/BTC"),
|
|
||||||
"side": task_data.get("side", "buy"),
|
|
||||||
"amount": task_data.get("amount", 0.1),
|
|
||||||
"price": task_data.get("price", market_data.get("price", 0.001))
|
|
||||||
}
|
|
||||||
|
|
||||||
# Submit transaction
|
|
||||||
tx_result = await integration.submit_transaction(transaction)
|
|
||||||
|
|
||||||
return {"status": "success", "transaction": tx_result}
|
|
||||||
except Exception as e:
|
|
||||||
return {"status": "error", "message": str(e)}
|
|
||||||
|
|
||||||
async def _execute_compliance_check(self, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute compliance check task"""
|
|
||||||
try:
|
|
||||||
# Basic compliance check
|
|
||||||
compliance_result = {
|
|
||||||
"user_id": task_data.get("user_id"),
|
|
||||||
"check_type": task_data.get("check_type", "basic"),
|
|
||||||
"status": "passed",
|
|
||||||
"checks_performed": ["kyc", "aml", "sanctions"],
|
|
||||||
"timestamp": datetime.utcnow().isoformat()
|
|
||||||
}
|
|
||||||
|
|
||||||
return {"status": "success", "result": compliance_result}
|
|
||||||
except Exception as e:
|
|
||||||
return {"status": "error", "message": str(e)}
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Compliance Agent
|
|
||||||
Automated compliance and regulatory monitoring agent
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import json
|
|
||||||
import time
|
|
||||||
from typing import Dict, Any, List
|
|
||||||
from datetime import datetime
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Add parent directory to path
|
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '../../../..'))
|
|
||||||
|
|
||||||
from apps.agent_services.agent_bridge.src.integration_layer import AgentServiceBridge
|
|
||||||
|
|
||||||
class ComplianceAgent:
|
|
||||||
"""Automated compliance agent"""
|
|
||||||
|
|
||||||
def __init__(self, agent_id: str, config: Dict[str, Any]):
|
|
||||||
self.agent_id = agent_id
|
|
||||||
self.config = config
|
|
||||||
self.bridge = AgentServiceBridge()
|
|
||||||
self.is_running = False
|
|
||||||
self.check_interval = config.get("check_interval", 300) # 5 minutes
|
|
||||||
self.monitored_entities = config.get("monitored_entities", [])
|
|
||||||
|
|
||||||
async def start(self) -> bool:
|
|
||||||
"""Start compliance agent"""
|
|
||||||
try:
|
|
||||||
success = await self.bridge.start_agent(self.agent_id, {
|
|
||||||
"type": "compliance",
|
|
||||||
"capabilities": ["kyc_check", "aml_screening", "regulatory_reporting"],
|
|
||||||
"endpoint": f"http://localhost:8006"
|
|
||||||
})
|
|
||||||
|
|
||||||
if success:
|
|
||||||
self.is_running = True
|
|
||||||
print(f"Compliance agent {self.agent_id} started successfully")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f"Failed to start compliance agent {self.agent_id}")
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error starting compliance agent: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def stop(self) -> bool:
|
|
||||||
"""Stop compliance agent"""
|
|
||||||
self.is_running = False
|
|
||||||
success = await self.bridge.stop_agent(self.agent_id)
|
|
||||||
if success:
|
|
||||||
print(f"Compliance agent {self.agent_id} stopped successfully")
|
|
||||||
return success
|
|
||||||
|
|
||||||
async def run_compliance_loop(self):
|
|
||||||
"""Main compliance monitoring loop"""
|
|
||||||
while self.is_running:
|
|
||||||
try:
|
|
||||||
for entity in self.monitored_entities:
|
|
||||||
await self._perform_compliance_check(entity)
|
|
||||||
|
|
||||||
await asyncio.sleep(self.check_interval)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error in compliance loop: {e}")
|
|
||||||
await asyncio.sleep(30) # Wait before retrying
|
|
||||||
|
|
||||||
async def _perform_compliance_check(self, entity_id: str) -> None:
|
|
||||||
"""Perform compliance check for entity"""
|
|
||||||
try:
|
|
||||||
compliance_task = {
|
|
||||||
"type": "compliance_check",
|
|
||||||
"user_id": entity_id,
|
|
||||||
"check_type": "full",
|
|
||||||
"monitored_activities": ["trading", "transfers", "wallet_creation"]
|
|
||||||
}
|
|
||||||
|
|
||||||
result = await self.bridge.execute_agent_task(self.agent_id, compliance_task)
|
|
||||||
|
|
||||||
if result.get("status") == "success":
|
|
||||||
compliance_result = result["result"]
|
|
||||||
await self._handle_compliance_result(entity_id, compliance_result)
|
|
||||||
else:
|
|
||||||
print(f"Compliance check failed for {entity_id}: {result}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error performing compliance check for {entity_id}: {e}")
|
|
||||||
|
|
||||||
async def _handle_compliance_result(self, entity_id: str, result: Dict[str, Any]) -> None:
|
|
||||||
"""Handle compliance check result"""
|
|
||||||
status = result.get("status", "unknown")
|
|
||||||
|
|
||||||
if status == "passed":
|
|
||||||
print(f"✅ Compliance check passed for {entity_id}")
|
|
||||||
elif status == "failed":
|
|
||||||
print(f"❌ Compliance check failed for {entity_id}")
|
|
||||||
# Trigger alert or further investigation
|
|
||||||
await self._trigger_compliance_alert(entity_id, result)
|
|
||||||
else:
|
|
||||||
print(f"⚠️ Compliance check inconclusive for {entity_id}")
|
|
||||||
|
|
||||||
async def _trigger_compliance_alert(self, entity_id: str, result: Dict[str, Any]) -> None:
|
|
||||||
"""Trigger compliance alert"""
|
|
||||||
alert_data = {
|
|
||||||
"entity_id": entity_id,
|
|
||||||
"alert_type": "compliance_failure",
|
|
||||||
"severity": "high",
|
|
||||||
"details": result,
|
|
||||||
"timestamp": datetime.utcnow().isoformat()
|
|
||||||
}
|
|
||||||
|
|
||||||
# In a real implementation, this would send to alert system
|
|
||||||
print(f"🚨 COMPLIANCE ALERT: {json.dumps(alert_data, indent=2)}")
|
|
||||||
|
|
||||||
async def get_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get agent status"""
|
|
||||||
status = await self.bridge.get_agent_status(self.agent_id)
|
|
||||||
status["monitored_entities"] = len(self.monitored_entities)
|
|
||||||
status["check_interval"] = self.check_interval
|
|
||||||
return status
|
|
||||||
|
|
||||||
# Main execution
|
|
||||||
async def main():
|
|
||||||
"""Main compliance agent execution"""
|
|
||||||
agent_id = "compliance-agent-001"
|
|
||||||
config = {
|
|
||||||
"check_interval": 60, # 1 minute for testing
|
|
||||||
"monitored_entities": ["user001", "user002", "user003"]
|
|
||||||
}
|
|
||||||
|
|
||||||
agent = ComplianceAgent(agent_id, config)
|
|
||||||
|
|
||||||
# Start agent
|
|
||||||
if await agent.start():
|
|
||||||
try:
|
|
||||||
# Run compliance loop
|
|
||||||
await agent.run_compliance_loop()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("Shutting down compliance agent...")
|
|
||||||
finally:
|
|
||||||
await agent.stop()
|
|
||||||
else:
|
|
||||||
print("Failed to start compliance agent")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
asyncio.run(main())
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Agent Coordinator Service
|
|
||||||
Agent task coordination and management
|
|
||||||
"""
|
|
||||||
|
|
||||||
from fastapi import FastAPI, HTTPException
|
|
||||||
from pydantic import BaseModel
|
|
||||||
from typing import List, Optional, Dict, Any
|
|
||||||
import json
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime
|
|
||||||
import sqlite3
|
|
||||||
from contextlib import contextmanager
|
|
||||||
from contextlib import asynccontextmanager
|
|
||||||
|
|
||||||
@asynccontextmanager
|
|
||||||
async def lifespan(app: FastAPI):
|
|
||||||
# Startup
|
|
||||||
init_db()
|
|
||||||
yield
|
|
||||||
# Shutdown (cleanup if needed)
|
|
||||||
pass
|
|
||||||
|
|
||||||
app = FastAPI(title="AITBC Agent Coordinator API", version="1.0.0", lifespan=lifespan)
|
|
||||||
|
|
||||||
# Database setup
|
|
||||||
def get_db():
|
|
||||||
conn = sqlite3.connect('agent_coordinator.db')
|
|
||||||
conn.row_factory = sqlite3.Row
|
|
||||||
return conn
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def get_db_connection():
|
|
||||||
conn = get_db()
|
|
||||||
try:
|
|
||||||
yield conn
|
|
||||||
finally:
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
# Initialize database
|
|
||||||
def init_db():
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
CREATE TABLE IF NOT EXISTS tasks (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
task_type TEXT NOT NULL,
|
|
||||||
payload TEXT NOT NULL,
|
|
||||||
required_capabilities TEXT NOT NULL,
|
|
||||||
priority TEXT NOT NULL,
|
|
||||||
status TEXT NOT NULL,
|
|
||||||
assigned_agent_id TEXT,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
result TEXT
|
|
||||||
)
|
|
||||||
''')
|
|
||||||
|
|
||||||
# Models
|
|
||||||
class Task(BaseModel):
|
|
||||||
id: str
|
|
||||||
task_type: str
|
|
||||||
payload: Dict[str, Any]
|
|
||||||
required_capabilities: List[str]
|
|
||||||
priority: str
|
|
||||||
status: str
|
|
||||||
assigned_agent_id: Optional[str] = None
|
|
||||||
|
|
||||||
class TaskCreation(BaseModel):
|
|
||||||
task_type: str
|
|
||||||
payload: Dict[str, Any]
|
|
||||||
required_capabilities: List[str]
|
|
||||||
priority: str = "normal"
|
|
||||||
|
|
||||||
# API Endpoints
|
|
||||||
|
|
||||||
@app.post("/api/tasks", response_model=Task)
|
|
||||||
async def create_task(task: TaskCreation):
|
|
||||||
"""Create a new task"""
|
|
||||||
task_id = str(uuid.uuid4())
|
|
||||||
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
INSERT INTO tasks (id, task_type, payload, required_capabilities, priority, status)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?)
|
|
||||||
''', (
|
|
||||||
task_id, task.task_type, json.dumps(task.payload),
|
|
||||||
json.dumps(task.required_capabilities), task.priority, "pending"
|
|
||||||
))
|
|
||||||
|
|
||||||
return Task(
|
|
||||||
id=task_id,
|
|
||||||
task_type=task.task_type,
|
|
||||||
payload=task.payload,
|
|
||||||
required_capabilities=task.required_capabilities,
|
|
||||||
priority=task.priority,
|
|
||||||
status="pending"
|
|
||||||
)
|
|
||||||
|
|
||||||
@app.get("/api/tasks", response_model=List[Task])
|
|
||||||
async def list_tasks(status: Optional[str] = None):
|
|
||||||
"""List tasks with optional status filter"""
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
query = "SELECT * FROM tasks"
|
|
||||||
params = []
|
|
||||||
|
|
||||||
if status:
|
|
||||||
query += " WHERE status = ?"
|
|
||||||
params.append(status)
|
|
||||||
|
|
||||||
tasks = conn.execute(query, params).fetchall()
|
|
||||||
|
|
||||||
return [
|
|
||||||
Task(
|
|
||||||
id=task["id"],
|
|
||||||
task_type=task["task_type"],
|
|
||||||
payload=json.loads(task["payload"]),
|
|
||||||
required_capabilities=json.loads(task["required_capabilities"]),
|
|
||||||
priority=task["priority"],
|
|
||||||
status=task["status"],
|
|
||||||
assigned_agent_id=task["assigned_agent_id"]
|
|
||||||
)
|
|
||||||
for task in tasks
|
|
||||||
]
|
|
||||||
|
|
||||||
@app.get("/api/health")
|
|
||||||
async def health_check():
|
|
||||||
"""Health check endpoint"""
|
|
||||||
return {"status": "ok", "timestamp": datetime.utcnow()}
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import uvicorn
|
|
||||||
uvicorn.run(app, host="0.0.0.0", port=8012)
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
# AITBC Agent Protocols Environment Configuration
|
|
||||||
# Copy this file to .env and update with your secure values
|
|
||||||
|
|
||||||
# Agent Protocol Encryption Key (generate a strong, unique key)
|
|
||||||
AITBC_AGENT_PROTOCOL_KEY=your-secure-encryption-key-here
|
|
||||||
|
|
||||||
# Agent Protocol Salt (generate a unique salt value)
|
|
||||||
AITBC_AGENT_PROTOCOL_SALT=your-unique-salt-value-here
|
|
||||||
|
|
||||||
# Agent Registry Configuration
|
|
||||||
AGENT_REGISTRY_HOST=0.0.0.0
|
|
||||||
AGENT_REGISTRY_PORT=8003
|
|
||||||
|
|
||||||
# Database Configuration
|
|
||||||
AGENT_REGISTRY_DB_PATH=agent_registry.db
|
|
||||||
|
|
||||||
# Security Settings
|
|
||||||
AGENT_PROTOCOL_TIMEOUT=300
|
|
||||||
AGENT_PROTOCOL_MAX_RETRIES=3
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
"""
|
|
||||||
Agent Protocols Package
|
|
||||||
"""
|
|
||||||
|
|
||||||
from .message_protocol import MessageProtocol, MessageTypes, AgentMessageClient
|
|
||||||
from .task_manager import TaskManager, TaskStatus, TaskPriority, Task
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
"MessageProtocol",
|
|
||||||
"MessageTypes",
|
|
||||||
"AgentMessageClient",
|
|
||||||
"TaskManager",
|
|
||||||
"TaskStatus",
|
|
||||||
"TaskPriority",
|
|
||||||
"Task"
|
|
||||||
]
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
"""
|
|
||||||
Message Protocol for AITBC Agents
|
|
||||||
Handles message creation, routing, and delivery between agents
|
|
||||||
"""
|
|
||||||
|
|
||||||
import json
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime
|
|
||||||
from typing import Dict, Any, Optional, List
|
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
class MessageTypes(Enum):
|
|
||||||
"""Message type enumeration"""
|
|
||||||
TASK_REQUEST = "task_request"
|
|
||||||
TASK_RESPONSE = "task_response"
|
|
||||||
HEARTBEAT = "heartbeat"
|
|
||||||
STATUS_UPDATE = "status_update"
|
|
||||||
ERROR = "error"
|
|
||||||
DATA = "data"
|
|
||||||
|
|
||||||
class MessageProtocol:
|
|
||||||
"""Message protocol handler for agent communication"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.messages = []
|
|
||||||
self.message_handlers = {}
|
|
||||||
|
|
||||||
def create_message(
|
|
||||||
self,
|
|
||||||
sender_id: str,
|
|
||||||
receiver_id: str,
|
|
||||||
message_type: MessageTypes,
|
|
||||||
content: Dict[str, Any],
|
|
||||||
message_id: Optional[str] = None
|
|
||||||
) -> Dict[str, Any]:
|
|
||||||
"""Create a new message"""
|
|
||||||
if message_id is None:
|
|
||||||
message_id = str(uuid.uuid4())
|
|
||||||
|
|
||||||
message = {
|
|
||||||
"message_id": message_id,
|
|
||||||
"sender_id": sender_id,
|
|
||||||
"receiver_id": receiver_id,
|
|
||||||
"message_type": message_type.value,
|
|
||||||
"content": content,
|
|
||||||
"timestamp": datetime.utcnow().isoformat(),
|
|
||||||
"status": "pending"
|
|
||||||
}
|
|
||||||
|
|
||||||
self.messages.append(message)
|
|
||||||
return message
|
|
||||||
|
|
||||||
def send_message(self, message: Dict[str, Any]) -> bool:
|
|
||||||
"""Send a message to the receiver"""
|
|
||||||
try:
|
|
||||||
message["status"] = "sent"
|
|
||||||
message["sent_timestamp"] = datetime.utcnow().isoformat()
|
|
||||||
return True
|
|
||||||
except Exception:
|
|
||||||
message["status"] = "failed"
|
|
||||||
return False
|
|
||||||
|
|
||||||
def receive_message(self, message_id: str) -> Optional[Dict[str, Any]]:
|
|
||||||
"""Receive and process a message"""
|
|
||||||
for message in self.messages:
|
|
||||||
if message["message_id"] == message_id:
|
|
||||||
message["status"] = "received"
|
|
||||||
message["received_timestamp"] = datetime.utcnow().isoformat()
|
|
||||||
return message
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_messages_by_agent(self, agent_id: str) -> List[Dict[str, Any]]:
|
|
||||||
"""Get all messages for a specific agent"""
|
|
||||||
return [
|
|
||||||
msg for msg in self.messages
|
|
||||||
if msg["sender_id"] == agent_id or msg["receiver_id"] == agent_id
|
|
||||||
]
|
|
||||||
|
|
||||||
class AgentMessageClient:
|
|
||||||
"""Client for agent message communication"""
|
|
||||||
|
|
||||||
def __init__(self, agent_id: str, protocol: MessageProtocol):
|
|
||||||
self.agent_id = agent_id
|
|
||||||
self.protocol = protocol
|
|
||||||
self.received_messages = []
|
|
||||||
|
|
||||||
def send_message(
|
|
||||||
self,
|
|
||||||
receiver_id: str,
|
|
||||||
message_type: MessageTypes,
|
|
||||||
content: Dict[str, Any]
|
|
||||||
) -> Dict[str, Any]:
|
|
||||||
"""Send a message to another agent"""
|
|
||||||
message = self.protocol.create_message(
|
|
||||||
sender_id=self.agent_id,
|
|
||||||
receiver_id=receiver_id,
|
|
||||||
message_type=message_type,
|
|
||||||
content=content
|
|
||||||
)
|
|
||||||
self.protocol.send_message(message)
|
|
||||||
return message
|
|
||||||
|
|
||||||
def receive_messages(self) -> List[Dict[str, Any]]:
|
|
||||||
"""Receive all pending messages for this agent"""
|
|
||||||
messages = []
|
|
||||||
for message in self.protocol.messages:
|
|
||||||
if (message["receiver_id"] == self.agent_id and
|
|
||||||
message["status"] == "sent" and
|
|
||||||
message not in self.received_messages):
|
|
||||||
self.protocol.receive_message(message["message_id"])
|
|
||||||
self.received_messages.append(message)
|
|
||||||
messages.append(message)
|
|
||||||
return messages
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
"""
|
|
||||||
Task Manager for AITBC Agents
|
|
||||||
Handles task creation, assignment, and tracking
|
|
||||||
"""
|
|
||||||
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
from typing import Dict, Any, Optional, List
|
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
class TaskStatus(Enum):
|
|
||||||
"""Task status enumeration"""
|
|
||||||
PENDING = "pending"
|
|
||||||
IN_PROGRESS = "in_progress"
|
|
||||||
COMPLETED = "completed"
|
|
||||||
FAILED = "failed"
|
|
||||||
CANCELLED = "cancelled"
|
|
||||||
|
|
||||||
class TaskPriority(Enum):
|
|
||||||
"""Task priority enumeration"""
|
|
||||||
LOW = "low"
|
|
||||||
MEDIUM = "medium"
|
|
||||||
HIGH = "high"
|
|
||||||
URGENT = "urgent"
|
|
||||||
|
|
||||||
class Task:
|
|
||||||
"""Task representation"""
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
task_id: str,
|
|
||||||
title: str,
|
|
||||||
description: str,
|
|
||||||
assigned_to: str,
|
|
||||||
priority: TaskPriority = TaskPriority.MEDIUM,
|
|
||||||
created_by: Optional[str] = None
|
|
||||||
):
|
|
||||||
self.task_id = task_id
|
|
||||||
self.title = title
|
|
||||||
self.description = description
|
|
||||||
self.assigned_to = assigned_to
|
|
||||||
self.priority = priority
|
|
||||||
self.created_by = created_by or assigned_to
|
|
||||||
self.status = TaskStatus.PENDING
|
|
||||||
self.created_at = datetime.utcnow()
|
|
||||||
self.updated_at = datetime.utcnow()
|
|
||||||
self.completed_at = None
|
|
||||||
self.result = None
|
|
||||||
self.error = None
|
|
||||||
|
|
||||||
class TaskManager:
|
|
||||||
"""Task manager for agent coordination"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.tasks = {}
|
|
||||||
self.task_history = []
|
|
||||||
|
|
||||||
def create_task(
|
|
||||||
self,
|
|
||||||
title: str,
|
|
||||||
description: str,
|
|
||||||
assigned_to: str,
|
|
||||||
priority: TaskPriority = TaskPriority.MEDIUM,
|
|
||||||
created_by: Optional[str] = None
|
|
||||||
) -> Task:
|
|
||||||
"""Create a new task"""
|
|
||||||
task_id = str(uuid.uuid4())
|
|
||||||
task = Task(
|
|
||||||
task_id=task_id,
|
|
||||||
title=title,
|
|
||||||
description=description,
|
|
||||||
assigned_to=assigned_to,
|
|
||||||
priority=priority,
|
|
||||||
created_by=created_by
|
|
||||||
)
|
|
||||||
|
|
||||||
self.tasks[task_id] = task
|
|
||||||
return task
|
|
||||||
|
|
||||||
def get_task(self, task_id: str) -> Optional[Task]:
|
|
||||||
"""Get a task by ID"""
|
|
||||||
return self.tasks.get(task_id)
|
|
||||||
|
|
||||||
def update_task_status(
|
|
||||||
self,
|
|
||||||
task_id: str,
|
|
||||||
status: TaskStatus,
|
|
||||||
result: Optional[Dict[str, Any]] = None,
|
|
||||||
error: Optional[str] = None
|
|
||||||
) -> bool:
|
|
||||||
"""Update task status"""
|
|
||||||
task = self.get_task(task_id)
|
|
||||||
if not task:
|
|
||||||
return False
|
|
||||||
|
|
||||||
task.status = status
|
|
||||||
task.updated_at = datetime.utcnow()
|
|
||||||
|
|
||||||
if status == TaskStatus.COMPLETED:
|
|
||||||
task.completed_at = datetime.utcnow()
|
|
||||||
task.result = result
|
|
||||||
elif status == TaskStatus.FAILED:
|
|
||||||
task.error = error
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def get_tasks_by_agent(self, agent_id: str) -> List[Task]:
|
|
||||||
"""Get all tasks assigned to an agent"""
|
|
||||||
return [
|
|
||||||
task for task in self.tasks.values()
|
|
||||||
if task.assigned_to == agent_id
|
|
||||||
]
|
|
||||||
|
|
||||||
def get_tasks_by_status(self, status: TaskStatus) -> List[Task]:
|
|
||||||
"""Get all tasks with a specific status"""
|
|
||||||
return [
|
|
||||||
task for task in self.tasks.values()
|
|
||||||
if task.status == status
|
|
||||||
]
|
|
||||||
|
|
||||||
def get_overdue_tasks(self, hours: int = 24) -> List[Task]:
|
|
||||||
"""Get tasks that are overdue"""
|
|
||||||
cutoff_time = datetime.utcnow() - timedelta(hours=hours)
|
|
||||||
return [
|
|
||||||
task for task in self.tasks.values()
|
|
||||||
if task.status in [TaskStatus.PENDING, TaskStatus.IN_PROGRESS] and
|
|
||||||
task.created_at < cutoff_time
|
|
||||||
]
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Agent Registry Service
|
|
||||||
Central agent discovery and registration system
|
|
||||||
"""
|
|
||||||
|
|
||||||
from fastapi import FastAPI, HTTPException, Depends
|
|
||||||
from pydantic import BaseModel
|
|
||||||
from typing import List, Optional, Dict, Any
|
|
||||||
import json
|
|
||||||
import time
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
import sqlite3
|
|
||||||
from contextlib import contextmanager
|
|
||||||
from contextlib import asynccontextmanager
|
|
||||||
|
|
||||||
@asynccontextmanager
|
|
||||||
async def lifespan(app: FastAPI):
|
|
||||||
# Startup
|
|
||||||
init_db()
|
|
||||||
yield
|
|
||||||
# Shutdown (cleanup if needed)
|
|
||||||
pass
|
|
||||||
|
|
||||||
app = FastAPI(title="AITBC Agent Registry API", version="1.0.0", lifespan=lifespan)
|
|
||||||
|
|
||||||
# Database setup
|
|
||||||
def get_db():
|
|
||||||
conn = sqlite3.connect('agent_registry.db')
|
|
||||||
conn.row_factory = sqlite3.Row
|
|
||||||
return conn
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def get_db_connection():
|
|
||||||
conn = get_db()
|
|
||||||
try:
|
|
||||||
yield conn
|
|
||||||
finally:
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
# Initialize database
|
|
||||||
def init_db():
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
CREATE TABLE IF NOT EXISTS agents (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
name TEXT NOT NULL,
|
|
||||||
type TEXT NOT NULL,
|
|
||||||
capabilities TEXT NOT NULL,
|
|
||||||
chain_id TEXT NOT NULL,
|
|
||||||
endpoint TEXT NOT NULL,
|
|
||||||
status TEXT DEFAULT 'active',
|
|
||||||
last_heartbeat TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
metadata TEXT,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
||||||
)
|
|
||||||
''')
|
|
||||||
|
|
||||||
# Models
|
|
||||||
class Agent(BaseModel):
|
|
||||||
id: str
|
|
||||||
name: str
|
|
||||||
type: str
|
|
||||||
capabilities: List[str]
|
|
||||||
chain_id: str
|
|
||||||
endpoint: str
|
|
||||||
metadata: Optional[Dict[str, Any]] = {}
|
|
||||||
|
|
||||||
class AgentRegistration(BaseModel):
|
|
||||||
name: str
|
|
||||||
type: str
|
|
||||||
capabilities: List[str]
|
|
||||||
chain_id: str
|
|
||||||
endpoint: str
|
|
||||||
metadata: Optional[Dict[str, Any]] = {}
|
|
||||||
|
|
||||||
# API Endpoints
|
|
||||||
|
|
||||||
@app.post("/api/agents/register", response_model=Agent)
|
|
||||||
async def register_agent(agent: AgentRegistration):
|
|
||||||
"""Register a new agent"""
|
|
||||||
agent_id = str(uuid.uuid4())
|
|
||||||
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
INSERT INTO agents (id, name, type, capabilities, chain_id, endpoint, metadata)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
||||||
''', (
|
|
||||||
agent_id, agent.name, agent.type,
|
|
||||||
json.dumps(agent.capabilities), agent.chain_id,
|
|
||||||
agent.endpoint, json.dumps(agent.metadata)
|
|
||||||
))
|
|
||||||
conn.commit()
|
|
||||||
|
|
||||||
return Agent(
|
|
||||||
id=agent_id,
|
|
||||||
name=agent.name,
|
|
||||||
type=agent.type,
|
|
||||||
capabilities=agent.capabilities,
|
|
||||||
chain_id=agent.chain_id,
|
|
||||||
endpoint=agent.endpoint,
|
|
||||||
metadata=agent.metadata
|
|
||||||
)
|
|
||||||
|
|
||||||
@app.get("/api/agents", response_model=List[Agent])
|
|
||||||
async def list_agents(
|
|
||||||
agent_type: Optional[str] = None,
|
|
||||||
chain_id: Optional[str] = None,
|
|
||||||
capability: Optional[str] = None
|
|
||||||
):
|
|
||||||
"""List registered agents with optional filters"""
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
query = "SELECT * FROM agents WHERE status = 'active'"
|
|
||||||
params = []
|
|
||||||
|
|
||||||
if agent_type:
|
|
||||||
query += " AND type = ?"
|
|
||||||
params.append(agent_type)
|
|
||||||
|
|
||||||
if chain_id:
|
|
||||||
query += " AND chain_id = ?"
|
|
||||||
params.append(chain_id)
|
|
||||||
|
|
||||||
if capability:
|
|
||||||
query += " AND capabilities LIKE ?"
|
|
||||||
params.append(f'%{capability}%')
|
|
||||||
|
|
||||||
agents = conn.execute(query, params).fetchall()
|
|
||||||
|
|
||||||
return [
|
|
||||||
Agent(
|
|
||||||
id=agent["id"],
|
|
||||||
name=agent["name"],
|
|
||||||
type=agent["type"],
|
|
||||||
capabilities=json.loads(agent["capabilities"]),
|
|
||||||
chain_id=agent["chain_id"],
|
|
||||||
endpoint=agent["endpoint"],
|
|
||||||
metadata=json.loads(agent["metadata"] or "{}")
|
|
||||||
)
|
|
||||||
for agent in agents
|
|
||||||
]
|
|
||||||
|
|
||||||
@app.get("/api/health")
|
|
||||||
async def health_check():
|
|
||||||
"""Health check endpoint"""
|
|
||||||
return {"status": "ok", "timestamp": datetime.utcnow()}
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import uvicorn
|
|
||||||
uvicorn.run(app, host="0.0.0.0", port=8013)
|
|
||||||
@@ -1,431 +0,0 @@
|
|||||||
"""
|
|
||||||
Agent Registration System
|
|
||||||
Handles AI agent registration, capability management, and discovery
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import time
|
|
||||||
import json
|
|
||||||
import hashlib
|
|
||||||
from typing import Dict, List, Optional, Set, Tuple
|
|
||||||
from dataclasses import dataclass, asdict
|
|
||||||
from enum import Enum
|
|
||||||
from decimal import Decimal
|
|
||||||
|
|
||||||
class AgentType(Enum):
|
|
||||||
AI_MODEL = "ai_model"
|
|
||||||
DATA_PROVIDER = "data_provider"
|
|
||||||
VALIDATOR = "validator"
|
|
||||||
MARKET_MAKER = "market_maker"
|
|
||||||
BROKER = "broker"
|
|
||||||
ORACLE = "oracle"
|
|
||||||
|
|
||||||
class AgentStatus(Enum):
|
|
||||||
REGISTERED = "registered"
|
|
||||||
ACTIVE = "active"
|
|
||||||
INACTIVE = "inactive"
|
|
||||||
SUSPENDED = "suspended"
|
|
||||||
BANNED = "banned"
|
|
||||||
|
|
||||||
class CapabilityType(Enum):
|
|
||||||
TEXT_GENERATION = "text_generation"
|
|
||||||
IMAGE_GENERATION = "image_generation"
|
|
||||||
DATA_ANALYSIS = "data_analysis"
|
|
||||||
PREDICTION = "prediction"
|
|
||||||
VALIDATION = "validation"
|
|
||||||
COMPUTATION = "computation"
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class AgentCapability:
|
|
||||||
capability_type: CapabilityType
|
|
||||||
name: str
|
|
||||||
version: str
|
|
||||||
parameters: Dict
|
|
||||||
performance_metrics: Dict
|
|
||||||
cost_per_use: Decimal
|
|
||||||
availability: float
|
|
||||||
max_concurrent_jobs: int
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class AgentInfo:
|
|
||||||
agent_id: str
|
|
||||||
agent_type: AgentType
|
|
||||||
name: str
|
|
||||||
owner_address: str
|
|
||||||
public_key: str
|
|
||||||
endpoint_url: str
|
|
||||||
capabilities: List[AgentCapability]
|
|
||||||
reputation_score: float
|
|
||||||
total_jobs_completed: int
|
|
||||||
total_earnings: Decimal
|
|
||||||
registration_time: float
|
|
||||||
last_active: float
|
|
||||||
status: AgentStatus
|
|
||||||
metadata: Dict
|
|
||||||
|
|
||||||
class AgentRegistry:
|
|
||||||
"""Manages AI agent registration and discovery"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.agents: Dict[str, AgentInfo] = {}
|
|
||||||
self.capability_index: Dict[CapabilityType, Set[str]] = {} # capability -> agent_ids
|
|
||||||
self.type_index: Dict[AgentType, Set[str]] = {} # agent_type -> agent_ids
|
|
||||||
self.reputation_scores: Dict[str, float] = {}
|
|
||||||
self.registration_queue: List[Dict] = []
|
|
||||||
|
|
||||||
# Registry parameters
|
|
||||||
self.min_reputation_threshold = 0.5
|
|
||||||
self.max_agents_per_type = 1000
|
|
||||||
self.registration_fee = Decimal('100.0')
|
|
||||||
self.inactivity_threshold = 86400 * 7 # 7 days
|
|
||||||
|
|
||||||
# Initialize capability index
|
|
||||||
for capability_type in CapabilityType:
|
|
||||||
self.capability_index[capability_type] = set()
|
|
||||||
|
|
||||||
# Initialize type index
|
|
||||||
for agent_type in AgentType:
|
|
||||||
self.type_index[agent_type] = set()
|
|
||||||
|
|
||||||
async def register_agent(self, agent_type: AgentType, name: str, owner_address: str,
|
|
||||||
public_key: str, endpoint_url: str, capabilities: List[Dict],
|
|
||||||
metadata: Dict = None) -> Tuple[bool, str, Optional[str]]:
|
|
||||||
"""Register a new AI agent"""
|
|
||||||
try:
|
|
||||||
# Validate inputs
|
|
||||||
if not self._validate_registration_inputs(agent_type, name, owner_address, public_key, endpoint_url):
|
|
||||||
return False, "Invalid registration inputs", None
|
|
||||||
|
|
||||||
# Check if agent already exists
|
|
||||||
agent_id = self._generate_agent_id(owner_address, name)
|
|
||||||
if agent_id in self.agents:
|
|
||||||
return False, "Agent already registered", None
|
|
||||||
|
|
||||||
# Check type limits
|
|
||||||
if len(self.type_index[agent_type]) >= self.max_agents_per_type:
|
|
||||||
return False, f"Maximum agents of type {agent_type.value} reached", None
|
|
||||||
|
|
||||||
# Convert capabilities
|
|
||||||
agent_capabilities = []
|
|
||||||
for cap_data in capabilities:
|
|
||||||
capability = self._create_capability_from_data(cap_data)
|
|
||||||
if capability:
|
|
||||||
agent_capabilities.append(capability)
|
|
||||||
|
|
||||||
if not agent_capabilities:
|
|
||||||
return False, "Agent must have at least one valid capability", None
|
|
||||||
|
|
||||||
# Create agent info
|
|
||||||
agent_info = AgentInfo(
|
|
||||||
agent_id=agent_id,
|
|
||||||
agent_type=agent_type,
|
|
||||||
name=name,
|
|
||||||
owner_address=owner_address,
|
|
||||||
public_key=public_key,
|
|
||||||
endpoint_url=endpoint_url,
|
|
||||||
capabilities=agent_capabilities,
|
|
||||||
reputation_score=1.0, # Start with neutral reputation
|
|
||||||
total_jobs_completed=0,
|
|
||||||
total_earnings=Decimal('0'),
|
|
||||||
registration_time=time.time(),
|
|
||||||
last_active=time.time(),
|
|
||||||
status=AgentStatus.REGISTERED,
|
|
||||||
metadata=metadata or {}
|
|
||||||
)
|
|
||||||
|
|
||||||
# Add to registry
|
|
||||||
self.agents[agent_id] = agent_info
|
|
||||||
|
|
||||||
# Update indexes
|
|
||||||
self.type_index[agent_type].add(agent_id)
|
|
||||||
for capability in agent_capabilities:
|
|
||||||
self.capability_index[capability.capability_type].add(agent_id)
|
|
||||||
|
|
||||||
log_info(f"Agent registered: {agent_id} ({name})")
|
|
||||||
return True, "Registration successful", agent_id
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
return False, f"Registration failed: {str(e)}", None
|
|
||||||
|
|
||||||
def _validate_registration_inputs(self, agent_type: AgentType, name: str,
|
|
||||||
owner_address: str, public_key: str, endpoint_url: str) -> bool:
|
|
||||||
"""Validate registration inputs"""
|
|
||||||
# Check required fields
|
|
||||||
if not all([agent_type, name, owner_address, public_key, endpoint_url]):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Validate address format (simplified)
|
|
||||||
if not owner_address.startswith('0x') or len(owner_address) != 42:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Validate URL format (simplified)
|
|
||||||
if not endpoint_url.startswith(('http://', 'https://')):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Validate name
|
|
||||||
if len(name) < 3 or len(name) > 100:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def _generate_agent_id(self, owner_address: str, name: str) -> str:
|
|
||||||
"""Generate unique agent ID"""
|
|
||||||
content = f"{owner_address}:{name}:{time.time()}"
|
|
||||||
return hashlib.sha256(content.encode()).hexdigest()[:16]
|
|
||||||
|
|
||||||
def _create_capability_from_data(self, cap_data: Dict) -> Optional[AgentCapability]:
|
|
||||||
"""Create capability from data dictionary"""
|
|
||||||
try:
|
|
||||||
# Validate required fields
|
|
||||||
required_fields = ['type', 'name', 'version', 'cost_per_use']
|
|
||||||
if not all(field in cap_data for field in required_fields):
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Parse capability type
|
|
||||||
try:
|
|
||||||
capability_type = CapabilityType(cap_data['type'])
|
|
||||||
except ValueError:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Create capability
|
|
||||||
return AgentCapability(
|
|
||||||
capability_type=capability_type,
|
|
||||||
name=cap_data['name'],
|
|
||||||
version=cap_data['version'],
|
|
||||||
parameters=cap_data.get('parameters', {}),
|
|
||||||
performance_metrics=cap_data.get('performance_metrics', {}),
|
|
||||||
cost_per_use=Decimal(str(cap_data['cost_per_use'])),
|
|
||||||
availability=cap_data.get('availability', 1.0),
|
|
||||||
max_concurrent_jobs=cap_data.get('max_concurrent_jobs', 1)
|
|
||||||
)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
log_error(f"Error creating capability: {e}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
async def update_agent_status(self, agent_id: str, status: AgentStatus) -> Tuple[bool, str]:
|
|
||||||
"""Update agent status"""
|
|
||||||
if agent_id not in self.agents:
|
|
||||||
return False, "Agent not found"
|
|
||||||
|
|
||||||
agent = self.agents[agent_id]
|
|
||||||
old_status = agent.status
|
|
||||||
agent.status = status
|
|
||||||
agent.last_active = time.time()
|
|
||||||
|
|
||||||
log_info(f"Agent {agent_id} status changed: {old_status.value} -> {status.value}")
|
|
||||||
return True, "Status updated successfully"
|
|
||||||
|
|
||||||
async def update_agent_capabilities(self, agent_id: str, capabilities: List[Dict]) -> Tuple[bool, str]:
|
|
||||||
"""Update agent capabilities"""
|
|
||||||
if agent_id not in self.agents:
|
|
||||||
return False, "Agent not found"
|
|
||||||
|
|
||||||
agent = self.agents[agent_id]
|
|
||||||
|
|
||||||
# Remove old capabilities from index
|
|
||||||
for old_capability in agent.capabilities:
|
|
||||||
self.capability_index[old_capability.capability_type].discard(agent_id)
|
|
||||||
|
|
||||||
# Add new capabilities
|
|
||||||
new_capabilities = []
|
|
||||||
for cap_data in capabilities:
|
|
||||||
capability = self._create_capability_from_data(cap_data)
|
|
||||||
if capability:
|
|
||||||
new_capabilities.append(capability)
|
|
||||||
self.capability_index[capability.capability_type].add(agent_id)
|
|
||||||
|
|
||||||
if not new_capabilities:
|
|
||||||
return False, "No valid capabilities provided"
|
|
||||||
|
|
||||||
agent.capabilities = new_capabilities
|
|
||||||
agent.last_active = time.time()
|
|
||||||
|
|
||||||
return True, "Capabilities updated successfully"
|
|
||||||
|
|
||||||
async def find_agents_by_capability(self, capability_type: CapabilityType,
|
|
||||||
filters: Dict = None) -> List[AgentInfo]:
|
|
||||||
"""Find agents by capability type"""
|
|
||||||
agent_ids = self.capability_index.get(capability_type, set())
|
|
||||||
|
|
||||||
agents = []
|
|
||||||
for agent_id in agent_ids:
|
|
||||||
agent = self.agents.get(agent_id)
|
|
||||||
if agent and agent.status == AgentStatus.ACTIVE:
|
|
||||||
if self._matches_filters(agent, filters):
|
|
||||||
agents.append(agent)
|
|
||||||
|
|
||||||
# Sort by reputation (highest first)
|
|
||||||
agents.sort(key=lambda x: x.reputation_score, reverse=True)
|
|
||||||
return agents
|
|
||||||
|
|
||||||
async def find_agents_by_type(self, agent_type: AgentType, filters: Dict = None) -> List[AgentInfo]:
|
|
||||||
"""Find agents by type"""
|
|
||||||
agent_ids = self.type_index.get(agent_type, set())
|
|
||||||
|
|
||||||
agents = []
|
|
||||||
for agent_id in agent_ids:
|
|
||||||
agent = self.agents.get(agent_id)
|
|
||||||
if agent and agent.status == AgentStatus.ACTIVE:
|
|
||||||
if self._matches_filters(agent, filters):
|
|
||||||
agents.append(agent)
|
|
||||||
|
|
||||||
# Sort by reputation (highest first)
|
|
||||||
agents.sort(key=lambda x: x.reputation_score, reverse=True)
|
|
||||||
return agents
|
|
||||||
|
|
||||||
def _matches_filters(self, agent: AgentInfo, filters: Dict) -> bool:
|
|
||||||
"""Check if agent matches filters"""
|
|
||||||
if not filters:
|
|
||||||
return True
|
|
||||||
|
|
||||||
# Reputation filter
|
|
||||||
if 'min_reputation' in filters:
|
|
||||||
if agent.reputation_score < filters['min_reputation']:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Cost filter
|
|
||||||
if 'max_cost_per_use' in filters:
|
|
||||||
max_cost = Decimal(str(filters['max_cost_per_use']))
|
|
||||||
if any(cap.cost_per_use > max_cost for cap in agent.capabilities):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Availability filter
|
|
||||||
if 'min_availability' in filters:
|
|
||||||
min_availability = filters['min_availability']
|
|
||||||
if any(cap.availability < min_availability for cap in agent.capabilities):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Location filter (if implemented)
|
|
||||||
if 'location' in filters:
|
|
||||||
agent_location = agent.metadata.get('location')
|
|
||||||
if agent_location != filters['location']:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
async def get_agent_info(self, agent_id: str) -> Optional[AgentInfo]:
|
|
||||||
"""Get agent information"""
|
|
||||||
return self.agents.get(agent_id)
|
|
||||||
|
|
||||||
async def search_agents(self, query: str, limit: int = 50) -> List[AgentInfo]:
|
|
||||||
"""Search agents by name or capability"""
|
|
||||||
query_lower = query.lower()
|
|
||||||
results = []
|
|
||||||
|
|
||||||
for agent in self.agents.values():
|
|
||||||
if agent.status != AgentStatus.ACTIVE:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Search in name
|
|
||||||
if query_lower in agent.name.lower():
|
|
||||||
results.append(agent)
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Search in capabilities
|
|
||||||
for capability in agent.capabilities:
|
|
||||||
if (query_lower in capability.name.lower() or
|
|
||||||
query_lower in capability.capability_type.value):
|
|
||||||
results.append(agent)
|
|
||||||
break
|
|
||||||
|
|
||||||
# Sort by relevance (reputation)
|
|
||||||
results.sort(key=lambda x: x.reputation_score, reverse=True)
|
|
||||||
return results[:limit]
|
|
||||||
|
|
||||||
async def get_agent_statistics(self, agent_id: str) -> Optional[Dict]:
|
|
||||||
"""Get detailed statistics for an agent"""
|
|
||||||
agent = self.agents.get(agent_id)
|
|
||||||
if not agent:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Calculate additional statistics
|
|
||||||
avg_job_earnings = agent.total_earnings / agent.total_jobs_completed if agent.total_jobs_completed > 0 else Decimal('0')
|
|
||||||
days_active = (time.time() - agent.registration_time) / 86400
|
|
||||||
jobs_per_day = agent.total_jobs_completed / days_active if days_active > 0 else 0
|
|
||||||
|
|
||||||
return {
|
|
||||||
'agent_id': agent_id,
|
|
||||||
'name': agent.name,
|
|
||||||
'type': agent.agent_type.value,
|
|
||||||
'status': agent.status.value,
|
|
||||||
'reputation_score': agent.reputation_score,
|
|
||||||
'total_jobs_completed': agent.total_jobs_completed,
|
|
||||||
'total_earnings': float(agent.total_earnings),
|
|
||||||
'avg_job_earnings': float(avg_job_earnings),
|
|
||||||
'jobs_per_day': jobs_per_day,
|
|
||||||
'days_active': int(days_active),
|
|
||||||
'capabilities_count': len(agent.capabilities),
|
|
||||||
'last_active': agent.last_active,
|
|
||||||
'registration_time': agent.registration_time
|
|
||||||
}
|
|
||||||
|
|
||||||
async def get_registry_statistics(self) -> Dict:
|
|
||||||
"""Get registry-wide statistics"""
|
|
||||||
total_agents = len(self.agents)
|
|
||||||
active_agents = len([a for a in self.agents.values() if a.status == AgentStatus.ACTIVE])
|
|
||||||
|
|
||||||
# Count by type
|
|
||||||
type_counts = {}
|
|
||||||
for agent_type in AgentType:
|
|
||||||
type_counts[agent_type.value] = len(self.type_index[agent_type])
|
|
||||||
|
|
||||||
# Count by capability
|
|
||||||
capability_counts = {}
|
|
||||||
for capability_type in CapabilityType:
|
|
||||||
capability_counts[capability_type.value] = len(self.capability_index[capability_type])
|
|
||||||
|
|
||||||
# Reputation statistics
|
|
||||||
reputations = [a.reputation_score for a in self.agents.values()]
|
|
||||||
avg_reputation = sum(reputations) / len(reputations) if reputations else 0
|
|
||||||
|
|
||||||
# Earnings statistics
|
|
||||||
total_earnings = sum(a.total_earnings for a in self.agents.values())
|
|
||||||
|
|
||||||
return {
|
|
||||||
'total_agents': total_agents,
|
|
||||||
'active_agents': active_agents,
|
|
||||||
'inactive_agents': total_agents - active_agents,
|
|
||||||
'agent_types': type_counts,
|
|
||||||
'capabilities': capability_counts,
|
|
||||||
'average_reputation': avg_reputation,
|
|
||||||
'total_earnings': float(total_earnings),
|
|
||||||
'registration_fee': float(self.registration_fee)
|
|
||||||
}
|
|
||||||
|
|
||||||
async def cleanup_inactive_agents(self) -> Tuple[int, str]:
|
|
||||||
"""Clean up inactive agents"""
|
|
||||||
current_time = time.time()
|
|
||||||
cleaned_count = 0
|
|
||||||
|
|
||||||
for agent_id, agent in list(self.agents.items()):
|
|
||||||
if (agent.status == AgentStatus.INACTIVE and
|
|
||||||
current_time - agent.last_active > self.inactivity_threshold):
|
|
||||||
|
|
||||||
# Remove from registry
|
|
||||||
del self.agents[agent_id]
|
|
||||||
|
|
||||||
# Update indexes
|
|
||||||
self.type_index[agent.agent_type].discard(agent_id)
|
|
||||||
for capability in agent.capabilities:
|
|
||||||
self.capability_index[capability.capability_type].discard(agent_id)
|
|
||||||
|
|
||||||
cleaned_count += 1
|
|
||||||
|
|
||||||
if cleaned_count > 0:
|
|
||||||
log_info(f"Cleaned up {cleaned_count} inactive agents")
|
|
||||||
|
|
||||||
return cleaned_count, f"Cleaned up {cleaned_count} inactive agents"
|
|
||||||
|
|
||||||
# Global agent registry
|
|
||||||
agent_registry: Optional[AgentRegistry] = None
|
|
||||||
|
|
||||||
def get_agent_registry() -> Optional[AgentRegistry]:
|
|
||||||
"""Get global agent registry"""
|
|
||||||
return agent_registry
|
|
||||||
|
|
||||||
def create_agent_registry() -> AgentRegistry:
|
|
||||||
"""Create and set global agent registry"""
|
|
||||||
global agent_registry
|
|
||||||
agent_registry = AgentRegistry()
|
|
||||||
return agent_registry
|
|
||||||
@@ -1,166 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Trading Agent
|
|
||||||
Automated trading agent for AITBC marketplace
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import json
|
|
||||||
import time
|
|
||||||
from typing import Dict, Any, List
|
|
||||||
from datetime import datetime
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Add parent directory to path
|
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '../../../..'))
|
|
||||||
|
|
||||||
from apps.agent_services.agent_bridge.src.integration_layer import AgentServiceBridge
|
|
||||||
|
|
||||||
class TradingAgent:
|
|
||||||
"""Automated trading agent"""
|
|
||||||
|
|
||||||
def __init__(self, agent_id: str, config: Dict[str, Any]):
|
|
||||||
self.agent_id = agent_id
|
|
||||||
self.config = config
|
|
||||||
self.bridge = AgentServiceBridge()
|
|
||||||
self.is_running = False
|
|
||||||
self.trading_strategy = config.get("strategy", "basic")
|
|
||||||
self.symbols = config.get("symbols", ["AITBC/BTC"])
|
|
||||||
self.trade_interval = config.get("trade_interval", 60) # seconds
|
|
||||||
|
|
||||||
async def start(self) -> bool:
|
|
||||||
"""Start trading agent"""
|
|
||||||
try:
|
|
||||||
# Register with service bridge
|
|
||||||
success = await self.bridge.start_agent(self.agent_id, {
|
|
||||||
"type": "trading",
|
|
||||||
"capabilities": ["market_analysis", "trading", "risk_management"],
|
|
||||||
"endpoint": f"http://localhost:8005"
|
|
||||||
})
|
|
||||||
|
|
||||||
if success:
|
|
||||||
self.is_running = True
|
|
||||||
print(f"Trading agent {self.agent_id} started successfully")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f"Failed to start trading agent {self.agent_id}")
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error starting trading agent: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def stop(self) -> bool:
|
|
||||||
"""Stop trading agent"""
|
|
||||||
self.is_running = False
|
|
||||||
success = await self.bridge.stop_agent(self.agent_id)
|
|
||||||
if success:
|
|
||||||
print(f"Trading agent {self.agent_id} stopped successfully")
|
|
||||||
return success
|
|
||||||
|
|
||||||
async def run_trading_loop(self):
|
|
||||||
"""Main trading loop"""
|
|
||||||
while self.is_running:
|
|
||||||
try:
|
|
||||||
for symbol in self.symbols:
|
|
||||||
await self._analyze_and_trade(symbol)
|
|
||||||
|
|
||||||
await asyncio.sleep(self.trade_interval)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error in trading loop: {e}")
|
|
||||||
await asyncio.sleep(10) # Wait before retrying
|
|
||||||
|
|
||||||
async def _analyze_and_trade(self, symbol: str) -> None:
|
|
||||||
"""Analyze market and execute trades"""
|
|
||||||
try:
|
|
||||||
# Perform market analysis
|
|
||||||
analysis_task = {
|
|
||||||
"type": "market_analysis",
|
|
||||||
"symbol": symbol,
|
|
||||||
"strategy": self.trading_strategy
|
|
||||||
}
|
|
||||||
|
|
||||||
analysis_result = await self.bridge.execute_agent_task(self.agent_id, analysis_task)
|
|
||||||
|
|
||||||
if analysis_result.get("status") == "success":
|
|
||||||
analysis = analysis_result["result"]["analysis"]
|
|
||||||
|
|
||||||
# Make trading decision
|
|
||||||
if self._should_trade(analysis):
|
|
||||||
await self._execute_trade(symbol, analysis)
|
|
||||||
else:
|
|
||||||
print(f"Market analysis failed for {symbol}: {analysis_result}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error in analyze_and_trade for {symbol}: {e}")
|
|
||||||
|
|
||||||
def _should_trade(self, analysis: Dict[str, Any]) -> bool:
|
|
||||||
"""Determine if should execute trade"""
|
|
||||||
recommendation = analysis.get("recommendation", "hold")
|
|
||||||
return recommendation in ["buy", "sell"]
|
|
||||||
|
|
||||||
async def _execute_trade(self, symbol: str, analysis: Dict[str, Any]) -> None:
|
|
||||||
"""Execute trade based on analysis"""
|
|
||||||
try:
|
|
||||||
recommendation = analysis.get("recommendation", "hold")
|
|
||||||
|
|
||||||
if recommendation == "buy":
|
|
||||||
trade_task = {
|
|
||||||
"type": "trading",
|
|
||||||
"symbol": symbol,
|
|
||||||
"side": "buy",
|
|
||||||
"amount": self.config.get("trade_amount", 0.1),
|
|
||||||
"strategy": self.trading_strategy
|
|
||||||
}
|
|
||||||
elif recommendation == "sell":
|
|
||||||
trade_task = {
|
|
||||||
"type": "trading",
|
|
||||||
"symbol": symbol,
|
|
||||||
"side": "sell",
|
|
||||||
"amount": self.config.get("trade_amount", 0.1),
|
|
||||||
"strategy": self.trading_strategy
|
|
||||||
}
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
|
|
||||||
trade_result = await self.bridge.execute_agent_task(self.agent_id, trade_task)
|
|
||||||
|
|
||||||
if trade_result.get("status") == "success":
|
|
||||||
print(f"Trade executed successfully: {trade_result}")
|
|
||||||
else:
|
|
||||||
print(f"Trade execution failed: {trade_result}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error executing trade: {e}")
|
|
||||||
|
|
||||||
async def get_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get agent status"""
|
|
||||||
return await self.bridge.get_agent_status(self.agent_id)
|
|
||||||
|
|
||||||
# Main execution
|
|
||||||
async def main():
|
|
||||||
"""Main trading agent execution"""
|
|
||||||
agent_id = "trading-agent-001"
|
|
||||||
config = {
|
|
||||||
"strategy": "basic",
|
|
||||||
"symbols": ["AITBC/BTC"],
|
|
||||||
"trade_interval": 30,
|
|
||||||
"trade_amount": 0.1
|
|
||||||
}
|
|
||||||
|
|
||||||
agent = TradingAgent(agent_id, config)
|
|
||||||
|
|
||||||
# Start agent
|
|
||||||
if await agent.start():
|
|
||||||
try:
|
|
||||||
# Run trading loop
|
|
||||||
await agent.run_trading_loop()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("Shutting down trading agent...")
|
|
||||||
finally:
|
|
||||||
await agent.stop()
|
|
||||||
else:
|
|
||||||
print("Failed to start trading agent")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
asyncio.run(main())
|
|
||||||
@@ -1,229 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Agent Integration Layer
|
|
||||||
Connects agent protocols to existing AITBC services
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import aiohttp
|
|
||||||
import json
|
|
||||||
from typing import Dict, Any, List, Optional
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
class AITBCServiceIntegration:
|
|
||||||
"""Integration layer for AITBC services"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.service_endpoints = {
|
|
||||||
"coordinator_api": "http://localhost:8000",
|
|
||||||
"blockchain_rpc": "http://localhost:8006",
|
|
||||||
"exchange_service": "http://localhost:8001",
|
|
||||||
"marketplace": "http://localhost:8002",
|
|
||||||
"agent_registry": "http://localhost:8013"
|
|
||||||
}
|
|
||||||
self.session = None
|
|
||||||
|
|
||||||
async def __aenter__(self):
|
|
||||||
self.session = aiohttp.ClientSession()
|
|
||||||
return self
|
|
||||||
|
|
||||||
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
||||||
if self.session:
|
|
||||||
await self.session.close()
|
|
||||||
|
|
||||||
async def get_blockchain_info(self) -> Dict[str, Any]:
|
|
||||||
"""Get blockchain information"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['blockchain_rpc']}/health") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "unavailable"}
|
|
||||||
|
|
||||||
async def get_exchange_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get exchange service status"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['exchange_service']}/api/health") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "unavailable"}
|
|
||||||
|
|
||||||
async def get_coordinator_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get coordinator API status"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['coordinator_api']}/health") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "unavailable"}
|
|
||||||
|
|
||||||
async def submit_transaction(self, transaction_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Submit transaction to blockchain"""
|
|
||||||
try:
|
|
||||||
async with self.session.post(
|
|
||||||
f"{self.service_endpoints['blockchain_rpc']}/rpc/submit",
|
|
||||||
json=transaction_data
|
|
||||||
) as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "failed"}
|
|
||||||
|
|
||||||
async def get_market_data(self, symbol: str = "AITBC/BTC") -> Dict[str, Any]:
|
|
||||||
"""Get market data from exchange"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['exchange_service']}/api/market/{symbol}") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "failed"}
|
|
||||||
|
|
||||||
async def register_agent_with_coordinator(self, agent_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Register agent with coordinator"""
|
|
||||||
try:
|
|
||||||
async with self.session.post(
|
|
||||||
f"{self.service_endpoints['agent_registry']}/api/agents/register",
|
|
||||||
json=agent_data
|
|
||||||
) as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "failed"}
|
|
||||||
|
|
||||||
class AgentServiceBridge:
|
|
||||||
"""Bridge between agents and AITBC services"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.integration = AITBCServiceIntegration()
|
|
||||||
self.active_agents = {}
|
|
||||||
|
|
||||||
async def start_agent(self, agent_id: str, agent_config: Dict[str, Any]) -> bool:
|
|
||||||
"""Start an agent with service integration"""
|
|
||||||
try:
|
|
||||||
# Register agent with coordinator
|
|
||||||
async with self.integration as integration:
|
|
||||||
registration_result = await integration.register_agent_with_coordinator({
|
|
||||||
"name": agent_id,
|
|
||||||
"type": agent_config.get("type", "generic"),
|
|
||||||
"capabilities": agent_config.get("capabilities", []),
|
|
||||||
"chain_id": agent_config.get("chain_id", "ait-mainnet"),
|
|
||||||
"endpoint": agent_config.get("endpoint", f"http://localhost:{8000 + len(self.active_agents) + 10}")
|
|
||||||
})
|
|
||||||
|
|
||||||
# The registry returns the created agent dict on success, not a {"status": "ok"} wrapper
|
|
||||||
if registration_result and "id" in registration_result:
|
|
||||||
self.active_agents[agent_id] = {
|
|
||||||
"config": agent_config,
|
|
||||||
"registration": registration_result,
|
|
||||||
"started_at": datetime.utcnow()
|
|
||||||
}
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f"Registration failed: {registration_result}")
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Failed to start agent {agent_id}: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def stop_agent(self, agent_id: str) -> bool:
|
|
||||||
"""Stop an agent"""
|
|
||||||
if agent_id in self.active_agents:
|
|
||||||
del self.active_agents[agent_id]
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def get_agent_status(self, agent_id: str) -> Dict[str, Any]:
|
|
||||||
"""Get agent status with service integration"""
|
|
||||||
if agent_id not in self.active_agents:
|
|
||||||
return {"status": "not_found"}
|
|
||||||
|
|
||||||
agent_info = self.active_agents[agent_id]
|
|
||||||
|
|
||||||
async with self.integration as integration:
|
|
||||||
# Get service statuses
|
|
||||||
blockchain_status = await integration.get_blockchain_info()
|
|
||||||
exchange_status = await integration.get_exchange_status()
|
|
||||||
coordinator_status = await integration.get_coordinator_status()
|
|
||||||
|
|
||||||
return {
|
|
||||||
"agent_id": agent_id,
|
|
||||||
"status": "active",
|
|
||||||
"started_at": agent_info["started_at"].isoformat(),
|
|
||||||
"services": {
|
|
||||||
"blockchain": blockchain_status,
|
|
||||||
"exchange": exchange_status,
|
|
||||||
"coordinator": coordinator_status
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async def execute_agent_task(self, agent_id: str, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute agent task with service integration"""
|
|
||||||
if agent_id not in self.active_agents:
|
|
||||||
return {"status": "error", "message": "Agent not found"}
|
|
||||||
|
|
||||||
task_type = task_data.get("type")
|
|
||||||
|
|
||||||
if task_type == "market_analysis":
|
|
||||||
return await self._execute_market_analysis(task_data)
|
|
||||||
elif task_type == "trading":
|
|
||||||
return await self._execute_trading_task(task_data)
|
|
||||||
elif task_type == "compliance_check":
|
|
||||||
return await self._execute_compliance_check(task_data)
|
|
||||||
else:
|
|
||||||
return {"status": "error", "message": f"Unknown task type: {task_type}"}
|
|
||||||
|
|
||||||
async def _execute_market_analysis(self, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute market analysis task"""
|
|
||||||
try:
|
|
||||||
async with self.integration as integration:
|
|
||||||
market_data = await integration.get_market_data(task_data.get("symbol", "AITBC/BTC"))
|
|
||||||
|
|
||||||
# Perform basic analysis
|
|
||||||
analysis_result = {
|
|
||||||
"symbol": task_data.get("symbol", "AITBC/BTC"),
|
|
||||||
"market_data": market_data,
|
|
||||||
"analysis": {
|
|
||||||
"trend": "neutral",
|
|
||||||
"volatility": "medium",
|
|
||||||
"recommendation": "hold"
|
|
||||||
},
|
|
||||||
"timestamp": datetime.utcnow().isoformat()
|
|
||||||
}
|
|
||||||
|
|
||||||
return {"status": "success", "result": analysis_result}
|
|
||||||
except Exception as e:
|
|
||||||
return {"status": "error", "message": str(e)}
|
|
||||||
|
|
||||||
async def _execute_trading_task(self, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute trading task"""
|
|
||||||
try:
|
|
||||||
# Get market data first
|
|
||||||
async with self.integration as integration:
|
|
||||||
market_data = await integration.get_market_data(task_data.get("symbol", "AITBC/BTC"))
|
|
||||||
|
|
||||||
# Create transaction
|
|
||||||
transaction = {
|
|
||||||
"type": "trade",
|
|
||||||
"symbol": task_data.get("symbol", "AITBC/BTC"),
|
|
||||||
"side": task_data.get("side", "buy"),
|
|
||||||
"amount": task_data.get("amount", 0.1),
|
|
||||||
"price": task_data.get("price", market_data.get("price", 0.001))
|
|
||||||
}
|
|
||||||
|
|
||||||
# Submit transaction
|
|
||||||
tx_result = await integration.submit_transaction(transaction)
|
|
||||||
|
|
||||||
return {"status": "success", "transaction": tx_result}
|
|
||||||
except Exception as e:
|
|
||||||
return {"status": "error", "message": str(e)}
|
|
||||||
|
|
||||||
async def _execute_compliance_check(self, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute compliance check task"""
|
|
||||||
try:
|
|
||||||
# Basic compliance check
|
|
||||||
compliance_result = {
|
|
||||||
"user_id": task_data.get("user_id"),
|
|
||||||
"check_type": task_data.get("check_type", "basic"),
|
|
||||||
"status": "passed",
|
|
||||||
"checks_performed": ["kyc", "aml", "sanctions"],
|
|
||||||
"timestamp": datetime.utcnow().isoformat()
|
|
||||||
}
|
|
||||||
|
|
||||||
return {"status": "success", "result": compliance_result}
|
|
||||||
except Exception as e:
|
|
||||||
return {"status": "error", "message": str(e)}
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Compliance Agent
|
|
||||||
Automated compliance and regulatory monitoring agent
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import json
|
|
||||||
import time
|
|
||||||
from typing import Dict, Any, List
|
|
||||||
from datetime import datetime
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Add parent directory to path
|
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '../../../..'))
|
|
||||||
|
|
||||||
from apps.agent_services.agent_bridge.src.integration_layer import AgentServiceBridge
|
|
||||||
|
|
||||||
class ComplianceAgent:
|
|
||||||
"""Automated compliance agent"""
|
|
||||||
|
|
||||||
def __init__(self, agent_id: str, config: Dict[str, Any]):
|
|
||||||
self.agent_id = agent_id
|
|
||||||
self.config = config
|
|
||||||
self.bridge = AgentServiceBridge()
|
|
||||||
self.is_running = False
|
|
||||||
self.check_interval = config.get("check_interval", 300) # 5 minutes
|
|
||||||
self.monitored_entities = config.get("monitored_entities", [])
|
|
||||||
|
|
||||||
async def start(self) -> bool:
|
|
||||||
"""Start compliance agent"""
|
|
||||||
try:
|
|
||||||
success = await self.bridge.start_agent(self.agent_id, {
|
|
||||||
"type": "compliance",
|
|
||||||
"capabilities": ["kyc_check", "aml_screening", "regulatory_reporting"],
|
|
||||||
"endpoint": f"http://localhost:8006"
|
|
||||||
})
|
|
||||||
|
|
||||||
if success:
|
|
||||||
self.is_running = True
|
|
||||||
print(f"Compliance agent {self.agent_id} started successfully")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f"Failed to start compliance agent {self.agent_id}")
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error starting compliance agent: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def stop(self) -> bool:
|
|
||||||
"""Stop compliance agent"""
|
|
||||||
self.is_running = False
|
|
||||||
success = await self.bridge.stop_agent(self.agent_id)
|
|
||||||
if success:
|
|
||||||
print(f"Compliance agent {self.agent_id} stopped successfully")
|
|
||||||
return success
|
|
||||||
|
|
||||||
async def run_compliance_loop(self):
|
|
||||||
"""Main compliance monitoring loop"""
|
|
||||||
while self.is_running:
|
|
||||||
try:
|
|
||||||
for entity in self.monitored_entities:
|
|
||||||
await self._perform_compliance_check(entity)
|
|
||||||
|
|
||||||
await asyncio.sleep(self.check_interval)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error in compliance loop: {e}")
|
|
||||||
await asyncio.sleep(30) # Wait before retrying
|
|
||||||
|
|
||||||
async def _perform_compliance_check(self, entity_id: str) -> None:
|
|
||||||
"""Perform compliance check for entity"""
|
|
||||||
try:
|
|
||||||
compliance_task = {
|
|
||||||
"type": "compliance_check",
|
|
||||||
"user_id": entity_id,
|
|
||||||
"check_type": "full",
|
|
||||||
"monitored_activities": ["trading", "transfers", "wallet_creation"]
|
|
||||||
}
|
|
||||||
|
|
||||||
result = await self.bridge.execute_agent_task(self.agent_id, compliance_task)
|
|
||||||
|
|
||||||
if result.get("status") == "success":
|
|
||||||
compliance_result = result["result"]
|
|
||||||
await self._handle_compliance_result(entity_id, compliance_result)
|
|
||||||
else:
|
|
||||||
print(f"Compliance check failed for {entity_id}: {result}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error performing compliance check for {entity_id}: {e}")
|
|
||||||
|
|
||||||
async def _handle_compliance_result(self, entity_id: str, result: Dict[str, Any]) -> None:
|
|
||||||
"""Handle compliance check result"""
|
|
||||||
status = result.get("status", "unknown")
|
|
||||||
|
|
||||||
if status == "passed":
|
|
||||||
print(f"✅ Compliance check passed for {entity_id}")
|
|
||||||
elif status == "failed":
|
|
||||||
print(f"❌ Compliance check failed for {entity_id}")
|
|
||||||
# Trigger alert or further investigation
|
|
||||||
await self._trigger_compliance_alert(entity_id, result)
|
|
||||||
else:
|
|
||||||
print(f"⚠️ Compliance check inconclusive for {entity_id}")
|
|
||||||
|
|
||||||
async def _trigger_compliance_alert(self, entity_id: str, result: Dict[str, Any]) -> None:
|
|
||||||
"""Trigger compliance alert"""
|
|
||||||
alert_data = {
|
|
||||||
"entity_id": entity_id,
|
|
||||||
"alert_type": "compliance_failure",
|
|
||||||
"severity": "high",
|
|
||||||
"details": result,
|
|
||||||
"timestamp": datetime.utcnow().isoformat()
|
|
||||||
}
|
|
||||||
|
|
||||||
# In a real implementation, this would send to alert system
|
|
||||||
print(f"🚨 COMPLIANCE ALERT: {json.dumps(alert_data, indent=2)}")
|
|
||||||
|
|
||||||
async def get_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get agent status"""
|
|
||||||
status = await self.bridge.get_agent_status(self.agent_id)
|
|
||||||
status["monitored_entities"] = len(self.monitored_entities)
|
|
||||||
status["check_interval"] = self.check_interval
|
|
||||||
return status
|
|
||||||
|
|
||||||
# Main execution
|
|
||||||
async def main():
|
|
||||||
"""Main compliance agent execution"""
|
|
||||||
agent_id = "compliance-agent-001"
|
|
||||||
config = {
|
|
||||||
"check_interval": 60, # 1 minute for testing
|
|
||||||
"monitored_entities": ["user001", "user002", "user003"]
|
|
||||||
}
|
|
||||||
|
|
||||||
agent = ComplianceAgent(agent_id, config)
|
|
||||||
|
|
||||||
# Start agent
|
|
||||||
if await agent.start():
|
|
||||||
try:
|
|
||||||
# Run compliance loop
|
|
||||||
await agent.run_compliance_loop()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("Shutting down compliance agent...")
|
|
||||||
finally:
|
|
||||||
await agent.stop()
|
|
||||||
else:
|
|
||||||
print("Failed to start compliance agent")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
asyncio.run(main())
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Agent Coordinator Service
|
|
||||||
Agent task coordination and management
|
|
||||||
"""
|
|
||||||
|
|
||||||
from fastapi import FastAPI, HTTPException
|
|
||||||
from pydantic import BaseModel
|
|
||||||
from typing import List, Optional, Dict, Any
|
|
||||||
import json
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime
|
|
||||||
import sqlite3
|
|
||||||
from contextlib import contextmanager
|
|
||||||
from contextlib import asynccontextmanager
|
|
||||||
|
|
||||||
@asynccontextmanager
|
|
||||||
async def lifespan(app: FastAPI):
|
|
||||||
# Startup
|
|
||||||
init_db()
|
|
||||||
yield
|
|
||||||
# Shutdown (cleanup if needed)
|
|
||||||
pass
|
|
||||||
|
|
||||||
app = FastAPI(title="AITBC Agent Coordinator API", version="1.0.0", lifespan=lifespan)
|
|
||||||
|
|
||||||
# Database setup
|
|
||||||
def get_db():
|
|
||||||
conn = sqlite3.connect('agent_coordinator.db')
|
|
||||||
conn.row_factory = sqlite3.Row
|
|
||||||
return conn
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def get_db_connection():
|
|
||||||
conn = get_db()
|
|
||||||
try:
|
|
||||||
yield conn
|
|
||||||
finally:
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
# Initialize database
|
|
||||||
def init_db():
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
CREATE TABLE IF NOT EXISTS tasks (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
task_type TEXT NOT NULL,
|
|
||||||
payload TEXT NOT NULL,
|
|
||||||
required_capabilities TEXT NOT NULL,
|
|
||||||
priority TEXT NOT NULL,
|
|
||||||
status TEXT NOT NULL,
|
|
||||||
assigned_agent_id TEXT,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
result TEXT
|
|
||||||
)
|
|
||||||
''')
|
|
||||||
|
|
||||||
# Models
|
|
||||||
class Task(BaseModel):
|
|
||||||
id: str
|
|
||||||
task_type: str
|
|
||||||
payload: Dict[str, Any]
|
|
||||||
required_capabilities: List[str]
|
|
||||||
priority: str
|
|
||||||
status: str
|
|
||||||
assigned_agent_id: Optional[str] = None
|
|
||||||
|
|
||||||
class TaskCreation(BaseModel):
|
|
||||||
task_type: str
|
|
||||||
payload: Dict[str, Any]
|
|
||||||
required_capabilities: List[str]
|
|
||||||
priority: str = "normal"
|
|
||||||
|
|
||||||
# API Endpoints
|
|
||||||
|
|
||||||
@app.post("/api/tasks", response_model=Task)
|
|
||||||
async def create_task(task: TaskCreation):
|
|
||||||
"""Create a new task"""
|
|
||||||
task_id = str(uuid.uuid4())
|
|
||||||
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
INSERT INTO tasks (id, task_type, payload, required_capabilities, priority, status)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?)
|
|
||||||
''', (
|
|
||||||
task_id, task.task_type, json.dumps(task.payload),
|
|
||||||
json.dumps(task.required_capabilities), task.priority, "pending"
|
|
||||||
))
|
|
||||||
|
|
||||||
return Task(
|
|
||||||
id=task_id,
|
|
||||||
task_type=task.task_type,
|
|
||||||
payload=task.payload,
|
|
||||||
required_capabilities=task.required_capabilities,
|
|
||||||
priority=task.priority,
|
|
||||||
status="pending"
|
|
||||||
)
|
|
||||||
|
|
||||||
@app.get("/api/tasks", response_model=List[Task])
|
|
||||||
async def list_tasks(status: Optional[str] = None):
|
|
||||||
"""List tasks with optional status filter"""
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
query = "SELECT * FROM tasks"
|
|
||||||
params = []
|
|
||||||
|
|
||||||
if status:
|
|
||||||
query += " WHERE status = ?"
|
|
||||||
params.append(status)
|
|
||||||
|
|
||||||
tasks = conn.execute(query, params).fetchall()
|
|
||||||
|
|
||||||
return [
|
|
||||||
Task(
|
|
||||||
id=task["id"],
|
|
||||||
task_type=task["task_type"],
|
|
||||||
payload=json.loads(task["payload"]),
|
|
||||||
required_capabilities=json.loads(task["required_capabilities"]),
|
|
||||||
priority=task["priority"],
|
|
||||||
status=task["status"],
|
|
||||||
assigned_agent_id=task["assigned_agent_id"]
|
|
||||||
)
|
|
||||||
for task in tasks
|
|
||||||
]
|
|
||||||
|
|
||||||
@app.get("/api/health")
|
|
||||||
async def health_check():
|
|
||||||
"""Health check endpoint"""
|
|
||||||
return {"status": "ok", "timestamp": datetime.utcnow()}
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import uvicorn
|
|
||||||
uvicorn.run(app, host="0.0.0.0", port=8012)
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
# AITBC Agent Protocols Environment Configuration
|
|
||||||
# Copy this file to .env and update with your secure values
|
|
||||||
|
|
||||||
# Agent Protocol Encryption Key (generate a strong, unique key)
|
|
||||||
AITBC_AGENT_PROTOCOL_KEY=your-secure-encryption-key-here
|
|
||||||
|
|
||||||
# Agent Protocol Salt (generate a unique salt value)
|
|
||||||
AITBC_AGENT_PROTOCOL_SALT=your-unique-salt-value-here
|
|
||||||
|
|
||||||
# Agent Registry Configuration
|
|
||||||
AGENT_REGISTRY_HOST=0.0.0.0
|
|
||||||
AGENT_REGISTRY_PORT=8003
|
|
||||||
|
|
||||||
# Database Configuration
|
|
||||||
AGENT_REGISTRY_DB_PATH=agent_registry.db
|
|
||||||
|
|
||||||
# Security Settings
|
|
||||||
AGENT_PROTOCOL_TIMEOUT=300
|
|
||||||
AGENT_PROTOCOL_MAX_RETRIES=3
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
"""
|
|
||||||
Agent Protocols Package
|
|
||||||
"""
|
|
||||||
|
|
||||||
from .message_protocol import MessageProtocol, MessageTypes, AgentMessageClient
|
|
||||||
from .task_manager import TaskManager, TaskStatus, TaskPriority, Task
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
"MessageProtocol",
|
|
||||||
"MessageTypes",
|
|
||||||
"AgentMessageClient",
|
|
||||||
"TaskManager",
|
|
||||||
"TaskStatus",
|
|
||||||
"TaskPriority",
|
|
||||||
"Task"
|
|
||||||
]
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
"""
|
|
||||||
Message Protocol for AITBC Agents
|
|
||||||
Handles message creation, routing, and delivery between agents
|
|
||||||
"""
|
|
||||||
|
|
||||||
import json
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime
|
|
||||||
from typing import Dict, Any, Optional, List
|
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
class MessageTypes(Enum):
|
|
||||||
"""Message type enumeration"""
|
|
||||||
TASK_REQUEST = "task_request"
|
|
||||||
TASK_RESPONSE = "task_response"
|
|
||||||
HEARTBEAT = "heartbeat"
|
|
||||||
STATUS_UPDATE = "status_update"
|
|
||||||
ERROR = "error"
|
|
||||||
DATA = "data"
|
|
||||||
|
|
||||||
class MessageProtocol:
|
|
||||||
"""Message protocol handler for agent communication"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.messages = []
|
|
||||||
self.message_handlers = {}
|
|
||||||
|
|
||||||
def create_message(
|
|
||||||
self,
|
|
||||||
sender_id: str,
|
|
||||||
receiver_id: str,
|
|
||||||
message_type: MessageTypes,
|
|
||||||
content: Dict[str, Any],
|
|
||||||
message_id: Optional[str] = None
|
|
||||||
) -> Dict[str, Any]:
|
|
||||||
"""Create a new message"""
|
|
||||||
if message_id is None:
|
|
||||||
message_id = str(uuid.uuid4())
|
|
||||||
|
|
||||||
message = {
|
|
||||||
"message_id": message_id,
|
|
||||||
"sender_id": sender_id,
|
|
||||||
"receiver_id": receiver_id,
|
|
||||||
"message_type": message_type.value,
|
|
||||||
"content": content,
|
|
||||||
"timestamp": datetime.utcnow().isoformat(),
|
|
||||||
"status": "pending"
|
|
||||||
}
|
|
||||||
|
|
||||||
self.messages.append(message)
|
|
||||||
return message
|
|
||||||
|
|
||||||
def send_message(self, message: Dict[str, Any]) -> bool:
|
|
||||||
"""Send a message to the receiver"""
|
|
||||||
try:
|
|
||||||
message["status"] = "sent"
|
|
||||||
message["sent_timestamp"] = datetime.utcnow().isoformat()
|
|
||||||
return True
|
|
||||||
except Exception:
|
|
||||||
message["status"] = "failed"
|
|
||||||
return False
|
|
||||||
|
|
||||||
def receive_message(self, message_id: str) -> Optional[Dict[str, Any]]:
|
|
||||||
"""Receive and process a message"""
|
|
||||||
for message in self.messages:
|
|
||||||
if message["message_id"] == message_id:
|
|
||||||
message["status"] = "received"
|
|
||||||
message["received_timestamp"] = datetime.utcnow().isoformat()
|
|
||||||
return message
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_messages_by_agent(self, agent_id: str) -> List[Dict[str, Any]]:
|
|
||||||
"""Get all messages for a specific agent"""
|
|
||||||
return [
|
|
||||||
msg for msg in self.messages
|
|
||||||
if msg["sender_id"] == agent_id or msg["receiver_id"] == agent_id
|
|
||||||
]
|
|
||||||
|
|
||||||
class AgentMessageClient:
|
|
||||||
"""Client for agent message communication"""
|
|
||||||
|
|
||||||
def __init__(self, agent_id: str, protocol: MessageProtocol):
|
|
||||||
self.agent_id = agent_id
|
|
||||||
self.protocol = protocol
|
|
||||||
self.received_messages = []
|
|
||||||
|
|
||||||
def send_message(
|
|
||||||
self,
|
|
||||||
receiver_id: str,
|
|
||||||
message_type: MessageTypes,
|
|
||||||
content: Dict[str, Any]
|
|
||||||
) -> Dict[str, Any]:
|
|
||||||
"""Send a message to another agent"""
|
|
||||||
message = self.protocol.create_message(
|
|
||||||
sender_id=self.agent_id,
|
|
||||||
receiver_id=receiver_id,
|
|
||||||
message_type=message_type,
|
|
||||||
content=content
|
|
||||||
)
|
|
||||||
self.protocol.send_message(message)
|
|
||||||
return message
|
|
||||||
|
|
||||||
def receive_messages(self) -> List[Dict[str, Any]]:
|
|
||||||
"""Receive all pending messages for this agent"""
|
|
||||||
messages = []
|
|
||||||
for message in self.protocol.messages:
|
|
||||||
if (message["receiver_id"] == self.agent_id and
|
|
||||||
message["status"] == "sent" and
|
|
||||||
message not in self.received_messages):
|
|
||||||
self.protocol.receive_message(message["message_id"])
|
|
||||||
self.received_messages.append(message)
|
|
||||||
messages.append(message)
|
|
||||||
return messages
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
"""
|
|
||||||
Task Manager for AITBC Agents
|
|
||||||
Handles task creation, assignment, and tracking
|
|
||||||
"""
|
|
||||||
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
from typing import Dict, Any, Optional, List
|
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
class TaskStatus(Enum):
|
|
||||||
"""Task status enumeration"""
|
|
||||||
PENDING = "pending"
|
|
||||||
IN_PROGRESS = "in_progress"
|
|
||||||
COMPLETED = "completed"
|
|
||||||
FAILED = "failed"
|
|
||||||
CANCELLED = "cancelled"
|
|
||||||
|
|
||||||
class TaskPriority(Enum):
|
|
||||||
"""Task priority enumeration"""
|
|
||||||
LOW = "low"
|
|
||||||
MEDIUM = "medium"
|
|
||||||
HIGH = "high"
|
|
||||||
URGENT = "urgent"
|
|
||||||
|
|
||||||
class Task:
|
|
||||||
"""Task representation"""
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
task_id: str,
|
|
||||||
title: str,
|
|
||||||
description: str,
|
|
||||||
assigned_to: str,
|
|
||||||
priority: TaskPriority = TaskPriority.MEDIUM,
|
|
||||||
created_by: Optional[str] = None
|
|
||||||
):
|
|
||||||
self.task_id = task_id
|
|
||||||
self.title = title
|
|
||||||
self.description = description
|
|
||||||
self.assigned_to = assigned_to
|
|
||||||
self.priority = priority
|
|
||||||
self.created_by = created_by or assigned_to
|
|
||||||
self.status = TaskStatus.PENDING
|
|
||||||
self.created_at = datetime.utcnow()
|
|
||||||
self.updated_at = datetime.utcnow()
|
|
||||||
self.completed_at = None
|
|
||||||
self.result = None
|
|
||||||
self.error = None
|
|
||||||
|
|
||||||
class TaskManager:
|
|
||||||
"""Task manager for agent coordination"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.tasks = {}
|
|
||||||
self.task_history = []
|
|
||||||
|
|
||||||
def create_task(
|
|
||||||
self,
|
|
||||||
title: str,
|
|
||||||
description: str,
|
|
||||||
assigned_to: str,
|
|
||||||
priority: TaskPriority = TaskPriority.MEDIUM,
|
|
||||||
created_by: Optional[str] = None
|
|
||||||
) -> Task:
|
|
||||||
"""Create a new task"""
|
|
||||||
task_id = str(uuid.uuid4())
|
|
||||||
task = Task(
|
|
||||||
task_id=task_id,
|
|
||||||
title=title,
|
|
||||||
description=description,
|
|
||||||
assigned_to=assigned_to,
|
|
||||||
priority=priority,
|
|
||||||
created_by=created_by
|
|
||||||
)
|
|
||||||
|
|
||||||
self.tasks[task_id] = task
|
|
||||||
return task
|
|
||||||
|
|
||||||
def get_task(self, task_id: str) -> Optional[Task]:
|
|
||||||
"""Get a task by ID"""
|
|
||||||
return self.tasks.get(task_id)
|
|
||||||
|
|
||||||
def update_task_status(
|
|
||||||
self,
|
|
||||||
task_id: str,
|
|
||||||
status: TaskStatus,
|
|
||||||
result: Optional[Dict[str, Any]] = None,
|
|
||||||
error: Optional[str] = None
|
|
||||||
) -> bool:
|
|
||||||
"""Update task status"""
|
|
||||||
task = self.get_task(task_id)
|
|
||||||
if not task:
|
|
||||||
return False
|
|
||||||
|
|
||||||
task.status = status
|
|
||||||
task.updated_at = datetime.utcnow()
|
|
||||||
|
|
||||||
if status == TaskStatus.COMPLETED:
|
|
||||||
task.completed_at = datetime.utcnow()
|
|
||||||
task.result = result
|
|
||||||
elif status == TaskStatus.FAILED:
|
|
||||||
task.error = error
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def get_tasks_by_agent(self, agent_id: str) -> List[Task]:
|
|
||||||
"""Get all tasks assigned to an agent"""
|
|
||||||
return [
|
|
||||||
task for task in self.tasks.values()
|
|
||||||
if task.assigned_to == agent_id
|
|
||||||
]
|
|
||||||
|
|
||||||
def get_tasks_by_status(self, status: TaskStatus) -> List[Task]:
|
|
||||||
"""Get all tasks with a specific status"""
|
|
||||||
return [
|
|
||||||
task for task in self.tasks.values()
|
|
||||||
if task.status == status
|
|
||||||
]
|
|
||||||
|
|
||||||
def get_overdue_tasks(self, hours: int = 24) -> List[Task]:
|
|
||||||
"""Get tasks that are overdue"""
|
|
||||||
cutoff_time = datetime.utcnow() - timedelta(hours=hours)
|
|
||||||
return [
|
|
||||||
task for task in self.tasks.values()
|
|
||||||
if task.status in [TaskStatus.PENDING, TaskStatus.IN_PROGRESS] and
|
|
||||||
task.created_at < cutoff_time
|
|
||||||
]
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Agent Registry Service
|
|
||||||
Central agent discovery and registration system
|
|
||||||
"""
|
|
||||||
|
|
||||||
from fastapi import FastAPI, HTTPException, Depends
|
|
||||||
from pydantic import BaseModel
|
|
||||||
from typing import List, Optional, Dict, Any
|
|
||||||
import json
|
|
||||||
import time
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
import sqlite3
|
|
||||||
from contextlib import contextmanager
|
|
||||||
from contextlib import asynccontextmanager
|
|
||||||
|
|
||||||
@asynccontextmanager
|
|
||||||
async def lifespan(app: FastAPI):
|
|
||||||
# Startup
|
|
||||||
init_db()
|
|
||||||
yield
|
|
||||||
# Shutdown (cleanup if needed)
|
|
||||||
pass
|
|
||||||
|
|
||||||
app = FastAPI(title="AITBC Agent Registry API", version="1.0.0", lifespan=lifespan)
|
|
||||||
|
|
||||||
# Database setup
|
|
||||||
def get_db():
|
|
||||||
conn = sqlite3.connect('agent_registry.db')
|
|
||||||
conn.row_factory = sqlite3.Row
|
|
||||||
return conn
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def get_db_connection():
|
|
||||||
conn = get_db()
|
|
||||||
try:
|
|
||||||
yield conn
|
|
||||||
finally:
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
# Initialize database
|
|
||||||
def init_db():
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
CREATE TABLE IF NOT EXISTS agents (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
name TEXT NOT NULL,
|
|
||||||
type TEXT NOT NULL,
|
|
||||||
capabilities TEXT NOT NULL,
|
|
||||||
chain_id TEXT NOT NULL,
|
|
||||||
endpoint TEXT NOT NULL,
|
|
||||||
status TEXT DEFAULT 'active',
|
|
||||||
last_heartbeat TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
metadata TEXT,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
||||||
)
|
|
||||||
''')
|
|
||||||
|
|
||||||
# Models
|
|
||||||
class Agent(BaseModel):
|
|
||||||
id: str
|
|
||||||
name: str
|
|
||||||
type: str
|
|
||||||
capabilities: List[str]
|
|
||||||
chain_id: str
|
|
||||||
endpoint: str
|
|
||||||
metadata: Optional[Dict[str, Any]] = {}
|
|
||||||
|
|
||||||
class AgentRegistration(BaseModel):
|
|
||||||
name: str
|
|
||||||
type: str
|
|
||||||
capabilities: List[str]
|
|
||||||
chain_id: str
|
|
||||||
endpoint: str
|
|
||||||
metadata: Optional[Dict[str, Any]] = {}
|
|
||||||
|
|
||||||
# API Endpoints
|
|
||||||
|
|
||||||
@app.post("/api/agents/register", response_model=Agent)
|
|
||||||
async def register_agent(agent: AgentRegistration):
|
|
||||||
"""Register a new agent"""
|
|
||||||
agent_id = str(uuid.uuid4())
|
|
||||||
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
INSERT INTO agents (id, name, type, capabilities, chain_id, endpoint, metadata)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
||||||
''', (
|
|
||||||
agent_id, agent.name, agent.type,
|
|
||||||
json.dumps(agent.capabilities), agent.chain_id,
|
|
||||||
agent.endpoint, json.dumps(agent.metadata)
|
|
||||||
))
|
|
||||||
conn.commit()
|
|
||||||
|
|
||||||
return Agent(
|
|
||||||
id=agent_id,
|
|
||||||
name=agent.name,
|
|
||||||
type=agent.type,
|
|
||||||
capabilities=agent.capabilities,
|
|
||||||
chain_id=agent.chain_id,
|
|
||||||
endpoint=agent.endpoint,
|
|
||||||
metadata=agent.metadata
|
|
||||||
)
|
|
||||||
|
|
||||||
@app.get("/api/agents", response_model=List[Agent])
|
|
||||||
async def list_agents(
|
|
||||||
agent_type: Optional[str] = None,
|
|
||||||
chain_id: Optional[str] = None,
|
|
||||||
capability: Optional[str] = None
|
|
||||||
):
|
|
||||||
"""List registered agents with optional filters"""
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
query = "SELECT * FROM agents WHERE status = 'active'"
|
|
||||||
params = []
|
|
||||||
|
|
||||||
if agent_type:
|
|
||||||
query += " AND type = ?"
|
|
||||||
params.append(agent_type)
|
|
||||||
|
|
||||||
if chain_id:
|
|
||||||
query += " AND chain_id = ?"
|
|
||||||
params.append(chain_id)
|
|
||||||
|
|
||||||
if capability:
|
|
||||||
query += " AND capabilities LIKE ?"
|
|
||||||
params.append(f'%{capability}%')
|
|
||||||
|
|
||||||
agents = conn.execute(query, params).fetchall()
|
|
||||||
|
|
||||||
return [
|
|
||||||
Agent(
|
|
||||||
id=agent["id"],
|
|
||||||
name=agent["name"],
|
|
||||||
type=agent["type"],
|
|
||||||
capabilities=json.loads(agent["capabilities"]),
|
|
||||||
chain_id=agent["chain_id"],
|
|
||||||
endpoint=agent["endpoint"],
|
|
||||||
metadata=json.loads(agent["metadata"] or "{}")
|
|
||||||
)
|
|
||||||
for agent in agents
|
|
||||||
]
|
|
||||||
|
|
||||||
@app.get("/api/health")
|
|
||||||
async def health_check():
|
|
||||||
"""Health check endpoint"""
|
|
||||||
return {"status": "ok", "timestamp": datetime.utcnow()}
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import uvicorn
|
|
||||||
uvicorn.run(app, host="0.0.0.0", port=8013)
|
|
||||||
@@ -1,431 +0,0 @@
|
|||||||
"""
|
|
||||||
Agent Registration System
|
|
||||||
Handles AI agent registration, capability management, and discovery
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import time
|
|
||||||
import json
|
|
||||||
import hashlib
|
|
||||||
from typing import Dict, List, Optional, Set, Tuple
|
|
||||||
from dataclasses import dataclass, asdict
|
|
||||||
from enum import Enum
|
|
||||||
from decimal import Decimal
|
|
||||||
|
|
||||||
class AgentType(Enum):
|
|
||||||
AI_MODEL = "ai_model"
|
|
||||||
DATA_PROVIDER = "data_provider"
|
|
||||||
VALIDATOR = "validator"
|
|
||||||
MARKET_MAKER = "market_maker"
|
|
||||||
BROKER = "broker"
|
|
||||||
ORACLE = "oracle"
|
|
||||||
|
|
||||||
class AgentStatus(Enum):
|
|
||||||
REGISTERED = "registered"
|
|
||||||
ACTIVE = "active"
|
|
||||||
INACTIVE = "inactive"
|
|
||||||
SUSPENDED = "suspended"
|
|
||||||
BANNED = "banned"
|
|
||||||
|
|
||||||
class CapabilityType(Enum):
|
|
||||||
TEXT_GENERATION = "text_generation"
|
|
||||||
IMAGE_GENERATION = "image_generation"
|
|
||||||
DATA_ANALYSIS = "data_analysis"
|
|
||||||
PREDICTION = "prediction"
|
|
||||||
VALIDATION = "validation"
|
|
||||||
COMPUTATION = "computation"
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class AgentCapability:
|
|
||||||
capability_type: CapabilityType
|
|
||||||
name: str
|
|
||||||
version: str
|
|
||||||
parameters: Dict
|
|
||||||
performance_metrics: Dict
|
|
||||||
cost_per_use: Decimal
|
|
||||||
availability: float
|
|
||||||
max_concurrent_jobs: int
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class AgentInfo:
|
|
||||||
agent_id: str
|
|
||||||
agent_type: AgentType
|
|
||||||
name: str
|
|
||||||
owner_address: str
|
|
||||||
public_key: str
|
|
||||||
endpoint_url: str
|
|
||||||
capabilities: List[AgentCapability]
|
|
||||||
reputation_score: float
|
|
||||||
total_jobs_completed: int
|
|
||||||
total_earnings: Decimal
|
|
||||||
registration_time: float
|
|
||||||
last_active: float
|
|
||||||
status: AgentStatus
|
|
||||||
metadata: Dict
|
|
||||||
|
|
||||||
class AgentRegistry:
|
|
||||||
"""Manages AI agent registration and discovery"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.agents: Dict[str, AgentInfo] = {}
|
|
||||||
self.capability_index: Dict[CapabilityType, Set[str]] = {} # capability -> agent_ids
|
|
||||||
self.type_index: Dict[AgentType, Set[str]] = {} # agent_type -> agent_ids
|
|
||||||
self.reputation_scores: Dict[str, float] = {}
|
|
||||||
self.registration_queue: List[Dict] = []
|
|
||||||
|
|
||||||
# Registry parameters
|
|
||||||
self.min_reputation_threshold = 0.5
|
|
||||||
self.max_agents_per_type = 1000
|
|
||||||
self.registration_fee = Decimal('100.0')
|
|
||||||
self.inactivity_threshold = 86400 * 7 # 7 days
|
|
||||||
|
|
||||||
# Initialize capability index
|
|
||||||
for capability_type in CapabilityType:
|
|
||||||
self.capability_index[capability_type] = set()
|
|
||||||
|
|
||||||
# Initialize type index
|
|
||||||
for agent_type in AgentType:
|
|
||||||
self.type_index[agent_type] = set()
|
|
||||||
|
|
||||||
async def register_agent(self, agent_type: AgentType, name: str, owner_address: str,
|
|
||||||
public_key: str, endpoint_url: str, capabilities: List[Dict],
|
|
||||||
metadata: Dict = None) -> Tuple[bool, str, Optional[str]]:
|
|
||||||
"""Register a new AI agent"""
|
|
||||||
try:
|
|
||||||
# Validate inputs
|
|
||||||
if not self._validate_registration_inputs(agent_type, name, owner_address, public_key, endpoint_url):
|
|
||||||
return False, "Invalid registration inputs", None
|
|
||||||
|
|
||||||
# Check if agent already exists
|
|
||||||
agent_id = self._generate_agent_id(owner_address, name)
|
|
||||||
if agent_id in self.agents:
|
|
||||||
return False, "Agent already registered", None
|
|
||||||
|
|
||||||
# Check type limits
|
|
||||||
if len(self.type_index[agent_type]) >= self.max_agents_per_type:
|
|
||||||
return False, f"Maximum agents of type {agent_type.value} reached", None
|
|
||||||
|
|
||||||
# Convert capabilities
|
|
||||||
agent_capabilities = []
|
|
||||||
for cap_data in capabilities:
|
|
||||||
capability = self._create_capability_from_data(cap_data)
|
|
||||||
if capability:
|
|
||||||
agent_capabilities.append(capability)
|
|
||||||
|
|
||||||
if not agent_capabilities:
|
|
||||||
return False, "Agent must have at least one valid capability", None
|
|
||||||
|
|
||||||
# Create agent info
|
|
||||||
agent_info = AgentInfo(
|
|
||||||
agent_id=agent_id,
|
|
||||||
agent_type=agent_type,
|
|
||||||
name=name,
|
|
||||||
owner_address=owner_address,
|
|
||||||
public_key=public_key,
|
|
||||||
endpoint_url=endpoint_url,
|
|
||||||
capabilities=agent_capabilities,
|
|
||||||
reputation_score=1.0, # Start with neutral reputation
|
|
||||||
total_jobs_completed=0,
|
|
||||||
total_earnings=Decimal('0'),
|
|
||||||
registration_time=time.time(),
|
|
||||||
last_active=time.time(),
|
|
||||||
status=AgentStatus.REGISTERED,
|
|
||||||
metadata=metadata or {}
|
|
||||||
)
|
|
||||||
|
|
||||||
# Add to registry
|
|
||||||
self.agents[agent_id] = agent_info
|
|
||||||
|
|
||||||
# Update indexes
|
|
||||||
self.type_index[agent_type].add(agent_id)
|
|
||||||
for capability in agent_capabilities:
|
|
||||||
self.capability_index[capability.capability_type].add(agent_id)
|
|
||||||
|
|
||||||
log_info(f"Agent registered: {agent_id} ({name})")
|
|
||||||
return True, "Registration successful", agent_id
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
return False, f"Registration failed: {str(e)}", None
|
|
||||||
|
|
||||||
def _validate_registration_inputs(self, agent_type: AgentType, name: str,
|
|
||||||
owner_address: str, public_key: str, endpoint_url: str) -> bool:
|
|
||||||
"""Validate registration inputs"""
|
|
||||||
# Check required fields
|
|
||||||
if not all([agent_type, name, owner_address, public_key, endpoint_url]):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Validate address format (simplified)
|
|
||||||
if not owner_address.startswith('0x') or len(owner_address) != 42:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Validate URL format (simplified)
|
|
||||||
if not endpoint_url.startswith(('http://', 'https://')):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Validate name
|
|
||||||
if len(name) < 3 or len(name) > 100:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def _generate_agent_id(self, owner_address: str, name: str) -> str:
|
|
||||||
"""Generate unique agent ID"""
|
|
||||||
content = f"{owner_address}:{name}:{time.time()}"
|
|
||||||
return hashlib.sha256(content.encode()).hexdigest()[:16]
|
|
||||||
|
|
||||||
def _create_capability_from_data(self, cap_data: Dict) -> Optional[AgentCapability]:
|
|
||||||
"""Create capability from data dictionary"""
|
|
||||||
try:
|
|
||||||
# Validate required fields
|
|
||||||
required_fields = ['type', 'name', 'version', 'cost_per_use']
|
|
||||||
if not all(field in cap_data for field in required_fields):
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Parse capability type
|
|
||||||
try:
|
|
||||||
capability_type = CapabilityType(cap_data['type'])
|
|
||||||
except ValueError:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Create capability
|
|
||||||
return AgentCapability(
|
|
||||||
capability_type=capability_type,
|
|
||||||
name=cap_data['name'],
|
|
||||||
version=cap_data['version'],
|
|
||||||
parameters=cap_data.get('parameters', {}),
|
|
||||||
performance_metrics=cap_data.get('performance_metrics', {}),
|
|
||||||
cost_per_use=Decimal(str(cap_data['cost_per_use'])),
|
|
||||||
availability=cap_data.get('availability', 1.0),
|
|
||||||
max_concurrent_jobs=cap_data.get('max_concurrent_jobs', 1)
|
|
||||||
)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
log_error(f"Error creating capability: {e}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
async def update_agent_status(self, agent_id: str, status: AgentStatus) -> Tuple[bool, str]:
|
|
||||||
"""Update agent status"""
|
|
||||||
if agent_id not in self.agents:
|
|
||||||
return False, "Agent not found"
|
|
||||||
|
|
||||||
agent = self.agents[agent_id]
|
|
||||||
old_status = agent.status
|
|
||||||
agent.status = status
|
|
||||||
agent.last_active = time.time()
|
|
||||||
|
|
||||||
log_info(f"Agent {agent_id} status changed: {old_status.value} -> {status.value}")
|
|
||||||
return True, "Status updated successfully"
|
|
||||||
|
|
||||||
async def update_agent_capabilities(self, agent_id: str, capabilities: List[Dict]) -> Tuple[bool, str]:
|
|
||||||
"""Update agent capabilities"""
|
|
||||||
if agent_id not in self.agents:
|
|
||||||
return False, "Agent not found"
|
|
||||||
|
|
||||||
agent = self.agents[agent_id]
|
|
||||||
|
|
||||||
# Remove old capabilities from index
|
|
||||||
for old_capability in agent.capabilities:
|
|
||||||
self.capability_index[old_capability.capability_type].discard(agent_id)
|
|
||||||
|
|
||||||
# Add new capabilities
|
|
||||||
new_capabilities = []
|
|
||||||
for cap_data in capabilities:
|
|
||||||
capability = self._create_capability_from_data(cap_data)
|
|
||||||
if capability:
|
|
||||||
new_capabilities.append(capability)
|
|
||||||
self.capability_index[capability.capability_type].add(agent_id)
|
|
||||||
|
|
||||||
if not new_capabilities:
|
|
||||||
return False, "No valid capabilities provided"
|
|
||||||
|
|
||||||
agent.capabilities = new_capabilities
|
|
||||||
agent.last_active = time.time()
|
|
||||||
|
|
||||||
return True, "Capabilities updated successfully"
|
|
||||||
|
|
||||||
async def find_agents_by_capability(self, capability_type: CapabilityType,
|
|
||||||
filters: Dict = None) -> List[AgentInfo]:
|
|
||||||
"""Find agents by capability type"""
|
|
||||||
agent_ids = self.capability_index.get(capability_type, set())
|
|
||||||
|
|
||||||
agents = []
|
|
||||||
for agent_id in agent_ids:
|
|
||||||
agent = self.agents.get(agent_id)
|
|
||||||
if agent and agent.status == AgentStatus.ACTIVE:
|
|
||||||
if self._matches_filters(agent, filters):
|
|
||||||
agents.append(agent)
|
|
||||||
|
|
||||||
# Sort by reputation (highest first)
|
|
||||||
agents.sort(key=lambda x: x.reputation_score, reverse=True)
|
|
||||||
return agents
|
|
||||||
|
|
||||||
async def find_agents_by_type(self, agent_type: AgentType, filters: Dict = None) -> List[AgentInfo]:
|
|
||||||
"""Find agents by type"""
|
|
||||||
agent_ids = self.type_index.get(agent_type, set())
|
|
||||||
|
|
||||||
agents = []
|
|
||||||
for agent_id in agent_ids:
|
|
||||||
agent = self.agents.get(agent_id)
|
|
||||||
if agent and agent.status == AgentStatus.ACTIVE:
|
|
||||||
if self._matches_filters(agent, filters):
|
|
||||||
agents.append(agent)
|
|
||||||
|
|
||||||
# Sort by reputation (highest first)
|
|
||||||
agents.sort(key=lambda x: x.reputation_score, reverse=True)
|
|
||||||
return agents
|
|
||||||
|
|
||||||
def _matches_filters(self, agent: AgentInfo, filters: Dict) -> bool:
|
|
||||||
"""Check if agent matches filters"""
|
|
||||||
if not filters:
|
|
||||||
return True
|
|
||||||
|
|
||||||
# Reputation filter
|
|
||||||
if 'min_reputation' in filters:
|
|
||||||
if agent.reputation_score < filters['min_reputation']:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Cost filter
|
|
||||||
if 'max_cost_per_use' in filters:
|
|
||||||
max_cost = Decimal(str(filters['max_cost_per_use']))
|
|
||||||
if any(cap.cost_per_use > max_cost for cap in agent.capabilities):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Availability filter
|
|
||||||
if 'min_availability' in filters:
|
|
||||||
min_availability = filters['min_availability']
|
|
||||||
if any(cap.availability < min_availability for cap in agent.capabilities):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Location filter (if implemented)
|
|
||||||
if 'location' in filters:
|
|
||||||
agent_location = agent.metadata.get('location')
|
|
||||||
if agent_location != filters['location']:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
async def get_agent_info(self, agent_id: str) -> Optional[AgentInfo]:
|
|
||||||
"""Get agent information"""
|
|
||||||
return self.agents.get(agent_id)
|
|
||||||
|
|
||||||
async def search_agents(self, query: str, limit: int = 50) -> List[AgentInfo]:
|
|
||||||
"""Search agents by name or capability"""
|
|
||||||
query_lower = query.lower()
|
|
||||||
results = []
|
|
||||||
|
|
||||||
for agent in self.agents.values():
|
|
||||||
if agent.status != AgentStatus.ACTIVE:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Search in name
|
|
||||||
if query_lower in agent.name.lower():
|
|
||||||
results.append(agent)
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Search in capabilities
|
|
||||||
for capability in agent.capabilities:
|
|
||||||
if (query_lower in capability.name.lower() or
|
|
||||||
query_lower in capability.capability_type.value):
|
|
||||||
results.append(agent)
|
|
||||||
break
|
|
||||||
|
|
||||||
# Sort by relevance (reputation)
|
|
||||||
results.sort(key=lambda x: x.reputation_score, reverse=True)
|
|
||||||
return results[:limit]
|
|
||||||
|
|
||||||
async def get_agent_statistics(self, agent_id: str) -> Optional[Dict]:
|
|
||||||
"""Get detailed statistics for an agent"""
|
|
||||||
agent = self.agents.get(agent_id)
|
|
||||||
if not agent:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Calculate additional statistics
|
|
||||||
avg_job_earnings = agent.total_earnings / agent.total_jobs_completed if agent.total_jobs_completed > 0 else Decimal('0')
|
|
||||||
days_active = (time.time() - agent.registration_time) / 86400
|
|
||||||
jobs_per_day = agent.total_jobs_completed / days_active if days_active > 0 else 0
|
|
||||||
|
|
||||||
return {
|
|
||||||
'agent_id': agent_id,
|
|
||||||
'name': agent.name,
|
|
||||||
'type': agent.agent_type.value,
|
|
||||||
'status': agent.status.value,
|
|
||||||
'reputation_score': agent.reputation_score,
|
|
||||||
'total_jobs_completed': agent.total_jobs_completed,
|
|
||||||
'total_earnings': float(agent.total_earnings),
|
|
||||||
'avg_job_earnings': float(avg_job_earnings),
|
|
||||||
'jobs_per_day': jobs_per_day,
|
|
||||||
'days_active': int(days_active),
|
|
||||||
'capabilities_count': len(agent.capabilities),
|
|
||||||
'last_active': agent.last_active,
|
|
||||||
'registration_time': agent.registration_time
|
|
||||||
}
|
|
||||||
|
|
||||||
async def get_registry_statistics(self) -> Dict:
|
|
||||||
"""Get registry-wide statistics"""
|
|
||||||
total_agents = len(self.agents)
|
|
||||||
active_agents = len([a for a in self.agents.values() if a.status == AgentStatus.ACTIVE])
|
|
||||||
|
|
||||||
# Count by type
|
|
||||||
type_counts = {}
|
|
||||||
for agent_type in AgentType:
|
|
||||||
type_counts[agent_type.value] = len(self.type_index[agent_type])
|
|
||||||
|
|
||||||
# Count by capability
|
|
||||||
capability_counts = {}
|
|
||||||
for capability_type in CapabilityType:
|
|
||||||
capability_counts[capability_type.value] = len(self.capability_index[capability_type])
|
|
||||||
|
|
||||||
# Reputation statistics
|
|
||||||
reputations = [a.reputation_score for a in self.agents.values()]
|
|
||||||
avg_reputation = sum(reputations) / len(reputations) if reputations else 0
|
|
||||||
|
|
||||||
# Earnings statistics
|
|
||||||
total_earnings = sum(a.total_earnings for a in self.agents.values())
|
|
||||||
|
|
||||||
return {
|
|
||||||
'total_agents': total_agents,
|
|
||||||
'active_agents': active_agents,
|
|
||||||
'inactive_agents': total_agents - active_agents,
|
|
||||||
'agent_types': type_counts,
|
|
||||||
'capabilities': capability_counts,
|
|
||||||
'average_reputation': avg_reputation,
|
|
||||||
'total_earnings': float(total_earnings),
|
|
||||||
'registration_fee': float(self.registration_fee)
|
|
||||||
}
|
|
||||||
|
|
||||||
async def cleanup_inactive_agents(self) -> Tuple[int, str]:
|
|
||||||
"""Clean up inactive agents"""
|
|
||||||
current_time = time.time()
|
|
||||||
cleaned_count = 0
|
|
||||||
|
|
||||||
for agent_id, agent in list(self.agents.items()):
|
|
||||||
if (agent.status == AgentStatus.INACTIVE and
|
|
||||||
current_time - agent.last_active > self.inactivity_threshold):
|
|
||||||
|
|
||||||
# Remove from registry
|
|
||||||
del self.agents[agent_id]
|
|
||||||
|
|
||||||
# Update indexes
|
|
||||||
self.type_index[agent.agent_type].discard(agent_id)
|
|
||||||
for capability in agent.capabilities:
|
|
||||||
self.capability_index[capability.capability_type].discard(agent_id)
|
|
||||||
|
|
||||||
cleaned_count += 1
|
|
||||||
|
|
||||||
if cleaned_count > 0:
|
|
||||||
log_info(f"Cleaned up {cleaned_count} inactive agents")
|
|
||||||
|
|
||||||
return cleaned_count, f"Cleaned up {cleaned_count} inactive agents"
|
|
||||||
|
|
||||||
# Global agent registry
|
|
||||||
agent_registry: Optional[AgentRegistry] = None
|
|
||||||
|
|
||||||
def get_agent_registry() -> Optional[AgentRegistry]:
|
|
||||||
"""Get global agent registry"""
|
|
||||||
return agent_registry
|
|
||||||
|
|
||||||
def create_agent_registry() -> AgentRegistry:
|
|
||||||
"""Create and set global agent registry"""
|
|
||||||
global agent_registry
|
|
||||||
agent_registry = AgentRegistry()
|
|
||||||
return agent_registry
|
|
||||||
@@ -1,166 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Trading Agent
|
|
||||||
Automated trading agent for AITBC marketplace
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import json
|
|
||||||
import time
|
|
||||||
from typing import Dict, Any, List
|
|
||||||
from datetime import datetime
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Add parent directory to path
|
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '../../../..'))
|
|
||||||
|
|
||||||
from apps.agent_services.agent_bridge.src.integration_layer import AgentServiceBridge
|
|
||||||
|
|
||||||
class TradingAgent:
|
|
||||||
"""Automated trading agent"""
|
|
||||||
|
|
||||||
def __init__(self, agent_id: str, config: Dict[str, Any]):
|
|
||||||
self.agent_id = agent_id
|
|
||||||
self.config = config
|
|
||||||
self.bridge = AgentServiceBridge()
|
|
||||||
self.is_running = False
|
|
||||||
self.trading_strategy = config.get("strategy", "basic")
|
|
||||||
self.symbols = config.get("symbols", ["AITBC/BTC"])
|
|
||||||
self.trade_interval = config.get("trade_interval", 60) # seconds
|
|
||||||
|
|
||||||
async def start(self) -> bool:
|
|
||||||
"""Start trading agent"""
|
|
||||||
try:
|
|
||||||
# Register with service bridge
|
|
||||||
success = await self.bridge.start_agent(self.agent_id, {
|
|
||||||
"type": "trading",
|
|
||||||
"capabilities": ["market_analysis", "trading", "risk_management"],
|
|
||||||
"endpoint": f"http://localhost:8005"
|
|
||||||
})
|
|
||||||
|
|
||||||
if success:
|
|
||||||
self.is_running = True
|
|
||||||
print(f"Trading agent {self.agent_id} started successfully")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f"Failed to start trading agent {self.agent_id}")
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error starting trading agent: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def stop(self) -> bool:
|
|
||||||
"""Stop trading agent"""
|
|
||||||
self.is_running = False
|
|
||||||
success = await self.bridge.stop_agent(self.agent_id)
|
|
||||||
if success:
|
|
||||||
print(f"Trading agent {self.agent_id} stopped successfully")
|
|
||||||
return success
|
|
||||||
|
|
||||||
async def run_trading_loop(self):
|
|
||||||
"""Main trading loop"""
|
|
||||||
while self.is_running:
|
|
||||||
try:
|
|
||||||
for symbol in self.symbols:
|
|
||||||
await self._analyze_and_trade(symbol)
|
|
||||||
|
|
||||||
await asyncio.sleep(self.trade_interval)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error in trading loop: {e}")
|
|
||||||
await asyncio.sleep(10) # Wait before retrying
|
|
||||||
|
|
||||||
async def _analyze_and_trade(self, symbol: str) -> None:
|
|
||||||
"""Analyze market and execute trades"""
|
|
||||||
try:
|
|
||||||
# Perform market analysis
|
|
||||||
analysis_task = {
|
|
||||||
"type": "market_analysis",
|
|
||||||
"symbol": symbol,
|
|
||||||
"strategy": self.trading_strategy
|
|
||||||
}
|
|
||||||
|
|
||||||
analysis_result = await self.bridge.execute_agent_task(self.agent_id, analysis_task)
|
|
||||||
|
|
||||||
if analysis_result.get("status") == "success":
|
|
||||||
analysis = analysis_result["result"]["analysis"]
|
|
||||||
|
|
||||||
# Make trading decision
|
|
||||||
if self._should_trade(analysis):
|
|
||||||
await self._execute_trade(symbol, analysis)
|
|
||||||
else:
|
|
||||||
print(f"Market analysis failed for {symbol}: {analysis_result}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error in analyze_and_trade for {symbol}: {e}")
|
|
||||||
|
|
||||||
def _should_trade(self, analysis: Dict[str, Any]) -> bool:
|
|
||||||
"""Determine if should execute trade"""
|
|
||||||
recommendation = analysis.get("recommendation", "hold")
|
|
||||||
return recommendation in ["buy", "sell"]
|
|
||||||
|
|
||||||
async def _execute_trade(self, symbol: str, analysis: Dict[str, Any]) -> None:
|
|
||||||
"""Execute trade based on analysis"""
|
|
||||||
try:
|
|
||||||
recommendation = analysis.get("recommendation", "hold")
|
|
||||||
|
|
||||||
if recommendation == "buy":
|
|
||||||
trade_task = {
|
|
||||||
"type": "trading",
|
|
||||||
"symbol": symbol,
|
|
||||||
"side": "buy",
|
|
||||||
"amount": self.config.get("trade_amount", 0.1),
|
|
||||||
"strategy": self.trading_strategy
|
|
||||||
}
|
|
||||||
elif recommendation == "sell":
|
|
||||||
trade_task = {
|
|
||||||
"type": "trading",
|
|
||||||
"symbol": symbol,
|
|
||||||
"side": "sell",
|
|
||||||
"amount": self.config.get("trade_amount", 0.1),
|
|
||||||
"strategy": self.trading_strategy
|
|
||||||
}
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
|
|
||||||
trade_result = await self.bridge.execute_agent_task(self.agent_id, trade_task)
|
|
||||||
|
|
||||||
if trade_result.get("status") == "success":
|
|
||||||
print(f"Trade executed successfully: {trade_result}")
|
|
||||||
else:
|
|
||||||
print(f"Trade execution failed: {trade_result}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error executing trade: {e}")
|
|
||||||
|
|
||||||
async def get_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get agent status"""
|
|
||||||
return await self.bridge.get_agent_status(self.agent_id)
|
|
||||||
|
|
||||||
# Main execution
|
|
||||||
async def main():
|
|
||||||
"""Main trading agent execution"""
|
|
||||||
agent_id = "trading-agent-001"
|
|
||||||
config = {
|
|
||||||
"strategy": "basic",
|
|
||||||
"symbols": ["AITBC/BTC"],
|
|
||||||
"trade_interval": 30,
|
|
||||||
"trade_amount": 0.1
|
|
||||||
}
|
|
||||||
|
|
||||||
agent = TradingAgent(agent_id, config)
|
|
||||||
|
|
||||||
# Start agent
|
|
||||||
if await agent.start():
|
|
||||||
try:
|
|
||||||
# Run trading loop
|
|
||||||
await agent.run_trading_loop()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("Shutting down trading agent...")
|
|
||||||
finally:
|
|
||||||
await agent.stop()
|
|
||||||
else:
|
|
||||||
print("Failed to start trading agent")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
asyncio.run(main())
|
|
||||||
@@ -1,229 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Agent Integration Layer
|
|
||||||
Connects agent protocols to existing AITBC services
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import aiohttp
|
|
||||||
import json
|
|
||||||
from typing import Dict, Any, List, Optional
|
|
||||||
from datetime import datetime
|
|
||||||
|
|
||||||
class AITBCServiceIntegration:
|
|
||||||
"""Integration layer for AITBC services"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.service_endpoints = {
|
|
||||||
"coordinator_api": "http://localhost:8000",
|
|
||||||
"blockchain_rpc": "http://localhost:8006",
|
|
||||||
"exchange_service": "http://localhost:8001",
|
|
||||||
"marketplace": "http://localhost:8002",
|
|
||||||
"agent_registry": "http://localhost:8013"
|
|
||||||
}
|
|
||||||
self.session = None
|
|
||||||
|
|
||||||
async def __aenter__(self):
|
|
||||||
self.session = aiohttp.ClientSession()
|
|
||||||
return self
|
|
||||||
|
|
||||||
async def __aexit__(self, exc_type, exc_val, exc_tb):
|
|
||||||
if self.session:
|
|
||||||
await self.session.close()
|
|
||||||
|
|
||||||
async def get_blockchain_info(self) -> Dict[str, Any]:
|
|
||||||
"""Get blockchain information"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['blockchain_rpc']}/health") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "unavailable"}
|
|
||||||
|
|
||||||
async def get_exchange_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get exchange service status"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['exchange_service']}/api/health") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "unavailable"}
|
|
||||||
|
|
||||||
async def get_coordinator_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get coordinator API status"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['coordinator_api']}/health") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "unavailable"}
|
|
||||||
|
|
||||||
async def submit_transaction(self, transaction_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Submit transaction to blockchain"""
|
|
||||||
try:
|
|
||||||
async with self.session.post(
|
|
||||||
f"{self.service_endpoints['blockchain_rpc']}/rpc/submit",
|
|
||||||
json=transaction_data
|
|
||||||
) as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "failed"}
|
|
||||||
|
|
||||||
async def get_market_data(self, symbol: str = "AITBC/BTC") -> Dict[str, Any]:
|
|
||||||
"""Get market data from exchange"""
|
|
||||||
try:
|
|
||||||
async with self.session.get(f"{self.service_endpoints['exchange_service']}/api/market/{symbol}") as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "failed"}
|
|
||||||
|
|
||||||
async def register_agent_with_coordinator(self, agent_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Register agent with coordinator"""
|
|
||||||
try:
|
|
||||||
async with self.session.post(
|
|
||||||
f"{self.service_endpoints['agent_registry']}/api/agents/register",
|
|
||||||
json=agent_data
|
|
||||||
) as response:
|
|
||||||
return await response.json()
|
|
||||||
except Exception as e:
|
|
||||||
return {"error": str(e), "status": "failed"}
|
|
||||||
|
|
||||||
class AgentServiceBridge:
|
|
||||||
"""Bridge between agents and AITBC services"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.integration = AITBCServiceIntegration()
|
|
||||||
self.active_agents = {}
|
|
||||||
|
|
||||||
async def start_agent(self, agent_id: str, agent_config: Dict[str, Any]) -> bool:
|
|
||||||
"""Start an agent with service integration"""
|
|
||||||
try:
|
|
||||||
# Register agent with coordinator
|
|
||||||
async with self.integration as integration:
|
|
||||||
registration_result = await integration.register_agent_with_coordinator({
|
|
||||||
"name": agent_id,
|
|
||||||
"type": agent_config.get("type", "generic"),
|
|
||||||
"capabilities": agent_config.get("capabilities", []),
|
|
||||||
"chain_id": agent_config.get("chain_id", "ait-mainnet"),
|
|
||||||
"endpoint": agent_config.get("endpoint", f"http://localhost:{8000 + len(self.active_agents) + 10}")
|
|
||||||
})
|
|
||||||
|
|
||||||
# The registry returns the created agent dict on success, not a {"status": "ok"} wrapper
|
|
||||||
if registration_result and "id" in registration_result:
|
|
||||||
self.active_agents[agent_id] = {
|
|
||||||
"config": agent_config,
|
|
||||||
"registration": registration_result,
|
|
||||||
"started_at": datetime.utcnow()
|
|
||||||
}
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f"Registration failed: {registration_result}")
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Failed to start agent {agent_id}: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def stop_agent(self, agent_id: str) -> bool:
|
|
||||||
"""Stop an agent"""
|
|
||||||
if agent_id in self.active_agents:
|
|
||||||
del self.active_agents[agent_id]
|
|
||||||
return True
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def get_agent_status(self, agent_id: str) -> Dict[str, Any]:
|
|
||||||
"""Get agent status with service integration"""
|
|
||||||
if agent_id not in self.active_agents:
|
|
||||||
return {"status": "not_found"}
|
|
||||||
|
|
||||||
agent_info = self.active_agents[agent_id]
|
|
||||||
|
|
||||||
async with self.integration as integration:
|
|
||||||
# Get service statuses
|
|
||||||
blockchain_status = await integration.get_blockchain_info()
|
|
||||||
exchange_status = await integration.get_exchange_status()
|
|
||||||
coordinator_status = await integration.get_coordinator_status()
|
|
||||||
|
|
||||||
return {
|
|
||||||
"agent_id": agent_id,
|
|
||||||
"status": "active",
|
|
||||||
"started_at": agent_info["started_at"].isoformat(),
|
|
||||||
"services": {
|
|
||||||
"blockchain": blockchain_status,
|
|
||||||
"exchange": exchange_status,
|
|
||||||
"coordinator": coordinator_status
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async def execute_agent_task(self, agent_id: str, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute agent task with service integration"""
|
|
||||||
if agent_id not in self.active_agents:
|
|
||||||
return {"status": "error", "message": "Agent not found"}
|
|
||||||
|
|
||||||
task_type = task_data.get("type")
|
|
||||||
|
|
||||||
if task_type == "market_analysis":
|
|
||||||
return await self._execute_market_analysis(task_data)
|
|
||||||
elif task_type == "trading":
|
|
||||||
return await self._execute_trading_task(task_data)
|
|
||||||
elif task_type == "compliance_check":
|
|
||||||
return await self._execute_compliance_check(task_data)
|
|
||||||
else:
|
|
||||||
return {"status": "error", "message": f"Unknown task type: {task_type}"}
|
|
||||||
|
|
||||||
async def _execute_market_analysis(self, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute market analysis task"""
|
|
||||||
try:
|
|
||||||
async with self.integration as integration:
|
|
||||||
market_data = await integration.get_market_data(task_data.get("symbol", "AITBC/BTC"))
|
|
||||||
|
|
||||||
# Perform basic analysis
|
|
||||||
analysis_result = {
|
|
||||||
"symbol": task_data.get("symbol", "AITBC/BTC"),
|
|
||||||
"market_data": market_data,
|
|
||||||
"analysis": {
|
|
||||||
"trend": "neutral",
|
|
||||||
"volatility": "medium",
|
|
||||||
"recommendation": "hold"
|
|
||||||
},
|
|
||||||
"timestamp": datetime.utcnow().isoformat()
|
|
||||||
}
|
|
||||||
|
|
||||||
return {"status": "success", "result": analysis_result}
|
|
||||||
except Exception as e:
|
|
||||||
return {"status": "error", "message": str(e)}
|
|
||||||
|
|
||||||
async def _execute_trading_task(self, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute trading task"""
|
|
||||||
try:
|
|
||||||
# Get market data first
|
|
||||||
async with self.integration as integration:
|
|
||||||
market_data = await integration.get_market_data(task_data.get("symbol", "AITBC/BTC"))
|
|
||||||
|
|
||||||
# Create transaction
|
|
||||||
transaction = {
|
|
||||||
"type": "trade",
|
|
||||||
"symbol": task_data.get("symbol", "AITBC/BTC"),
|
|
||||||
"side": task_data.get("side", "buy"),
|
|
||||||
"amount": task_data.get("amount", 0.1),
|
|
||||||
"price": task_data.get("price", market_data.get("price", 0.001))
|
|
||||||
}
|
|
||||||
|
|
||||||
# Submit transaction
|
|
||||||
tx_result = await integration.submit_transaction(transaction)
|
|
||||||
|
|
||||||
return {"status": "success", "transaction": tx_result}
|
|
||||||
except Exception as e:
|
|
||||||
return {"status": "error", "message": str(e)}
|
|
||||||
|
|
||||||
async def _execute_compliance_check(self, task_data: Dict[str, Any]) -> Dict[str, Any]:
|
|
||||||
"""Execute compliance check task"""
|
|
||||||
try:
|
|
||||||
# Basic compliance check
|
|
||||||
compliance_result = {
|
|
||||||
"user_id": task_data.get("user_id"),
|
|
||||||
"check_type": task_data.get("check_type", "basic"),
|
|
||||||
"status": "passed",
|
|
||||||
"checks_performed": ["kyc", "aml", "sanctions"],
|
|
||||||
"timestamp": datetime.utcnow().isoformat()
|
|
||||||
}
|
|
||||||
|
|
||||||
return {"status": "success", "result": compliance_result}
|
|
||||||
except Exception as e:
|
|
||||||
return {"status": "error", "message": str(e)}
|
|
||||||
@@ -1,149 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Compliance Agent
|
|
||||||
Automated compliance and regulatory monitoring agent
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import json
|
|
||||||
import time
|
|
||||||
from typing import Dict, Any, List
|
|
||||||
from datetime import datetime
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Add parent directory to path
|
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '../../../..'))
|
|
||||||
|
|
||||||
from apps.agent_services.agent_bridge.src.integration_layer import AgentServiceBridge
|
|
||||||
|
|
||||||
class ComplianceAgent:
|
|
||||||
"""Automated compliance agent"""
|
|
||||||
|
|
||||||
def __init__(self, agent_id: str, config: Dict[str, Any]):
|
|
||||||
self.agent_id = agent_id
|
|
||||||
self.config = config
|
|
||||||
self.bridge = AgentServiceBridge()
|
|
||||||
self.is_running = False
|
|
||||||
self.check_interval = config.get("check_interval", 300) # 5 minutes
|
|
||||||
self.monitored_entities = config.get("monitored_entities", [])
|
|
||||||
|
|
||||||
async def start(self) -> bool:
|
|
||||||
"""Start compliance agent"""
|
|
||||||
try:
|
|
||||||
success = await self.bridge.start_agent(self.agent_id, {
|
|
||||||
"type": "compliance",
|
|
||||||
"capabilities": ["kyc_check", "aml_screening", "regulatory_reporting"],
|
|
||||||
"endpoint": f"http://localhost:8006"
|
|
||||||
})
|
|
||||||
|
|
||||||
if success:
|
|
||||||
self.is_running = True
|
|
||||||
print(f"Compliance agent {self.agent_id} started successfully")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f"Failed to start compliance agent {self.agent_id}")
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error starting compliance agent: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def stop(self) -> bool:
|
|
||||||
"""Stop compliance agent"""
|
|
||||||
self.is_running = False
|
|
||||||
success = await self.bridge.stop_agent(self.agent_id)
|
|
||||||
if success:
|
|
||||||
print(f"Compliance agent {self.agent_id} stopped successfully")
|
|
||||||
return success
|
|
||||||
|
|
||||||
async def run_compliance_loop(self):
|
|
||||||
"""Main compliance monitoring loop"""
|
|
||||||
while self.is_running:
|
|
||||||
try:
|
|
||||||
for entity in self.monitored_entities:
|
|
||||||
await self._perform_compliance_check(entity)
|
|
||||||
|
|
||||||
await asyncio.sleep(self.check_interval)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error in compliance loop: {e}")
|
|
||||||
await asyncio.sleep(30) # Wait before retrying
|
|
||||||
|
|
||||||
async def _perform_compliance_check(self, entity_id: str) -> None:
|
|
||||||
"""Perform compliance check for entity"""
|
|
||||||
try:
|
|
||||||
compliance_task = {
|
|
||||||
"type": "compliance_check",
|
|
||||||
"user_id": entity_id,
|
|
||||||
"check_type": "full",
|
|
||||||
"monitored_activities": ["trading", "transfers", "wallet_creation"]
|
|
||||||
}
|
|
||||||
|
|
||||||
result = await self.bridge.execute_agent_task(self.agent_id, compliance_task)
|
|
||||||
|
|
||||||
if result.get("status") == "success":
|
|
||||||
compliance_result = result["result"]
|
|
||||||
await self._handle_compliance_result(entity_id, compliance_result)
|
|
||||||
else:
|
|
||||||
print(f"Compliance check failed for {entity_id}: {result}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error performing compliance check for {entity_id}: {e}")
|
|
||||||
|
|
||||||
async def _handle_compliance_result(self, entity_id: str, result: Dict[str, Any]) -> None:
|
|
||||||
"""Handle compliance check result"""
|
|
||||||
status = result.get("status", "unknown")
|
|
||||||
|
|
||||||
if status == "passed":
|
|
||||||
print(f"✅ Compliance check passed for {entity_id}")
|
|
||||||
elif status == "failed":
|
|
||||||
print(f"❌ Compliance check failed for {entity_id}")
|
|
||||||
# Trigger alert or further investigation
|
|
||||||
await self._trigger_compliance_alert(entity_id, result)
|
|
||||||
else:
|
|
||||||
print(f"⚠️ Compliance check inconclusive for {entity_id}")
|
|
||||||
|
|
||||||
async def _trigger_compliance_alert(self, entity_id: str, result: Dict[str, Any]) -> None:
|
|
||||||
"""Trigger compliance alert"""
|
|
||||||
alert_data = {
|
|
||||||
"entity_id": entity_id,
|
|
||||||
"alert_type": "compliance_failure",
|
|
||||||
"severity": "high",
|
|
||||||
"details": result,
|
|
||||||
"timestamp": datetime.utcnow().isoformat()
|
|
||||||
}
|
|
||||||
|
|
||||||
# In a real implementation, this would send to alert system
|
|
||||||
print(f"🚨 COMPLIANCE ALERT: {json.dumps(alert_data, indent=2)}")
|
|
||||||
|
|
||||||
async def get_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get agent status"""
|
|
||||||
status = await self.bridge.get_agent_status(self.agent_id)
|
|
||||||
status["monitored_entities"] = len(self.monitored_entities)
|
|
||||||
status["check_interval"] = self.check_interval
|
|
||||||
return status
|
|
||||||
|
|
||||||
# Main execution
|
|
||||||
async def main():
|
|
||||||
"""Main compliance agent execution"""
|
|
||||||
agent_id = "compliance-agent-001"
|
|
||||||
config = {
|
|
||||||
"check_interval": 60, # 1 minute for testing
|
|
||||||
"monitored_entities": ["user001", "user002", "user003"]
|
|
||||||
}
|
|
||||||
|
|
||||||
agent = ComplianceAgent(agent_id, config)
|
|
||||||
|
|
||||||
# Start agent
|
|
||||||
if await agent.start():
|
|
||||||
try:
|
|
||||||
# Run compliance loop
|
|
||||||
await agent.run_compliance_loop()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("Shutting down compliance agent...")
|
|
||||||
finally:
|
|
||||||
await agent.stop()
|
|
||||||
else:
|
|
||||||
print("Failed to start compliance agent")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
asyncio.run(main())
|
|
||||||
@@ -1,132 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Agent Coordinator Service
|
|
||||||
Agent task coordination and management
|
|
||||||
"""
|
|
||||||
|
|
||||||
from fastapi import FastAPI, HTTPException
|
|
||||||
from pydantic import BaseModel
|
|
||||||
from typing import List, Optional, Dict, Any
|
|
||||||
import json
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime
|
|
||||||
import sqlite3
|
|
||||||
from contextlib import contextmanager
|
|
||||||
from contextlib import asynccontextmanager
|
|
||||||
|
|
||||||
@asynccontextmanager
|
|
||||||
async def lifespan(app: FastAPI):
|
|
||||||
# Startup
|
|
||||||
init_db()
|
|
||||||
yield
|
|
||||||
# Shutdown (cleanup if needed)
|
|
||||||
pass
|
|
||||||
|
|
||||||
app = FastAPI(title="AITBC Agent Coordinator API", version="1.0.0", lifespan=lifespan)
|
|
||||||
|
|
||||||
# Database setup
|
|
||||||
def get_db():
|
|
||||||
conn = sqlite3.connect('agent_coordinator.db')
|
|
||||||
conn.row_factory = sqlite3.Row
|
|
||||||
return conn
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def get_db_connection():
|
|
||||||
conn = get_db()
|
|
||||||
try:
|
|
||||||
yield conn
|
|
||||||
finally:
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
# Initialize database
|
|
||||||
def init_db():
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
CREATE TABLE IF NOT EXISTS tasks (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
task_type TEXT NOT NULL,
|
|
||||||
payload TEXT NOT NULL,
|
|
||||||
required_capabilities TEXT NOT NULL,
|
|
||||||
priority TEXT NOT NULL,
|
|
||||||
status TEXT NOT NULL,
|
|
||||||
assigned_agent_id TEXT,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
result TEXT
|
|
||||||
)
|
|
||||||
''')
|
|
||||||
|
|
||||||
# Models
|
|
||||||
class Task(BaseModel):
|
|
||||||
id: str
|
|
||||||
task_type: str
|
|
||||||
payload: Dict[str, Any]
|
|
||||||
required_capabilities: List[str]
|
|
||||||
priority: str
|
|
||||||
status: str
|
|
||||||
assigned_agent_id: Optional[str] = None
|
|
||||||
|
|
||||||
class TaskCreation(BaseModel):
|
|
||||||
task_type: str
|
|
||||||
payload: Dict[str, Any]
|
|
||||||
required_capabilities: List[str]
|
|
||||||
priority: str = "normal"
|
|
||||||
|
|
||||||
# API Endpoints
|
|
||||||
|
|
||||||
@app.post("/api/tasks", response_model=Task)
|
|
||||||
async def create_task(task: TaskCreation):
|
|
||||||
"""Create a new task"""
|
|
||||||
task_id = str(uuid.uuid4())
|
|
||||||
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
INSERT INTO tasks (id, task_type, payload, required_capabilities, priority, status)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?)
|
|
||||||
''', (
|
|
||||||
task_id, task.task_type, json.dumps(task.payload),
|
|
||||||
json.dumps(task.required_capabilities), task.priority, "pending"
|
|
||||||
))
|
|
||||||
|
|
||||||
return Task(
|
|
||||||
id=task_id,
|
|
||||||
task_type=task.task_type,
|
|
||||||
payload=task.payload,
|
|
||||||
required_capabilities=task.required_capabilities,
|
|
||||||
priority=task.priority,
|
|
||||||
status="pending"
|
|
||||||
)
|
|
||||||
|
|
||||||
@app.get("/api/tasks", response_model=List[Task])
|
|
||||||
async def list_tasks(status: Optional[str] = None):
|
|
||||||
"""List tasks with optional status filter"""
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
query = "SELECT * FROM tasks"
|
|
||||||
params = []
|
|
||||||
|
|
||||||
if status:
|
|
||||||
query += " WHERE status = ?"
|
|
||||||
params.append(status)
|
|
||||||
|
|
||||||
tasks = conn.execute(query, params).fetchall()
|
|
||||||
|
|
||||||
return [
|
|
||||||
Task(
|
|
||||||
id=task["id"],
|
|
||||||
task_type=task["task_type"],
|
|
||||||
payload=json.loads(task["payload"]),
|
|
||||||
required_capabilities=json.loads(task["required_capabilities"]),
|
|
||||||
priority=task["priority"],
|
|
||||||
status=task["status"],
|
|
||||||
assigned_agent_id=task["assigned_agent_id"]
|
|
||||||
)
|
|
||||||
for task in tasks
|
|
||||||
]
|
|
||||||
|
|
||||||
@app.get("/api/health")
|
|
||||||
async def health_check():
|
|
||||||
"""Health check endpoint"""
|
|
||||||
return {"status": "ok", "timestamp": datetime.utcnow()}
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import uvicorn
|
|
||||||
uvicorn.run(app, host="0.0.0.0", port=8012)
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
# AITBC Agent Protocols Environment Configuration
|
|
||||||
# Copy this file to .env and update with your secure values
|
|
||||||
|
|
||||||
# Agent Protocol Encryption Key (generate a strong, unique key)
|
|
||||||
AITBC_AGENT_PROTOCOL_KEY=your-secure-encryption-key-here
|
|
||||||
|
|
||||||
# Agent Protocol Salt (generate a unique salt value)
|
|
||||||
AITBC_AGENT_PROTOCOL_SALT=your-unique-salt-value-here
|
|
||||||
|
|
||||||
# Agent Registry Configuration
|
|
||||||
AGENT_REGISTRY_HOST=0.0.0.0
|
|
||||||
AGENT_REGISTRY_PORT=8003
|
|
||||||
|
|
||||||
# Database Configuration
|
|
||||||
AGENT_REGISTRY_DB_PATH=agent_registry.db
|
|
||||||
|
|
||||||
# Security Settings
|
|
||||||
AGENT_PROTOCOL_TIMEOUT=300
|
|
||||||
AGENT_PROTOCOL_MAX_RETRIES=3
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
"""
|
|
||||||
Agent Protocols Package
|
|
||||||
"""
|
|
||||||
|
|
||||||
from .message_protocol import MessageProtocol, MessageTypes, AgentMessageClient
|
|
||||||
from .task_manager import TaskManager, TaskStatus, TaskPriority, Task
|
|
||||||
|
|
||||||
__all__ = [
|
|
||||||
"MessageProtocol",
|
|
||||||
"MessageTypes",
|
|
||||||
"AgentMessageClient",
|
|
||||||
"TaskManager",
|
|
||||||
"TaskStatus",
|
|
||||||
"TaskPriority",
|
|
||||||
"Task"
|
|
||||||
]
|
|
||||||
@@ -1,113 +0,0 @@
|
|||||||
"""
|
|
||||||
Message Protocol for AITBC Agents
|
|
||||||
Handles message creation, routing, and delivery between agents
|
|
||||||
"""
|
|
||||||
|
|
||||||
import json
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime
|
|
||||||
from typing import Dict, Any, Optional, List
|
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
class MessageTypes(Enum):
|
|
||||||
"""Message type enumeration"""
|
|
||||||
TASK_REQUEST = "task_request"
|
|
||||||
TASK_RESPONSE = "task_response"
|
|
||||||
HEARTBEAT = "heartbeat"
|
|
||||||
STATUS_UPDATE = "status_update"
|
|
||||||
ERROR = "error"
|
|
||||||
DATA = "data"
|
|
||||||
|
|
||||||
class MessageProtocol:
|
|
||||||
"""Message protocol handler for agent communication"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.messages = []
|
|
||||||
self.message_handlers = {}
|
|
||||||
|
|
||||||
def create_message(
|
|
||||||
self,
|
|
||||||
sender_id: str,
|
|
||||||
receiver_id: str,
|
|
||||||
message_type: MessageTypes,
|
|
||||||
content: Dict[str, Any],
|
|
||||||
message_id: Optional[str] = None
|
|
||||||
) -> Dict[str, Any]:
|
|
||||||
"""Create a new message"""
|
|
||||||
if message_id is None:
|
|
||||||
message_id = str(uuid.uuid4())
|
|
||||||
|
|
||||||
message = {
|
|
||||||
"message_id": message_id,
|
|
||||||
"sender_id": sender_id,
|
|
||||||
"receiver_id": receiver_id,
|
|
||||||
"message_type": message_type.value,
|
|
||||||
"content": content,
|
|
||||||
"timestamp": datetime.utcnow().isoformat(),
|
|
||||||
"status": "pending"
|
|
||||||
}
|
|
||||||
|
|
||||||
self.messages.append(message)
|
|
||||||
return message
|
|
||||||
|
|
||||||
def send_message(self, message: Dict[str, Any]) -> bool:
|
|
||||||
"""Send a message to the receiver"""
|
|
||||||
try:
|
|
||||||
message["status"] = "sent"
|
|
||||||
message["sent_timestamp"] = datetime.utcnow().isoformat()
|
|
||||||
return True
|
|
||||||
except Exception:
|
|
||||||
message["status"] = "failed"
|
|
||||||
return False
|
|
||||||
|
|
||||||
def receive_message(self, message_id: str) -> Optional[Dict[str, Any]]:
|
|
||||||
"""Receive and process a message"""
|
|
||||||
for message in self.messages:
|
|
||||||
if message["message_id"] == message_id:
|
|
||||||
message["status"] = "received"
|
|
||||||
message["received_timestamp"] = datetime.utcnow().isoformat()
|
|
||||||
return message
|
|
||||||
return None
|
|
||||||
|
|
||||||
def get_messages_by_agent(self, agent_id: str) -> List[Dict[str, Any]]:
|
|
||||||
"""Get all messages for a specific agent"""
|
|
||||||
return [
|
|
||||||
msg for msg in self.messages
|
|
||||||
if msg["sender_id"] == agent_id or msg["receiver_id"] == agent_id
|
|
||||||
]
|
|
||||||
|
|
||||||
class AgentMessageClient:
|
|
||||||
"""Client for agent message communication"""
|
|
||||||
|
|
||||||
def __init__(self, agent_id: str, protocol: MessageProtocol):
|
|
||||||
self.agent_id = agent_id
|
|
||||||
self.protocol = protocol
|
|
||||||
self.received_messages = []
|
|
||||||
|
|
||||||
def send_message(
|
|
||||||
self,
|
|
||||||
receiver_id: str,
|
|
||||||
message_type: MessageTypes,
|
|
||||||
content: Dict[str, Any]
|
|
||||||
) -> Dict[str, Any]:
|
|
||||||
"""Send a message to another agent"""
|
|
||||||
message = self.protocol.create_message(
|
|
||||||
sender_id=self.agent_id,
|
|
||||||
receiver_id=receiver_id,
|
|
||||||
message_type=message_type,
|
|
||||||
content=content
|
|
||||||
)
|
|
||||||
self.protocol.send_message(message)
|
|
||||||
return message
|
|
||||||
|
|
||||||
def receive_messages(self) -> List[Dict[str, Any]]:
|
|
||||||
"""Receive all pending messages for this agent"""
|
|
||||||
messages = []
|
|
||||||
for message in self.protocol.messages:
|
|
||||||
if (message["receiver_id"] == self.agent_id and
|
|
||||||
message["status"] == "sent" and
|
|
||||||
message not in self.received_messages):
|
|
||||||
self.protocol.receive_message(message["message_id"])
|
|
||||||
self.received_messages.append(message)
|
|
||||||
messages.append(message)
|
|
||||||
return messages
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
"""
|
|
||||||
Task Manager for AITBC Agents
|
|
||||||
Handles task creation, assignment, and tracking
|
|
||||||
"""
|
|
||||||
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
from typing import Dict, Any, Optional, List
|
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
class TaskStatus(Enum):
|
|
||||||
"""Task status enumeration"""
|
|
||||||
PENDING = "pending"
|
|
||||||
IN_PROGRESS = "in_progress"
|
|
||||||
COMPLETED = "completed"
|
|
||||||
FAILED = "failed"
|
|
||||||
CANCELLED = "cancelled"
|
|
||||||
|
|
||||||
class TaskPriority(Enum):
|
|
||||||
"""Task priority enumeration"""
|
|
||||||
LOW = "low"
|
|
||||||
MEDIUM = "medium"
|
|
||||||
HIGH = "high"
|
|
||||||
URGENT = "urgent"
|
|
||||||
|
|
||||||
class Task:
|
|
||||||
"""Task representation"""
|
|
||||||
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
task_id: str,
|
|
||||||
title: str,
|
|
||||||
description: str,
|
|
||||||
assigned_to: str,
|
|
||||||
priority: TaskPriority = TaskPriority.MEDIUM,
|
|
||||||
created_by: Optional[str] = None
|
|
||||||
):
|
|
||||||
self.task_id = task_id
|
|
||||||
self.title = title
|
|
||||||
self.description = description
|
|
||||||
self.assigned_to = assigned_to
|
|
||||||
self.priority = priority
|
|
||||||
self.created_by = created_by or assigned_to
|
|
||||||
self.status = TaskStatus.PENDING
|
|
||||||
self.created_at = datetime.utcnow()
|
|
||||||
self.updated_at = datetime.utcnow()
|
|
||||||
self.completed_at = None
|
|
||||||
self.result = None
|
|
||||||
self.error = None
|
|
||||||
|
|
||||||
class TaskManager:
|
|
||||||
"""Task manager for agent coordination"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.tasks = {}
|
|
||||||
self.task_history = []
|
|
||||||
|
|
||||||
def create_task(
|
|
||||||
self,
|
|
||||||
title: str,
|
|
||||||
description: str,
|
|
||||||
assigned_to: str,
|
|
||||||
priority: TaskPriority = TaskPriority.MEDIUM,
|
|
||||||
created_by: Optional[str] = None
|
|
||||||
) -> Task:
|
|
||||||
"""Create a new task"""
|
|
||||||
task_id = str(uuid.uuid4())
|
|
||||||
task = Task(
|
|
||||||
task_id=task_id,
|
|
||||||
title=title,
|
|
||||||
description=description,
|
|
||||||
assigned_to=assigned_to,
|
|
||||||
priority=priority,
|
|
||||||
created_by=created_by
|
|
||||||
)
|
|
||||||
|
|
||||||
self.tasks[task_id] = task
|
|
||||||
return task
|
|
||||||
|
|
||||||
def get_task(self, task_id: str) -> Optional[Task]:
|
|
||||||
"""Get a task by ID"""
|
|
||||||
return self.tasks.get(task_id)
|
|
||||||
|
|
||||||
def update_task_status(
|
|
||||||
self,
|
|
||||||
task_id: str,
|
|
||||||
status: TaskStatus,
|
|
||||||
result: Optional[Dict[str, Any]] = None,
|
|
||||||
error: Optional[str] = None
|
|
||||||
) -> bool:
|
|
||||||
"""Update task status"""
|
|
||||||
task = self.get_task(task_id)
|
|
||||||
if not task:
|
|
||||||
return False
|
|
||||||
|
|
||||||
task.status = status
|
|
||||||
task.updated_at = datetime.utcnow()
|
|
||||||
|
|
||||||
if status == TaskStatus.COMPLETED:
|
|
||||||
task.completed_at = datetime.utcnow()
|
|
||||||
task.result = result
|
|
||||||
elif status == TaskStatus.FAILED:
|
|
||||||
task.error = error
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def get_tasks_by_agent(self, agent_id: str) -> List[Task]:
|
|
||||||
"""Get all tasks assigned to an agent"""
|
|
||||||
return [
|
|
||||||
task for task in self.tasks.values()
|
|
||||||
if task.assigned_to == agent_id
|
|
||||||
]
|
|
||||||
|
|
||||||
def get_tasks_by_status(self, status: TaskStatus) -> List[Task]:
|
|
||||||
"""Get all tasks with a specific status"""
|
|
||||||
return [
|
|
||||||
task for task in self.tasks.values()
|
|
||||||
if task.status == status
|
|
||||||
]
|
|
||||||
|
|
||||||
def get_overdue_tasks(self, hours: int = 24) -> List[Task]:
|
|
||||||
"""Get tasks that are overdue"""
|
|
||||||
cutoff_time = datetime.utcnow() - timedelta(hours=hours)
|
|
||||||
return [
|
|
||||||
task for task in self.tasks.values()
|
|
||||||
if task.status in [TaskStatus.PENDING, TaskStatus.IN_PROGRESS] and
|
|
||||||
task.created_at < cutoff_time
|
|
||||||
]
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Agent Registry Service
|
|
||||||
Central agent discovery and registration system
|
|
||||||
"""
|
|
||||||
|
|
||||||
from fastapi import FastAPI, HTTPException, Depends
|
|
||||||
from pydantic import BaseModel
|
|
||||||
from typing import List, Optional, Dict, Any
|
|
||||||
import json
|
|
||||||
import time
|
|
||||||
import uuid
|
|
||||||
from datetime import datetime, timedelta
|
|
||||||
import sqlite3
|
|
||||||
from contextlib import contextmanager
|
|
||||||
from contextlib import asynccontextmanager
|
|
||||||
|
|
||||||
@asynccontextmanager
|
|
||||||
async def lifespan(app: FastAPI):
|
|
||||||
# Startup
|
|
||||||
init_db()
|
|
||||||
yield
|
|
||||||
# Shutdown (cleanup if needed)
|
|
||||||
pass
|
|
||||||
|
|
||||||
app = FastAPI(title="AITBC Agent Registry API", version="1.0.0", lifespan=lifespan)
|
|
||||||
|
|
||||||
# Database setup
|
|
||||||
def get_db():
|
|
||||||
conn = sqlite3.connect('agent_registry.db')
|
|
||||||
conn.row_factory = sqlite3.Row
|
|
||||||
return conn
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def get_db_connection():
|
|
||||||
conn = get_db()
|
|
||||||
try:
|
|
||||||
yield conn
|
|
||||||
finally:
|
|
||||||
conn.close()
|
|
||||||
|
|
||||||
# Initialize database
|
|
||||||
def init_db():
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
CREATE TABLE IF NOT EXISTS agents (
|
|
||||||
id TEXT PRIMARY KEY,
|
|
||||||
name TEXT NOT NULL,
|
|
||||||
type TEXT NOT NULL,
|
|
||||||
capabilities TEXT NOT NULL,
|
|
||||||
chain_id TEXT NOT NULL,
|
|
||||||
endpoint TEXT NOT NULL,
|
|
||||||
status TEXT DEFAULT 'active',
|
|
||||||
last_heartbeat TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
metadata TEXT,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
||||||
)
|
|
||||||
''')
|
|
||||||
|
|
||||||
# Models
|
|
||||||
class Agent(BaseModel):
|
|
||||||
id: str
|
|
||||||
name: str
|
|
||||||
type: str
|
|
||||||
capabilities: List[str]
|
|
||||||
chain_id: str
|
|
||||||
endpoint: str
|
|
||||||
metadata: Optional[Dict[str, Any]] = {}
|
|
||||||
|
|
||||||
class AgentRegistration(BaseModel):
|
|
||||||
name: str
|
|
||||||
type: str
|
|
||||||
capabilities: List[str]
|
|
||||||
chain_id: str
|
|
||||||
endpoint: str
|
|
||||||
metadata: Optional[Dict[str, Any]] = {}
|
|
||||||
|
|
||||||
# API Endpoints
|
|
||||||
|
|
||||||
@app.post("/api/agents/register", response_model=Agent)
|
|
||||||
async def register_agent(agent: AgentRegistration):
|
|
||||||
"""Register a new agent"""
|
|
||||||
agent_id = str(uuid.uuid4())
|
|
||||||
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
conn.execute('''
|
|
||||||
INSERT INTO agents (id, name, type, capabilities, chain_id, endpoint, metadata)
|
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
||||||
''', (
|
|
||||||
agent_id, agent.name, agent.type,
|
|
||||||
json.dumps(agent.capabilities), agent.chain_id,
|
|
||||||
agent.endpoint, json.dumps(agent.metadata)
|
|
||||||
))
|
|
||||||
conn.commit()
|
|
||||||
|
|
||||||
return Agent(
|
|
||||||
id=agent_id,
|
|
||||||
name=agent.name,
|
|
||||||
type=agent.type,
|
|
||||||
capabilities=agent.capabilities,
|
|
||||||
chain_id=agent.chain_id,
|
|
||||||
endpoint=agent.endpoint,
|
|
||||||
metadata=agent.metadata
|
|
||||||
)
|
|
||||||
|
|
||||||
@app.get("/api/agents", response_model=List[Agent])
|
|
||||||
async def list_agents(
|
|
||||||
agent_type: Optional[str] = None,
|
|
||||||
chain_id: Optional[str] = None,
|
|
||||||
capability: Optional[str] = None
|
|
||||||
):
|
|
||||||
"""List registered agents with optional filters"""
|
|
||||||
with get_db_connection() as conn:
|
|
||||||
query = "SELECT * FROM agents WHERE status = 'active'"
|
|
||||||
params = []
|
|
||||||
|
|
||||||
if agent_type:
|
|
||||||
query += " AND type = ?"
|
|
||||||
params.append(agent_type)
|
|
||||||
|
|
||||||
if chain_id:
|
|
||||||
query += " AND chain_id = ?"
|
|
||||||
params.append(chain_id)
|
|
||||||
|
|
||||||
if capability:
|
|
||||||
query += " AND capabilities LIKE ?"
|
|
||||||
params.append(f'%{capability}%')
|
|
||||||
|
|
||||||
agents = conn.execute(query, params).fetchall()
|
|
||||||
|
|
||||||
return [
|
|
||||||
Agent(
|
|
||||||
id=agent["id"],
|
|
||||||
name=agent["name"],
|
|
||||||
type=agent["type"],
|
|
||||||
capabilities=json.loads(agent["capabilities"]),
|
|
||||||
chain_id=agent["chain_id"],
|
|
||||||
endpoint=agent["endpoint"],
|
|
||||||
metadata=json.loads(agent["metadata"] or "{}")
|
|
||||||
)
|
|
||||||
for agent in agents
|
|
||||||
]
|
|
||||||
|
|
||||||
@app.get("/api/health")
|
|
||||||
async def health_check():
|
|
||||||
"""Health check endpoint"""
|
|
||||||
return {"status": "ok", "timestamp": datetime.utcnow()}
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
import uvicorn
|
|
||||||
uvicorn.run(app, host="0.0.0.0", port=8013)
|
|
||||||
@@ -1,431 +0,0 @@
|
|||||||
"""
|
|
||||||
Agent Registration System
|
|
||||||
Handles AI agent registration, capability management, and discovery
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import time
|
|
||||||
import json
|
|
||||||
import hashlib
|
|
||||||
from typing import Dict, List, Optional, Set, Tuple
|
|
||||||
from dataclasses import dataclass, asdict
|
|
||||||
from enum import Enum
|
|
||||||
from decimal import Decimal
|
|
||||||
|
|
||||||
class AgentType(Enum):
|
|
||||||
AI_MODEL = "ai_model"
|
|
||||||
DATA_PROVIDER = "data_provider"
|
|
||||||
VALIDATOR = "validator"
|
|
||||||
MARKET_MAKER = "market_maker"
|
|
||||||
BROKER = "broker"
|
|
||||||
ORACLE = "oracle"
|
|
||||||
|
|
||||||
class AgentStatus(Enum):
|
|
||||||
REGISTERED = "registered"
|
|
||||||
ACTIVE = "active"
|
|
||||||
INACTIVE = "inactive"
|
|
||||||
SUSPENDED = "suspended"
|
|
||||||
BANNED = "banned"
|
|
||||||
|
|
||||||
class CapabilityType(Enum):
|
|
||||||
TEXT_GENERATION = "text_generation"
|
|
||||||
IMAGE_GENERATION = "image_generation"
|
|
||||||
DATA_ANALYSIS = "data_analysis"
|
|
||||||
PREDICTION = "prediction"
|
|
||||||
VALIDATION = "validation"
|
|
||||||
COMPUTATION = "computation"
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class AgentCapability:
|
|
||||||
capability_type: CapabilityType
|
|
||||||
name: str
|
|
||||||
version: str
|
|
||||||
parameters: Dict
|
|
||||||
performance_metrics: Dict
|
|
||||||
cost_per_use: Decimal
|
|
||||||
availability: float
|
|
||||||
max_concurrent_jobs: int
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class AgentInfo:
|
|
||||||
agent_id: str
|
|
||||||
agent_type: AgentType
|
|
||||||
name: str
|
|
||||||
owner_address: str
|
|
||||||
public_key: str
|
|
||||||
endpoint_url: str
|
|
||||||
capabilities: List[AgentCapability]
|
|
||||||
reputation_score: float
|
|
||||||
total_jobs_completed: int
|
|
||||||
total_earnings: Decimal
|
|
||||||
registration_time: float
|
|
||||||
last_active: float
|
|
||||||
status: AgentStatus
|
|
||||||
metadata: Dict
|
|
||||||
|
|
||||||
class AgentRegistry:
|
|
||||||
"""Manages AI agent registration and discovery"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.agents: Dict[str, AgentInfo] = {}
|
|
||||||
self.capability_index: Dict[CapabilityType, Set[str]] = {} # capability -> agent_ids
|
|
||||||
self.type_index: Dict[AgentType, Set[str]] = {} # agent_type -> agent_ids
|
|
||||||
self.reputation_scores: Dict[str, float] = {}
|
|
||||||
self.registration_queue: List[Dict] = []
|
|
||||||
|
|
||||||
# Registry parameters
|
|
||||||
self.min_reputation_threshold = 0.5
|
|
||||||
self.max_agents_per_type = 1000
|
|
||||||
self.registration_fee = Decimal('100.0')
|
|
||||||
self.inactivity_threshold = 86400 * 7 # 7 days
|
|
||||||
|
|
||||||
# Initialize capability index
|
|
||||||
for capability_type in CapabilityType:
|
|
||||||
self.capability_index[capability_type] = set()
|
|
||||||
|
|
||||||
# Initialize type index
|
|
||||||
for agent_type in AgentType:
|
|
||||||
self.type_index[agent_type] = set()
|
|
||||||
|
|
||||||
async def register_agent(self, agent_type: AgentType, name: str, owner_address: str,
|
|
||||||
public_key: str, endpoint_url: str, capabilities: List[Dict],
|
|
||||||
metadata: Dict = None) -> Tuple[bool, str, Optional[str]]:
|
|
||||||
"""Register a new AI agent"""
|
|
||||||
try:
|
|
||||||
# Validate inputs
|
|
||||||
if not self._validate_registration_inputs(agent_type, name, owner_address, public_key, endpoint_url):
|
|
||||||
return False, "Invalid registration inputs", None
|
|
||||||
|
|
||||||
# Check if agent already exists
|
|
||||||
agent_id = self._generate_agent_id(owner_address, name)
|
|
||||||
if agent_id in self.agents:
|
|
||||||
return False, "Agent already registered", None
|
|
||||||
|
|
||||||
# Check type limits
|
|
||||||
if len(self.type_index[agent_type]) >= self.max_agents_per_type:
|
|
||||||
return False, f"Maximum agents of type {agent_type.value} reached", None
|
|
||||||
|
|
||||||
# Convert capabilities
|
|
||||||
agent_capabilities = []
|
|
||||||
for cap_data in capabilities:
|
|
||||||
capability = self._create_capability_from_data(cap_data)
|
|
||||||
if capability:
|
|
||||||
agent_capabilities.append(capability)
|
|
||||||
|
|
||||||
if not agent_capabilities:
|
|
||||||
return False, "Agent must have at least one valid capability", None
|
|
||||||
|
|
||||||
# Create agent info
|
|
||||||
agent_info = AgentInfo(
|
|
||||||
agent_id=agent_id,
|
|
||||||
agent_type=agent_type,
|
|
||||||
name=name,
|
|
||||||
owner_address=owner_address,
|
|
||||||
public_key=public_key,
|
|
||||||
endpoint_url=endpoint_url,
|
|
||||||
capabilities=agent_capabilities,
|
|
||||||
reputation_score=1.0, # Start with neutral reputation
|
|
||||||
total_jobs_completed=0,
|
|
||||||
total_earnings=Decimal('0'),
|
|
||||||
registration_time=time.time(),
|
|
||||||
last_active=time.time(),
|
|
||||||
status=AgentStatus.REGISTERED,
|
|
||||||
metadata=metadata or {}
|
|
||||||
)
|
|
||||||
|
|
||||||
# Add to registry
|
|
||||||
self.agents[agent_id] = agent_info
|
|
||||||
|
|
||||||
# Update indexes
|
|
||||||
self.type_index[agent_type].add(agent_id)
|
|
||||||
for capability in agent_capabilities:
|
|
||||||
self.capability_index[capability.capability_type].add(agent_id)
|
|
||||||
|
|
||||||
log_info(f"Agent registered: {agent_id} ({name})")
|
|
||||||
return True, "Registration successful", agent_id
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
return False, f"Registration failed: {str(e)}", None
|
|
||||||
|
|
||||||
def _validate_registration_inputs(self, agent_type: AgentType, name: str,
|
|
||||||
owner_address: str, public_key: str, endpoint_url: str) -> bool:
|
|
||||||
"""Validate registration inputs"""
|
|
||||||
# Check required fields
|
|
||||||
if not all([agent_type, name, owner_address, public_key, endpoint_url]):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Validate address format (simplified)
|
|
||||||
if not owner_address.startswith('0x') or len(owner_address) != 42:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Validate URL format (simplified)
|
|
||||||
if not endpoint_url.startswith(('http://', 'https://')):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Validate name
|
|
||||||
if len(name) < 3 or len(name) > 100:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
def _generate_agent_id(self, owner_address: str, name: str) -> str:
|
|
||||||
"""Generate unique agent ID"""
|
|
||||||
content = f"{owner_address}:{name}:{time.time()}"
|
|
||||||
return hashlib.sha256(content.encode()).hexdigest()[:16]
|
|
||||||
|
|
||||||
def _create_capability_from_data(self, cap_data: Dict) -> Optional[AgentCapability]:
|
|
||||||
"""Create capability from data dictionary"""
|
|
||||||
try:
|
|
||||||
# Validate required fields
|
|
||||||
required_fields = ['type', 'name', 'version', 'cost_per_use']
|
|
||||||
if not all(field in cap_data for field in required_fields):
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Parse capability type
|
|
||||||
try:
|
|
||||||
capability_type = CapabilityType(cap_data['type'])
|
|
||||||
except ValueError:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Create capability
|
|
||||||
return AgentCapability(
|
|
||||||
capability_type=capability_type,
|
|
||||||
name=cap_data['name'],
|
|
||||||
version=cap_data['version'],
|
|
||||||
parameters=cap_data.get('parameters', {}),
|
|
||||||
performance_metrics=cap_data.get('performance_metrics', {}),
|
|
||||||
cost_per_use=Decimal(str(cap_data['cost_per_use'])),
|
|
||||||
availability=cap_data.get('availability', 1.0),
|
|
||||||
max_concurrent_jobs=cap_data.get('max_concurrent_jobs', 1)
|
|
||||||
)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
log_error(f"Error creating capability: {e}")
|
|
||||||
return None
|
|
||||||
|
|
||||||
async def update_agent_status(self, agent_id: str, status: AgentStatus) -> Tuple[bool, str]:
|
|
||||||
"""Update agent status"""
|
|
||||||
if agent_id not in self.agents:
|
|
||||||
return False, "Agent not found"
|
|
||||||
|
|
||||||
agent = self.agents[agent_id]
|
|
||||||
old_status = agent.status
|
|
||||||
agent.status = status
|
|
||||||
agent.last_active = time.time()
|
|
||||||
|
|
||||||
log_info(f"Agent {agent_id} status changed: {old_status.value} -> {status.value}")
|
|
||||||
return True, "Status updated successfully"
|
|
||||||
|
|
||||||
async def update_agent_capabilities(self, agent_id: str, capabilities: List[Dict]) -> Tuple[bool, str]:
|
|
||||||
"""Update agent capabilities"""
|
|
||||||
if agent_id not in self.agents:
|
|
||||||
return False, "Agent not found"
|
|
||||||
|
|
||||||
agent = self.agents[agent_id]
|
|
||||||
|
|
||||||
# Remove old capabilities from index
|
|
||||||
for old_capability in agent.capabilities:
|
|
||||||
self.capability_index[old_capability.capability_type].discard(agent_id)
|
|
||||||
|
|
||||||
# Add new capabilities
|
|
||||||
new_capabilities = []
|
|
||||||
for cap_data in capabilities:
|
|
||||||
capability = self._create_capability_from_data(cap_data)
|
|
||||||
if capability:
|
|
||||||
new_capabilities.append(capability)
|
|
||||||
self.capability_index[capability.capability_type].add(agent_id)
|
|
||||||
|
|
||||||
if not new_capabilities:
|
|
||||||
return False, "No valid capabilities provided"
|
|
||||||
|
|
||||||
agent.capabilities = new_capabilities
|
|
||||||
agent.last_active = time.time()
|
|
||||||
|
|
||||||
return True, "Capabilities updated successfully"
|
|
||||||
|
|
||||||
async def find_agents_by_capability(self, capability_type: CapabilityType,
|
|
||||||
filters: Dict = None) -> List[AgentInfo]:
|
|
||||||
"""Find agents by capability type"""
|
|
||||||
agent_ids = self.capability_index.get(capability_type, set())
|
|
||||||
|
|
||||||
agents = []
|
|
||||||
for agent_id in agent_ids:
|
|
||||||
agent = self.agents.get(agent_id)
|
|
||||||
if agent and agent.status == AgentStatus.ACTIVE:
|
|
||||||
if self._matches_filters(agent, filters):
|
|
||||||
agents.append(agent)
|
|
||||||
|
|
||||||
# Sort by reputation (highest first)
|
|
||||||
agents.sort(key=lambda x: x.reputation_score, reverse=True)
|
|
||||||
return agents
|
|
||||||
|
|
||||||
async def find_agents_by_type(self, agent_type: AgentType, filters: Dict = None) -> List[AgentInfo]:
|
|
||||||
"""Find agents by type"""
|
|
||||||
agent_ids = self.type_index.get(agent_type, set())
|
|
||||||
|
|
||||||
agents = []
|
|
||||||
for agent_id in agent_ids:
|
|
||||||
agent = self.agents.get(agent_id)
|
|
||||||
if agent and agent.status == AgentStatus.ACTIVE:
|
|
||||||
if self._matches_filters(agent, filters):
|
|
||||||
agents.append(agent)
|
|
||||||
|
|
||||||
# Sort by reputation (highest first)
|
|
||||||
agents.sort(key=lambda x: x.reputation_score, reverse=True)
|
|
||||||
return agents
|
|
||||||
|
|
||||||
def _matches_filters(self, agent: AgentInfo, filters: Dict) -> bool:
|
|
||||||
"""Check if agent matches filters"""
|
|
||||||
if not filters:
|
|
||||||
return True
|
|
||||||
|
|
||||||
# Reputation filter
|
|
||||||
if 'min_reputation' in filters:
|
|
||||||
if agent.reputation_score < filters['min_reputation']:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Cost filter
|
|
||||||
if 'max_cost_per_use' in filters:
|
|
||||||
max_cost = Decimal(str(filters['max_cost_per_use']))
|
|
||||||
if any(cap.cost_per_use > max_cost for cap in agent.capabilities):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Availability filter
|
|
||||||
if 'min_availability' in filters:
|
|
||||||
min_availability = filters['min_availability']
|
|
||||||
if any(cap.availability < min_availability for cap in agent.capabilities):
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Location filter (if implemented)
|
|
||||||
if 'location' in filters:
|
|
||||||
agent_location = agent.metadata.get('location')
|
|
||||||
if agent_location != filters['location']:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
async def get_agent_info(self, agent_id: str) -> Optional[AgentInfo]:
|
|
||||||
"""Get agent information"""
|
|
||||||
return self.agents.get(agent_id)
|
|
||||||
|
|
||||||
async def search_agents(self, query: str, limit: int = 50) -> List[AgentInfo]:
|
|
||||||
"""Search agents by name or capability"""
|
|
||||||
query_lower = query.lower()
|
|
||||||
results = []
|
|
||||||
|
|
||||||
for agent in self.agents.values():
|
|
||||||
if agent.status != AgentStatus.ACTIVE:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Search in name
|
|
||||||
if query_lower in agent.name.lower():
|
|
||||||
results.append(agent)
|
|
||||||
continue
|
|
||||||
|
|
||||||
# Search in capabilities
|
|
||||||
for capability in agent.capabilities:
|
|
||||||
if (query_lower in capability.name.lower() or
|
|
||||||
query_lower in capability.capability_type.value):
|
|
||||||
results.append(agent)
|
|
||||||
break
|
|
||||||
|
|
||||||
# Sort by relevance (reputation)
|
|
||||||
results.sort(key=lambda x: x.reputation_score, reverse=True)
|
|
||||||
return results[:limit]
|
|
||||||
|
|
||||||
async def get_agent_statistics(self, agent_id: str) -> Optional[Dict]:
|
|
||||||
"""Get detailed statistics for an agent"""
|
|
||||||
agent = self.agents.get(agent_id)
|
|
||||||
if not agent:
|
|
||||||
return None
|
|
||||||
|
|
||||||
# Calculate additional statistics
|
|
||||||
avg_job_earnings = agent.total_earnings / agent.total_jobs_completed if agent.total_jobs_completed > 0 else Decimal('0')
|
|
||||||
days_active = (time.time() - agent.registration_time) / 86400
|
|
||||||
jobs_per_day = agent.total_jobs_completed / days_active if days_active > 0 else 0
|
|
||||||
|
|
||||||
return {
|
|
||||||
'agent_id': agent_id,
|
|
||||||
'name': agent.name,
|
|
||||||
'type': agent.agent_type.value,
|
|
||||||
'status': agent.status.value,
|
|
||||||
'reputation_score': agent.reputation_score,
|
|
||||||
'total_jobs_completed': agent.total_jobs_completed,
|
|
||||||
'total_earnings': float(agent.total_earnings),
|
|
||||||
'avg_job_earnings': float(avg_job_earnings),
|
|
||||||
'jobs_per_day': jobs_per_day,
|
|
||||||
'days_active': int(days_active),
|
|
||||||
'capabilities_count': len(agent.capabilities),
|
|
||||||
'last_active': agent.last_active,
|
|
||||||
'registration_time': agent.registration_time
|
|
||||||
}
|
|
||||||
|
|
||||||
async def get_registry_statistics(self) -> Dict:
|
|
||||||
"""Get registry-wide statistics"""
|
|
||||||
total_agents = len(self.agents)
|
|
||||||
active_agents = len([a for a in self.agents.values() if a.status == AgentStatus.ACTIVE])
|
|
||||||
|
|
||||||
# Count by type
|
|
||||||
type_counts = {}
|
|
||||||
for agent_type in AgentType:
|
|
||||||
type_counts[agent_type.value] = len(self.type_index[agent_type])
|
|
||||||
|
|
||||||
# Count by capability
|
|
||||||
capability_counts = {}
|
|
||||||
for capability_type in CapabilityType:
|
|
||||||
capability_counts[capability_type.value] = len(self.capability_index[capability_type])
|
|
||||||
|
|
||||||
# Reputation statistics
|
|
||||||
reputations = [a.reputation_score for a in self.agents.values()]
|
|
||||||
avg_reputation = sum(reputations) / len(reputations) if reputations else 0
|
|
||||||
|
|
||||||
# Earnings statistics
|
|
||||||
total_earnings = sum(a.total_earnings for a in self.agents.values())
|
|
||||||
|
|
||||||
return {
|
|
||||||
'total_agents': total_agents,
|
|
||||||
'active_agents': active_agents,
|
|
||||||
'inactive_agents': total_agents - active_agents,
|
|
||||||
'agent_types': type_counts,
|
|
||||||
'capabilities': capability_counts,
|
|
||||||
'average_reputation': avg_reputation,
|
|
||||||
'total_earnings': float(total_earnings),
|
|
||||||
'registration_fee': float(self.registration_fee)
|
|
||||||
}
|
|
||||||
|
|
||||||
async def cleanup_inactive_agents(self) -> Tuple[int, str]:
|
|
||||||
"""Clean up inactive agents"""
|
|
||||||
current_time = time.time()
|
|
||||||
cleaned_count = 0
|
|
||||||
|
|
||||||
for agent_id, agent in list(self.agents.items()):
|
|
||||||
if (agent.status == AgentStatus.INACTIVE and
|
|
||||||
current_time - agent.last_active > self.inactivity_threshold):
|
|
||||||
|
|
||||||
# Remove from registry
|
|
||||||
del self.agents[agent_id]
|
|
||||||
|
|
||||||
# Update indexes
|
|
||||||
self.type_index[agent.agent_type].discard(agent_id)
|
|
||||||
for capability in agent.capabilities:
|
|
||||||
self.capability_index[capability.capability_type].discard(agent_id)
|
|
||||||
|
|
||||||
cleaned_count += 1
|
|
||||||
|
|
||||||
if cleaned_count > 0:
|
|
||||||
log_info(f"Cleaned up {cleaned_count} inactive agents")
|
|
||||||
|
|
||||||
return cleaned_count, f"Cleaned up {cleaned_count} inactive agents"
|
|
||||||
|
|
||||||
# Global agent registry
|
|
||||||
agent_registry: Optional[AgentRegistry] = None
|
|
||||||
|
|
||||||
def get_agent_registry() -> Optional[AgentRegistry]:
|
|
||||||
"""Get global agent registry"""
|
|
||||||
return agent_registry
|
|
||||||
|
|
||||||
def create_agent_registry() -> AgentRegistry:
|
|
||||||
"""Create and set global agent registry"""
|
|
||||||
global agent_registry
|
|
||||||
agent_registry = AgentRegistry()
|
|
||||||
return agent_registry
|
|
||||||
@@ -1,166 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
AITBC Trading Agent
|
|
||||||
Automated trading agent for AITBC marketplace
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import json
|
|
||||||
import time
|
|
||||||
from typing import Dict, Any, List
|
|
||||||
from datetime import datetime
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Add parent directory to path
|
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '../../../..'))
|
|
||||||
|
|
||||||
from apps.agent_services.agent_bridge.src.integration_layer import AgentServiceBridge
|
|
||||||
|
|
||||||
class TradingAgent:
|
|
||||||
"""Automated trading agent"""
|
|
||||||
|
|
||||||
def __init__(self, agent_id: str, config: Dict[str, Any]):
|
|
||||||
self.agent_id = agent_id
|
|
||||||
self.config = config
|
|
||||||
self.bridge = AgentServiceBridge()
|
|
||||||
self.is_running = False
|
|
||||||
self.trading_strategy = config.get("strategy", "basic")
|
|
||||||
self.symbols = config.get("symbols", ["AITBC/BTC"])
|
|
||||||
self.trade_interval = config.get("trade_interval", 60) # seconds
|
|
||||||
|
|
||||||
async def start(self) -> bool:
|
|
||||||
"""Start trading agent"""
|
|
||||||
try:
|
|
||||||
# Register with service bridge
|
|
||||||
success = await self.bridge.start_agent(self.agent_id, {
|
|
||||||
"type": "trading",
|
|
||||||
"capabilities": ["market_analysis", "trading", "risk_management"],
|
|
||||||
"endpoint": f"http://localhost:8005"
|
|
||||||
})
|
|
||||||
|
|
||||||
if success:
|
|
||||||
self.is_running = True
|
|
||||||
print(f"Trading agent {self.agent_id} started successfully")
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
print(f"Failed to start trading agent {self.agent_id}")
|
|
||||||
return False
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error starting trading agent: {e}")
|
|
||||||
return False
|
|
||||||
|
|
||||||
async def stop(self) -> bool:
|
|
||||||
"""Stop trading agent"""
|
|
||||||
self.is_running = False
|
|
||||||
success = await self.bridge.stop_agent(self.agent_id)
|
|
||||||
if success:
|
|
||||||
print(f"Trading agent {self.agent_id} stopped successfully")
|
|
||||||
return success
|
|
||||||
|
|
||||||
async def run_trading_loop(self):
|
|
||||||
"""Main trading loop"""
|
|
||||||
while self.is_running:
|
|
||||||
try:
|
|
||||||
for symbol in self.symbols:
|
|
||||||
await self._analyze_and_trade(symbol)
|
|
||||||
|
|
||||||
await asyncio.sleep(self.trade_interval)
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error in trading loop: {e}")
|
|
||||||
await asyncio.sleep(10) # Wait before retrying
|
|
||||||
|
|
||||||
async def _analyze_and_trade(self, symbol: str) -> None:
|
|
||||||
"""Analyze market and execute trades"""
|
|
||||||
try:
|
|
||||||
# Perform market analysis
|
|
||||||
analysis_task = {
|
|
||||||
"type": "market_analysis",
|
|
||||||
"symbol": symbol,
|
|
||||||
"strategy": self.trading_strategy
|
|
||||||
}
|
|
||||||
|
|
||||||
analysis_result = await self.bridge.execute_agent_task(self.agent_id, analysis_task)
|
|
||||||
|
|
||||||
if analysis_result.get("status") == "success":
|
|
||||||
analysis = analysis_result["result"]["analysis"]
|
|
||||||
|
|
||||||
# Make trading decision
|
|
||||||
if self._should_trade(analysis):
|
|
||||||
await self._execute_trade(symbol, analysis)
|
|
||||||
else:
|
|
||||||
print(f"Market analysis failed for {symbol}: {analysis_result}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error in analyze_and_trade for {symbol}: {e}")
|
|
||||||
|
|
||||||
def _should_trade(self, analysis: Dict[str, Any]) -> bool:
|
|
||||||
"""Determine if should execute trade"""
|
|
||||||
recommendation = analysis.get("recommendation", "hold")
|
|
||||||
return recommendation in ["buy", "sell"]
|
|
||||||
|
|
||||||
async def _execute_trade(self, symbol: str, analysis: Dict[str, Any]) -> None:
|
|
||||||
"""Execute trade based on analysis"""
|
|
||||||
try:
|
|
||||||
recommendation = analysis.get("recommendation", "hold")
|
|
||||||
|
|
||||||
if recommendation == "buy":
|
|
||||||
trade_task = {
|
|
||||||
"type": "trading",
|
|
||||||
"symbol": symbol,
|
|
||||||
"side": "buy",
|
|
||||||
"amount": self.config.get("trade_amount", 0.1),
|
|
||||||
"strategy": self.trading_strategy
|
|
||||||
}
|
|
||||||
elif recommendation == "sell":
|
|
||||||
trade_task = {
|
|
||||||
"type": "trading",
|
|
||||||
"symbol": symbol,
|
|
||||||
"side": "sell",
|
|
||||||
"amount": self.config.get("trade_amount", 0.1),
|
|
||||||
"strategy": self.trading_strategy
|
|
||||||
}
|
|
||||||
else:
|
|
||||||
return
|
|
||||||
|
|
||||||
trade_result = await self.bridge.execute_agent_task(self.agent_id, trade_task)
|
|
||||||
|
|
||||||
if trade_result.get("status") == "success":
|
|
||||||
print(f"Trade executed successfully: {trade_result}")
|
|
||||||
else:
|
|
||||||
print(f"Trade execution failed: {trade_result}")
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error executing trade: {e}")
|
|
||||||
|
|
||||||
async def get_status(self) -> Dict[str, Any]:
|
|
||||||
"""Get agent status"""
|
|
||||||
return await self.bridge.get_agent_status(self.agent_id)
|
|
||||||
|
|
||||||
# Main execution
|
|
||||||
async def main():
|
|
||||||
"""Main trading agent execution"""
|
|
||||||
agent_id = "trading-agent-001"
|
|
||||||
config = {
|
|
||||||
"strategy": "basic",
|
|
||||||
"symbols": ["AITBC/BTC"],
|
|
||||||
"trade_interval": 30,
|
|
||||||
"trade_amount": 0.1
|
|
||||||
}
|
|
||||||
|
|
||||||
agent = TradingAgent(agent_id, config)
|
|
||||||
|
|
||||||
# Start agent
|
|
||||||
if await agent.start():
|
|
||||||
try:
|
|
||||||
# Run trading loop
|
|
||||||
await agent.run_trading_loop()
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("Shutting down trading agent...")
|
|
||||||
finally:
|
|
||||||
await agent.stop()
|
|
||||||
else:
|
|
||||||
print("Failed to start trading agent")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
asyncio.run(main())
|
|
||||||
Reference in New Issue
Block a user