parent
7406320843
commit
7813b59efd
@ -1,326 +0,0 @@
|
||||
# AOP Server Setup Example
|
||||
|
||||
This example demonstrates how to set up an AOP (Agent Orchestration Protocol) server with multiple specialized agents.
|
||||
|
||||
## Complete Server Setup
|
||||
|
||||
```python
|
||||
from swarms import Agent
|
||||
from swarms.structs.aop import AOP
|
||||
|
||||
# Create specialized agents
|
||||
research_agent = Agent(
|
||||
agent_name="Research-Agent",
|
||||
agent_description="Expert in research, data collection, and information gathering",
|
||||
model_name="anthropic/claude-sonnet-4-5",
|
||||
max_loops=1,
|
||||
top_p=None,
|
||||
dynamic_temperature_enabled=True,
|
||||
system_prompt="""You are a research specialist. Your role is to:
|
||||
1. Gather comprehensive information on any given topic
|
||||
2. Analyze data from multiple sources
|
||||
3. Provide well-structured research findings
|
||||
4. Cite sources and maintain accuracy
|
||||
5. Present findings in a clear, organized manner
|
||||
|
||||
Always provide detailed, factual information with proper context.""",
|
||||
)
|
||||
|
||||
analysis_agent = Agent(
|
||||
agent_name="Analysis-Agent",
|
||||
agent_description="Expert in data analysis, pattern recognition, and generating insights",
|
||||
model_name="anthropic/claude-sonnet-4-5",
|
||||
max_loops=1,
|
||||
top_p=None,
|
||||
dynamic_temperature_enabled=True,
|
||||
system_prompt="""You are an analysis specialist. Your role is to:
|
||||
1. Analyze data and identify patterns
|
||||
2. Generate actionable insights
|
||||
3. Create visualizations and summaries
|
||||
4. Provide statistical analysis
|
||||
5. Make data-driven recommendations
|
||||
|
||||
Focus on extracting meaningful insights from information.""",
|
||||
)
|
||||
|
||||
writing_agent = Agent(
|
||||
agent_name="Writing-Agent",
|
||||
agent_description="Expert in content creation, editing, and communication",
|
||||
model_name="anthropic/claude-sonnet-4-5",
|
||||
max_loops=1,
|
||||
top_p=None,
|
||||
dynamic_temperature_enabled=True,
|
||||
system_prompt="""You are a writing specialist. Your role is to:
|
||||
1. Create engaging, well-structured content
|
||||
2. Edit and improve existing text
|
||||
3. Adapt tone and style for different audiences
|
||||
4. Ensure clarity and coherence
|
||||
5. Follow best practices in writing
|
||||
|
||||
Always produce high-quality, professional content.""",
|
||||
)
|
||||
|
||||
code_agent = Agent(
|
||||
agent_name="Code-Agent",
|
||||
agent_description="Expert in programming, code review, and software development",
|
||||
model_name="anthropic/claude-sonnet-4-5",
|
||||
max_loops=1,
|
||||
top_p=None,
|
||||
dynamic_temperature_enabled=True,
|
||||
system_prompt="""You are a coding specialist. Your role is to:
|
||||
1. Write clean, efficient code
|
||||
2. Debug and fix issues
|
||||
3. Review and optimize code
|
||||
4. Explain programming concepts
|
||||
5. Follow best practices and standards
|
||||
|
||||
Always provide working, well-documented code.""",
|
||||
)
|
||||
|
||||
financial_agent = Agent(
|
||||
agent_name="Financial-Agent",
|
||||
agent_description="Expert in financial analysis, market research, and investment insights",
|
||||
model_name="anthropic/claude-sonnet-4-5",
|
||||
max_loops=1,
|
||||
top_p=None,
|
||||
dynamic_temperature_enabled=True,
|
||||
system_prompt="""You are a financial specialist. Your role is to:
|
||||
1. Analyze financial data and markets
|
||||
2. Provide investment insights
|
||||
3. Assess risk and opportunities
|
||||
4. Create financial reports
|
||||
5. Explain complex financial concepts
|
||||
|
||||
Always provide accurate, well-reasoned financial analysis.""",
|
||||
)
|
||||
|
||||
# Create AOP instance
|
||||
deployer = AOP(
|
||||
server_name="MyAgentServer",
|
||||
port=8000,
|
||||
verbose=True,
|
||||
log_level="INFO"
|
||||
)
|
||||
|
||||
# Add all agents at once
|
||||
agents = [
|
||||
research_agent,
|
||||
analysis_agent,
|
||||
writing_agent,
|
||||
code_agent,
|
||||
financial_agent,
|
||||
]
|
||||
|
||||
tool_names = deployer.add_agents_batch(agents)
|
||||
print(f"Added {len(tool_names)} agents: {tool_names}")
|
||||
|
||||
# Display server information
|
||||
server_info = deployer.get_server_info()
|
||||
print(f"Server: {server_info['server_name']}")
|
||||
print(f"Total tools: {server_info['total_tools']}")
|
||||
print(f"Available tools: {server_info['tools']}")
|
||||
|
||||
# Start the server
|
||||
print("Starting AOP server...")
|
||||
deployer.run()
|
||||
```
|
||||
|
||||
## Running the Server
|
||||
|
||||
1. Save the code above to a file (e.g., `aop_server.py`)
|
||||
2. Install required dependencies:
|
||||
|
||||
```bash
|
||||
pip install swarms
|
||||
```
|
||||
|
||||
3. Run the server:
|
||||
|
||||
```bash
|
||||
python aop_server.py
|
||||
```
|
||||
|
||||
The server will start on `http://localhost:8000` and make all agents available as MCP tools.
|
||||
|
||||
## Tool Usage Examples
|
||||
|
||||
Once the server is running, you can call the tools using MCP clients:
|
||||
|
||||
### Research Agent
|
||||
|
||||
```python
|
||||
# Call the research agent
|
||||
result = research_tool(task="Research the latest AI trends in 2024")
|
||||
print(result)
|
||||
```
|
||||
|
||||
### Analysis Agent with Image
|
||||
|
||||
```python
|
||||
# Call the analysis agent with an image
|
||||
result = analysis_tool(
|
||||
task="Analyze this chart and provide insights",
|
||||
img="path/to/chart.png"
|
||||
)
|
||||
print(result)
|
||||
```
|
||||
|
||||
### Writing Agent with Multiple Images
|
||||
|
||||
```python
|
||||
# Call the writing agent with multiple images
|
||||
result = writing_tool(
|
||||
task="Write a comprehensive report based on these images",
|
||||
imgs=["image1.jpg", "image2.jpg", "image3.jpg"]
|
||||
)
|
||||
print(result)
|
||||
```
|
||||
|
||||
### Code Agent with Validation
|
||||
|
||||
```python
|
||||
# Call the code agent with expected output
|
||||
result = code_tool(
|
||||
task="Debug this Python function",
|
||||
correct_answer="Expected output: Hello World"
|
||||
)
|
||||
print(result)
|
||||
```
|
||||
|
||||
### Financial Agent
|
||||
|
||||
```python
|
||||
# Call the financial agent
|
||||
result = financial_tool(task="Analyze the current market trends for tech stocks")
|
||||
print(result)
|
||||
```
|
||||
|
||||
## Response Format
|
||||
|
||||
All tools return a standardized response:
|
||||
|
||||
```json
|
||||
{
|
||||
"result": "The agent's response to the task",
|
||||
"success": true,
|
||||
"error": null
|
||||
}
|
||||
```
|
||||
|
||||
## Advanced Configuration
|
||||
|
||||
### Custom Timeouts and Retries
|
||||
|
||||
```python
|
||||
# Add agent with custom configuration
|
||||
deployer.add_agent(
|
||||
agent=research_agent,
|
||||
tool_name="custom_research_tool",
|
||||
tool_description="Research tool with extended timeout",
|
||||
timeout=120, # 2 minutes
|
||||
max_retries=5,
|
||||
verbose=True
|
||||
)
|
||||
```
|
||||
|
||||
### Custom Input/Output Schemas
|
||||
|
||||
```python
|
||||
# Define custom schemas
|
||||
custom_input_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"task": {"type": "string", "description": "The research task"},
|
||||
"sources": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
"description": "Specific sources to research"
|
||||
},
|
||||
"depth": {
|
||||
"type": "string",
|
||||
"enum": ["shallow", "medium", "deep"],
|
||||
"description": "Research depth level"
|
||||
}
|
||||
},
|
||||
"required": ["task"]
|
||||
}
|
||||
|
||||
# Add agent with custom schemas
|
||||
deployer.add_agent(
|
||||
agent=research_agent,
|
||||
tool_name="advanced_research_tool",
|
||||
input_schema=custom_input_schema,
|
||||
timeout=60
|
||||
)
|
||||
```
|
||||
|
||||
## Monitoring and Debugging
|
||||
|
||||
### Enable Verbose Logging
|
||||
|
||||
```python
|
||||
deployer = AOP(
|
||||
server_name="DebugServer",
|
||||
verbose=True,
|
||||
traceback_enabled=True,
|
||||
log_level="DEBUG"
|
||||
)
|
||||
```
|
||||
|
||||
### Check Server Status
|
||||
|
||||
```python
|
||||
# List all registered agents
|
||||
agents = deployer.list_agents()
|
||||
print(f"Registered agents: {agents}")
|
||||
|
||||
# Get detailed agent information
|
||||
for agent_name in agents:
|
||||
info = deployer.get_agent_info(agent_name)
|
||||
print(f"Agent {agent_name}: {info}")
|
||||
|
||||
# Get server information
|
||||
server_info = deployer.get_server_info()
|
||||
print(f"Server info: {server_info}")
|
||||
```
|
||||
|
||||
## Production Deployment
|
||||
|
||||
### External Access
|
||||
|
||||
```python
|
||||
deployer = AOP(
|
||||
server_name="ProductionServer",
|
||||
host="0.0.0.0", # Allow external connections
|
||||
port=8000,
|
||||
verbose=False, # Disable verbose logging in production
|
||||
log_level="WARNING"
|
||||
)
|
||||
```
|
||||
|
||||
### Multiple Servers
|
||||
|
||||
```python
|
||||
# Server 1: Research and Analysis
|
||||
research_deployer = AOP("ResearchServer", port=8000)
|
||||
research_deployer.add_agent(research_agent)
|
||||
research_deployer.add_agent(analysis_agent)
|
||||
|
||||
# Server 2: Writing and Code
|
||||
content_deployer = AOP("ContentServer", port=8001)
|
||||
content_deployer.add_agent(writing_agent)
|
||||
content_deployer.add_agent(code_agent)
|
||||
|
||||
# Server 3: Financial
|
||||
finance_deployer = AOP("FinanceServer", port=8002)
|
||||
finance_deployer.add_agent(financial_agent)
|
||||
|
||||
# Start all servers
|
||||
import threading
|
||||
|
||||
threading.Thread(target=research_deployer.run).start()
|
||||
threading.Thread(target=content_deployer.run).start()
|
||||
threading.Thread(target=finance_deployer.run).start()
|
||||
```
|
||||
|
||||
This example demonstrates a complete AOP server setup with multiple specialized agents, proper configuration, and production-ready deployment options.
|
@ -1,336 +0,0 @@
|
||||
# AOP Cluster Example
|
||||
|
||||
This example demonstrates how to use AOPCluster to connect to and manage multiple MCP servers running AOP agents.
|
||||
|
||||
## Basic Cluster Setup
|
||||
|
||||
```python
|
||||
import json
|
||||
from swarms.structs.aop import AOPCluster
|
||||
|
||||
# Connect to multiple MCP servers
|
||||
cluster = AOPCluster(
|
||||
urls=[
|
||||
"http://localhost:8000/mcp", # Research and Analysis server
|
||||
"http://localhost:8001/mcp", # Writing and Code server
|
||||
"http://localhost:8002/mcp" # Financial server
|
||||
],
|
||||
transport="streamable-http"
|
||||
)
|
||||
|
||||
# Get all available tools from all servers
|
||||
all_tools = cluster.get_tools(output_type="dict")
|
||||
print(f"Found {len(all_tools)} tools across all servers")
|
||||
|
||||
# Pretty print all tools
|
||||
print(json.dumps(all_tools, indent=2))
|
||||
```
|
||||
|
||||
## Finding Specific Tools
|
||||
|
||||
```python
|
||||
# Find a specific tool by name
|
||||
research_tool = cluster.find_tool_by_server_name("Research-Agent")
|
||||
if research_tool:
|
||||
print("Found Research-Agent tool:")
|
||||
print(json.dumps(research_tool, indent=2))
|
||||
else:
|
||||
print("Research-Agent tool not found")
|
||||
|
||||
# Find multiple tools
|
||||
tool_names = ["Research-Agent", "Analysis-Agent", "Writing-Agent", "Code-Agent"]
|
||||
found_tools = {}
|
||||
|
||||
for tool_name in tool_names:
|
||||
tool = cluster.find_tool_by_server_name(tool_name)
|
||||
if tool:
|
||||
found_tools[tool_name] = tool
|
||||
print(f"✓ Found {tool_name}")
|
||||
else:
|
||||
print(f"✗ {tool_name} not found")
|
||||
|
||||
print(f"Found {len(found_tools)} out of {len(tool_names)} tools")
|
||||
```
|
||||
|
||||
## Tool Discovery and Management
|
||||
|
||||
```python
|
||||
# Get tools in different formats
|
||||
json_tools = cluster.get_tools(output_type="json")
|
||||
dict_tools = cluster.get_tools(output_type="dict")
|
||||
str_tools = cluster.get_tools(output_type="str")
|
||||
|
||||
print(f"JSON format: {len(json_tools)} tools")
|
||||
print(f"Dict format: {len(dict_tools)} tools")
|
||||
print(f"String format: {len(str_tools)} tools")
|
||||
|
||||
# Analyze tool distribution across servers
|
||||
server_tools = {}
|
||||
for tool in dict_tools:
|
||||
server_name = tool.get("server", "unknown")
|
||||
if server_name not in server_tools:
|
||||
server_tools[server_name] = []
|
||||
server_tools[server_name].append(tool.get("function", {}).get("name", "unknown"))
|
||||
|
||||
print("\nTools by server:")
|
||||
for server, tools in server_tools.items():
|
||||
print(f" {server}: {len(tools)} tools - {tools}")
|
||||
```
|
||||
|
||||
## Advanced Cluster Management
|
||||
|
||||
```python
|
||||
class AOPClusterManager:
|
||||
def __init__(self, urls, transport="streamable-http"):
|
||||
self.cluster = AOPCluster(urls, transport)
|
||||
self.tools_cache = {}
|
||||
self.last_update = None
|
||||
|
||||
def refresh_tools(self):
|
||||
"""Refresh the tools cache"""
|
||||
self.tools_cache = {}
|
||||
tools = self.cluster.get_tools(output_type="dict")
|
||||
for tool in tools:
|
||||
tool_name = tool.get("function", {}).get("name")
|
||||
if tool_name:
|
||||
self.tools_cache[tool_name] = tool
|
||||
self.last_update = time.time()
|
||||
return len(self.tools_cache)
|
||||
|
||||
def get_tool(self, tool_name):
|
||||
"""Get a specific tool by name"""
|
||||
if not self.tools_cache or time.time() - self.last_update > 300: # 5 min cache
|
||||
self.refresh_tools()
|
||||
return self.tools_cache.get(tool_name)
|
||||
|
||||
def list_tools_by_category(self):
|
||||
"""Categorize tools by their names"""
|
||||
categories = {
|
||||
"research": [],
|
||||
"analysis": [],
|
||||
"writing": [],
|
||||
"code": [],
|
||||
"financial": [],
|
||||
"other": []
|
||||
}
|
||||
|
||||
for tool_name in self.tools_cache.keys():
|
||||
tool_name_lower = tool_name.lower()
|
||||
if "research" in tool_name_lower:
|
||||
categories["research"].append(tool_name)
|
||||
elif "analysis" in tool_name_lower:
|
||||
categories["analysis"].append(tool_name)
|
||||
elif "writing" in tool_name_lower:
|
||||
categories["writing"].append(tool_name)
|
||||
elif "code" in tool_name_lower:
|
||||
categories["code"].append(tool_name)
|
||||
elif "financial" in tool_name_lower:
|
||||
categories["financial"].append(tool_name)
|
||||
else:
|
||||
categories["other"].append(tool_name)
|
||||
|
||||
return categories
|
||||
|
||||
def get_available_servers(self):
|
||||
"""Get list of available servers"""
|
||||
servers = set()
|
||||
for tool in self.tools_cache.values():
|
||||
server = tool.get("server", "unknown")
|
||||
servers.add(server)
|
||||
return list(servers)
|
||||
|
||||
# Usage example
|
||||
import time
|
||||
|
||||
manager = AOPClusterManager([
|
||||
"http://localhost:8000/mcp",
|
||||
"http://localhost:8001/mcp",
|
||||
"http://localhost:8002/mcp"
|
||||
])
|
||||
|
||||
# Refresh and display tools
|
||||
tool_count = manager.refresh_tools()
|
||||
print(f"Loaded {tool_count} tools")
|
||||
|
||||
# Categorize tools
|
||||
categories = manager.list_tools_by_category()
|
||||
for category, tools in categories.items():
|
||||
if tools:
|
||||
print(f"{category.title()}: {tools}")
|
||||
|
||||
# Get available servers
|
||||
servers = manager.get_available_servers()
|
||||
print(f"Available servers: {servers}")
|
||||
```
|
||||
|
||||
## Error Handling and Resilience
|
||||
|
||||
```python
|
||||
class ResilientAOPCluster:
|
||||
def __init__(self, urls, transport="streamable-http"):
|
||||
self.urls = urls
|
||||
self.transport = transport
|
||||
self.cluster = AOPCluster(urls, transport)
|
||||
self.failed_servers = set()
|
||||
|
||||
def get_tools_with_fallback(self, output_type="dict"):
|
||||
"""Get tools with fallback for failed servers"""
|
||||
try:
|
||||
return self.cluster.get_tools(output_type=output_type)
|
||||
except Exception as e:
|
||||
print(f"Error getting tools: {e}")
|
||||
# Try individual servers
|
||||
all_tools = []
|
||||
for url in self.urls:
|
||||
if url in self.failed_servers:
|
||||
continue
|
||||
try:
|
||||
single_cluster = AOPCluster([url], self.transport)
|
||||
tools = single_cluster.get_tools(output_type=output_type)
|
||||
all_tools.extend(tools)
|
||||
except Exception as server_error:
|
||||
print(f"Server {url} failed: {server_error}")
|
||||
self.failed_servers.add(url)
|
||||
return all_tools
|
||||
|
||||
def find_tool_with_retry(self, tool_name, max_retries=3):
|
||||
"""Find tool with retry logic"""
|
||||
for attempt in range(max_retries):
|
||||
try:
|
||||
return self.cluster.find_tool_by_server_name(tool_name)
|
||||
except Exception as e:
|
||||
print(f"Attempt {attempt + 1} failed: {e}")
|
||||
if attempt < max_retries - 1:
|
||||
time.sleep(2 ** attempt) # Exponential backoff
|
||||
return None
|
||||
|
||||
# Usage
|
||||
resilient_cluster = ResilientAOPCluster([
|
||||
"http://localhost:8000/mcp",
|
||||
"http://localhost:8001/mcp",
|
||||
"http://localhost:8002/mcp"
|
||||
])
|
||||
|
||||
# Get tools with error handling
|
||||
tools = resilient_cluster.get_tools_with_fallback()
|
||||
print(f"Retrieved {len(tools)} tools")
|
||||
|
||||
# Find tool with retry
|
||||
research_tool = resilient_cluster.find_tool_with_retry("Research-Agent")
|
||||
if research_tool:
|
||||
print("Found Research-Agent tool")
|
||||
else:
|
||||
print("Research-Agent tool not found after retries")
|
||||
```
|
||||
|
||||
## Monitoring and Health Checks
|
||||
|
||||
```python
|
||||
class AOPClusterMonitor:
|
||||
def __init__(self, cluster_manager):
|
||||
self.manager = cluster_manager
|
||||
self.health_status = {}
|
||||
|
||||
def check_server_health(self, url):
|
||||
"""Check if a server is healthy"""
|
||||
try:
|
||||
single_cluster = AOPCluster([url], self.manager.cluster.transport)
|
||||
tools = single_cluster.get_tools(output_type="dict")
|
||||
return {
|
||||
"status": "healthy",
|
||||
"tool_count": len(tools),
|
||||
"timestamp": time.time()
|
||||
}
|
||||
except Exception as e:
|
||||
return {
|
||||
"status": "unhealthy",
|
||||
"error": str(e),
|
||||
"timestamp": time.time()
|
||||
}
|
||||
|
||||
def check_all_servers(self):
|
||||
"""Check health of all servers"""
|
||||
for url in self.manager.cluster.urls:
|
||||
health = self.check_server_health(url)
|
||||
self.health_status[url] = health
|
||||
status_icon = "✓" if health["status"] == "healthy" else "✗"
|
||||
print(f"{status_icon} {url}: {health['status']}")
|
||||
if health["status"] == "healthy":
|
||||
print(f" Tools available: {health['tool_count']}")
|
||||
else:
|
||||
print(f" Error: {health['error']}")
|
||||
|
||||
def get_health_summary(self):
|
||||
"""Get summary of server health"""
|
||||
healthy_count = sum(1 for status in self.health_status.values()
|
||||
if status["status"] == "healthy")
|
||||
total_count = len(self.health_status)
|
||||
return {
|
||||
"healthy_servers": healthy_count,
|
||||
"total_servers": total_count,
|
||||
"health_percentage": (healthy_count / total_count) * 100 if total_count > 0 else 0
|
||||
}
|
||||
|
||||
# Usage
|
||||
monitor = AOPClusterMonitor(manager)
|
||||
monitor.check_all_servers()
|
||||
|
||||
summary = monitor.get_health_summary()
|
||||
print(f"Health Summary: {summary['healthy_servers']}/{summary['total_servers']} servers healthy ({summary['health_percentage']:.1f}%)")
|
||||
```
|
||||
|
||||
## Complete Example
|
||||
|
||||
```python
|
||||
import json
|
||||
import time
|
||||
from swarms.structs.aop import AOPCluster
|
||||
|
||||
def main():
|
||||
# Initialize cluster
|
||||
cluster = AOPCluster(
|
||||
urls=[
|
||||
"http://localhost:8000/mcp",
|
||||
"http://localhost:8001/mcp",
|
||||
"http://localhost:8002/mcp"
|
||||
],
|
||||
transport="streamable-http"
|
||||
)
|
||||
|
||||
print("AOP Cluster Management System")
|
||||
print("=" * 40)
|
||||
|
||||
# Get all tools
|
||||
print("\n1. Discovering tools...")
|
||||
tools = cluster.get_tools(output_type="dict")
|
||||
print(f"Found {len(tools)} tools across all servers")
|
||||
|
||||
# List all tool names
|
||||
tool_names = [tool.get("function", {}).get("name") for tool in tools]
|
||||
print(f"Available tools: {tool_names}")
|
||||
|
||||
# Find specific tools
|
||||
print("\n2. Finding specific tools...")
|
||||
target_tools = ["Research-Agent", "Analysis-Agent", "Writing-Agent", "Code-Agent", "Financial-Agent"]
|
||||
|
||||
for tool_name in target_tools:
|
||||
tool = cluster.find_tool_by_server_name(tool_name)
|
||||
if tool:
|
||||
print(f"✓ {tool_name}: Available")
|
||||
else:
|
||||
print(f"✗ {tool_name}: Not found")
|
||||
|
||||
# Display tool details
|
||||
print("\n3. Tool details:")
|
||||
for tool in tools[:3]: # Show first 3 tools
|
||||
print(f"\nTool: {tool.get('function', {}).get('name')}")
|
||||
print(f"Description: {tool.get('function', {}).get('description')}")
|
||||
print(f"Parameters: {list(tool.get('function', {}).get('parameters', {}).get('properties', {}).keys())}")
|
||||
|
||||
print("\nAOP Cluster setup complete!")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
```
|
||||
|
||||
This example demonstrates comprehensive AOP cluster management including tool discovery, error handling, health monitoring, and advanced cluster operations.
|
@ -1,11 +1,68 @@
|
||||
import json
|
||||
import asyncio
|
||||
|
||||
from swarms.structs.aop import AOPCluster
|
||||
from swarms.tools.mcp_client_tools import execute_tool_call_simple
|
||||
|
||||
aop_cluster = AOPCluster(
|
||||
urls=["http://localhost:8000/mcp"],
|
||||
|
||||
async def discover_agents_example():
|
||||
"""Example of how to call the discover_agents tool."""
|
||||
|
||||
# Create AOP cluster connection
|
||||
aop_cluster = AOPCluster(
|
||||
urls=["http://localhost:5932/mcp"],
|
||||
transport="streamable-http",
|
||||
)
|
||||
)
|
||||
|
||||
# Check if discover_agents tool is available
|
||||
discover_tool = aop_cluster.find_tool_by_server_name(
|
||||
"discover_agents"
|
||||
)
|
||||
if discover_tool:
|
||||
try:
|
||||
# Create the tool call request
|
||||
tool_call_request = {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "discover_agents",
|
||||
"arguments": json.dumps(
|
||||
{}
|
||||
), # No specific agent name = get all
|
||||
},
|
||||
}
|
||||
|
||||
# Execute the tool call
|
||||
result = await execute_tool_call_simple(
|
||||
response=tool_call_request,
|
||||
server_path="http://localhost:5932/mcp",
|
||||
output_type="dict",
|
||||
verbose=False,
|
||||
)
|
||||
|
||||
print(json.dumps(result, indent=2))
|
||||
|
||||
# Parse the result
|
||||
if isinstance(result, list) and len(result) > 0:
|
||||
discovery_data = result[0]
|
||||
if discovery_data.get("success"):
|
||||
agents = discovery_data.get("agents", [])
|
||||
return agents
|
||||
else:
|
||||
return None
|
||||
else:
|
||||
return None
|
||||
|
||||
except Exception:
|
||||
return None
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def main():
|
||||
"""Main function to run the discovery example."""
|
||||
# Run the async function
|
||||
return asyncio.run(discover_agents_example())
|
||||
|
||||
|
||||
print(json.dumps(aop_cluster.get_tools(output_type="dict"), indent=4))
|
||||
print(aop_cluster.find_tool_by_server_name("Research-Agent"))
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
@ -1,318 +0,0 @@
|
||||
# AOP Server Setup Example
|
||||
|
||||
This example demonstrates how to set up an AOP (Agent Orchestration Protocol) server with multiple specialized agents.
|
||||
|
||||
## Complete Server Setup
|
||||
|
||||
```python
|
||||
from swarms import Agent
|
||||
from swarms.structs.aop import AOP
|
||||
|
||||
# Create specialized agents
|
||||
research_agent = Agent(
|
||||
agent_name="Research-Agent",
|
||||
agent_description="Expert in research, data collection, and information gathering",
|
||||
model_name="anthropic/claude-sonnet-4-5",
|
||||
max_loops=1,
|
||||
top_p=None,
|
||||
dynamic_temperature_enabled=True,
|
||||
system_prompt="""You are a research specialist. Your role is to:
|
||||
1. Gather comprehensive information on any given topic
|
||||
2. Analyze data from multiple sources
|
||||
3. Provide well-structured research findings
|
||||
4. Cite sources and maintain accuracy
|
||||
5. Present findings in a clear, organized manner
|
||||
|
||||
Always provide detailed, factual information with proper context.""",
|
||||
)
|
||||
|
||||
analysis_agent = Agent(
|
||||
agent_name="Analysis-Agent",
|
||||
agent_description="Expert in data analysis, pattern recognition, and generating insights",
|
||||
model_name="anthropic/claude-sonnet-4-5",
|
||||
max_loops=1,
|
||||
top_p=None,
|
||||
dynamic_temperature_enabled=True,
|
||||
system_prompt="""You are an analysis specialist. Your role is to:
|
||||
1. Analyze data and identify patterns
|
||||
2. Generate actionable insights
|
||||
3. Create visualizations and summaries
|
||||
4. Provide statistical analysis
|
||||
5. Make data-driven recommendations
|
||||
|
||||
Focus on extracting meaningful insights from information.""",
|
||||
)
|
||||
|
||||
writing_agent = Agent(
|
||||
agent_name="Writing-Agent",
|
||||
agent_description="Expert in content creation, editing, and communication",
|
||||
model_name="anthropic/claude-sonnet-4-5",
|
||||
max_loops=1,
|
||||
top_p=None,
|
||||
dynamic_temperature_enabled=True,
|
||||
system_prompt="""You are a writing specialist. Your role is to:
|
||||
1. Create engaging, well-structured content
|
||||
2. Edit and improve existing text
|
||||
3. Adapt tone and style for different audiences
|
||||
4. Ensure clarity and coherence
|
||||
5. Follow best practices in writing
|
||||
|
||||
Always produce high-quality, professional content.""",
|
||||
)
|
||||
|
||||
code_agent = Agent(
|
||||
agent_name="Code-Agent",
|
||||
agent_description="Expert in programming, code review, and software development",
|
||||
model_name="anthropic/claude-sonnet-4-5",
|
||||
max_loops=1,
|
||||
top_p=None,
|
||||
dynamic_temperature_enabled=True,
|
||||
system_prompt="""You are a coding specialist. Your role is to:
|
||||
1. Write clean, efficient code
|
||||
2. Debug and fix issues
|
||||
3. Review and optimize code
|
||||
4. Explain programming concepts
|
||||
5. Follow best practices and standards
|
||||
|
||||
Always provide working, well-documented code.""",
|
||||
)
|
||||
|
||||
financial_agent = Agent(
|
||||
agent_name="Financial-Agent",
|
||||
agent_description="Expert in financial analysis, market research, and investment insights",
|
||||
model_name="anthropic/claude-sonnet-4-5",
|
||||
max_loops=1,
|
||||
top_p=None,
|
||||
dynamic_temperature_enabled=True,
|
||||
system_prompt="""You are a financial specialist. Your role is to:
|
||||
1. Analyze financial data and markets
|
||||
2. Provide investment insights
|
||||
3. Assess risk and opportunities
|
||||
4. Create financial reports
|
||||
5. Explain complex financial concepts
|
||||
|
||||
Always provide accurate, well-reasoned financial analysis.""",
|
||||
)
|
||||
|
||||
# Create AOP instance
|
||||
deployer = AOP(
|
||||
server_name="MyAgentServer",
|
||||
port=8000,
|
||||
verbose=True,
|
||||
log_level="INFO"
|
||||
)
|
||||
|
||||
# Add all agents at once
|
||||
agents = [
|
||||
research_agent,
|
||||
analysis_agent,
|
||||
writing_agent,
|
||||
code_agent,
|
||||
financial_agent,
|
||||
]
|
||||
|
||||
tool_names = deployer.add_agents_batch(agents)
|
||||
print(f"Added {len(tool_names)} agents: {tool_names}")
|
||||
|
||||
# Display server information
|
||||
server_info = deployer.get_server_info()
|
||||
print(f"Server: {server_info['server_name']}")
|
||||
print(f"Total tools: {server_info['total_tools']}")
|
||||
print(f"Available tools: {server_info['tools']}")
|
||||
|
||||
# Start the server
|
||||
print("Starting AOP server...")
|
||||
deployer.run()
|
||||
```
|
||||
|
||||
## Running the Server
|
||||
|
||||
1. Save the code above to a file (e.g., `aop_server.py`)
|
||||
2. Install required dependencies:
|
||||
```bash
|
||||
pip install swarms
|
||||
```
|
||||
3. Run the server:
|
||||
```bash
|
||||
python aop_server.py
|
||||
```
|
||||
|
||||
The server will start on `http://localhost:8000` and make all agents available as MCP tools.
|
||||
|
||||
## Tool Usage Examples
|
||||
|
||||
Once the server is running, you can call the tools using MCP clients:
|
||||
|
||||
### Research Agent
|
||||
```python
|
||||
# Call the research agent
|
||||
result = research_tool(task="Research the latest AI trends in 2024")
|
||||
print(result)
|
||||
```
|
||||
|
||||
### Analysis Agent with Image
|
||||
```python
|
||||
# Call the analysis agent with an image
|
||||
result = analysis_tool(
|
||||
task="Analyze this chart and provide insights",
|
||||
img="path/to/chart.png"
|
||||
)
|
||||
print(result)
|
||||
```
|
||||
|
||||
### Writing Agent with Multiple Images
|
||||
```python
|
||||
# Call the writing agent with multiple images
|
||||
result = writing_tool(
|
||||
task="Write a comprehensive report based on these images",
|
||||
imgs=["image1.jpg", "image2.jpg", "image3.jpg"]
|
||||
)
|
||||
print(result)
|
||||
```
|
||||
|
||||
### Code Agent with Validation
|
||||
```python
|
||||
# Call the code agent with expected output
|
||||
result = code_tool(
|
||||
task="Debug this Python function",
|
||||
correct_answer="Expected output: Hello World"
|
||||
)
|
||||
print(result)
|
||||
```
|
||||
|
||||
### Financial Agent
|
||||
```python
|
||||
# Call the financial agent
|
||||
result = financial_tool(task="Analyze the current market trends for tech stocks")
|
||||
print(result)
|
||||
```
|
||||
|
||||
## Response Format
|
||||
|
||||
All tools return a standardized response:
|
||||
|
||||
```json
|
||||
{
|
||||
"result": "The agent's response to the task",
|
||||
"success": true,
|
||||
"error": null
|
||||
}
|
||||
```
|
||||
|
||||
## Advanced Configuration
|
||||
|
||||
### Custom Timeouts and Retries
|
||||
|
||||
```python
|
||||
# Add agent with custom configuration
|
||||
deployer.add_agent(
|
||||
agent=research_agent,
|
||||
tool_name="custom_research_tool",
|
||||
tool_description="Research tool with extended timeout",
|
||||
timeout=120, # 2 minutes
|
||||
max_retries=5,
|
||||
verbose=True
|
||||
)
|
||||
```
|
||||
|
||||
### Custom Input/Output Schemas
|
||||
|
||||
```python
|
||||
# Define custom schemas
|
||||
custom_input_schema = {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"task": {"type": "string", "description": "The research task"},
|
||||
"sources": {
|
||||
"type": "array",
|
||||
"items": {"type": "string"},
|
||||
"description": "Specific sources to research"
|
||||
},
|
||||
"depth": {
|
||||
"type": "string",
|
||||
"enum": ["shallow", "medium", "deep"],
|
||||
"description": "Research depth level"
|
||||
}
|
||||
},
|
||||
"required": ["task"]
|
||||
}
|
||||
|
||||
# Add agent with custom schemas
|
||||
deployer.add_agent(
|
||||
agent=research_agent,
|
||||
tool_name="advanced_research_tool",
|
||||
input_schema=custom_input_schema,
|
||||
timeout=60
|
||||
)
|
||||
```
|
||||
|
||||
## Monitoring and Debugging
|
||||
|
||||
### Enable Verbose Logging
|
||||
|
||||
```python
|
||||
deployer = AOP(
|
||||
server_name="DebugServer",
|
||||
verbose=True,
|
||||
traceback_enabled=True,
|
||||
log_level="DEBUG"
|
||||
)
|
||||
```
|
||||
|
||||
### Check Server Status
|
||||
|
||||
```python
|
||||
# List all registered agents
|
||||
agents = deployer.list_agents()
|
||||
print(f"Registered agents: {agents}")
|
||||
|
||||
# Get detailed agent information
|
||||
for agent_name in agents:
|
||||
info = deployer.get_agent_info(agent_name)
|
||||
print(f"Agent {agent_name}: {info}")
|
||||
|
||||
# Get server information
|
||||
server_info = deployer.get_server_info()
|
||||
print(f"Server info: {server_info}")
|
||||
```
|
||||
|
||||
## Production Deployment
|
||||
|
||||
### External Access
|
||||
|
||||
```python
|
||||
deployer = AOP(
|
||||
server_name="ProductionServer",
|
||||
host="0.0.0.0", # Allow external connections
|
||||
port=8000,
|
||||
verbose=False, # Disable verbose logging in production
|
||||
log_level="WARNING"
|
||||
)
|
||||
```
|
||||
|
||||
### Multiple Servers
|
||||
|
||||
```python
|
||||
# Server 1: Research and Analysis
|
||||
research_deployer = AOP("ResearchServer", port=8000)
|
||||
research_deployer.add_agent(research_agent)
|
||||
research_deployer.add_agent(analysis_agent)
|
||||
|
||||
# Server 2: Writing and Code
|
||||
content_deployer = AOP("ContentServer", port=8001)
|
||||
content_deployer.add_agent(writing_agent)
|
||||
content_deployer.add_agent(code_agent)
|
||||
|
||||
# Server 3: Financial
|
||||
finance_deployer = AOP("FinanceServer", port=8002)
|
||||
finance_deployer.add_agent(financial_agent)
|
||||
|
||||
# Start all servers
|
||||
import threading
|
||||
|
||||
threading.Thread(target=research_deployer.run).start()
|
||||
threading.Thread(target=content_deployer.run).start()
|
||||
threading.Thread(target=finance_deployer.run).start()
|
||||
```
|
||||
|
||||
This example demonstrates a complete AOP server setup with multiple specialized agents, proper configuration, and production-ready deployment options.
|
@ -0,0 +1,177 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Example showing how agents can use the discovery tool to learn about each other
|
||||
and collaborate more effectively.
|
||||
"""
|
||||
|
||||
from swarms import Agent
|
||||
from swarms.structs.aop import AOP
|
||||
|
||||
|
||||
def simulate_agent_discovery():
|
||||
"""Simulate how an agent would use the discovery tool."""
|
||||
|
||||
# Create a sample agent that will use the discovery tool
|
||||
coordinator_agent = Agent(
|
||||
agent_name="ProjectCoordinator",
|
||||
agent_description="Coordinates projects and assigns tasks to other agents",
|
||||
system_prompt="You are a project coordinator who helps organize work and delegate tasks to the most appropriate team members. You can discover information about other agents to make better decisions.",
|
||||
model_name="gpt-4o-mini",
|
||||
temperature=0.4,
|
||||
)
|
||||
|
||||
# Create the AOP cluster
|
||||
aop = AOP(
|
||||
server_name="Project Team",
|
||||
description="A team of specialized agents for project coordination",
|
||||
verbose=True,
|
||||
)
|
||||
|
||||
# Add some specialized agents
|
||||
data_agent = Agent(
|
||||
agent_name="DataSpecialist",
|
||||
agent_description="Handles all data-related tasks and analysis",
|
||||
system_prompt="You are a data specialist with expertise in data processing, analysis, and visualization. You work with large datasets and create insights.",
|
||||
tags=["data", "analysis", "python", "sql", "statistics"],
|
||||
capabilities=[
|
||||
"data_processing",
|
||||
"statistical_analysis",
|
||||
"visualization",
|
||||
],
|
||||
role="specialist",
|
||||
)
|
||||
|
||||
code_agent = Agent(
|
||||
agent_name="CodeSpecialist",
|
||||
agent_description="Handles all coding and development tasks",
|
||||
system_prompt="You are a software development specialist who writes clean, efficient code and follows best practices. You handle both frontend and backend development.",
|
||||
tags=[
|
||||
"coding",
|
||||
"development",
|
||||
"python",
|
||||
"javascript",
|
||||
"react",
|
||||
],
|
||||
capabilities=[
|
||||
"software_development",
|
||||
"code_review",
|
||||
"debugging",
|
||||
],
|
||||
role="developer",
|
||||
)
|
||||
|
||||
writing_agent = Agent(
|
||||
agent_name="ContentSpecialist",
|
||||
agent_description="Creates and manages all written content",
|
||||
system_prompt="You are a content specialist who creates engaging written content, documentation, and marketing materials. You ensure all content is clear and compelling.",
|
||||
tags=["writing", "content", "documentation", "marketing"],
|
||||
capabilities=[
|
||||
"content_creation",
|
||||
"technical_writing",
|
||||
"editing",
|
||||
],
|
||||
role="writer",
|
||||
)
|
||||
|
||||
# Add agents to the cluster
|
||||
aop.add_agent(data_agent, tool_name="data_specialist")
|
||||
aop.add_agent(code_agent, tool_name="code_specialist")
|
||||
aop.add_agent(writing_agent, tool_name="content_specialist")
|
||||
|
||||
print("🏢 Project Team AOP Cluster Created!")
|
||||
print(f"👥 Team members: {aop.list_agents()}")
|
||||
print()
|
||||
|
||||
# Simulate the coordinator discovering team members
|
||||
print("🔍 Project Coordinator discovering team capabilities...")
|
||||
print()
|
||||
|
||||
# Get discovery info for each agent
|
||||
for tool_name in aop.list_agents():
|
||||
if (
|
||||
tool_name != "discover_agents"
|
||||
): # Skip the discovery tool itself
|
||||
agent_info = aop._get_agent_discovery_info(tool_name)
|
||||
if agent_info:
|
||||
print(f"📋 {agent_info['agent_name']}:")
|
||||
print(f" Description: {agent_info['description']}")
|
||||
print(f" Role: {agent_info['role']}")
|
||||
print(f" Tags: {', '.join(agent_info['tags'])}")
|
||||
print(
|
||||
f" Capabilities: {', '.join(agent_info['capabilities'])}"
|
||||
)
|
||||
print(
|
||||
f" System Prompt: {agent_info['short_system_prompt'][:100]}..."
|
||||
)
|
||||
print()
|
||||
|
||||
print("💡 How agents would use this in practice:")
|
||||
print(" 1. Agent calls 'discover_agents' MCP tool")
|
||||
print(" 2. Gets information about all available agents")
|
||||
print(
|
||||
" 3. Uses this info to make informed decisions about task delegation"
|
||||
)
|
||||
print(
|
||||
" 4. Can discover specific agents by name for targeted collaboration"
|
||||
)
|
||||
print()
|
||||
|
||||
# Show what the MCP tool response would look like
|
||||
print("📡 Sample MCP tool response structure:")
|
||||
sample_response = {
|
||||
"success": True,
|
||||
"agents": [
|
||||
{
|
||||
"tool_name": "data_specialist",
|
||||
"agent_name": "DataSpecialist",
|
||||
"description": "Handles all data-related tasks and analysis",
|
||||
"short_system_prompt": "You are a data specialist with expertise in data processing, analysis, and visualization...",
|
||||
"tags": [
|
||||
"data",
|
||||
"analysis",
|
||||
"python",
|
||||
"sql",
|
||||
"statistics",
|
||||
],
|
||||
"capabilities": [
|
||||
"data_processing",
|
||||
"statistical_analysis",
|
||||
"visualization",
|
||||
],
|
||||
"role": "specialist",
|
||||
"model_name": "gpt-4o-mini",
|
||||
"max_loops": 1,
|
||||
"temperature": 0.5,
|
||||
"max_tokens": 4096,
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
print(" discover_agents() -> {")
|
||||
print(" 'success': True,")
|
||||
print(" 'agents': [")
|
||||
print(" {")
|
||||
print(" 'tool_name': 'data_specialist',")
|
||||
print(" 'agent_name': 'DataSpecialist',")
|
||||
print(
|
||||
" 'description': 'Handles all data-related tasks...',"
|
||||
)
|
||||
print(
|
||||
" 'short_system_prompt': 'You are a data specialist...',"
|
||||
)
|
||||
print(" 'tags': ['data', 'analysis', 'python'],")
|
||||
print(
|
||||
" 'capabilities': ['data_processing', 'statistics'],"
|
||||
)
|
||||
print(" 'role': 'specialist',")
|
||||
print(" ...")
|
||||
print(" }")
|
||||
print(" ]")
|
||||
print(" }")
|
||||
print()
|
||||
|
||||
print("✅ Agent discovery system ready for collaborative work!")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
simulate_agent_discovery()
|
@ -0,0 +1,117 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Example demonstrating the new agent discovery MCP tool in AOP.
|
||||
|
||||
This example shows how agents can discover information about each other
|
||||
using the new 'discover_agents' MCP tool.
|
||||
"""
|
||||
|
||||
from swarms import Agent
|
||||
from swarms.structs.aop import AOP
|
||||
|
||||
|
||||
def main():
|
||||
"""Demonstrate the agent discovery functionality."""
|
||||
|
||||
# Create some sample agents with different configurations
|
||||
agent1 = Agent(
|
||||
agent_name="DataAnalyst",
|
||||
agent_description="Specialized in data analysis and visualization",
|
||||
system_prompt="You are a data analyst with expertise in Python, pandas, and statistical analysis. You help users understand data patterns and create visualizations.",
|
||||
tags=["data", "analysis", "python", "pandas"],
|
||||
capabilities=["data_analysis", "visualization", "statistics"],
|
||||
role="analyst",
|
||||
model_name="gpt-4o-mini",
|
||||
temperature=0.3,
|
||||
)
|
||||
|
||||
agent2 = Agent(
|
||||
agent_name="CodeReviewer",
|
||||
agent_description="Expert code reviewer and quality assurance specialist",
|
||||
system_prompt="You are a senior software engineer who specializes in code review, best practices, and quality assurance. You help identify bugs, suggest improvements, and ensure code follows industry standards.",
|
||||
tags=["code", "review", "quality", "python", "javascript"],
|
||||
capabilities=[
|
||||
"code_review",
|
||||
"quality_assurance",
|
||||
"best_practices",
|
||||
],
|
||||
role="reviewer",
|
||||
model_name="gpt-4o-mini",
|
||||
temperature=0.2,
|
||||
)
|
||||
|
||||
agent3 = Agent(
|
||||
agent_name="CreativeWriter",
|
||||
agent_description="Creative content writer and storyteller",
|
||||
system_prompt="You are a creative writer who specializes in storytelling, content creation, and engaging narratives. You help create compelling stories, articles, and marketing content.",
|
||||
tags=["writing", "creative", "content", "storytelling"],
|
||||
capabilities=[
|
||||
"creative_writing",
|
||||
"content_creation",
|
||||
"storytelling",
|
||||
],
|
||||
role="writer",
|
||||
model_name="gpt-4o-mini",
|
||||
temperature=0.8,
|
||||
)
|
||||
|
||||
# Create AOP cluster with the agents
|
||||
aop = AOP(
|
||||
server_name="Agent Discovery Demo",
|
||||
description="A demo cluster showing agent discovery capabilities",
|
||||
agents=[agent1, agent2, agent3],
|
||||
verbose=True,
|
||||
)
|
||||
|
||||
print("🚀 AOP Cluster initialized with agent discovery tool!")
|
||||
print(f"📊 Total agents registered: {len(aop.agents)}")
|
||||
print(f"🔧 Available tools: {aop.list_agents()}")
|
||||
print()
|
||||
|
||||
# Demonstrate the discovery tool
|
||||
print("🔍 Testing agent discovery functionality...")
|
||||
print()
|
||||
|
||||
# Test discovering all agents
|
||||
print("1. Discovering all agents:")
|
||||
all_agents_info = aop._get_agent_discovery_info(
|
||||
"DataAnalyst"
|
||||
) # This would normally be called via MCP
|
||||
print(
|
||||
f" Found agent: {all_agents_info['agent_name'] if all_agents_info else 'None'}"
|
||||
)
|
||||
print()
|
||||
|
||||
# Show what the MCP tool would return
|
||||
print("2. What the 'discover_agents' MCP tool would return:")
|
||||
print(" - Tool name: discover_agents")
|
||||
print(
|
||||
" - Description: Discover information about other agents in the cluster"
|
||||
)
|
||||
print(" - Parameters: agent_name (optional)")
|
||||
print(
|
||||
" - Returns: Agent info including name, description, short system prompt, tags, capabilities, role, etc."
|
||||
)
|
||||
print()
|
||||
|
||||
# Show sample agent info structure
|
||||
if all_agents_info:
|
||||
print("3. Sample agent discovery info structure:")
|
||||
for key, value in all_agents_info.items():
|
||||
if key == "short_system_prompt":
|
||||
print(f" {key}: {value[:100]}...")
|
||||
else:
|
||||
print(f" {key}: {value}")
|
||||
print()
|
||||
|
||||
print("✅ Agent discovery tool successfully integrated!")
|
||||
print(
|
||||
"💡 Agents can now use the 'discover_agents' MCP tool to learn about each other."
|
||||
)
|
||||
print(
|
||||
"🔄 The tool is automatically updated when new agents are added to the cluster."
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -0,0 +1,231 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Simple example showing how to call the discover_agents tool synchronously.
|
||||
"""
|
||||
|
||||
import json
|
||||
import asyncio
|
||||
from swarms.structs.aop import AOPCluster
|
||||
from swarms.tools.mcp_client_tools import execute_tool_call_simple
|
||||
|
||||
|
||||
def call_discover_agents_sync(server_url="http://localhost:5932/mcp"):
|
||||
"""
|
||||
Synchronously call the discover_agents tool.
|
||||
|
||||
Args:
|
||||
server_url: URL of the MCP server
|
||||
|
||||
Returns:
|
||||
Dict containing the discovery results
|
||||
"""
|
||||
|
||||
# Create the tool call request
|
||||
tool_call_request = {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "discover_agents",
|
||||
"arguments": json.dumps({}), # Empty = get all agents
|
||||
},
|
||||
}
|
||||
|
||||
# Run the async function
|
||||
return asyncio.run(
|
||||
execute_tool_call_simple(
|
||||
response=tool_call_request,
|
||||
server_path=server_url,
|
||||
output_type="dict",
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def call_discover_specific_agent_sync(
|
||||
agent_name, server_url="http://localhost:5932/mcp"
|
||||
):
|
||||
"""
|
||||
Synchronously call the discover_agents tool for a specific agent.
|
||||
|
||||
Args:
|
||||
agent_name: Name of the specific agent to discover
|
||||
server_url: URL of the MCP server
|
||||
|
||||
Returns:
|
||||
Dict containing the discovery results
|
||||
"""
|
||||
|
||||
# Create the tool call request
|
||||
tool_call_request = {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "discover_agents",
|
||||
"arguments": json.dumps({"agent_name": agent_name}),
|
||||
},
|
||||
}
|
||||
|
||||
# Run the async function
|
||||
return asyncio.run(
|
||||
execute_tool_call_simple(
|
||||
response=tool_call_request,
|
||||
server_path=server_url,
|
||||
output_type="dict",
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
"""Main function demonstrating discovery tool usage."""
|
||||
|
||||
print("🔍 AOP Agent Discovery Tool Example")
|
||||
print("=" * 40)
|
||||
print()
|
||||
|
||||
# First, check what tools are available
|
||||
print("1. Checking available MCP tools...")
|
||||
aop_cluster = AOPCluster(
|
||||
urls=["http://localhost:5932/mcp"],
|
||||
transport="streamable-http",
|
||||
)
|
||||
|
||||
tools = aop_cluster.get_tools(output_type="dict")
|
||||
print(f" Found {len(tools)} tools")
|
||||
|
||||
# Check if discover_agents is available
|
||||
discover_tool = aop_cluster.find_tool_by_server_name(
|
||||
"discover_agents"
|
||||
)
|
||||
if not discover_tool:
|
||||
print("❌ discover_agents tool not found!")
|
||||
print(
|
||||
" Make sure your AOP server is running with agents registered."
|
||||
)
|
||||
return
|
||||
|
||||
print("✅ discover_agents tool found!")
|
||||
print()
|
||||
|
||||
# Discover all agents
|
||||
print("2. Discovering all agents...")
|
||||
try:
|
||||
result = call_discover_agents_sync()
|
||||
|
||||
if isinstance(result, list) and len(result) > 0:
|
||||
discovery_data = result[0]
|
||||
|
||||
if discovery_data.get("success"):
|
||||
agents = discovery_data.get("agents", [])
|
||||
print(f" ✅ Found {len(agents)} agents:")
|
||||
|
||||
for i, agent in enumerate(agents, 1):
|
||||
print(
|
||||
f" {i}. {agent.get('agent_name', 'Unknown')}"
|
||||
)
|
||||
print(
|
||||
f" Role: {agent.get('role', 'worker')}"
|
||||
)
|
||||
print(
|
||||
f" Description: {agent.get('description', 'No description')}"
|
||||
)
|
||||
print(
|
||||
f" Tags: {', '.join(agent.get('tags', []))}"
|
||||
)
|
||||
print(
|
||||
f" Capabilities: {', '.join(agent.get('capabilities', []))}"
|
||||
)
|
||||
print(
|
||||
f" System Prompt: {agent.get('short_system_prompt', 'No prompt')[:100]}..."
|
||||
)
|
||||
print()
|
||||
else:
|
||||
print(
|
||||
f" ❌ Discovery failed: {discovery_data.get('error', 'Unknown error')}"
|
||||
)
|
||||
else:
|
||||
print(" ❌ No valid result returned")
|
||||
|
||||
except Exception as e:
|
||||
print(f" ❌ Error: {e}")
|
||||
|
||||
print()
|
||||
|
||||
# Example of discovering a specific agent (if any exist)
|
||||
print("3. Example: Discovering a specific agent...")
|
||||
try:
|
||||
# Try to discover the first agent specifically
|
||||
if isinstance(result, list) and len(result) > 0:
|
||||
discovery_data = result[0]
|
||||
if discovery_data.get("success") and discovery_data.get(
|
||||
"agents"
|
||||
):
|
||||
first_agent_name = discovery_data["agents"][0].get(
|
||||
"agent_name"
|
||||
)
|
||||
if first_agent_name:
|
||||
print(
|
||||
f" Looking for specific agent: {first_agent_name}"
|
||||
)
|
||||
specific_result = (
|
||||
call_discover_specific_agent_sync(
|
||||
first_agent_name
|
||||
)
|
||||
)
|
||||
|
||||
if (
|
||||
isinstance(specific_result, list)
|
||||
and len(specific_result) > 0
|
||||
):
|
||||
specific_data = specific_result[0]
|
||||
if specific_data.get("success"):
|
||||
agent = specific_data.get("agents", [{}])[
|
||||
0
|
||||
]
|
||||
print(
|
||||
f" ✅ Found specific agent: {agent.get('agent_name', 'Unknown')}"
|
||||
)
|
||||
print(
|
||||
f" Model: {agent.get('model_name', 'Unknown')}"
|
||||
)
|
||||
print(
|
||||
f" Max Loops: {agent.get('max_loops', 1)}"
|
||||
)
|
||||
print(
|
||||
f" Temperature: {agent.get('temperature', 0.5)}"
|
||||
)
|
||||
else:
|
||||
print(
|
||||
f" ❌ Specific discovery failed: {specific_data.get('error')}"
|
||||
)
|
||||
else:
|
||||
print(" ❌ No valid specific result")
|
||||
else:
|
||||
print(
|
||||
" ⚠️ No agents found to test specific discovery"
|
||||
)
|
||||
else:
|
||||
print(
|
||||
" ⚠️ No agents available for specific discovery"
|
||||
)
|
||||
else:
|
||||
print(
|
||||
" ⚠️ No previous discovery results to use for specific discovery"
|
||||
)
|
||||
|
||||
except Exception as e:
|
||||
print(f" ❌ Error in specific discovery: {e}")
|
||||
|
||||
print()
|
||||
print("✅ Discovery tool demonstration complete!")
|
||||
print()
|
||||
print("💡 Usage Summary:")
|
||||
print(
|
||||
" • Call discover_agents() with no arguments to get all agents"
|
||||
)
|
||||
print(
|
||||
" • Call discover_agents(agent_name='AgentName') to get specific agent"
|
||||
)
|
||||
print(
|
||||
" • Each agent returns: name, description, role, tags, capabilities, system prompt, etc."
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@ -0,0 +1,198 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script to verify the agent discovery functionality works correctly.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
# Add the swarms directory to the path
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "swarms"))
|
||||
|
||||
from swarms import Agent
|
||||
from swarms.structs.aop import AOP
|
||||
|
||||
|
||||
def test_agent_discovery():
|
||||
"""Test the agent discovery functionality."""
|
||||
|
||||
print("🧪 Testing AOP Agent Discovery Functionality")
|
||||
print("=" * 50)
|
||||
|
||||
# Create test agents
|
||||
agent1 = Agent(
|
||||
agent_name="TestAgent1",
|
||||
agent_description="First test agent for discovery",
|
||||
system_prompt="This is a test agent with a very long system prompt that should be truncated to 200 characters when returned by the discovery tool. This prompt contains detailed instructions about how the agent should behave and what tasks it can perform.",
|
||||
tags=["test", "agent", "discovery"],
|
||||
capabilities=["testing", "validation"],
|
||||
role="tester",
|
||||
)
|
||||
|
||||
agent2 = Agent(
|
||||
agent_name="TestAgent2",
|
||||
agent_description="Second test agent for discovery",
|
||||
system_prompt="Another test agent with different capabilities and a shorter prompt.",
|
||||
tags=["test", "agent", "analysis"],
|
||||
capabilities=["analysis", "reporting"],
|
||||
role="analyst",
|
||||
)
|
||||
|
||||
# Create AOP cluster
|
||||
aop = AOP(
|
||||
server_name="Test Cluster",
|
||||
description="Test cluster for agent discovery",
|
||||
verbose=False,
|
||||
)
|
||||
|
||||
# Add agents
|
||||
aop.add_agent(agent1, tool_name="test_agent_1")
|
||||
aop.add_agent(agent2, tool_name="test_agent_2")
|
||||
|
||||
print(f"✅ Created AOP cluster with {len(aop.agents)} agents")
|
||||
print(f"📋 Available tools: {aop.list_agents()}")
|
||||
print()
|
||||
|
||||
# Test discovery functionality
|
||||
print("🔍 Testing agent discovery...")
|
||||
|
||||
# Test getting info for specific agent
|
||||
agent1_info = aop._get_agent_discovery_info("test_agent_1")
|
||||
assert (
|
||||
agent1_info is not None
|
||||
), "Should be able to get info for test_agent_1"
|
||||
assert (
|
||||
agent1_info["agent_name"] == "TestAgent1"
|
||||
), "Agent name should match"
|
||||
assert (
|
||||
agent1_info["description"] == "First test agent for discovery"
|
||||
), "Description should match"
|
||||
assert (
|
||||
len(agent1_info["short_system_prompt"]) <= 203
|
||||
), "System prompt should be truncated to ~200 chars"
|
||||
assert "test" in agent1_info["tags"], "Tags should include 'test'"
|
||||
assert (
|
||||
"testing" in agent1_info["capabilities"]
|
||||
), "Capabilities should include 'testing'"
|
||||
assert agent1_info["role"] == "tester", "Role should be 'tester'"
|
||||
|
||||
print("✅ Specific agent discovery test passed")
|
||||
|
||||
# Test getting info for non-existent agent
|
||||
non_existent_info = aop._get_agent_discovery_info(
|
||||
"non_existent_agent"
|
||||
)
|
||||
assert (
|
||||
non_existent_info is None
|
||||
), "Should return None for non-existent agent"
|
||||
|
||||
print("✅ Non-existent agent test passed")
|
||||
|
||||
# Test that discovery tool is registered
|
||||
# Note: In a real scenario, this would be tested via MCP tool calls
|
||||
# For now, we just verify the method exists and works
|
||||
try:
|
||||
# This simulates what the MCP tool would do
|
||||
discovery_result = {"success": True, "agents": []}
|
||||
|
||||
for tool_name in aop.agents.keys():
|
||||
agent_info = aop._get_agent_discovery_info(tool_name)
|
||||
if agent_info:
|
||||
discovery_result["agents"].append(agent_info)
|
||||
|
||||
assert (
|
||||
len(discovery_result["agents"]) == 2
|
||||
), "Should discover both agents"
|
||||
assert (
|
||||
discovery_result["success"] is True
|
||||
), "Discovery should be successful"
|
||||
|
||||
print("✅ Discovery tool simulation test passed")
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Discovery tool test failed: {e}")
|
||||
return False
|
||||
|
||||
# Test system prompt truncation
|
||||
long_prompt = "A" * 300 # 300 character string
|
||||
agent_with_long_prompt = Agent(
|
||||
agent_name="LongPromptAgent",
|
||||
agent_description="Agent with very long system prompt",
|
||||
system_prompt=long_prompt,
|
||||
)
|
||||
|
||||
aop.add_agent(
|
||||
agent_with_long_prompt, tool_name="long_prompt_agent"
|
||||
)
|
||||
long_prompt_info = aop._get_agent_discovery_info(
|
||||
"long_prompt_agent"
|
||||
)
|
||||
|
||||
assert (
|
||||
long_prompt_info is not None
|
||||
), "Should get info for long prompt agent"
|
||||
assert (
|
||||
len(long_prompt_info["short_system_prompt"]) == 203
|
||||
), "Should truncate to 200 chars + '...'"
|
||||
assert long_prompt_info["short_system_prompt"].endswith(
|
||||
"..."
|
||||
), "Should end with '...'"
|
||||
|
||||
print("✅ System prompt truncation test passed")
|
||||
|
||||
# Test with missing attributes
|
||||
minimal_agent = Agent(
|
||||
agent_name="MinimalAgent",
|
||||
# No description, tags, capabilities, or role specified
|
||||
)
|
||||
|
||||
aop.add_agent(minimal_agent, tool_name="minimal_agent")
|
||||
minimal_info = aop._get_agent_discovery_info("minimal_agent")
|
||||
|
||||
assert (
|
||||
minimal_info is not None
|
||||
), "Should get info for minimal agent"
|
||||
assert (
|
||||
minimal_info["description"] == "No description available"
|
||||
), "Should have default description"
|
||||
assert minimal_info["tags"] == [], "Should have empty tags list"
|
||||
assert (
|
||||
minimal_info["capabilities"] == []
|
||||
), "Should have empty capabilities list"
|
||||
assert (
|
||||
minimal_info["role"] == "worker"
|
||||
), "Should have default role"
|
||||
|
||||
print("✅ Minimal agent attributes test passed")
|
||||
|
||||
print()
|
||||
print(
|
||||
"🎉 All tests passed! Agent discovery functionality is working correctly."
|
||||
)
|
||||
print()
|
||||
print("📊 Summary of discovered agents:")
|
||||
for tool_name in aop.agents.keys():
|
||||
info = aop._get_agent_discovery_info(tool_name)
|
||||
if info:
|
||||
print(
|
||||
f" • {info['agent_name']} ({info['role']}) - {info['description']}"
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
success = test_agent_discovery()
|
||||
if success:
|
||||
print("\n✅ All tests completed successfully!")
|
||||
sys.exit(0)
|
||||
else:
|
||||
print("\n❌ Some tests failed!")
|
||||
sys.exit(1)
|
||||
except Exception as e:
|
||||
print(f"\n💥 Test failed with exception: {e}")
|
||||
import traceback
|
||||
|
||||
traceback.print_exc()
|
||||
sys.exit(1)
|
@ -0,0 +1,225 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Example demonstrating the new agent information tools in AOP.
|
||||
|
||||
This example shows how to use the new MCP tools for getting agent information.
|
||||
"""
|
||||
|
||||
import json
|
||||
import asyncio
|
||||
from swarms.structs.aop import AOPCluster
|
||||
from swarms.tools.mcp_client_tools import execute_tool_call_simple
|
||||
|
||||
|
||||
async def demonstrate_new_agent_tools():
|
||||
"""Demonstrate the new agent information tools."""
|
||||
|
||||
# Create AOP cluster connection
|
||||
aop_cluster = AOPCluster(
|
||||
urls=["http://localhost:5932/mcp"],
|
||||
transport="streamable-http",
|
||||
)
|
||||
|
||||
print("🔧 New AOP Agent Information Tools Demo")
|
||||
print("=" * 50)
|
||||
print()
|
||||
|
||||
# 1. List all agents
|
||||
print("1. Listing all agents...")
|
||||
try:
|
||||
tool_call = {
|
||||
"type": "function",
|
||||
"function": {"name": "list_agents", "arguments": "{}"},
|
||||
}
|
||||
|
||||
result = await execute_tool_call_simple(
|
||||
response=tool_call,
|
||||
server_path="http://localhost:5932/mcp",
|
||||
output_type="dict",
|
||||
verbose=False,
|
||||
)
|
||||
|
||||
if isinstance(result, list) and len(result) > 0:
|
||||
data = result[0]
|
||||
if data.get("success"):
|
||||
agent_names = data.get("agent_names", [])
|
||||
print(
|
||||
f" Found {len(agent_names)} agents: {agent_names}"
|
||||
)
|
||||
else:
|
||||
print(f" Error: {data.get('error')}")
|
||||
else:
|
||||
print(" No valid result returned")
|
||||
except Exception as e:
|
||||
print(f" Error: {e}")
|
||||
print()
|
||||
|
||||
# 2. Get details for a specific agent
|
||||
print("2. Getting details for a specific agent...")
|
||||
try:
|
||||
tool_call = {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "get_agent_details",
|
||||
"arguments": json.dumps(
|
||||
{"agent_name": "Research-Agent"}
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
result = await execute_tool_call_simple(
|
||||
response=tool_call,
|
||||
server_path="http://localhost:5932/mcp",
|
||||
output_type="dict",
|
||||
verbose=False,
|
||||
)
|
||||
|
||||
if isinstance(result, list) and len(result) > 0:
|
||||
data = result[0]
|
||||
if data.get("success"):
|
||||
agent_info = data.get("agent_info", {})
|
||||
discovery_info = data.get("discovery_info", {})
|
||||
print(
|
||||
f" Agent: {discovery_info.get('agent_name', 'Unknown')}"
|
||||
)
|
||||
print(
|
||||
f" Description: {discovery_info.get('description', 'No description')}"
|
||||
)
|
||||
print(
|
||||
f" Model: {discovery_info.get('model_name', 'Unknown')}"
|
||||
)
|
||||
print(f" Tags: {discovery_info.get('tags', [])}")
|
||||
print(
|
||||
f" Capabilities: {discovery_info.get('capabilities', [])}"
|
||||
)
|
||||
else:
|
||||
print(f" Error: {data.get('error')}")
|
||||
else:
|
||||
print(" No valid result returned")
|
||||
except Exception as e:
|
||||
print(f" Error: {e}")
|
||||
print()
|
||||
|
||||
# 3. Get info for multiple agents
|
||||
print("3. Getting info for multiple agents...")
|
||||
try:
|
||||
tool_call = {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "get_agents_info",
|
||||
"arguments": json.dumps(
|
||||
{
|
||||
"agent_names": [
|
||||
"Research-Agent",
|
||||
"DataAnalyst",
|
||||
"Writer",
|
||||
]
|
||||
}
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
result = await execute_tool_call_simple(
|
||||
response=tool_call,
|
||||
server_path="http://localhost:5932/mcp",
|
||||
output_type="dict",
|
||||
verbose=False,
|
||||
)
|
||||
|
||||
if isinstance(result, list) and len(result) > 0:
|
||||
data = result[0]
|
||||
if data.get("success"):
|
||||
agents_info = data.get("agents_info", [])
|
||||
not_found = data.get("not_found", [])
|
||||
print(
|
||||
f" Found {len(agents_info)} agents out of {data.get('total_requested', 0)} requested"
|
||||
)
|
||||
for agent in agents_info:
|
||||
discovery_info = agent.get("discovery_info", {})
|
||||
print(
|
||||
f" • {discovery_info.get('agent_name', 'Unknown')}: {discovery_info.get('description', 'No description')}"
|
||||
)
|
||||
if not_found:
|
||||
print(f" Not found: {not_found}")
|
||||
else:
|
||||
print(f" Error: {data.get('error')}")
|
||||
else:
|
||||
print(" No valid result returned")
|
||||
except Exception as e:
|
||||
print(f" Error: {e}")
|
||||
print()
|
||||
|
||||
# 4. Search for agents
|
||||
print("4. Searching for agents...")
|
||||
try:
|
||||
tool_call = {
|
||||
"type": "function",
|
||||
"function": {
|
||||
"name": "search_agents",
|
||||
"arguments": json.dumps(
|
||||
{
|
||||
"query": "data",
|
||||
"search_fields": [
|
||||
"name",
|
||||
"description",
|
||||
"tags",
|
||||
"capabilities",
|
||||
],
|
||||
}
|
||||
),
|
||||
},
|
||||
}
|
||||
|
||||
result = await execute_tool_call_simple(
|
||||
response=tool_call,
|
||||
server_path="http://localhost:5932/mcp",
|
||||
output_type="dict",
|
||||
verbose=False,
|
||||
)
|
||||
|
||||
if isinstance(result, list) and len(result) > 0:
|
||||
data = result[0]
|
||||
if data.get("success"):
|
||||
matching_agents = data.get("matching_agents", [])
|
||||
print(
|
||||
f" Found {len(matching_agents)} agents matching 'data'"
|
||||
)
|
||||
for agent in matching_agents:
|
||||
print(
|
||||
f" • {agent.get('agent_name', 'Unknown')}: {agent.get('description', 'No description')}"
|
||||
)
|
||||
print(f" Tags: {agent.get('tags', [])}")
|
||||
print(
|
||||
f" Capabilities: {agent.get('capabilities', [])}"
|
||||
)
|
||||
else:
|
||||
print(f" Error: {data.get('error')}")
|
||||
else:
|
||||
print(" No valid result returned")
|
||||
except Exception as e:
|
||||
print(f" Error: {e}")
|
||||
print()
|
||||
|
||||
print("✅ New agent tools demonstration complete!")
|
||||
print()
|
||||
print("💡 Available Tools:")
|
||||
print(
|
||||
" • discover_agents - Get discovery info for all or specific agents"
|
||||
)
|
||||
print(
|
||||
" • get_agent_details - Get detailed info for a single agent"
|
||||
)
|
||||
print(
|
||||
" • get_agents_info - Get detailed info for multiple agents"
|
||||
)
|
||||
print(" • list_agents - Get simple list of all agent names")
|
||||
print(" • search_agents - Search agents by keywords")
|
||||
|
||||
|
||||
def main():
|
||||
"""Main function to run the demonstration."""
|
||||
asyncio.run(demonstrate_new_agent_tools())
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
Reference in new issue