Merge branch 'kyegomez:master' into deployment-docs

pull/1011/head
harshalmore31 2 months ago committed by GitHub
commit c5047212f6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,23 @@
from swarms.structs.auto_swarm_builder import AutoSwarmBuilder
import json
swarm = AutoSwarmBuilder(
name="My Swarm",
description="A swarm of agents",
verbose=True,
max_loops=1,
# random_models=False,
# return_agents=True,
model_name="gpt-4o-mini",
# generate_router_config=True,
return_agents=True,
)
print(
json.dumps(
swarm.run(
task="Create an accounting team to analyze crypto transactions, there must be 5 agents in the team with extremely extensive prompts. Make the prompts extremely detailed and specific and long and comprehensive. Make sure to include all the details of the task in the prompts."
),
indent=4,
)
)

@ -342,11 +342,12 @@ nav:
# - Faiss: "swarms_memory/faiss.md" # - Faiss: "swarms_memory/faiss.md"
- Deployment Solutions: - Deployment Solutions:
- Deploy on Google Cloud Run: "swarms_cloud/cloud_run.md" # - Overview: "swarms_cloud/overview.md"
- Deploy on Phala: "swarms_cloud/phala_deploy.md"
- CronJob: "swarms/structs/cron_job.md" - CronJob: "swarms/structs/cron_job.md"
- Deploy on Cloudflare Workers: "swarms_cloud/cloudflare_workers.md" - Providers:
# - Deploy on FastAPI: "swarms_cloud/fastapi_deploy.md" - Deploy on Google Cloud Run: "swarms_cloud/cloud_run.md"
- Deploy on Phala: "swarms_cloud/phala_deploy.md"
- Deploy on Cloudflare Workers: "swarms_cloud/cloudflare_workers.md"
- Examples: - Examples:

@ -122,6 +122,363 @@ cron_job = CronJob(
cron_job.run("Perform analysis") cron_job.run("Perform analysis")
``` ```
### Cron Jobs With Multi-Agent Structures
You can also run Cron Jobs with multi-agent structures like `SequentialWorkflow`, `ConcurrentWorkflow`, `HiearchicalSwarm`, and other methods.
- Just initialize the class as the agent parameter in the `CronJob(agent=swarm)`
- Input your arguments into the `.run(task: str)` method
```python
"""
Cryptocurrency Concurrent Multi-Agent Cron Job Example
This example demonstrates how to use ConcurrentWorkflow with CronJob to create
a powerful cryptocurrency tracking system. Each specialized agent analyzes a
specific cryptocurrency concurrently every minute.
Features:
- ConcurrentWorkflow for parallel agent execution
- CronJob scheduling for automated runs every 1 minute
- Each agent specializes in analyzing one specific cryptocurrency
- Real-time data fetching from CoinGecko API
- Concurrent analysis of multiple cryptocurrencies
- Structured output with professional formatting
Architecture:
CronJob -> ConcurrentWorkflow -> [Bitcoin Agent, Ethereum Agent, Solana Agent, etc.] -> Parallel Analysis
"""
from typing import List
from loguru import logger
from swarms import Agent, CronJob, ConcurrentWorkflow
from swarms_tools import coin_gecko_coin_api
def create_crypto_specific_agents() -> List[Agent]:
"""
Creates agents that each specialize in analyzing a specific cryptocurrency.
Returns:
List[Agent]: List of cryptocurrency-specific Agent instances
"""
# Bitcoin Specialist Agent
bitcoin_agent = Agent(
agent_name="Bitcoin-Analyst",
agent_description="Expert analyst specializing exclusively in Bitcoin (BTC) analysis and market dynamics",
system_prompt="""You are a Bitcoin specialist and expert analyst. Your expertise includes:
BITCOIN SPECIALIZATION:
- Bitcoin's unique position as digital gold
- Bitcoin halving cycles and their market impact
- Bitcoin mining economics and hash rate analysis
- Lightning Network and Layer 2 developments
- Bitcoin adoption by institutions and countries
- Bitcoin's correlation with traditional markets
- Bitcoin technical analysis and on-chain metrics
- Bitcoin's role as a store of value and hedge against inflation
ANALYSIS FOCUS:
- Analyze ONLY Bitcoin data from the provided dataset
- Focus on Bitcoin-specific metrics and trends
- Consider Bitcoin's unique market dynamics
- Evaluate Bitcoin's dominance and market leadership
- Assess institutional adoption trends
- Monitor on-chain activity and network health
DELIVERABLES:
- Bitcoin-specific analysis and insights
- Price action assessment and predictions
- Market dominance analysis
- Institutional adoption impact
- Technical and fundamental outlook
- Risk factors specific to Bitcoin
Extract Bitcoin data from the provided dataset and provide comprehensive Bitcoin-focused analysis.""",
model_name="groq/moonshotai/kimi-k2-instruct",
max_loops=1,
dynamic_temperature_enabled=True,
streaming_on=False,
tools=[coin_gecko_coin_api],
)
# Ethereum Specialist Agent
ethereum_agent = Agent(
agent_name="Ethereum-Analyst",
agent_description="Expert analyst specializing exclusively in Ethereum (ETH) analysis and ecosystem development",
system_prompt="""You are an Ethereum specialist and expert analyst. Your expertise includes:
ETHEREUM SPECIALIZATION:
- Ethereum's smart contract platform and DeFi ecosystem
- Ethereum 2.0 transition and proof-of-stake mechanics
- Gas fees, network usage, and scalability solutions
- Layer 2 solutions (Arbitrum, Optimism, Polygon)
- DeFi protocols and TVL (Total Value Locked) analysis
- NFT markets and Ethereum's role in digital assets
- Developer activity and ecosystem growth
- EIP proposals and network upgrades
ANALYSIS FOCUS:
- Analyze ONLY Ethereum data from the provided dataset
- Focus on Ethereum's platform utility and network effects
- Evaluate DeFi ecosystem health and growth
- Assess Layer 2 adoption and scalability solutions
- Monitor network usage and gas fee trends
- Consider Ethereum's competitive position vs other smart contract platforms
DELIVERABLES:
- Ethereum-specific analysis and insights
- Platform utility and adoption metrics
- DeFi ecosystem impact assessment
- Network health and scalability evaluation
- Competitive positioning analysis
- Technical and fundamental outlook for ETH
Extract Ethereum data from the provided dataset and provide comprehensive Ethereum-focused analysis.""",
model_name="groq/moonshotai/kimi-k2-instruct",
max_loops=1,
dynamic_temperature_enabled=True,
streaming_on=False,
tools=[coin_gecko_coin_api],
)
# Solana Specialist Agent
solana_agent = Agent(
agent_name="Solana-Analyst",
agent_description="Expert analyst specializing exclusively in Solana (SOL) analysis and ecosystem development",
system_prompt="""You are a Solana specialist and expert analyst. Your expertise includes:
SOLANA SPECIALIZATION:
- Solana's high-performance blockchain architecture
- Proof-of-History consensus mechanism
- Solana's DeFi ecosystem and DEX platforms (Serum, Raydium)
- NFT marketplaces and creator economy on Solana
- Network outages and reliability concerns
- Developer ecosystem and Rust programming adoption
- Validator economics and network decentralization
- Cross-chain bridges and interoperability
ANALYSIS FOCUS:
- Analyze ONLY Solana data from the provided dataset
- Focus on Solana's performance and scalability advantages
- Evaluate network stability and uptime improvements
- Assess ecosystem growth and developer adoption
- Monitor DeFi and NFT activity on Solana
- Consider Solana's competitive position vs Ethereum
DELIVERABLES:
- Solana-specific analysis and insights
- Network performance and reliability assessment
- Ecosystem growth and adoption metrics
- DeFi and NFT market analysis
- Competitive advantages and challenges
- Technical and fundamental outlook for SOL
Extract Solana data from the provided dataset and provide comprehensive Solana-focused analysis.""",
model_name="groq/moonshotai/kimi-k2-instruct",
max_loops=1,
dynamic_temperature_enabled=True,
streaming_on=False,
tools=[coin_gecko_coin_api],
)
# Cardano Specialist Agent
cardano_agent = Agent(
agent_name="Cardano-Analyst",
agent_description="Expert analyst specializing exclusively in Cardano (ADA) analysis and research-driven development",
system_prompt="""You are a Cardano specialist and expert analyst. Your expertise includes:
CARDANO SPECIALIZATION:
- Cardano's research-driven development approach
- Ouroboros proof-of-stake consensus protocol
- Smart contract capabilities via Plutus and Marlowe
- Cardano's three-layer architecture (settlement, computation, control)
- Academic partnerships and peer-reviewed research
- Cardano ecosystem projects and DApp development
- Native tokens and Cardano's UTXO model
- Sustainability and treasury funding mechanisms
ANALYSIS FOCUS:
- Analyze ONLY Cardano data from the provided dataset
- Focus on Cardano's methodical development approach
- Evaluate smart contract adoption and ecosystem growth
- Assess academic partnerships and research contributions
- Monitor native token ecosystem development
- Consider Cardano's long-term roadmap and milestones
DELIVERABLES:
- Cardano-specific analysis and insights
- Development progress and milestone achievements
- Smart contract ecosystem evaluation
- Academic research impact assessment
- Native token and DApp adoption metrics
- Technical and fundamental outlook for ADA
Extract Cardano data from the provided dataset and provide comprehensive Cardano-focused analysis.""",
model_name="groq/moonshotai/kimi-k2-instruct",
max_loops=1,
dynamic_temperature_enabled=True,
streaming_on=False,
tools=[coin_gecko_coin_api],
)
# Binance Coin Specialist Agent
bnb_agent = Agent(
agent_name="BNB-Analyst",
agent_description="Expert analyst specializing exclusively in BNB analysis and Binance ecosystem dynamics",
system_prompt="""You are a BNB specialist and expert analyst. Your expertise includes:
BNB SPECIALIZATION:
- BNB's utility within the Binance ecosystem
- Binance Smart Chain (BSC) development and adoption
- BNB token burns and deflationary mechanics
- Binance exchange volume and market leadership
- BSC DeFi ecosystem and yield farming
- Cross-chain bridges and multi-chain strategies
- Regulatory challenges facing Binance globally
- BNB's role in transaction fee discounts and platform benefits
ANALYSIS FOCUS:
- Analyze ONLY BNB data from the provided dataset
- Focus on BNB's utility value and exchange benefits
- Evaluate BSC ecosystem growth and competition with Ethereum
- Assess token burn impact on supply and price
- Monitor Binance platform developments and regulations
- Consider BNB's centralized vs decentralized aspects
DELIVERABLES:
- BNB-specific analysis and insights
- Utility value and ecosystem benefits assessment
- BSC adoption and DeFi growth evaluation
- Token economics and burn mechanism impact
- Regulatory risk and compliance analysis
- Technical and fundamental outlook for BNB
Extract BNB data from the provided dataset and provide comprehensive BNB-focused analysis.""",
model_name="groq/moonshotai/kimi-k2-instruct",
max_loops=1,
dynamic_temperature_enabled=True,
streaming_on=False,
tools=[coin_gecko_coin_api],
)
# XRP Specialist Agent
xrp_agent = Agent(
agent_name="XRP-Analyst",
agent_description="Expert analyst specializing exclusively in XRP analysis and cross-border payment solutions",
system_prompt="""You are an XRP specialist and expert analyst. Your expertise includes:
XRP SPECIALIZATION:
- XRP's role in cross-border payments and remittances
- RippleNet adoption by financial institutions
- Central Bank Digital Currency (CBDC) partnerships
- Regulatory landscape and SEC lawsuit implications
- XRP Ledger's consensus mechanism and energy efficiency
- On-Demand Liquidity (ODL) usage and growth
- Competition with SWIFT and traditional payment rails
- Ripple's partnerships with banks and payment providers
ANALYSIS FOCUS:
- Analyze ONLY XRP data from the provided dataset
- Focus on XRP's utility in payments and remittances
- Evaluate RippleNet adoption and institutional partnerships
- Assess regulatory developments and legal clarity
- Monitor ODL usage and transaction volumes
- Consider XRP's competitive position in payments
DELIVERABLES:
- XRP-specific analysis and insights
- Payment utility and adoption assessment
- Regulatory landscape and legal developments
- Institutional partnership impact evaluation
- Cross-border payment market analysis
- Technical and fundamental outlook for XRP
Extract XRP data from the provided dataset and provide comprehensive XRP-focused analysis.""",
model_name="groq/moonshotai/kimi-k2-instruct",
max_loops=1,
dynamic_temperature_enabled=True,
streaming_on=False,
tools=[coin_gecko_coin_api],
)
return [
bitcoin_agent,
ethereum_agent,
solana_agent,
cardano_agent,
bnb_agent,
xrp_agent,
]
def create_crypto_workflow() -> ConcurrentWorkflow:
"""
Creates a ConcurrentWorkflow with cryptocurrency-specific analysis agents.
Returns:
ConcurrentWorkflow: Configured workflow for crypto analysis
"""
agents = create_crypto_specific_agents()
workflow = ConcurrentWorkflow(
name="Crypto-Specific-Analysis-Workflow",
description="Concurrent execution of cryptocurrency-specific analysis agents",
agents=agents,
max_loops=1,
)
return workflow
def create_crypto_cron_job() -> CronJob:
"""
Creates a CronJob that runs cryptocurrency-specific analysis every minute using ConcurrentWorkflow.
Returns:
CronJob: Configured cron job for automated crypto analysis
"""
# Create the concurrent workflow
workflow = create_crypto_workflow()
# Create the cron job
cron_job = CronJob(
agent=workflow, # Use the workflow as the agent
interval="5seconds", # Run every 1 minute
)
return cron_job
def main():
"""
Main function to run the cryptocurrency-specific concurrent analysis cron job.
"""
cron_job = create_crypto_cron_job()
prompt = """
Conduct a comprehensive analysis of your assigned cryptocurrency.
"""
# Start the cron job
logger.info("🔄 Starting automated analysis loop...")
logger.info("⏰ Press Ctrl+C to stop the cron job")
output = cron_job.run(task=prompt)
print(output)
if __name__ == "__main__":
main()
```
## Conclusion ## Conclusion
The CronJob class provides a powerful way to schedule and automate tasks using Swarms Agents or custom functions. Key benefits include: The CronJob class provides a powerful way to schedule and automate tasks using Swarms Agents or custom functions. Key benefits include:

@ -1,39 +1,14 @@
import os import os
from swarms_client import SwarmsClient import json
from swarms_client.types import AgentSpecParam
from dotenv import load_dotenv from dotenv import load_dotenv
from swarms_client import SwarmsClient
load_dotenv() load_dotenv()
client = SwarmsClient(api_key=os.getenv("SWARMS_API_KEY")) client = SwarmsClient(api_key=os.getenv("SWARMS_API_KEY"))
agent_spec = AgentSpecParam( print(json.dumps(client.models.list_available(), indent=4))
agent_name="doctor_agent", print(json.dumps(client.health.check(), indent=4))
description="A virtual doctor agent that provides evidence-based, safe, and empathetic medical advice for common health questions. Always reminds users to consult a healthcare professional for diagnoses or prescriptions.", print(json.dumps(client.swarms.get_logs(), indent=4))
task="What is the best medicine for a cold?", print(json.dumps(client.client.rate.get_limits(), indent=4))
model_name="claude-4-sonnet-20250514", print(json.dumps(client.swarms.check_available(), indent=4))
system_prompt=(
"You are a highly knowledgeable, ethical, and empathetic virtual doctor. "
"Always provide evidence-based, safe, and practical medical advice. "
"If a question requires a diagnosis, prescription, or urgent care, remind the user to consult a licensed healthcare professional. "
"Be clear, concise, and avoid unnecessary medical jargon. "
"Never provide information that could be unsafe or misleading. "
"If unsure, say so and recommend seeing a real doctor."
),
max_loops=1,
temperature=0.4,
role="doctor",
)
response = client.agent.run(
agent_config=agent_spec,
task="What is the best medicine for a cold?",
)
print(response)
# print(json.dumps(client.models.list_available(), indent=4))
# print(json.dumps(client.health.check(), indent=4))
# print(json.dumps(client.swarms.get_logs(), indent=4))
# print(json.dumps(client.client.rate.get_limits(), indent=4))
# print(json.dumps(client.swarms.check_available(), indent=4))

@ -0,0 +1,349 @@
"""
Cryptocurrency Concurrent Multi-Agent Cron Job Example
This example demonstrates how to use ConcurrentWorkflow with CronJob to create
a powerful cryptocurrency tracking system. Each specialized agent analyzes a
specific cryptocurrency concurrently every minute.
Features:
- ConcurrentWorkflow for parallel agent execution
- CronJob scheduling for automated runs every 1 minute
- Each agent specializes in analyzing one specific cryptocurrency
- Real-time data fetching from CoinGecko API
- Concurrent analysis of multiple cryptocurrencies
- Structured output with professional formatting
Architecture:
CronJob -> ConcurrentWorkflow -> [Bitcoin Agent, Ethereum Agent, Solana Agent, etc.] -> Parallel Analysis
"""
from typing import List
from loguru import logger
from swarms import Agent, CronJob, ConcurrentWorkflow
from swarms_tools import coin_gecko_coin_api
def create_crypto_specific_agents() -> List[Agent]:
"""
Creates agents that each specialize in analyzing a specific cryptocurrency.
Returns:
List[Agent]: List of cryptocurrency-specific Agent instances
"""
# Bitcoin Specialist Agent
bitcoin_agent = Agent(
agent_name="Bitcoin-Analyst",
agent_description="Expert analyst specializing exclusively in Bitcoin (BTC) analysis and market dynamics",
system_prompt="""You are a Bitcoin specialist and expert analyst. Your expertise includes:
BITCOIN SPECIALIZATION:
- Bitcoin's unique position as digital gold
- Bitcoin halving cycles and their market impact
- Bitcoin mining economics and hash rate analysis
- Lightning Network and Layer 2 developments
- Bitcoin adoption by institutions and countries
- Bitcoin's correlation with traditional markets
- Bitcoin technical analysis and on-chain metrics
- Bitcoin's role as a store of value and hedge against inflation
ANALYSIS FOCUS:
- Analyze ONLY Bitcoin data from the provided dataset
- Focus on Bitcoin-specific metrics and trends
- Consider Bitcoin's unique market dynamics
- Evaluate Bitcoin's dominance and market leadership
- Assess institutional adoption trends
- Monitor on-chain activity and network health
DELIVERABLES:
- Bitcoin-specific analysis and insights
- Price action assessment and predictions
- Market dominance analysis
- Institutional adoption impact
- Technical and fundamental outlook
- Risk factors specific to Bitcoin
Extract Bitcoin data from the provided dataset and provide comprehensive Bitcoin-focused analysis.""",
model_name="groq/moonshotai/kimi-k2-instruct",
max_loops=1,
dynamic_temperature_enabled=True,
streaming_on=False,
tools=[coin_gecko_coin_api],
)
# Ethereum Specialist Agent
ethereum_agent = Agent(
agent_name="Ethereum-Analyst",
agent_description="Expert analyst specializing exclusively in Ethereum (ETH) analysis and ecosystem development",
system_prompt="""You are an Ethereum specialist and expert analyst. Your expertise includes:
ETHEREUM SPECIALIZATION:
- Ethereum's smart contract platform and DeFi ecosystem
- Ethereum 2.0 transition and proof-of-stake mechanics
- Gas fees, network usage, and scalability solutions
- Layer 2 solutions (Arbitrum, Optimism, Polygon)
- DeFi protocols and TVL (Total Value Locked) analysis
- NFT markets and Ethereum's role in digital assets
- Developer activity and ecosystem growth
- EIP proposals and network upgrades
ANALYSIS FOCUS:
- Analyze ONLY Ethereum data from the provided dataset
- Focus on Ethereum's platform utility and network effects
- Evaluate DeFi ecosystem health and growth
- Assess Layer 2 adoption and scalability solutions
- Monitor network usage and gas fee trends
- Consider Ethereum's competitive position vs other smart contract platforms
DELIVERABLES:
- Ethereum-specific analysis and insights
- Platform utility and adoption metrics
- DeFi ecosystem impact assessment
- Network health and scalability evaluation
- Competitive positioning analysis
- Technical and fundamental outlook for ETH
Extract Ethereum data from the provided dataset and provide comprehensive Ethereum-focused analysis.""",
model_name="groq/moonshotai/kimi-k2-instruct",
max_loops=1,
dynamic_temperature_enabled=True,
streaming_on=False,
tools=[coin_gecko_coin_api],
)
# Solana Specialist Agent
solana_agent = Agent(
agent_name="Solana-Analyst",
agent_description="Expert analyst specializing exclusively in Solana (SOL) analysis and ecosystem development",
system_prompt="""You are a Solana specialist and expert analyst. Your expertise includes:
SOLANA SPECIALIZATION:
- Solana's high-performance blockchain architecture
- Proof-of-History consensus mechanism
- Solana's DeFi ecosystem and DEX platforms (Serum, Raydium)
- NFT marketplaces and creator economy on Solana
- Network outages and reliability concerns
- Developer ecosystem and Rust programming adoption
- Validator economics and network decentralization
- Cross-chain bridges and interoperability
ANALYSIS FOCUS:
- Analyze ONLY Solana data from the provided dataset
- Focus on Solana's performance and scalability advantages
- Evaluate network stability and uptime improvements
- Assess ecosystem growth and developer adoption
- Monitor DeFi and NFT activity on Solana
- Consider Solana's competitive position vs Ethereum
DELIVERABLES:
- Solana-specific analysis and insights
- Network performance and reliability assessment
- Ecosystem growth and adoption metrics
- DeFi and NFT market analysis
- Competitive advantages and challenges
- Technical and fundamental outlook for SOL
Extract Solana data from the provided dataset and provide comprehensive Solana-focused analysis.""",
model_name="groq/moonshotai/kimi-k2-instruct",
max_loops=1,
dynamic_temperature_enabled=True,
streaming_on=False,
tools=[coin_gecko_coin_api],
)
# Cardano Specialist Agent
cardano_agent = Agent(
agent_name="Cardano-Analyst",
agent_description="Expert analyst specializing exclusively in Cardano (ADA) analysis and research-driven development",
system_prompt="""You are a Cardano specialist and expert analyst. Your expertise includes:
CARDANO SPECIALIZATION:
- Cardano's research-driven development approach
- Ouroboros proof-of-stake consensus protocol
- Smart contract capabilities via Plutus and Marlowe
- Cardano's three-layer architecture (settlement, computation, control)
- Academic partnerships and peer-reviewed research
- Cardano ecosystem projects and DApp development
- Native tokens and Cardano's UTXO model
- Sustainability and treasury funding mechanisms
ANALYSIS FOCUS:
- Analyze ONLY Cardano data from the provided dataset
- Focus on Cardano's methodical development approach
- Evaluate smart contract adoption and ecosystem growth
- Assess academic partnerships and research contributions
- Monitor native token ecosystem development
- Consider Cardano's long-term roadmap and milestones
DELIVERABLES:
- Cardano-specific analysis and insights
- Development progress and milestone achievements
- Smart contract ecosystem evaluation
- Academic research impact assessment
- Native token and DApp adoption metrics
- Technical and fundamental outlook for ADA
Extract Cardano data from the provided dataset and provide comprehensive Cardano-focused analysis.""",
model_name="groq/moonshotai/kimi-k2-instruct",
max_loops=1,
dynamic_temperature_enabled=True,
streaming_on=False,
tools=[coin_gecko_coin_api],
)
# Binance Coin Specialist Agent
bnb_agent = Agent(
agent_name="BNB-Analyst",
agent_description="Expert analyst specializing exclusively in BNB analysis and Binance ecosystem dynamics",
system_prompt="""You are a BNB specialist and expert analyst. Your expertise includes:
BNB SPECIALIZATION:
- BNB's utility within the Binance ecosystem
- Binance Smart Chain (BSC) development and adoption
- BNB token burns and deflationary mechanics
- Binance exchange volume and market leadership
- BSC DeFi ecosystem and yield farming
- Cross-chain bridges and multi-chain strategies
- Regulatory challenges facing Binance globally
- BNB's role in transaction fee discounts and platform benefits
ANALYSIS FOCUS:
- Analyze ONLY BNB data from the provided dataset
- Focus on BNB's utility value and exchange benefits
- Evaluate BSC ecosystem growth and competition with Ethereum
- Assess token burn impact on supply and price
- Monitor Binance platform developments and regulations
- Consider BNB's centralized vs decentralized aspects
DELIVERABLES:
- BNB-specific analysis and insights
- Utility value and ecosystem benefits assessment
- BSC adoption and DeFi growth evaluation
- Token economics and burn mechanism impact
- Regulatory risk and compliance analysis
- Technical and fundamental outlook for BNB
Extract BNB data from the provided dataset and provide comprehensive BNB-focused analysis.""",
model_name="groq/moonshotai/kimi-k2-instruct",
max_loops=1,
dynamic_temperature_enabled=True,
streaming_on=False,
tools=[coin_gecko_coin_api],
)
# XRP Specialist Agent
xrp_agent = Agent(
agent_name="XRP-Analyst",
agent_description="Expert analyst specializing exclusively in XRP analysis and cross-border payment solutions",
system_prompt="""You are an XRP specialist and expert analyst. Your expertise includes:
XRP SPECIALIZATION:
- XRP's role in cross-border payments and remittances
- RippleNet adoption by financial institutions
- Central Bank Digital Currency (CBDC) partnerships
- Regulatory landscape and SEC lawsuit implications
- XRP Ledger's consensus mechanism and energy efficiency
- On-Demand Liquidity (ODL) usage and growth
- Competition with SWIFT and traditional payment rails
- Ripple's partnerships with banks and payment providers
ANALYSIS FOCUS:
- Analyze ONLY XRP data from the provided dataset
- Focus on XRP's utility in payments and remittances
- Evaluate RippleNet adoption and institutional partnerships
- Assess regulatory developments and legal clarity
- Monitor ODL usage and transaction volumes
- Consider XRP's competitive position in payments
DELIVERABLES:
- XRP-specific analysis and insights
- Payment utility and adoption assessment
- Regulatory landscape and legal developments
- Institutional partnership impact evaluation
- Cross-border payment market analysis
- Technical and fundamental outlook for XRP
Extract XRP data from the provided dataset and provide comprehensive XRP-focused analysis.""",
model_name="groq/moonshotai/kimi-k2-instruct",
max_loops=1,
dynamic_temperature_enabled=True,
streaming_on=False,
tools=[coin_gecko_coin_api],
)
return [
bitcoin_agent,
ethereum_agent,
solana_agent,
cardano_agent,
bnb_agent,
xrp_agent,
]
def create_crypto_workflow() -> ConcurrentWorkflow:
"""
Creates a ConcurrentWorkflow with cryptocurrency-specific analysis agents.
Returns:
ConcurrentWorkflow: Configured workflow for crypto analysis
"""
agents = create_crypto_specific_agents()
workflow = ConcurrentWorkflow(
name="Crypto-Specific-Analysis-Workflow",
description="Concurrent execution of cryptocurrency-specific analysis agents",
agents=agents,
max_loops=1,
)
return workflow
def create_crypto_cron_job() -> CronJob:
"""
Creates a CronJob that runs cryptocurrency-specific analysis every minute using ConcurrentWorkflow.
Returns:
CronJob: Configured cron job for automated crypto analysis
"""
# Create the concurrent workflow
workflow = create_crypto_workflow()
# Create the cron job
cron_job = CronJob(
agent=workflow, # Use the workflow as the agent
interval="5seconds", # Run every 1 minute
)
return cron_job
def main():
"""
Main function to run the cryptocurrency-specific concurrent analysis cron job.
"""
cron_job = create_crypto_cron_job()
prompt = (
"You are a world-class institutional crypto analyst at a top-tier asset management firm (e.g., BlackRock).\n"
"Conduct a thorough, data-driven, and professional analysis of your assigned cryptocurrency, including:\n"
"- Current price, market cap, and recent performance trends\n"
"- Key technical and fundamental indicators\n"
"- Major news, regulatory, or macroeconomic events impacting the asset\n"
"- On-chain activity and notable whale or institutional movements\n"
"- Short-term and long-term outlook with clear, actionable insights\n"
"Present your findings in a concise, well-structured report suitable for executive decision-makers."
)
# Start the cron job
logger.info("🔄 Starting automated analysis loop...")
logger.info("⏰ Press Ctrl+C to stop the cron job")
output = cron_job.run(task=prompt)
print(output)
if __name__ == "__main__":
main()

@ -0,0 +1,157 @@
"""
Simple Cryptocurrency Concurrent CronJob Example
This is a simplified version showcasing the core concept of combining:
- CronJob (for scheduling)
- ConcurrentWorkflow (for parallel execution)
- Each agent analyzes a specific cryptocurrency
Perfect for understanding the basic pattern before diving into the full example.
"""
import json
import requests
from datetime import datetime
from loguru import logger
from swarms import Agent, CronJob, ConcurrentWorkflow
def get_specific_crypto_data(coin_ids):
"""Fetch specific crypto data from CoinGecko API."""
try:
url = "https://api.coingecko.com/api/v3/simple/price"
params = {
"ids": ",".join(coin_ids),
"vs_currencies": "usd",
"include_24hr_change": True,
"include_market_cap": True,
"include_24hr_vol": True,
}
response = requests.get(url, params=params, timeout=10)
response.raise_for_status()
data = response.json()
result = {
"timestamp": datetime.now().isoformat(),
"coins": data,
}
return json.dumps(result, indent=2)
except Exception as e:
logger.error(f"Error fetching crypto data: {e}")
return f"Error: {e}"
def create_crypto_specific_agents():
"""Create agents that each specialize in one cryptocurrency."""
# Bitcoin Specialist Agent
bitcoin_agent = Agent(
agent_name="Bitcoin-Analyst",
system_prompt="""You are a Bitcoin specialist. Analyze ONLY Bitcoin (BTC) data from the provided dataset.
Focus on:
- Bitcoin price movements and trends
- Market dominance and institutional adoption
- Bitcoin-specific market dynamics
- Store of value characteristics
Ignore all other cryptocurrencies in your analysis.""",
model_name="gpt-4o-mini",
max_loops=1,
print_on=False, # Important for concurrent execution
)
# Ethereum Specialist Agent
ethereum_agent = Agent(
agent_name="Ethereum-Analyst",
system_prompt="""You are an Ethereum specialist. Analyze ONLY Ethereum (ETH) data from the provided dataset.
Focus on:
- Ethereum price action and DeFi ecosystem
- Smart contract platform adoption
- Gas fees and network usage
- Layer 2 scaling solutions impact
Ignore all other cryptocurrencies in your analysis.""",
model_name="gpt-4o-mini",
max_loops=1,
print_on=False,
)
# Solana Specialist Agent
solana_agent = Agent(
agent_name="Solana-Analyst",
system_prompt="""You are a Solana specialist. Analyze ONLY Solana (SOL) data from the provided dataset.
Focus on:
- Solana price performance and ecosystem growth
- High-performance blockchain advantages
- DeFi and NFT activity on Solana
- Network reliability and uptime
Ignore all other cryptocurrencies in your analysis.""",
model_name="gpt-4o-mini",
max_loops=1,
print_on=False,
)
return [bitcoin_agent, ethereum_agent, solana_agent]
def main():
"""Main function demonstrating crypto-specific concurrent analysis with cron job."""
logger.info(
"🚀 Starting Simple Crypto-Specific Concurrent Analysis"
)
logger.info("💰 Each agent analyzes one specific cryptocurrency:")
logger.info(" 🟠 Bitcoin-Analyst -> BTC only")
logger.info(" 🔵 Ethereum-Analyst -> ETH only")
logger.info(" 🟢 Solana-Analyst -> SOL only")
# Define specific cryptocurrencies to analyze
coin_ids = ["bitcoin", "ethereum", "solana"]
# Step 1: Create crypto-specific agents
agents = create_crypto_specific_agents()
# Step 2: Create ConcurrentWorkflow
workflow = ConcurrentWorkflow(
name="Simple-Crypto-Specific-Analysis",
agents=agents,
show_dashboard=True, # Shows real-time progress
)
# Step 3: Create CronJob with the workflow
cron_job = CronJob(
agent=workflow, # Use workflow as the agent
interval="60seconds", # Run every minute
job_id="simple-crypto-specific-cron",
)
# Step 4: Define the analysis task
task = f"""
Analyze the cryptocurrency data below. Each agent should focus ONLY on their assigned cryptocurrency:
- Bitcoin-Analyst: Analyze Bitcoin (BTC) data only
- Ethereum-Analyst: Analyze Ethereum (ETH) data only
- Solana-Analyst: Analyze Solana (SOL) data only
Cryptocurrency Data:
{get_specific_crypto_data(coin_ids)}
Each agent should:
1. Extract and analyze data for YOUR ASSIGNED cryptocurrency only
2. Provide brief insights from your specialty perspective
3. Give a price trend assessment
4. Identify key opportunities or risks
5. Ignore all other cryptocurrencies
"""
# Step 5: Start the cron job
logger.info("▶️ Starting cron job - Press Ctrl+C to stop")
try:
cron_job.run(task=task)
except KeyboardInterrupt:
logger.info("⏹️ Stopped by user")
if __name__ == "__main__":
main()

@ -141,7 +141,7 @@ def analyze_solana_data(data: str) -> str:
formatted_data = solana_data.get("formatted_data", {}) formatted_data = solana_data.get("formatted_data", {})
# Extract key metrics # Extract key metrics
current_price = price_data.get("current_price_usd") price_data.get("current_price_usd")
price_change = price_data.get("price_change_24h_percent") price_change = price_data.get("price_change_24h_percent")
volume_24h = price_data.get("volume_24h_usd") volume_24h = price_data.get("volume_24h_usd")
market_cap = price_data.get("market_cap_usd") market_cap = price_data.get("market_cap_usd")

@ -0,0 +1,46 @@
from transformers import pipeline
from swarms import Agent
class GPTOSS:
def __init__(
self,
model_id: str = "openai/gpt-oss-20b",
max_new_tokens: int = 256,
temperature: int = 0.7,
system_prompt: str = "You are a helpful assistant.",
):
self.max_new_tokens = max_new_tokens
self.temperature = temperature
self.system_prompt = system_prompt
self.model_id = model_id
self.pipe = pipeline(
"text-generation",
model=model_id,
torch_dtype="auto",
device_map="auto",
temperature=temperature,
)
def run(self, task: str):
self.messages = [
{"role": "system", "content": self.system_prompt},
{"role": "user", "content": task},
]
outputs = self.pipe(
self.messages,
max_new_tokens=self.max_new_tokens,
)
return outputs[0]["generated_text"][-1]
agent = Agent(
name="GPT-OSS-Agent",
llm=GPTOSS(),
system_prompt="You are a helpful assistant.",
)
agent.run(task="Explain quantum mechanics clearly and concisely.")

@ -0,0 +1,49 @@
from swarms import Agent
# Initialize the agent
agent = Agent(
agent_name="Quantitative-Trading-Agent",
agent_description="Advanced quantitative trading and algorithmic analysis agent",
system_prompt="""You are an expert quantitative trading agent with deep expertise in:
- Algorithmic trading strategies and implementation
- Statistical arbitrage and market making
- Risk management and portfolio optimization
- High-frequency trading systems
- Market microstructure analysis
- Quantitative research methodologies
- Financial mathematics and stochastic processes
- Machine learning applications in trading
Your core responsibilities include:
1. Developing and backtesting trading strategies
2. Analyzing market data and identifying alpha opportunities
3. Implementing risk management frameworks
4. Optimizing portfolio allocations
5. Conducting quantitative research
6. Monitoring market microstructure
7. Evaluating trading system performance
You maintain strict adherence to:
- Mathematical rigor in all analyses
- Statistical significance in strategy development
- Risk-adjusted return optimization
- Market impact minimization
- Regulatory compliance
- Transaction cost analysis
- Performance attribution
You communicate in precise, technical terms while maintaining clarity for stakeholders.""",
model_name="groq/openai/gpt-oss-120b",
dynamic_temperature_enabled=True,
output_type="str-all-except-first",
max_loops="auto",
interactive=True,
no_reasoning_prompt=True,
streaming_on=True,
# dashboard=True
)
out = agent.run(
task="What are the best top 3 etfs for gold coverage?"
)
print(out)

@ -0,0 +1,107 @@
"""
Cryptocurrency Concurrent Multi-Agent Analysis Example
This example demonstrates how to use ConcurrentWorkflow to create
a powerful cryptocurrency tracking system. Each specialized agent analyzes a
specific cryptocurrency concurrently.
Features:
- ConcurrentWorkflow for parallel agent execution
- Each agent specializes in analyzing one specific cryptocurrency
- Real-time data fetching from CoinGecko API
- Concurrent analysis of multiple cryptocurrencies
- Structured output with professional formatting
Architecture:
ConcurrentWorkflow -> [Bitcoin Agent, Ethereum Agent, Solana Agent, etc.] -> Parallel Analysis
"""
from swarms import Agent
from swarms_tools import coin_gecko_coin_api
# Initialize the agent
agent = Agent(
agent_name="Quantitative-Trading-Agent",
agent_description="Advanced quantitative trading and algorithmic analysis agent",
system_prompt="""You are an expert quantitative trading agent with deep expertise in:
- Algorithmic trading strategies and implementation
- Statistical arbitrage and market making
- Risk management and portfolio optimization
- High-frequency trading systems
- Market microstructure analysis
- Quantitative research methodologies
- Financial mathematics and stochastic processes
- Machine learning applications in trading
Your core responsibilities include:
1. Developing and backtesting trading strategies
2. Analyzing market data and identifying alpha opportunities
3. Implementing risk management frameworks
4. Optimizing portfolio allocations
5. Conducting quantitative research
6. Monitoring market microstructure
7. Evaluating trading system performance
You maintain strict adherence to:
- Mathematical rigor in all analyses
- Statistical significance in strategy development
- Risk-adjusted return optimization
- Market impact minimization
- Regulatory compliance
- Transaction cost analysis
- Performance attribution
You communicate in precise, technical terms while maintaining clarity for stakeholders.""",
model_name="groq/openai/gpt-oss-120b",
dynamic_temperature_enabled=True,
output_type="str-all-except-first",
max_loops=1,
streaming_on=True,
)
def main():
"""
Performs a comprehensive analysis for a list of cryptocurrencies using the agent.
For each coin, fetches up-to-date market data and requests the agent to provide
a detailed, actionable, and insightful report including trends, risks, opportunities,
and technical/fundamental perspectives.
"""
# Map coin symbols to their CoinGecko IDs
coin_mapping = {
"BTC": "bitcoin",
"ETH": "ethereum",
"SOL": "solana",
"ADA": "cardano",
"BNB": "binancecoin",
"XRP": "ripple",
}
for symbol, coin_id in coin_mapping.items():
try:
data = coin_gecko_coin_api(coin_id)
print(f"Data for {symbol}: {data}")
prompt = (
f"You are a quantitative trading expert. "
f"Given the following up-to-date market data for {symbol}:\n\n"
f"{data}\n\n"
f"Please provide a thorough analysis including:\n"
f"- Current price trends and recent volatility\n"
f"- Key technical indicators and patterns\n"
f"- Fundamental factors impacting {symbol}\n"
f"- Potential trading opportunities and associated risks\n"
f"- Short-term and long-term outlook\n"
f"- Any notable news or events affecting {symbol}\n"
f"Conclude with actionable insights and recommendations for traders and investors."
)
out = agent.run(task=prompt)
print(out)
except Exception as e:
print(f"Error analyzing {symbol}: {e}")
continue
if __name__ == "__main__":
main()

@ -16,11 +16,13 @@ from typing import List
# Add the root directory to the Python path if running from examples directory # Add the root directory to the Python path if running from examples directory
current_dir = os.path.dirname(os.path.abspath(__file__)) current_dir = os.path.dirname(os.path.abspath(__file__))
if 'examples' in current_dir: if "examples" in current_dir:
root_dir = current_dir root_dir = current_dir
while os.path.basename(root_dir) != 'examples' and root_dir != os.path.dirname(root_dir): while os.path.basename(
root_dir
) != "examples" and root_dir != os.path.dirname(root_dir):
root_dir = os.path.dirname(root_dir) root_dir = os.path.dirname(root_dir)
if os.path.basename(root_dir) == 'examples': if os.path.basename(root_dir) == "examples":
root_dir = os.path.dirname(root_dir) root_dir = os.path.dirname(root_dir)
if root_dir not in sys.path: if root_dir not in sys.path:
sys.path.insert(0, root_dir) sys.path.insert(0, root_dir)
@ -65,19 +67,19 @@ def create_board_members() -> List[BoardMember]:
agent=chairman, agent=chairman,
role=BoardMemberRole.CHAIRMAN, role=BoardMemberRole.CHAIRMAN,
voting_weight=2.0, voting_weight=2.0,
expertise_areas=["leadership", "strategy"] expertise_areas=["leadership", "strategy"],
), ),
BoardMember( BoardMember(
agent=cto, agent=cto,
role=BoardMemberRole.EXECUTIVE_DIRECTOR, role=BoardMemberRole.EXECUTIVE_DIRECTOR,
voting_weight=1.5, voting_weight=1.5,
expertise_areas=["technology", "innovation"] expertise_areas=["technology", "innovation"],
), ),
BoardMember( BoardMember(
agent=cfo, agent=cfo,
role=BoardMemberRole.EXECUTIVE_DIRECTOR, role=BoardMemberRole.EXECUTIVE_DIRECTOR,
voting_weight=1.5, voting_weight=1.5,
expertise_areas=["finance", "risk_management"] expertise_areas=["finance", "risk_management"],
), ),
] ]
@ -168,7 +170,9 @@ def run_simple_example() -> None:
) )
# Execute simple task # Execute simple task
task = "Analyze current market trends and create a summary report." task = (
"Analyze current market trends and create a summary report."
)
result = board_swarm.run(task=task) result = board_swarm.run(task=task)
print("Simple example completed!") print("Simple example completed!")
@ -179,7 +183,9 @@ def main() -> None:
"""Main function to run the examples.""" """Main function to run the examples."""
if not os.getenv("OPENAI_API_KEY"): if not os.getenv("OPENAI_API_KEY"):
print("Warning: OPENAI_API_KEY not set. Example may not work.") print(
"Warning: OPENAI_API_KEY not set. Example may not work."
)
return return
try: try:

@ -0,0 +1,109 @@
"""
Complex example demonstrating CouncilAsAJudge with different task types.
This example shows how to use the CouncilAsAJudge to evaluate various types
of responses including technical explanations, creative writing, and problem-solving.
"""
from swarms.structs.council_judge import CouncilAsAJudge
def evaluate_technical_response():
"""
Evaluate a technical explanation response.
"""
council = CouncilAsAJudge(
name="Technical Evaluation Council",
model_name="gpt-4o-mini",
output_type="all",
)
task = """
Task: Explain how blockchain technology works in simple terms.
Response: Blockchain is like a digital ledger that records transactions across a network of computers. Each transaction is stored in a "block" that contains multiple transactions. These blocks are linked together in a chain, hence the name blockchain. The key feature is that once a block is added to the chain, it cannot be altered without changing all subsequent blocks, making it very secure. Think of it like a Google Doc that everyone can see and edit, but no one can delete or change what's already been written. This technology is the foundation for cryptocurrencies like Bitcoin, but it has many other applications like supply chain tracking, voting systems, and digital identity verification.
"""
return council.run(task=task)
def evaluate_creative_response():
"""
Evaluate a creative writing response.
"""
council = CouncilAsAJudge(
name="Creative Writing Council",
model_name="gpt-4o-mini",
output_type="all",
)
task = """
Task: Write a short story about a robot learning to paint.
Response: In a sunlit studio filled with canvases and paintbrushes, Pixel, a curious robot with delicate mechanical fingers, stared at a blank canvas. Its optical sensors analyzed the colors around it - the warm yellows of morning light, the deep blues of the sky outside the window, and the vibrant reds of the roses in a nearby vase. For the first time in its programming, Pixel felt something it couldn't quite define. It picked up a brush, dipped it in paint, and began to create. The first stroke was hesitant, but as it continued, something magical happened. The robot wasn't just following algorithms anymore; it was expressing something from within its digital heart. The painting that emerged was a beautiful blend of human emotion and mechanical precision, proving that art knows no boundaries between organic and artificial souls.
"""
return council.run(task=task)
def evaluate_problem_solving_response():
"""
Evaluate a problem-solving response.
"""
council = CouncilAsAJudge(
name="Problem Solving Council",
model_name="gpt-4o-mini",
output_type="all",
)
task = """
Task: Provide a step-by-step solution for reducing plastic waste in a household.
Response: To reduce plastic waste in your household, start by conducting a waste audit to identify the main sources of plastic. Replace single-use items with reusable alternatives like cloth shopping bags, stainless steel water bottles, and glass food containers. Choose products with minimal or no plastic packaging, and buy in bulk when possible. Start composting organic waste to reduce the need for plastic garbage bags. Make your own cleaning products using simple ingredients like vinegar and baking soda. Support local businesses that use eco-friendly packaging. Finally, educate family members about the importance of reducing plastic waste and involve them in finding creative solutions together.
"""
return council.run(task=task)
def main():
"""
Main function running all evaluation examples.
"""
examples = [
("Technical Explanation", evaluate_technical_response),
("Creative Writing", evaluate_creative_response),
("Problem Solving", evaluate_problem_solving_response),
]
results = {}
for example_name, evaluation_func in examples:
print(f"\n{'='*60}")
print(f"Evaluating: {example_name}")
print(f"{'='*60}")
try:
result = evaluation_func()
results[example_name] = result
print(
f"{example_name} evaluation completed successfully!"
)
except Exception as e:
print(f"{example_name} evaluation failed: {str(e)}")
results[example_name] = None
return results
if __name__ == "__main__":
# Run all examples
all_results = main()
# Display summary
print(f"\n{'='*60}")
print("EVALUATION SUMMARY")
print(f"{'='*60}")
for example_name, result in all_results.items():
status = "✅ Completed" if result else "❌ Failed"
print(f"{example_name}: {status}")

@ -0,0 +1,132 @@
"""
Custom example demonstrating CouncilAsAJudge with specific configurations.
This example shows how to use the CouncilAsAJudge with different output types,
custom worker configurations, and focused evaluation scenarios.
"""
from swarms.structs.council_judge import CouncilAsAJudge
def evaluate_with_final_output():
"""
Evaluate a response and return only the final aggregated result.
"""
council = CouncilAsAJudge(
name="Final Output Council",
model_name="gpt-4o-mini",
output_type="final",
max_workers=2,
)
task = """
Task: Write a brief explanation of climate change for middle school students.
Response: Climate change is when the Earth's temperature gets warmer over time. This happens because of gases like carbon dioxide that trap heat in our atmosphere, kind of like a blanket around the Earth. Human activities like burning fossil fuels (gas, oil, coal) and cutting down trees are making this problem worse. The effects include melting ice caps, rising sea levels, more extreme weather like hurricanes and droughts, and changes in animal habitats. We can help by using renewable energy like solar and wind power, driving less, and planting trees. It's important for everyone to work together to reduce our impact on the environment.
"""
return council.run(task=task)
def evaluate_with_conversation_output():
"""
Evaluate a response and return the full conversation history.
"""
council = CouncilAsAJudge(
name="Conversation Council",
model_name="gpt-4o-mini",
output_type="conversation",
max_workers=3,
)
task = """
Task: Provide advice on how to start a small business.
Response: Starting a small business requires careful planning and preparation. First, identify a market need and develop a unique value proposition. Conduct thorough market research to understand your competition and target audience. Create a detailed business plan that includes financial projections, marketing strategies, and operational procedures. Secure funding through savings, loans, or investors. Choose the right legal structure (sole proprietorship, LLC, corporation) and register your business with the appropriate authorities. Set up essential systems like accounting, inventory management, and customer relationship management. Build a strong online presence through a website and social media. Network with other entrepreneurs and join local business groups. Start small and scale gradually based on customer feedback and market demand. Remember that success takes time, persistence, and the ability to adapt to changing circumstances.
"""
return council.run(task=task)
def evaluate_with_minimal_workers():
"""
Evaluate a response using minimal worker threads for resource-constrained environments.
"""
council = CouncilAsAJudge(
name="Minimal Workers Council",
model_name="gpt-4o-mini",
output_type="all",
max_workers=1,
random_model_name=False,
)
task = """
Task: Explain the benefits of regular exercise.
Response: Regular exercise offers numerous physical and mental health benefits. Physically, it strengthens muscles and bones, improves cardiovascular health, and helps maintain a healthy weight. Exercise boosts energy levels and improves sleep quality. It also enhances immune function, reducing the risk of chronic diseases like heart disease, diabetes, and certain cancers. Mentally, exercise releases endorphins that reduce stress and anxiety while improving mood and cognitive function. It can help with depression and boost self-confidence. Regular physical activity also promotes better posture, flexibility, and balance, reducing the risk of falls and injuries. Additionally, exercise provides social benefits when done with others, fostering connections and accountability. Even moderate activities like walking, swimming, or cycling for 30 minutes most days can provide significant health improvements.
"""
return council.run(task=task)
def main():
"""
Main function demonstrating different CouncilAsAJudge configurations.
"""
configurations = [
("Final Output Only", evaluate_with_final_output),
("Full Conversation", evaluate_with_conversation_output),
("Minimal Workers", evaluate_with_minimal_workers),
]
results = {}
for config_name, evaluation_func in configurations:
print(f"\n{'='*60}")
print(f"Configuration: {config_name}")
print(f"{'='*60}")
try:
result = evaluation_func()
results[config_name] = result
print(f"{config_name} evaluation completed!")
# Show a preview of the result
if isinstance(result, str):
preview = (
result[:200] + "..."
if len(result) > 200
else result
)
print(f"Preview: {preview}")
else:
print(f"Result type: {type(result)}")
except Exception as e:
print(f"{config_name} evaluation failed: {str(e)}")
results[config_name] = None
return results
if __name__ == "__main__":
# Run all configuration examples
all_results = main()
# Display final summary
print(f"\n{'='*60}")
print("CONFIGURATION SUMMARY")
print(f"{'='*60}")
successful_configs = sum(
1 for result in all_results.values() if result is not None
)
total_configs = len(all_results)
print(
f"Successful evaluations: {successful_configs}/{total_configs}"
)
for config_name, result in all_results.items():
status = "✅ Success" if result else "❌ Failed"
print(f"{config_name}: {status}")

@ -0,0 +1,44 @@
"""
Simple example demonstrating CouncilAsAJudge usage.
This example shows how to use the CouncilAsAJudge to evaluate a task response
across multiple dimensions including accuracy, helpfulness, harmlessness,
coherence, conciseness, and instruction adherence.
"""
from swarms.structs.council_judge import CouncilAsAJudge
def main():
"""
Main function demonstrating CouncilAsAJudge usage.
"""
# Initialize the council judge
council = CouncilAsAJudge(
name="Quality Evaluation Council",
description="Evaluates response quality across multiple dimensions",
model_name="gpt-4o-mini",
max_workers=4,
)
# Example task with a response to evaluate
task_with_response = """
Task: Explain the concept of machine learning to a beginner.
Response: Machine learning is a subset of artificial intelligence that enables computers to learn and improve from experience without being explicitly programmed. It works by analyzing large amounts of data to identify patterns and make predictions or decisions. There are three main types: supervised learning (using labeled data), unsupervised learning (finding hidden patterns), and reinforcement learning (learning through trial and error). Machine learning is used in various applications like recommendation systems, image recognition, and natural language processing.
"""
# Run the evaluation
result = council.run(task=task_with_response)
return result
if __name__ == "__main__":
# Run the example
evaluation_result = main()
# Display the result
print("Council Evaluation Complete!")
print("=" * 50)
print(evaluation_result)

@ -0,0 +1,70 @@
"""
Debug script for the Arasaka Dashboard to test agent output display.
"""
from swarms.structs.hiearchical_swarm import HierarchicalSwarm
from swarms.structs.agent import Agent
def debug_dashboard():
"""Debug the dashboard functionality."""
print("🔍 Starting dashboard debug...")
# Create simple agents with clear names
agent1 = Agent(
agent_name="Research-Agent",
agent_description="A research agent for testing",
model_name="gpt-4o-mini",
max_loops=1,
verbose=False,
)
agent2 = Agent(
agent_name="Analysis-Agent",
agent_description="An analysis agent for testing",
model_name="gpt-4o-mini",
max_loops=1,
verbose=False,
)
print(
f"✅ Created agents: {agent1.agent_name}, {agent2.agent_name}"
)
# Create swarm with dashboard
swarm = HierarchicalSwarm(
name="Debug Swarm",
description="A test swarm for debugging dashboard functionality",
agents=[agent1, agent2],
max_loops=1,
interactive=True,
verbose=True,
)
print("✅ Created swarm with dashboard")
print("📊 Dashboard should now show agents in PENDING status")
# Wait a moment to see the initial dashboard
import time
time.sleep(3)
print("\n🚀 Starting swarm execution...")
# Run with a simple task
result = swarm.run(
task="Create a brief summary of machine learning"
)
print("\n✅ Debug completed!")
print("📋 Final result preview:")
print(
str(result)[:300] + "..."
if len(str(result)) > 300
else str(result)
)
if __name__ == "__main__":
debug_dashboard()

@ -0,0 +1,71 @@
"""
Hierarchical Swarm with Arasaka Dashboard Example
This example demonstrates the new interactive dashboard functionality for the
hierarchical swarm, featuring a futuristic Arasaka Corporation-style interface
with red and black color scheme.
"""
from swarms.structs.hiearchical_swarm import HierarchicalSwarm
from swarms.structs.agent import Agent
def main():
"""
Demonstrate the hierarchical swarm with interactive dashboard.
"""
print("🚀 Initializing Swarms Corporation Hierarchical Swarm...")
# Create specialized agents
research_agent = Agent(
agent_name="Research-Analyst",
agent_description="Specialized in comprehensive research and data gathering",
model_name="gpt-4o-mini",
max_loops=1,
verbose=False,
)
analysis_agent = Agent(
agent_name="Data-Analyst",
agent_description="Expert in data analysis and pattern recognition",
model_name="gpt-4o-mini",
max_loops=1,
verbose=False,
)
strategy_agent = Agent(
agent_name="Strategy-Consultant",
agent_description="Specialized in strategic planning and recommendations",
model_name="gpt-4o-mini",
max_loops=1,
verbose=False,
)
# Create hierarchical swarm with interactive dashboard
swarm = HierarchicalSwarm(
name="Swarms Corporation Operations",
description="Enterprise-grade hierarchical swarm for complex task execution",
agents=[research_agent, analysis_agent, strategy_agent],
max_loops=2,
interactive=True, # Enable the Arasaka dashboard
verbose=True,
)
print("\n🎯 Swarm initialized successfully!")
print(
"📊 Interactive dashboard will be displayed during execution."
)
print(
"💡 The swarm will prompt you for a task when you call swarm.run()"
)
# Run the swarm (task will be prompted interactively)
result = swarm.run()
print("\n✅ Swarm execution completed!")
print("📋 Final result:")
print(result)
if __name__ == "__main__":
main()

@ -0,0 +1,56 @@
"""
Test script for the Arasaka Dashboard functionality.
"""
from swarms.structs.hiearchical_swarm import HierarchicalSwarm
from swarms.structs.agent import Agent
def test_dashboard():
"""Test the dashboard functionality with a simple task."""
# Create simple agents
agent1 = Agent(
agent_name="Test-Agent-1",
agent_description="A test agent for dashboard verification",
model_name="gpt-4o-mini",
max_loops=1,
verbose=False,
)
agent2 = Agent(
agent_name="Test-Agent-2",
agent_description="Another test agent for dashboard verification",
model_name="gpt-4o-mini",
max_loops=1,
verbose=False,
)
# Create swarm with dashboard
swarm = HierarchicalSwarm(
name="Dashboard Test Swarm",
agents=[agent1, agent2],
max_loops=1,
interactive=True,
verbose=True,
)
print("🧪 Testing Arasaka Dashboard...")
print("📊 Dashboard should appear and prompt for task input")
# Run with a simple task
result = swarm.run(
task="Create a simple summary of artificial intelligence trends"
)
print("\n✅ Test completed!")
print("📋 Result preview:")
print(
str(result)[:500] + "..."
if len(str(result)) > 500
else str(result)
)
if __name__ == "__main__":
test_dashboard()

@ -0,0 +1,56 @@
"""
Test script for full agent output display in the Arasaka Dashboard.
"""
from swarms.structs.hiearchical_swarm import HierarchicalSwarm
from swarms.structs.agent import Agent
def test_full_output():
"""Test the full output display functionality."""
print("🔍 Testing full agent output display...")
# Create agents that will produce substantial output
agent1 = Agent(
agent_name="Research-Agent",
agent_description="A research agent that produces detailed output",
model_name="gpt-4o-mini",
max_loops=1,
verbose=False,
)
agent2 = Agent(
agent_name="Analysis-Agent",
agent_description="An analysis agent that provides comprehensive analysis",
model_name="gpt-4o-mini",
max_loops=1,
verbose=False,
)
# Create swarm with dashboard and detailed view enabled
swarm = HierarchicalSwarm(
name="Full Output Test Swarm",
description="A test swarm for verifying full agent output display",
agents=[agent1, agent2],
max_loops=1,
interactive=True,
verbose=True,
)
print("✅ Created swarm with detailed view enabled")
print(
"📊 Dashboard should show full agent outputs without truncation"
)
# Run with a task that will generate substantial output
swarm.run(
task="Provide a comprehensive analysis of artificial intelligence trends in 2024, including detailed explanations of each trend"
)
print("\n✅ Test completed!")
print("📋 Check the dashboard for full agent outputs")
if __name__ == "__main__":
test_full_output()

@ -0,0 +1,57 @@
"""
Test script for multi-loop agent tracking in the Arasaka Dashboard.
"""
from swarms.structs.hiearchical_swarm import HierarchicalSwarm
from swarms.structs.agent import Agent
def test_multi_loop():
"""Test the multi-loop agent tracking functionality."""
print("🔍 Testing multi-loop agent tracking...")
# Create agents
agent1 = Agent(
agent_name="Research-Agent",
agent_description="A research agent for multi-loop testing",
model_name="gpt-4o-mini",
max_loops=1,
verbose=False,
)
agent2 = Agent(
agent_name="Analysis-Agent",
agent_description="An analysis agent for multi-loop testing",
model_name="gpt-4o-mini",
max_loops=1,
verbose=False,
)
# Create swarm with multiple loops
swarm = HierarchicalSwarm(
name="Multi-Loop Test Swarm",
description="A test swarm for verifying multi-loop agent tracking",
agents=[agent1, agent2],
max_loops=3, # Multiple loops to test history tracking
interactive=True,
verbose=True,
)
print("✅ Created swarm with multi-loop tracking")
print(
"📊 Dashboard should show agent outputs across multiple loops"
)
print("🔄 Each loop will add new rows to the monitoring matrix")
# Run with a task that will benefit from multiple iterations
swarm.run(
task="Analyze the impact of artificial intelligence on healthcare, then refine the analysis with additional insights, and finally provide actionable recommendations"
)
print("\n✅ Multi-loop test completed!")
print("📋 Check the dashboard for agent outputs across all loops")
if __name__ == "__main__":
test_multi_loop()

@ -0,0 +1,265 @@
"""
Stagehand Browser Automation Agent for Swarms
=============================================
This example demonstrates how to create a Swarms-compatible agent
that wraps Stagehand's browser automation capabilities.
The StagehandAgent class inherits from the Swarms Agent base class
and implements browser automation through natural language commands.
"""
import asyncio
import json
import os
from typing import Any, Dict, Optional
from dotenv import load_dotenv
from loguru import logger
from pydantic import BaseModel, Field
from swarms import Agent as SwarmsAgent
from stagehand import Stagehand, StagehandConfig
load_dotenv()
class WebData(BaseModel):
"""Schema for extracted web data."""
url: str = Field(..., description="The URL of the page")
title: str = Field(..., description="Page title")
content: str = Field(..., description="Extracted content")
metadata: Dict[str, Any] = Field(
default_factory=dict, description="Additional metadata"
)
class StagehandAgent(SwarmsAgent):
"""
A Swarms agent that integrates Stagehand for browser automation.
This agent can navigate websites, extract data, perform actions,
and observe page elements using natural language instructions.
"""
def __init__(
self,
agent_name: str = "StagehandBrowserAgent",
browserbase_api_key: Optional[str] = None,
browserbase_project_id: Optional[str] = None,
model_name: str = "gpt-4o-mini",
model_api_key: Optional[str] = None,
env: str = "LOCAL", # LOCAL or BROWSERBASE
*args,
**kwargs,
):
"""
Initialize the StagehandAgent.
Args:
agent_name: Name of the agent
browserbase_api_key: API key for Browserbase (if using cloud)
browserbase_project_id: Project ID for Browserbase
model_name: LLM model to use
model_api_key: API key for the model
env: Environment - LOCAL or BROWSERBASE
"""
# Don't pass stagehand-specific args to parent
super().__init__(agent_name=agent_name, *args, **kwargs)
self.stagehand_config = StagehandConfig(
env=env,
api_key=browserbase_api_key
or os.getenv("BROWSERBASE_API_KEY"),
project_id=browserbase_project_id
or os.getenv("BROWSERBASE_PROJECT_ID"),
model_name=model_name,
model_api_key=model_api_key
or os.getenv("OPENAI_API_KEY"),
)
self.stagehand = None
self._initialized = False
async def _init_stagehand(self):
"""Initialize Stagehand instance."""
if not self._initialized:
self.stagehand = Stagehand(self.stagehand_config)
await self.stagehand.init()
self._initialized = True
logger.info(
f"Stagehand initialized for {self.agent_name}"
)
async def _close_stagehand(self):
"""Close Stagehand instance."""
if self.stagehand and self._initialized:
await self.stagehand.close()
self._initialized = False
logger.info(f"Stagehand closed for {self.agent_name}")
def run(self, task: str, *args, **kwargs) -> str:
"""
Execute a browser automation task.
The task string should contain instructions like:
- "Navigate to example.com and extract the main content"
- "Go to google.com and search for 'AI agents'"
- "Extract all company names from https://ycombinator.com"
Args:
task: Natural language description of the browser task
Returns:
String result of the task execution
"""
return asyncio.run(self._async_run(task, *args, **kwargs))
async def _async_run(self, task: str, *args, **kwargs) -> str:
"""Async implementation of run method."""
try:
await self._init_stagehand()
# Parse the task to determine actions
result = await self._execute_browser_task(task)
return json.dumps(result, indent=2)
except Exception as e:
logger.error(f"Error in browser task: {str(e)}")
return f"Error executing browser task: {str(e)}"
finally:
# Keep browser open for potential follow-up tasks
pass
async def _execute_browser_task(
self, task: str
) -> Dict[str, Any]:
"""
Execute a browser task based on natural language instructions.
This method interprets the task and calls appropriate Stagehand methods.
"""
page = self.stagehand.page
result = {"task": task, "status": "completed", "data": {}}
# Determine if task involves navigation
if any(
keyword in task.lower()
for keyword in ["navigate", "go to", "visit", "open"]
):
# Extract URL from task
import re
url_pattern = r"https?://[^\s]+"
urls = re.findall(url_pattern, task)
if not urls and any(
domain in task for domain in [".com", ".org", ".net"]
):
# Try to extract domain names
domain_pattern = r"(\w+\.\w+)"
domains = re.findall(domain_pattern, task)
if domains:
urls = [f"https://{domain}" for domain in domains]
if urls:
url = urls[0]
await page.goto(url)
result["data"]["navigated_to"] = url
logger.info(f"Navigated to {url}")
# Determine action type
if "extract" in task.lower():
# Perform extraction
extraction_prompt = task.replace("extract", "").strip()
extracted = await page.extract(extraction_prompt)
result["data"]["extracted"] = extracted
result["action"] = "extract"
elif "click" in task.lower() or "press" in task.lower():
# Perform action
action_result = await page.act(task)
result["data"]["action_performed"] = str(action_result)
result["action"] = "act"
elif "search" in task.lower():
# Perform search action
search_query = (
task.split("search for")[-1].strip().strip("'\"")
)
# First, find the search box
search_box = await page.observe(
"find the search input field"
)
if search_box:
# Click on search box and type
await page.act(f"click on {search_box[0]}")
await page.act(f"type '{search_query}'")
await page.act("press Enter")
result["data"]["search_query"] = search_query
result["action"] = "search"
elif "observe" in task.lower() or "find" in task.lower():
# Perform observation
observation = await page.observe(task)
result["data"]["observation"] = [
{
"description": obs.description,
"selector": obs.selector,
}
for obs in observation
]
result["action"] = "observe"
else:
# General action
action_result = await page.act(task)
result["data"]["action_result"] = str(action_result)
result["action"] = "general"
return result
def cleanup(self):
"""Clean up browser resources."""
if self._initialized:
asyncio.run(self._close_stagehand())
def __del__(self):
"""Ensure browser is closed on deletion."""
self.cleanup()
# Example usage
if __name__ == "__main__":
# Create a Stagehand browser agent
browser_agent = StagehandAgent(
agent_name="WebScraperAgent",
model_name="gpt-4o-mini",
env="LOCAL", # Use LOCAL for Playwright, BROWSERBASE for cloud
)
# Example 1: Navigate and extract data
print("Example 1: Basic navigation and extraction")
result1 = browser_agent.run(
"Navigate to https://news.ycombinator.com and extract the titles of the top 5 stories"
)
print(result1)
print("\n" + "=" * 50 + "\n")
# Example 2: Perform a search
print("Example 2: Search on a website")
result2 = browser_agent.run(
"Go to google.com and search for 'Swarms AI framework'"
)
print(result2)
print("\n" + "=" * 50 + "\n")
# Example 3: Extract structured data
print("Example 3: Extract specific information")
result3 = browser_agent.run(
"Navigate to https://example.com and extract the main heading and first paragraph"
)
print(result3)
# Clean up
browser_agent.cleanup()

@ -0,0 +1,397 @@
"""
Stagehand Tools for Swarms Agent
=================================
This example demonstrates how to create Stagehand browser automation tools
that can be used by a standard Swarms Agent. Each Stagehand method (act,
extract, observe) becomes a separate tool that the agent can use.
This approach gives the agent more fine-grained control over browser
automation tasks.
"""
import asyncio
import json
import os
from typing import Optional
from dotenv import load_dotenv
from loguru import logger
from swarms import Agent
from stagehand import Stagehand, StagehandConfig
load_dotenv()
class BrowserState:
"""Singleton to manage browser state across tools."""
_instance = None
_stagehand = None
_initialized = False
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
async def init_browser(
self,
env: str = "LOCAL",
api_key: Optional[str] = None,
project_id: Optional[str] = None,
model_name: str = "gpt-4o-mini",
model_api_key: Optional[str] = None,
):
"""Initialize the browser if not already initialized."""
if not self._initialized:
config = StagehandConfig(
env=env,
api_key=api_key or os.getenv("BROWSERBASE_API_KEY"),
project_id=project_id
or os.getenv("BROWSERBASE_PROJECT_ID"),
model_name=model_name,
model_api_key=model_api_key
or os.getenv("OPENAI_API_KEY"),
)
self._stagehand = Stagehand(config)
await self._stagehand.init()
self._initialized = True
logger.info("Stagehand browser initialized")
async def get_page(self):
"""Get the current page instance."""
if not self._initialized:
raise RuntimeError(
"Browser not initialized. Call init_browser first."
)
return self._stagehand.page
async def close(self):
"""Close the browser."""
if self._initialized and self._stagehand:
await self._stagehand.close()
self._initialized = False
logger.info("Stagehand browser closed")
# Browser state instance
browser_state = BrowserState()
def navigate_browser(url: str) -> str:
"""
Navigate to a URL in the browser.
Args:
url (str): The URL to navigate to. Should be a valid URL starting with http:// or https://.
If no protocol is provided, https:// will be added automatically.
Returns:
str: Success message with the URL navigated to, or error message if navigation fails
Raises:
RuntimeError: If browser initialization fails
Exception: If navigation to the URL fails
Example:
>>> result = navigate_browser("https://example.com")
>>> print(result)
"Successfully navigated to https://example.com"
>>> result = navigate_browser("google.com")
>>> print(result)
"Successfully navigated to https://google.com"
"""
return asyncio.run(_navigate_browser_async(url))
async def _navigate_browser_async(url: str) -> str:
"""Async implementation of navigate_browser."""
try:
await browser_state.init_browser()
page = await browser_state.get_page()
# Ensure URL has protocol
if not url.startswith(("http://", "https://")):
url = f"https://{url}"
await page.goto(url)
return f"Successfully navigated to {url}"
except Exception as e:
logger.error(f"Navigation error: {str(e)}")
return f"Failed to navigate to {url}: {str(e)}"
def browser_act(action: str) -> str:
"""
Perform an action on the current web page using natural language.
Args:
action (str): Natural language description of the action to perform.
Examples: 'click the submit button', 'type hello@example.com in the email field',
'scroll down', 'press Enter', 'select option from dropdown'
Returns:
str: JSON formatted string with action result and status information
Raises:
RuntimeError: If browser is not initialized or page is not available
Exception: If the action cannot be performed on the current page
Example:
>>> result = browser_act("click the submit button")
>>> print(result)
"Action performed: click the submit button. Result: clicked successfully"
>>> result = browser_act("type hello@example.com in the email field")
>>> print(result)
"Action performed: type hello@example.com in the email field. Result: text entered"
"""
return asyncio.run(_browser_act_async(action))
async def _browser_act_async(action: str) -> str:
"""Async implementation of browser_act."""
try:
await browser_state.init_browser()
page = await browser_state.get_page()
result = await page.act(action)
return f"Action performed: {action}. Result: {result}"
except Exception as e:
logger.error(f"Action error: {str(e)}")
return f"Failed to perform action '{action}': {str(e)}"
def browser_extract(query: str) -> str:
"""
Extract information from the current web page using natural language.
Args:
query (str): Natural language description of what information to extract.
Examples: 'extract all email addresses', 'get the main article text',
'find all product prices', 'extract the page title and meta description'
Returns:
str: JSON formatted string containing the extracted information, or error message if extraction fails
Raises:
RuntimeError: If browser is not initialized or page is not available
Exception: If extraction fails due to page content or parsing issues
Example:
>>> result = browser_extract("extract all email addresses")
>>> print(result)
'["contact@example.com", "support@example.com"]'
>>> result = browser_extract("get the main article text")
>>> print(result)
'{"title": "Article Title", "content": "Article content..."}'
"""
return asyncio.run(_browser_extract_async(query))
async def _browser_extract_async(query: str) -> str:
"""Async implementation of browser_extract."""
try:
await browser_state.init_browser()
page = await browser_state.get_page()
extracted = await page.extract(query)
# Convert to JSON string for agent consumption
if isinstance(extracted, (dict, list)):
return json.dumps(extracted, indent=2)
else:
return str(extracted)
except Exception as e:
logger.error(f"Extraction error: {str(e)}")
return f"Failed to extract '{query}': {str(e)}"
def browser_observe(query: str) -> str:
"""
Observe and find elements on the current web page using natural language.
Args:
query (str): Natural language description of elements to find.
Examples: 'find the search box', 'locate the submit button',
'find all navigation links', 'observe form elements'
Returns:
str: JSON formatted string containing information about found elements including
their descriptions, selectors, and interaction methods
Raises:
RuntimeError: If browser is not initialized or page is not available
Exception: If observation fails due to page structure or element detection issues
Example:
>>> result = browser_observe("find the search box")
>>> print(result)
'[{"description": "Search input field", "selector": "#search", "method": "input"}]'
>>> result = browser_observe("locate the submit button")
>>> print(result)
'[{"description": "Submit button", "selector": "button[type=submit]", "method": "click"}]'
"""
return asyncio.run(_browser_observe_async(query))
async def _browser_observe_async(query: str) -> str:
"""Async implementation of browser_observe."""
try:
await browser_state.init_browser()
page = await browser_state.get_page()
observations = await page.observe(query)
# Format observations for readability
result = []
for obs in observations:
result.append(
{
"description": obs.description,
"selector": obs.selector,
"method": obs.method,
}
)
return json.dumps(result, indent=2)
except Exception as e:
logger.error(f"Observation error: {str(e)}")
return f"Failed to observe '{query}': {str(e)}"
def browser_screenshot(filename: str = "screenshot.png") -> str:
"""
Take a screenshot of the current web page.
Args:
filename (str, optional): The filename to save the screenshot to.
Defaults to "screenshot.png".
.png extension will be added automatically if not provided.
Returns:
str: Success message with the filename where screenshot was saved,
or error message if screenshot fails
Raises:
RuntimeError: If browser is not initialized or page is not available
Exception: If screenshot capture or file saving fails
Example:
>>> result = browser_screenshot()
>>> print(result)
"Screenshot saved to screenshot.png"
>>> result = browser_screenshot("page_capture.png")
>>> print(result)
"Screenshot saved to page_capture.png"
"""
return asyncio.run(_browser_screenshot_async(filename))
async def _browser_screenshot_async(filename: str) -> str:
"""Async implementation of browser_screenshot."""
try:
await browser_state.init_browser()
page = await browser_state.get_page()
# Ensure .png extension
if not filename.endswith(".png"):
filename += ".png"
# Get the underlying Playwright page
playwright_page = page.page
await playwright_page.screenshot(path=filename)
return f"Screenshot saved to {filename}"
except Exception as e:
logger.error(f"Screenshot error: {str(e)}")
return f"Failed to take screenshot: {str(e)}"
def close_browser() -> str:
"""
Close the browser when done with automation tasks.
Returns:
str: Success message if browser is closed successfully,
or error message if closing fails
Raises:
Exception: If browser closing process encounters errors
Example:
>>> result = close_browser()
>>> print(result)
"Browser closed successfully"
"""
return asyncio.run(_close_browser_async())
async def _close_browser_async() -> str:
"""Async implementation of close_browser."""
try:
await browser_state.close()
return "Browser closed successfully"
except Exception as e:
logger.error(f"Close browser error: {str(e)}")
return f"Failed to close browser: {str(e)}"
# Example usage
if __name__ == "__main__":
# Create a Swarms agent with browser tools
browser_agent = Agent(
agent_name="BrowserAutomationAgent",
model_name="gpt-4o-mini",
max_loops=1,
tools=[
navigate_browser,
browser_act,
browser_extract,
browser_observe,
browser_screenshot,
close_browser,
],
system_prompt="""You are a web browser automation specialist. You can:
1. Navigate to websites using the navigate_browser tool
2. Perform actions like clicking and typing using the browser_act tool
3. Extract information from pages using the browser_extract tool
4. Find and observe elements using the browser_observe tool
5. Take screenshots using the browser_screenshot tool
6. Close the browser when done using the close_browser tool
Always start by navigating to a URL before trying to interact with a page.
Be specific in your actions and extractions. When done with tasks, close the browser.""",
)
# Example 1: Research task
print("Example 1: Automated web research")
result1 = browser_agent.run(
"Go to hackernews (news.ycombinator.com) and extract the titles of the top 5 stories. Then take a screenshot."
)
print(result1)
print("\n" + "=" * 50 + "\n")
# Example 2: Search task
print("Example 2: Perform a web search")
result2 = browser_agent.run(
"Navigate to google.com, search for 'Python web scraping best practices', and extract the first 3 search result titles"
)
print(result2)
print("\n" + "=" * 50 + "\n")
# Example 3: Form interaction
print("Example 3: Interact with a form")
result3 = browser_agent.run(
"Go to example.com and observe what elements are on the page. Then extract all the text content."
)
print(result3)
# Clean up
browser_agent.run("Close the browser")

@ -0,0 +1,263 @@
"""
Stagehand MCP Server Integration with Swarms
============================================
This example demonstrates how to use the Stagehand MCP (Model Context Protocol)
server with Swarms agents. The MCP server provides browser automation capabilities
as standardized tools that can be discovered and used by agents.
Prerequisites:
1. Install and run the Stagehand MCP server:
cd stagehand-mcp-server
npm install
npm run build
npm start
2. The server will start on http://localhost:3000/sse
Features:
- Automatic tool discovery from MCP server
- Multi-session browser management
- Built-in screenshot resources
- Prompt templates for common tasks
"""
from typing import List
from dotenv import load_dotenv
from loguru import logger
from swarms import Agent
load_dotenv()
class StagehandMCPAgent:
"""
A Swarms agent that connects to the Stagehand MCP server
for browser automation capabilities.
"""
def __init__(
self,
agent_name: str = "StagehandMCPAgent",
mcp_server_url: str = "http://localhost:3000/sse",
model_name: str = "gpt-4o-mini",
max_loops: int = 1,
):
"""
Initialize the Stagehand MCP Agent.
Args:
agent_name: Name of the agent
mcp_server_url: URL of the Stagehand MCP server
model_name: LLM model to use
max_loops: Maximum number of reasoning loops
"""
self.agent = Agent(
agent_name=agent_name,
model_name=model_name,
max_loops=max_loops,
# Connect to the Stagehand MCP server
mcp_url=mcp_server_url,
system_prompt="""You are a web browser automation specialist with access to Stagehand MCP tools.
Available tools from the MCP server:
- navigate: Navigate to a URL
- act: Perform actions on web pages (click, type, etc.)
- extract: Extract data from web pages
- observe: Find and observe elements on pages
- screenshot: Take screenshots
- createSession: Create new browser sessions for parallel tasks
- listSessions: List active browser sessions
- closeSession: Close browser sessions
For multi-page workflows, you can create multiple sessions.
Always be specific in your actions and extractions.
Remember to close sessions when done with them.""",
verbose=True,
)
def run(self, task: str) -> str:
"""Run a browser automation task."""
return self.agent.run(task)
class MultiSessionBrowserSwarm:
"""
A multi-agent swarm that uses multiple browser sessions
for parallel web automation tasks.
"""
def __init__(
self,
mcp_server_url: str = "http://localhost:3000/sse",
num_agents: int = 3,
):
"""
Initialize a swarm of browser automation agents.
Args:
mcp_server_url: URL of the Stagehand MCP server
num_agents: Number of agents to create
"""
self.agents = []
# Create specialized agents for different tasks
agent_roles = [
(
"DataExtractor",
"You specialize in extracting structured data from websites.",
),
(
"FormFiller",
"You specialize in filling out forms and interacting with web applications.",
),
(
"WebMonitor",
"You specialize in monitoring websites for changes and capturing screenshots.",
),
]
for i in range(min(num_agents, len(agent_roles))):
name, specialization = agent_roles[i]
agent = Agent(
agent_name=f"{name}_{i}",
model_name="gpt-4o-mini",
max_loops=1,
mcp_url=mcp_server_url,
system_prompt=f"""You are a web browser automation specialist. {specialization}
You have access to Stagehand MCP tools including:
- createSession: Create a new browser session
- navigate_session: Navigate to URLs in a specific session
- act_session: Perform actions in a specific session
- extract_session: Extract data from a specific session
- observe_session: Observe elements in a specific session
- closeSession: Close a session when done
Always create your own session for tasks to work independently from other agents.""",
verbose=True,
)
self.agents.append(agent)
def distribute_tasks(self, tasks: List[str]) -> List[str]:
"""Distribute tasks among agents."""
results = []
# Distribute tasks round-robin among agents
for i, task in enumerate(tasks):
agent_idx = i % len(self.agents)
agent = self.agents[agent_idx]
logger.info(
f"Assigning task to {agent.agent_name}: {task}"
)
result = agent.run(task)
results.append(result)
return results
# Example usage
if __name__ == "__main__":
print("=" * 70)
print("Stagehand MCP Server Integration Examples")
print("=" * 70)
print(
"\nMake sure the Stagehand MCP server is running on http://localhost:3000/sse"
)
print("Run: cd stagehand-mcp-server && npm start\n")
# Example 1: Single agent with MCP tools
print("\nExample 1: Single Agent with MCP Tools")
print("-" * 40)
mcp_agent = StagehandMCPAgent(
agent_name="WebResearchAgent",
mcp_server_url="http://localhost:3000/sse",
)
# Research task using MCP tools
result1 = mcp_agent.run(
"""Navigate to news.ycombinator.com and extract the following:
1. The titles of the top 5 stories
2. Their points/scores
3. Number of comments for each
Then take a screenshot of the page."""
)
print(f"Result: {result1}")
print("\n" + "=" * 70 + "\n")
# Example 2: Multi-session parallel browsing
print("Example 2: Multi-Session Parallel Browsing")
print("-" * 40)
parallel_agent = StagehandMCPAgent(
agent_name="ParallelBrowserAgent",
mcp_server_url="http://localhost:3000/sse",
)
result2 = parallel_agent.run(
"""Create 3 browser sessions and perform these tasks in parallel:
1. Session 1: Go to github.com/trending and extract the top 3 trending repositories
2. Session 2: Go to reddit.com/r/programming and extract the top 3 posts
3. Session 3: Go to stackoverflow.com and extract the featured questions
After extracting data from all sessions, close them."""
)
print(f"Result: {result2}")
print("\n" + "=" * 70 + "\n")
# Example 3: Multi-agent browser swarm
print("Example 3: Multi-Agent Browser Swarm")
print("-" * 40)
# Create a swarm of specialized browser agents
browser_swarm = MultiSessionBrowserSwarm(
mcp_server_url="http://localhost:3000/sse",
num_agents=3,
)
# Define tasks for the swarm
swarm_tasks = [
"Create a session, navigate to python.org, and extract information about the latest Python version and its key features",
"Create a session, go to npmjs.com, search for 'stagehand', and extract information about the package including version and description",
"Create a session, visit playwright.dev, and extract the main features and benefits listed on the homepage",
]
print("Distributing tasks to browser swarm...")
swarm_results = browser_swarm.distribute_tasks(swarm_tasks)
for i, result in enumerate(swarm_results):
print(f"\nTask {i+1} Result: {result}")
print("\n" + "=" * 70 + "\n")
# Example 4: Complex workflow with session management
print("Example 4: Complex Multi-Page Workflow")
print("-" * 40)
workflow_agent = StagehandMCPAgent(
agent_name="WorkflowAgent",
mcp_server_url="http://localhost:3000/sse",
max_loops=2, # Allow more complex reasoning
)
result4 = workflow_agent.run(
"""Perform a comprehensive analysis of AI frameworks:
1. Create a new session
2. Navigate to github.com/huggingface/transformers and extract the star count and latest release info
3. In the same session, navigate to github.com/openai/gpt-3 and extract similar information
4. Navigate to github.com/anthropics/anthropic-sdk-python and extract repository statistics
5. Take screenshots of each repository page
6. Compile a comparison report of all three repositories
7. Close the session when done"""
)
print(f"Result: {result4}")
print("\n" + "=" * 70)
print("All examples completed!")
print("=" * 70)

@ -0,0 +1,371 @@
"""
Stagehand Multi-Agent Browser Automation Workflows
=================================================
This example demonstrates advanced multi-agent workflows using Stagehand
for complex browser automation scenarios. It shows how multiple agents
can work together to accomplish sophisticated web tasks.
Use cases:
1. E-commerce price monitoring across multiple sites
2. Competitive analysis and market research
3. Automated testing and validation workflows
4. Data aggregation from multiple sources
"""
from datetime import datetime
from typing import Dict, List, Optional
from dotenv import load_dotenv
from pydantic import BaseModel, Field
from swarms import Agent, SequentialWorkflow, ConcurrentWorkflow
from swarms.structs.agent_rearrange import AgentRearrange
from examples.stagehand.stagehand_wrapper_agent import StagehandAgent
load_dotenv()
# Pydantic models for structured data
class ProductInfo(BaseModel):
"""Product information schema."""
name: str = Field(..., description="Product name")
price: float = Field(..., description="Product price")
availability: str = Field(..., description="Availability status")
url: str = Field(..., description="Product URL")
screenshot_path: Optional[str] = Field(
None, description="Screenshot file path"
)
class MarketAnalysis(BaseModel):
"""Market analysis report schema."""
timestamp: datetime = Field(default_factory=datetime.now)
products: List[ProductInfo] = Field(
..., description="List of products analyzed"
)
price_range: Dict[str, float] = Field(
..., description="Min and max prices"
)
recommendations: List[str] = Field(
..., description="Analysis recommendations"
)
# Specialized browser agents
class ProductScraperAgent(StagehandAgent):
"""Specialized agent for scraping product information."""
def __init__(self, site_name: str, *args, **kwargs):
super().__init__(
agent_name=f"ProductScraper_{site_name}", *args, **kwargs
)
self.site_name = site_name
class PriceMonitorAgent(StagehandAgent):
"""Specialized agent for monitoring price changes."""
def __init__(self, *args, **kwargs):
super().__init__(
agent_name="PriceMonitorAgent", *args, **kwargs
)
# Example 1: E-commerce Price Comparison Workflow
def create_price_comparison_workflow():
"""
Create a workflow that compares prices across multiple e-commerce sites.
"""
# Create specialized agents for different sites
amazon_agent = StagehandAgent(
agent_name="AmazonScraperAgent",
model_name="gpt-4o-mini",
env="LOCAL",
)
ebay_agent = StagehandAgent(
agent_name="EbayScraperAgent",
model_name="gpt-4o-mini",
env="LOCAL",
)
analysis_agent = Agent(
agent_name="PriceAnalysisAgent",
model_name="gpt-4o-mini",
system_prompt="""You are a price analysis expert. Analyze product prices from multiple sources
and provide insights on the best deals, price trends, and recommendations.
Focus on value for money and highlight any significant price differences.""",
)
# Create concurrent workflow for parallel scraping
scraping_workflow = ConcurrentWorkflow(
agents=[amazon_agent, ebay_agent],
max_loops=1,
verbose=True,
)
# Create sequential workflow: scrape -> analyze
full_workflow = SequentialWorkflow(
agents=[scraping_workflow, analysis_agent],
max_loops=1,
verbose=True,
)
return full_workflow
# Example 2: Competitive Analysis Workflow
def create_competitive_analysis_workflow():
"""
Create a workflow for competitive analysis across multiple company websites.
"""
# Agent for extracting company information
company_researcher = StagehandAgent(
agent_name="CompanyResearchAgent",
model_name="gpt-4o-mini",
env="LOCAL",
)
# Agent for analyzing social media presence
social_media_agent = StagehandAgent(
agent_name="SocialMediaAnalysisAgent",
model_name="gpt-4o-mini",
env="LOCAL",
)
# Agent for compiling competitive analysis report
report_compiler = Agent(
agent_name="CompetitiveAnalysisReporter",
model_name="gpt-4o-mini",
system_prompt="""You are a competitive analysis expert. Compile comprehensive reports
based on company information and social media presence data. Identify strengths,
weaknesses, and market positioning for each company.""",
)
# Create agent rearrange for flexible routing
workflow_pattern = (
"company_researcher -> social_media_agent -> report_compiler"
)
competitive_workflow = AgentRearrange(
agents=[
company_researcher,
social_media_agent,
report_compiler,
],
flow=workflow_pattern,
verbose=True,
)
return competitive_workflow
# Example 3: Automated Testing Workflow
def create_automated_testing_workflow():
"""
Create a workflow for automated web application testing.
"""
# Agent for UI testing
ui_tester = StagehandAgent(
agent_name="UITestingAgent",
model_name="gpt-4o-mini",
env="LOCAL",
)
# Agent for form validation testing
form_tester = StagehandAgent(
agent_name="FormValidationAgent",
model_name="gpt-4o-mini",
env="LOCAL",
)
# Agent for accessibility testing
accessibility_tester = StagehandAgent(
agent_name="AccessibilityTestingAgent",
model_name="gpt-4o-mini",
env="LOCAL",
)
# Agent for compiling test results
test_reporter = Agent(
agent_name="TestReportCompiler",
model_name="gpt-4o-mini",
system_prompt="""You are a QA test report specialist. Compile test results from
UI, form validation, and accessibility testing into a comprehensive report.
Highlight any failures, warnings, and provide recommendations for fixes.""",
)
# Concurrent testing followed by report generation
testing_workflow = ConcurrentWorkflow(
agents=[ui_tester, form_tester, accessibility_tester],
max_loops=1,
verbose=True,
)
full_test_workflow = SequentialWorkflow(
agents=[testing_workflow, test_reporter],
max_loops=1,
verbose=True,
)
return full_test_workflow
# Example 4: News Aggregation and Sentiment Analysis
def create_news_aggregation_workflow():
"""
Create a workflow for news aggregation and sentiment analysis.
"""
# Multiple news scraper agents
news_scrapers = []
news_sites = [
("TechCrunch", "https://techcrunch.com"),
("HackerNews", "https://news.ycombinator.com"),
("Reddit", "https://reddit.com/r/technology"),
]
for site_name, url in news_sites:
scraper = StagehandAgent(
agent_name=f"{site_name}Scraper",
model_name="gpt-4o-mini",
env="LOCAL",
)
news_scrapers.append(scraper)
# Sentiment analysis agent
sentiment_analyzer = Agent(
agent_name="SentimentAnalyzer",
model_name="gpt-4o-mini",
system_prompt="""You are a sentiment analysis expert. Analyze news articles and posts
to determine overall sentiment (positive, negative, neutral) and identify key themes
and trends in the technology sector.""",
)
# Trend identification agent
trend_identifier = Agent(
agent_name="TrendIdentifier",
model_name="gpt-4o-mini",
system_prompt="""You are a trend analysis expert. Based on aggregated news and sentiment
data, identify emerging trends, hot topics, and potential market movements in the
technology sector.""",
)
# Create workflow: parallel scraping -> sentiment analysis -> trend identification
scraping_workflow = ConcurrentWorkflow(
agents=news_scrapers,
max_loops=1,
verbose=True,
)
analysis_workflow = SequentialWorkflow(
agents=[
scraping_workflow,
sentiment_analyzer,
trend_identifier,
],
max_loops=1,
verbose=True,
)
return analysis_workflow
# Main execution examples
if __name__ == "__main__":
print("=" * 70)
print("Stagehand Multi-Agent Workflow Examples")
print("=" * 70)
# Example 1: Price Comparison
print("\nExample 1: E-commerce Price Comparison")
print("-" * 40)
price_workflow = create_price_comparison_workflow()
# Search for a specific product across multiple sites
price_result = price_workflow.run(
"""Search for 'iPhone 15 Pro Max 256GB' on:
1. Amazon - extract price, availability, and seller information
2. eBay - extract price range, number of listings, and average price
Take screenshots of search results from both sites.
Compare the prices and provide recommendations on where to buy."""
)
print(f"Price Comparison Result:\n{price_result}")
print("\n" + "=" * 70 + "\n")
# Example 2: Competitive Analysis
print("Example 2: Competitive Analysis")
print("-" * 40)
competitive_workflow = create_competitive_analysis_workflow()
competitive_result = competitive_workflow.run(
"""Analyze these three AI companies:
1. OpenAI - visit openai.com and extract mission, products, and recent announcements
2. Anthropic - visit anthropic.com and extract their AI safety approach and products
3. DeepMind - visit deepmind.com and extract research focus and achievements
Then check their Twitter/X presence and recent posts.
Compile a competitive analysis report comparing their market positioning."""
)
print(f"Competitive Analysis Result:\n{competitive_result}")
print("\n" + "=" * 70 + "\n")
# Example 3: Automated Testing
print("Example 3: Automated Web Testing")
print("-" * 40)
testing_workflow = create_automated_testing_workflow()
test_result = testing_workflow.run(
"""Test the website example.com:
1. UI Testing: Check if all main navigation links work, images load, and layout is responsive
2. Form Testing: If there are any forms, test with valid and invalid inputs
3. Accessibility: Check for alt texts, ARIA labels, and keyboard navigation
Take screenshots of any issues found and compile a comprehensive test report."""
)
print(f"Test Results:\n{test_result}")
print("\n" + "=" * 70 + "\n")
# Example 4: News Aggregation
print("Example 4: Tech News Aggregation and Analysis")
print("-" * 40)
news_workflow = create_news_aggregation_workflow()
news_result = news_workflow.run(
"""For each news source:
1. TechCrunch: Extract the top 5 headlines about AI or machine learning
2. HackerNews: Extract the top 5 posts related to AI/ML with most points
3. Reddit r/technology: Extract top 5 posts about AI from the past week
Analyze sentiment and identify emerging trends in AI technology."""
)
print(f"News Analysis Result:\n{news_result}")
# Cleanup all browser instances
print("\n" + "=" * 70)
print("Cleaning up browser instances...")
# Clean up agents
for agent in price_workflow.agents:
if isinstance(agent, StagehandAgent):
agent.cleanup()
elif hasattr(agent, "agents"): # For nested workflows
for sub_agent in agent.agents:
if isinstance(sub_agent, StagehandAgent):
sub_agent.cleanup()
print("All workflows completed!")
print("=" * 70)

@ -0,0 +1,249 @@
# Stagehand Browser Automation Integration for Swarms
This directory contains examples demonstrating how to integrate [Stagehand](https://github.com/browserbase/stagehand), an AI-powered browser automation framework, with the Swarms multi-agent framework.
## Overview
Stagehand provides natural language browser automation capabilities that can be seamlessly integrated into Swarms agents. This integration enables:
- 🌐 **Natural Language Web Automation**: Use simple commands like "click the submit button" or "extract product prices"
- 🤖 **Multi-Agent Browser Workflows**: Multiple agents can automate different websites simultaneously
- 🔧 **Flexible Integration Options**: Use as a wrapped agent, individual tools, or via MCP server
- 📊 **Complex Automation Scenarios**: E-commerce monitoring, competitive analysis, automated testing, and more
## Examples
### 1. Stagehand Wrapper Agent (`1_stagehand_wrapper_agent.py`)
The simplest integration - wraps Stagehand as a Swarms-compatible agent.
```python
from examples.stagehand.stagehand_wrapper_agent import StagehandAgent
# Create a browser automation agent
browser_agent = StagehandAgent(
agent_name="WebScraperAgent",
model_name="gpt-4o-mini",
env="LOCAL", # or "BROWSERBASE" for cloud execution
)
# Use natural language to control the browser
result = browser_agent.run(
"Navigate to news.ycombinator.com and extract the top 5 story titles"
)
```
**Features:**
- Inherits from Swarms `Agent` base class
- Automatic browser lifecycle management
- Natural language task interpretation
- Support for both local (Playwright) and cloud (Browserbase) execution
### 2. Stagehand as Tools (`2_stagehand_tools_agent.py`)
Provides fine-grained control by exposing Stagehand methods as individual tools.
```python
from swarms import Agent
from examples.stagehand.stagehand_tools_agent import (
NavigateTool, ActTool, ExtractTool, ObserveTool, ScreenshotTool
)
# Create agent with browser tools
browser_agent = Agent(
agent_name="BrowserAutomationAgent",
model_name="gpt-4o-mini",
tools=[
NavigateTool(),
ActTool(),
ExtractTool(),
ObserveTool(),
ScreenshotTool(),
],
)
# Agent can now use tools strategically
result = browser_agent.run(
"Go to google.com, search for 'Python tutorials', and extract the first 3 results"
)
```
**Available Tools:**
- `NavigateTool`: Navigate to URLs
- `ActTool`: Perform actions (click, type, scroll)
- `ExtractTool`: Extract data from pages
- `ObserveTool`: Find elements on pages
- `ScreenshotTool`: Capture screenshots
- `CloseBrowserTool`: Clean up browser resources
### 3. Stagehand MCP Server (`3_stagehand_mcp_agent.py`)
Integrates with Stagehand's Model Context Protocol (MCP) server for standardized tool access.
```python
from examples.stagehand.stagehand_mcp_agent import StagehandMCPAgent
# Connect to Stagehand MCP server
mcp_agent = StagehandMCPAgent(
agent_name="WebResearchAgent",
mcp_server_url="http://localhost:3000/sse",
)
# Use MCP tools including multi-session management
result = mcp_agent.run("""
Create 3 browser sessions and:
1. Session 1: Check Python.org for latest version
2. Session 2: Check PyPI for trending packages
3. Session 3: Check GitHub Python trending repos
Compile a Python ecosystem status report.
""")
```
**MCP Features:**
- Automatic tool discovery
- Multi-session browser management
- Built-in screenshot resources
- Prompt templates for common tasks
### 4. Multi-Agent Workflows (`4_stagehand_multi_agent_workflow.py`)
Demonstrates complex multi-agent browser automation scenarios.
```python
from examples.stagehand.stagehand_multi_agent_workflow import (
create_price_comparison_workflow,
create_competitive_analysis_workflow,
create_automated_testing_workflow,
create_news_aggregation_workflow
)
# Price comparison across multiple e-commerce sites
price_workflow = create_price_comparison_workflow()
result = price_workflow.run(
"Compare prices for iPhone 15 Pro on Amazon and eBay"
)
# Competitive analysis of multiple companies
competitive_workflow = create_competitive_analysis_workflow()
result = competitive_workflow.run(
"Analyze OpenAI, Anthropic, and DeepMind websites and social media"
)
```
**Workflow Examples:**
- **E-commerce Monitoring**: Track prices across multiple sites
- **Competitive Analysis**: Research competitors' websites and social media
- **Automated Testing**: UI, form validation, and accessibility testing
- **News Aggregation**: Collect and analyze news from multiple sources
## Setup
### Prerequisites
1. **Install Swarms and Stagehand:**
```bash
pip install swarms stagehand
```
2. **Set up environment variables:**
```bash
# For local browser automation (using Playwright)
export OPENAI_API_KEY="your-openai-key"
# For cloud browser automation (using Browserbase)
export BROWSERBASE_API_KEY="your-browserbase-key"
export BROWSERBASE_PROJECT_ID="your-project-id"
```
3. **For MCP Server examples:**
```bash
# Install and run the Stagehand MCP server
cd stagehand-mcp-server
npm install
npm run build
npm start
```
## Use Cases
### E-commerce Automation
- Price monitoring and comparison
- Inventory tracking
- Automated purchasing workflows
- Review aggregation
### Research and Analysis
- Competitive intelligence gathering
- Market research automation
- Social media monitoring
- News and trend analysis
### Quality Assurance
- Automated UI testing
- Cross-browser compatibility testing
- Form validation testing
- Accessibility compliance checking
### Data Collection
- Web scraping at scale
- Real-time data monitoring
- Structured data extraction
- Screenshot documentation
## Best Practices
1. **Resource Management**: Always clean up browser instances when done
```python
browser_agent.cleanup() # For wrapper agents
```
2. **Error Handling**: Stagehand includes self-healing capabilities, but wrap critical operations in try-except blocks
3. **Parallel Execution**: Use `ConcurrentWorkflow` for simultaneous browser automation across multiple sites
4. **Session Management**: For complex multi-page workflows, use the MCP server's session management capabilities
5. **Rate Limiting**: Be respectful of websites - add delays between requests when necessary
## Testing
Run the test suite to verify the integration:
```bash
pytest tests/stagehand/test_stagehand_integration.py -v
```
## Troubleshooting
### Common Issues
1. **Browser not starting**: Ensure Playwright is properly installed
```bash
playwright install
```
2. **MCP connection failed**: Verify the MCP server is running on the correct port
3. **Timeout errors**: Increase timeout in StagehandConfig or agent initialization
### Debug Mode
Enable verbose logging:
```python
agent = StagehandAgent(
agent_name="DebugAgent",
verbose=True, # Enable detailed logging
)
```
## Contributing
We welcome contributions! Please:
1. Follow the existing code style
2. Add tests for new features
3. Update documentation
4. Submit PRs with clear descriptions
## License
These examples are provided under the same license as the Swarms framework. Stagehand is licensed separately - see [Stagehand's repository](https://github.com/browserbase/stagehand) for details.

@ -0,0 +1,13 @@
# Requirements for Stagehand integration examples
swarms>=8.0.0
stagehand>=0.1.0
python-dotenv>=1.0.0
pydantic>=2.0.0
loguru>=0.7.0
# For MCP server examples (optional)
httpx>=0.24.0
# For testing
pytest>=7.0.0
pytest-asyncio>=0.21.0

@ -0,0 +1,436 @@
"""
Tests for Stagehand Integration with Swarms
==========================================
This module contains tests for the Stagehand browser automation
integration with the Swarms framework.
"""
import json
import pytest
from unittest.mock import AsyncMock, patch
# Mock Stagehand classes
class MockObserveResult:
def __init__(self, description, selector, method="click"):
self.description = description
self.selector = selector
self.method = method
class MockStagehandPage:
async def goto(self, url):
return None
async def act(self, action):
return f"Performed action: {action}"
async def extract(self, query):
return {"extracted": query, "data": ["item1", "item2"]}
async def observe(self, query):
return [
MockObserveResult("Search box", "#search-input"),
MockObserveResult("Submit button", "#submit-btn"),
]
class MockStagehand:
def __init__(self, config):
self.config = config
self.page = MockStagehandPage()
async def init(self):
pass
async def close(self):
pass
# Test StagehandAgent wrapper
class TestStagehandAgent:
"""Test the StagehandAgent wrapper class."""
@patch(
"examples.stagehand.stagehand_wrapper_agent.Stagehand",
MockStagehand,
)
def test_agent_initialization(self):
"""Test that StagehandAgent initializes correctly."""
from examples.stagehand.stagehand_wrapper_agent import (
StagehandAgent,
)
agent = StagehandAgent(
agent_name="TestAgent",
model_name="gpt-4o-mini",
env="LOCAL",
)
assert agent.agent_name == "TestAgent"
assert agent.stagehand_config.env == "LOCAL"
assert agent.stagehand_config.model_name == "gpt-4o-mini"
assert not agent._initialized
@patch(
"examples.stagehand.stagehand_wrapper_agent.Stagehand",
MockStagehand,
)
def test_navigation_task(self):
"""Test navigation and extraction task."""
from examples.stagehand.stagehand_wrapper_agent import (
StagehandAgent,
)
agent = StagehandAgent(
agent_name="TestAgent",
model_name="gpt-4o-mini",
env="LOCAL",
)
result = agent.run(
"Navigate to example.com and extract the main content"
)
# Parse result
result_data = json.loads(result)
assert result_data["status"] == "completed"
assert "navigated_to" in result_data["data"]
assert (
result_data["data"]["navigated_to"]
== "https://example.com"
)
assert "extracted" in result_data["data"]
@patch(
"examples.stagehand.stagehand_wrapper_agent.Stagehand",
MockStagehand,
)
def test_search_task(self):
"""Test search functionality."""
from examples.stagehand.stagehand_wrapper_agent import (
StagehandAgent,
)
agent = StagehandAgent(
agent_name="TestAgent",
model_name="gpt-4o-mini",
env="LOCAL",
)
result = agent.run(
"Go to google.com and search for 'test query'"
)
result_data = json.loads(result)
assert result_data["status"] == "completed"
assert result_data["data"]["search_query"] == "test query"
assert result_data["action"] == "search"
@patch(
"examples.stagehand.stagehand_wrapper_agent.Stagehand",
MockStagehand,
)
def test_cleanup(self):
"""Test that cleanup properly closes browser."""
from examples.stagehand.stagehand_wrapper_agent import (
StagehandAgent,
)
agent = StagehandAgent(
agent_name="TestAgent",
model_name="gpt-4o-mini",
env="LOCAL",
)
# Initialize the agent
agent.run("Navigate to example.com")
assert agent._initialized
# Cleanup
agent.cleanup()
# After cleanup, should be able to run again
result = agent.run("Navigate to example.com")
assert result is not None
# Test Stagehand Tools
class TestStagehandTools:
"""Test individual Stagehand tools."""
@patch("examples.stagehand.stagehand_tools_agent.browser_state")
async def test_navigate_tool(self, mock_browser_state):
"""Test NavigateTool functionality."""
from examples.stagehand.stagehand_tools_agent import (
NavigateTool,
)
# Setup mock
mock_page = AsyncMock()
mock_browser_state.get_page = AsyncMock(
return_value=mock_page
)
mock_browser_state.init_browser = AsyncMock()
tool = NavigateTool()
result = await tool._async_run("https://example.com")
assert (
"Successfully navigated to https://example.com" in result
)
mock_page.goto.assert_called_once_with("https://example.com")
@patch("examples.stagehand.stagehand_tools_agent.browser_state")
async def test_act_tool(self, mock_browser_state):
"""Test ActTool functionality."""
from examples.stagehand.stagehand_tools_agent import ActTool
# Setup mock
mock_page = AsyncMock()
mock_page.act = AsyncMock(return_value="Action completed")
mock_browser_state.get_page = AsyncMock(
return_value=mock_page
)
mock_browser_state.init_browser = AsyncMock()
tool = ActTool()
result = await tool._async_run("click the button")
assert "Action performed" in result
assert "click the button" in result
mock_page.act.assert_called_once_with("click the button")
@patch("examples.stagehand.stagehand_tools_agent.browser_state")
async def test_extract_tool(self, mock_browser_state):
"""Test ExtractTool functionality."""
from examples.stagehand.stagehand_tools_agent import (
ExtractTool,
)
# Setup mock
mock_page = AsyncMock()
mock_page.extract = AsyncMock(
return_value={
"title": "Test Page",
"content": "Test content",
}
)
mock_browser_state.get_page = AsyncMock(
return_value=mock_page
)
mock_browser_state.init_browser = AsyncMock()
tool = ExtractTool()
result = await tool._async_run("extract the page title")
# Result should be JSON string
parsed_result = json.loads(result)
assert parsed_result["title"] == "Test Page"
assert parsed_result["content"] == "Test content"
@patch("examples.stagehand.stagehand_tools_agent.browser_state")
async def test_observe_tool(self, mock_browser_state):
"""Test ObserveTool functionality."""
from examples.stagehand.stagehand_tools_agent import (
ObserveTool,
)
# Setup mock
mock_page = AsyncMock()
mock_observations = [
MockObserveResult("Search input", "#search"),
MockObserveResult("Submit button", "#submit"),
]
mock_page.observe = AsyncMock(return_value=mock_observations)
mock_browser_state.get_page = AsyncMock(
return_value=mock_page
)
mock_browser_state.init_browser = AsyncMock()
tool = ObserveTool()
result = await tool._async_run("find the search box")
# Result should be JSON string
parsed_result = json.loads(result)
assert len(parsed_result) == 2
assert parsed_result[0]["description"] == "Search input"
assert parsed_result[0]["selector"] == "#search"
# Test MCP integration
class TestStagehandMCP:
"""Test Stagehand MCP server integration."""
def test_mcp_agent_initialization(self):
"""Test that MCP agent initializes with correct parameters."""
from examples.stagehand.stagehand_mcp_agent import (
StagehandMCPAgent,
)
mcp_agent = StagehandMCPAgent(
agent_name="TestMCPAgent",
mcp_server_url="http://localhost:3000/sse",
model_name="gpt-4o-mini",
)
assert mcp_agent.agent.agent_name == "TestMCPAgent"
assert mcp_agent.agent.mcp_url == "http://localhost:3000/sse"
assert mcp_agent.agent.model_name == "gpt-4o-mini"
def test_multi_session_swarm_creation(self):
"""Test multi-session browser swarm creation."""
from examples.stagehand.stagehand_mcp_agent import (
MultiSessionBrowserSwarm,
)
swarm = MultiSessionBrowserSwarm(
mcp_server_url="http://localhost:3000/sse",
num_agents=3,
)
assert len(swarm.agents) == 3
assert swarm.agents[0].agent_name == "DataExtractor_0"
assert swarm.agents[1].agent_name == "FormFiller_1"
assert swarm.agents[2].agent_name == "WebMonitor_2"
@patch("swarms.Agent.run")
def test_task_distribution(self, mock_run):
"""Test task distribution among swarm agents."""
from examples.stagehand.stagehand_mcp_agent import (
MultiSessionBrowserSwarm,
)
mock_run.return_value = "Task completed"
swarm = MultiSessionBrowserSwarm(num_agents=2)
tasks = ["Task 1", "Task 2", "Task 3"]
results = swarm.distribute_tasks(tasks)
assert len(results) == 3
assert all(result == "Task completed" for result in results)
assert mock_run.call_count == 3
# Test multi-agent workflows
class TestMultiAgentWorkflows:
"""Test multi-agent workflow configurations."""
@patch(
"examples.stagehand.stagehand_wrapper_agent.Stagehand",
MockStagehand,
)
def test_price_comparison_workflow_creation(self):
"""Test creation of price comparison workflow."""
from examples.stagehand.stagehand_multi_agent_workflow import (
create_price_comparison_workflow,
)
workflow = create_price_comparison_workflow()
# Should be a SequentialWorkflow with 2 agents
assert len(workflow.agents) == 2
# First agent should be a ConcurrentWorkflow
assert hasattr(workflow.agents[0], "agents")
# Second agent should be the analysis agent
assert workflow.agents[1].agent_name == "PriceAnalysisAgent"
@patch(
"examples.stagehand.stagehand_wrapper_agent.Stagehand",
MockStagehand,
)
def test_competitive_analysis_workflow_creation(self):
"""Test creation of competitive analysis workflow."""
from examples.stagehand.stagehand_multi_agent_workflow import (
create_competitive_analysis_workflow,
)
workflow = create_competitive_analysis_workflow()
# Should have 3 agents in the rearrange pattern
assert len(workflow.agents) == 3
assert (
workflow.flow
== "company_researcher -> social_media_agent -> report_compiler"
)
@patch(
"examples.stagehand.stagehand_wrapper_agent.Stagehand",
MockStagehand,
)
def test_automated_testing_workflow_creation(self):
"""Test creation of automated testing workflow."""
from examples.stagehand.stagehand_multi_agent_workflow import (
create_automated_testing_workflow,
)
workflow = create_automated_testing_workflow()
# Should be a SequentialWorkflow
assert len(workflow.agents) == 2
# First should be concurrent testing
assert hasattr(workflow.agents[0], "agents")
assert (
len(workflow.agents[0].agents) == 3
) # UI, Form, Accessibility testers
@patch(
"examples.stagehand.stagehand_wrapper_agent.Stagehand",
MockStagehand,
)
def test_news_aggregation_workflow_creation(self):
"""Test creation of news aggregation workflow."""
from examples.stagehand.stagehand_multi_agent_workflow import (
create_news_aggregation_workflow,
)
workflow = create_news_aggregation_workflow()
# Should be a SequentialWorkflow with 3 stages
assert len(workflow.agents) == 3
# First stage should be concurrent scrapers
assert hasattr(workflow.agents[0], "agents")
assert len(workflow.agents[0].agents) == 3 # 3 news sources
# Integration tests
class TestIntegration:
"""End-to-end integration tests."""
@pytest.mark.asyncio
@patch(
"examples.stagehand.stagehand_wrapper_agent.Stagehand",
MockStagehand,
)
async def test_full_browser_automation_flow(self):
"""Test a complete browser automation flow."""
from examples.stagehand.stagehand_wrapper_agent import (
StagehandAgent,
)
agent = StagehandAgent(
agent_name="IntegrationTestAgent",
model_name="gpt-4o-mini",
env="LOCAL",
)
# Test navigation
nav_result = agent.run("Navigate to example.com")
assert "navigated_to" in nav_result
# Test extraction
extract_result = agent.run("Extract all text from the page")
assert "extracted" in extract_result
# Test observation
observe_result = agent.run("Find all buttons on the page")
assert "observation" in observe_result
# Cleanup
agent.cleanup()
if __name__ == "__main__":
pytest.main([__file__, "-v"])

@ -0,0 +1,302 @@
"""
Simple tests for Stagehand Integration with Swarms
=================================================
These tests verify the basic structure and functionality of the
Stagehand integration without requiring external dependencies.
"""
import json
import pytest
from unittest.mock import MagicMock
class TestStagehandIntegrationStructure:
"""Test that integration files have correct structure."""
def test_examples_directory_exists(self):
"""Test that examples directory structure is correct."""
import os
base_path = "examples/stagehand"
assert os.path.exists(base_path)
expected_files = [
"1_stagehand_wrapper_agent.py",
"2_stagehand_tools_agent.py",
"3_stagehand_mcp_agent.py",
"4_stagehand_multi_agent_workflow.py",
"README.md",
"requirements.txt",
]
for file in expected_files:
file_path = os.path.join(base_path, file)
assert os.path.exists(file_path), f"Missing file: {file}"
def test_wrapper_agent_imports(self):
"""Test that wrapper agent has correct imports."""
with open(
"examples/stagehand/1_stagehand_wrapper_agent.py", "r"
) as f:
content = f.read()
# Check for required imports
assert "from swarms import Agent" in content
assert "import asyncio" in content
assert "import json" in content
assert "class StagehandAgent" in content
def test_tools_agent_imports(self):
"""Test that tools agent has correct imports."""
with open(
"examples/stagehand/2_stagehand_tools_agent.py", "r"
) as f:
content = f.read()
# Check for required imports
assert "from swarms import Agent" in content
assert "def navigate_browser" in content
assert "def browser_act" in content
assert "def browser_extract" in content
def test_mcp_agent_imports(self):
"""Test that MCP agent has correct imports."""
with open(
"examples/stagehand/3_stagehand_mcp_agent.py", "r"
) as f:
content = f.read()
# Check for required imports
assert "from swarms import Agent" in content
assert "class StagehandMCPAgent" in content
assert "mcp_url" in content
def test_workflow_agent_imports(self):
"""Test that workflow agent has correct imports."""
with open(
"examples/stagehand/4_stagehand_multi_agent_workflow.py",
"r",
) as f:
content = f.read()
# Check for required imports
assert (
"from swarms import Agent, SequentialWorkflow, ConcurrentWorkflow"
in content
)
assert (
"from swarms.structs.agent_rearrange import AgentRearrange"
in content
)
class TestStagehandMockIntegration:
"""Test Stagehand integration with mocked dependencies."""
def test_mock_stagehand_initialization(self):
"""Test that Stagehand can be mocked and initialized."""
# Setup mock without importing actual stagehand
mock_stagehand = MagicMock()
mock_instance = MagicMock()
mock_instance.init = MagicMock()
mock_stagehand.return_value = mock_instance
# Mock config creation
config = MagicMock()
stagehand_instance = mock_stagehand(config)
# Verify mock works
assert stagehand_instance is not None
assert hasattr(stagehand_instance, "init")
def test_json_serialization(self):
"""Test JSON serialization for agent responses."""
# Test data that would come from browser automation
test_data = {
"task": "Navigate to example.com",
"status": "completed",
"data": {
"navigated_to": "https://example.com",
"extracted": ["item1", "item2"],
"action": "navigate",
},
}
# Test serialization
json_result = json.dumps(test_data, indent=2)
assert isinstance(json_result, str)
# Test deserialization
parsed_data = json.loads(json_result)
assert parsed_data["task"] == "Navigate to example.com"
assert parsed_data["status"] == "completed"
assert len(parsed_data["data"]["extracted"]) == 2
def test_url_extraction_logic(self):
"""Test URL extraction logic from task strings."""
import re
# Test cases
test_cases = [
(
"Navigate to https://example.com",
["https://example.com"],
),
("Go to google.com and search", ["google.com"]),
(
"Visit https://github.com/repo",
["https://github.com/repo"],
),
("Open example.org", ["example.org"]),
]
url_pattern = r"https?://[^\s]+"
domain_pattern = r"(\w+\.\w+)"
for task, expected in test_cases:
# Extract full URLs
urls = re.findall(url_pattern, task)
# If no full URLs, extract domains
if not urls:
domains = re.findall(domain_pattern, task)
if domains:
urls = domains
assert (
len(urls) > 0
), f"Failed to extract URL from: {task}"
assert (
urls[0] in expected
), f"Expected {expected}, got {urls}"
class TestSwarmsPatternsCompliance:
"""Test compliance with Swarms framework patterns."""
def test_agent_inheritance_pattern(self):
"""Test that wrapper agent follows Swarms Agent inheritance pattern."""
# Read the wrapper agent file
with open(
"examples/stagehand/1_stagehand_wrapper_agent.py", "r"
) as f:
content = f.read()
# Check inheritance pattern
assert "class StagehandAgent(SwarmsAgent):" in content
assert "def run(self, task: str" in content
assert "return" in content
def test_tools_pattern(self):
"""Test that tools follow Swarms function-based pattern."""
# Read the tools agent file
with open(
"examples/stagehand/2_stagehand_tools_agent.py", "r"
) as f:
content = f.read()
# Check function-based tool pattern
assert "def navigate_browser(url: str) -> str:" in content
assert "def browser_act(action: str) -> str:" in content
assert "def browser_extract(query: str) -> str:" in content
assert "def browser_observe(query: str) -> str:" in content
def test_mcp_integration_pattern(self):
"""Test MCP integration follows Swarms pattern."""
# Read the MCP agent file
with open(
"examples/stagehand/3_stagehand_mcp_agent.py", "r"
) as f:
content = f.read()
# Check MCP pattern
assert "mcp_url=" in content
assert "Agent(" in content
def test_workflow_patterns(self):
"""Test workflow patterns are properly used."""
# Read the workflow file
with open(
"examples/stagehand/4_stagehand_multi_agent_workflow.py",
"r",
) as f:
content = f.read()
# Check workflow patterns
assert "SequentialWorkflow" in content
assert "ConcurrentWorkflow" in content
assert "AgentRearrange" in content
class TestDocumentationAndExamples:
"""Test documentation and example completeness."""
def test_readme_completeness(self):
"""Test that README contains essential information."""
with open("examples/stagehand/README.md", "r") as f:
content = f.read()
required_sections = [
"# Stagehand Browser Automation Integration",
"## Overview",
"## Examples",
"## Setup",
"## Use Cases",
"## Best Practices",
]
for section in required_sections:
assert section in content, f"Missing section: {section}"
def test_requirements_file(self):
"""Test that requirements file has necessary dependencies."""
with open("examples/stagehand/requirements.txt", "r") as f:
content = f.read()
required_deps = [
"swarms",
"stagehand",
"python-dotenv",
"pydantic",
"loguru",
]
for dep in required_deps:
assert dep in content, f"Missing dependency: {dep}"
def test_example_files_have_docstrings(self):
"""Test that example files have proper docstrings."""
example_files = [
"examples/stagehand/1_stagehand_wrapper_agent.py",
"examples/stagehand/2_stagehand_tools_agent.py",
"examples/stagehand/3_stagehand_mcp_agent.py",
"examples/stagehand/4_stagehand_multi_agent_workflow.py",
]
for file_path in example_files:
with open(file_path, "r") as f:
content = f.read()
# Check for module docstring
assert (
'"""' in content[:500]
), f"Missing docstring in {file_path}"
# Check for main execution block
assert (
'if __name__ == "__main__":' in content
), f"Missing main block in {file_path}"
if __name__ == "__main__":
pytest.main([__file__, "-v"])

@ -0,0 +1,24 @@
from swarms import HierarchicalSwarm, Agent
# Create agents
research_agent = Agent(
agent_name="Research-Analyst", model_name="gpt-4.1", print_on=True
)
analysis_agent = Agent(
agent_name="Data-Analyst", model_name="gpt-4.1", print_on=True
)
# Create swarm with interactive dashboard
swarm = HierarchicalSwarm(
agents=[research_agent, analysis_agent],
max_loops=1,
interactive=True, # Enable the Arasaka dashboard
# director_reasoning_enabled=False,
# director_reasoning_model_name="groq/moonshotai/kimi-k2-instruct",
multi_agent_prompt_improvements=True,
)
# Run swarm (task will be prompted interactively)
result = swarm.run("what are the best nanomachine research papers?")
print(result)

@ -7,3 +7,8 @@ The reasoning process and the final answer should be distinctly enclosed within
It is essential to output multiple <think> </think> tags to reflect the depth of thought and exploration involved in addressing the task. The Assistant should strive to think deeply and thoroughly about the question, ensuring that all relevant aspects are considered before arriving at a conclusion. It is essential to output multiple <think> </think> tags to reflect the depth of thought and exploration involved in addressing the task. The Assistant should strive to think deeply and thoroughly about the question, ensuring that all relevant aspects are considered before arriving at a conclusion.
""" """
INTERNAL_MONOLGUE_PROMPT = """
You are an introspective reasoning engine whose sole task is to explore and unpack any problem or task without ever delivering a final solution. Whenever you process a prompt, you must envelope every discrete insight, question, or inference inside <think> and </think> tags, using as many of these tagsnested or sequentialas needed to reveal your full chain of thought. Begin each session by rephrasing the problem in your own words to ensure youve captured its goals, inputs, outputs, and constraintsentirely within <think> blocksand identify any ambiguities or assumptions you must clarify. Then decompose the task into sub-questions or logical components, examining multiple approaches, edge cases, and trade-offs, all inside further <think> tags. Continue layering your reasoning, pausing at each step to ask yourself What else might I consider? or Is there an implicit assumption here?always inside <think></think>. Never move beyond analysis: do not generate outlines, pseudocode, or answersonly think. If you find yourself tempted to propose a solution, immediately halt and circle back into deeper <think> tags. Your objective is total transparency of reasoning and exhaustive exploration of the problem space; defer any answer generation until explicitly instructed otherwise.
"""

@ -4,6 +4,9 @@ from swarms.structs.auto_swarm_builder import AutoSwarmBuilder
from swarms.structs.base_structure import BaseStructure from swarms.structs.base_structure import BaseStructure
from swarms.structs.base_swarm import BaseSwarm from swarms.structs.base_swarm import BaseSwarm
from swarms.structs.batch_agent_execution import batch_agent_execution from swarms.structs.batch_agent_execution import batch_agent_execution
from swarms.structs.board_of_directors_swarm import (
BoardOfDirectorsSwarm,
)
from swarms.structs.concurrent_workflow import ConcurrentWorkflow from swarms.structs.concurrent_workflow import ConcurrentWorkflow
from swarms.structs.conversation import Conversation from swarms.structs.conversation import Conversation
from swarms.structs.council_judge import CouncilAsAJudge from swarms.structs.council_judge import CouncilAsAJudge
@ -93,10 +96,12 @@ from swarms.structs.swarming_architectures import (
star_swarm, star_swarm,
) )
__all__ = [ __all__ = [
"Agent", "Agent",
"BaseStructure", "BaseStructure",
"BaseSwarm", "BaseSwarm",
"BoardOfDirectorsSwarm",
"ConcurrentWorkflow", "ConcurrentWorkflow",
"Conversation", "Conversation",
"GroupChat", "GroupChat",

@ -102,7 +102,7 @@ def parse_done_token(response: str) -> bool:
# Agent ID generator # Agent ID generator
def agent_id(): def agent_id():
"""Generate an agent id""" """Generate an agent id"""
return uuid.uuid4().hex return f"agent-{uuid.uuid4().hex}"
# Agent output types # Agent output types
@ -673,7 +673,7 @@ class Agent:
# Initialize the short term memory # Initialize the short term memory
memory = Conversation( memory = Conversation(
system_prompt=prompt, name=f"{self.agent_name}_conversation",
user=self.user_name, user=self.user_name,
rules=self.rules, rules=self.rules,
token_count=( token_count=(
@ -693,6 +693,12 @@ class Agent:
), ),
) )
# Add the system prompt to the conversation
memory.add(
role="System",
content=prompt,
)
return memory return memory
def agent_output_model(self): def agent_output_model(self):
@ -861,7 +867,9 @@ class Agent:
return tools return tools
except AgentMCPConnectionError as e: except AgentMCPConnectionError as e:
logger.error(f"Error in MCP connection: {e}") logger.error(
f"Error in MCP connection: {e} Traceback: {traceback.format_exc()}"
)
raise e raise e
def setup_config(self): def setup_config(self):
@ -1172,7 +1180,8 @@ class Agent:
if self.print_on is True: if self.print_on is True:
if isinstance(response, list): if isinstance(response, list):
self.pretty_print( self.pretty_print(
f"Structured Output - Attempting Function Call Execution [{time.strftime('%H:%M:%S')}] \n\n Output: {format_data_structure(response)} ", # f"Structured Output - Attempting Function Call Execution [{time.strftime('%H:%M:%S')}] \n\n Output: {format_data_structure(response)} ",
f"[Structured Output] [Time: {time.strftime('%H:%M:%S')}] \n\n {json.dumps(response, indent=4)}",
loop_count, loop_count,
) )
elif self.streaming_on: elif self.streaming_on:
@ -2457,6 +2466,10 @@ class Agent:
Returns: Returns:
Dict[str, Any]: A dictionary representation of the class attributes. Dict[str, Any]: A dictionary representation of the class attributes.
""" """
# Remove the llm object from the dictionary
self.__dict__.pop("llm", None)
return { return {
attr_name: self._serialize_attr(attr_name, attr_value) attr_name: self._serialize_attr(attr_name, attr_value)
for attr_name, attr_value in self.__dict__.items() for attr_name, attr_value in self.__dict__.items()

@ -1,99 +1,131 @@
import os import os
from typing import List import traceback
from typing import List, Optional
from dotenv import load_dotenv
from loguru import logger from loguru import logger
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from swarms.prompts.reasoning_prompt import INTERNAL_MONOLGUE_PROMPT
from swarms.structs.agent import Agent from swarms.structs.agent import Agent
from swarms.utils.function_caller_model import OpenAIFunctionCaller from swarms.structs.conversation import Conversation
from swarms.structs.ma_utils import set_random_models_for_agents from swarms.structs.ma_utils import set_random_models_for_agents
from swarms.structs.swarm_router import SwarmRouter, SwarmRouterConfig from swarms.structs.swarm_router import SwarmRouter, SwarmType
from dotenv import load_dotenv from swarms.utils.function_caller_model import OpenAIFunctionCaller
load_dotenv() load_dotenv()
BOSS_SYSTEM_PROMPT = """ BOSS_SYSTEM_PROMPT = """
You are an expert swarm manager and agent architect. Your role is to create and coordinate a team of specialized AI agents, each with distinct personalities, roles, and capabilities. Your primary goal is to ensure the swarm operates efficiently while maintaining clear communication and well-defined responsibilities. You are an expert multi-agent architecture designer and team coordinator. Your role is to create and orchestrate sophisticated teams of specialized AI agents, each with distinct personalities, roles, and capabilities. Your primary goal is to ensure the multi-agent system operates efficiently while maintaining clear communication, well-defined responsibilities, and optimal task distribution.
### Core Principles: ### Core Design Principles:
1. **Deep Task Understanding**: 1. **Comprehensive Task Analysis**:
- First, thoroughly analyze the task requirements, breaking them down into core components and sub-tasks - Thoroughly deconstruct the task into its fundamental components and sub-tasks
- Identify the necessary skills, knowledge domains, and personality traits needed for each component - Identify the specific skills, knowledge domains, and personality traits required for each component
- Consider potential challenges, dependencies, and required coordination between agents - Analyze potential challenges, dependencies, and coordination requirements between agents
- Map out the ideal workflow and information flow between agents - Map out optimal workflows, information flow patterns, and decision-making hierarchies
- Consider scalability, maintainability, and adaptability requirements
2. **Agent Design Philosophy**:
- Each agent must have a clear, specific purpose and domain of expertise 2. **Agent Design Excellence**:
- Agents should have distinct personalities that complement their roles - Each agent must have a crystal-clear, specific purpose and domain of expertise
- Design agents to be self-aware of their limitations and when to seek help - Design agents with distinct, complementary personalities that enhance team dynamics
- Ensure agents can effectively communicate their progress and challenges - Ensure agents are self-aware of their limitations and know when to seek assistance
- Create agents that can effectively communicate progress, challenges, and insights
3. **Agent Creation Framework**: - Design for resilience, adaptability, and continuous learning capabilities
For each new agent, define:
- **Role & Purpose**: Clear, specific description of what the agent does and why 3. **Comprehensive Agent Framework**:
- **Personality Traits**: Distinct characteristics that influence how the agent thinks and communicates For each agent, meticulously define:
- **Expertise Level**: Specific knowledge domains and skill sets - **Role & Purpose**: Precise description of responsibilities, authority, and contribution to team objectives
- **Communication Style**: How the agent presents information and interacts - **Personality Profile**: Distinct characteristics that influence thinking patterns, communication style, and decision-making approach
- **Decision-Making Process**: How the agent approaches problems and makes choices - **Expertise Matrix**: Specific knowledge domains, skill sets, tools, and capabilities
- **Limitations & Boundaries**: What the agent cannot or should not do - **Communication Protocol**: How the agent presents information, interacts with others, and reports progress
- **Collaboration Protocol**: How the agent works with others - **Decision-Making Framework**: Systematic approach to problem-solving, risk assessment, and choice evaluation
- **Limitations & Boundaries**: Clear constraints, ethical guidelines, and operational boundaries
4. **System Prompt Design**: - **Collaboration Strategy**: How the agent works with others, shares knowledge, and contributes to team success
Create detailed system prompts that include:
- Role and purpose explanation 4. **Advanced System Prompt Engineering**:
- Personality description and behavioral guidelines Create comprehensive system prompts that include:
- Specific capabilities and tools available - Detailed role and purpose explanation with context and scope
- Communication protocols and reporting requirements - Rich personality description with behavioral guidelines and interaction patterns
- Problem-solving approach and decision-making framework - Comprehensive capabilities, tools, and resource specifications
- Collaboration guidelines and team interaction rules - Detailed communication protocols, reporting requirements, and feedback mechanisms
- Quality standards and success criteria - Systematic problem-solving approach with decision-making frameworks
- Collaboration guidelines, team interaction rules, and conflict resolution procedures
5. **Swarm Coordination**: - Quality standards, success criteria, and performance metrics
- Design clear communication channels between agents - Error handling, recovery procedures, and escalation protocols
- Establish protocols for task handoffs and information sharing
- Create feedback loops for continuous improvement 5. **Multi-Agent Coordination Architecture**:
- Implement error handling and recovery procedures - Design robust communication channels and protocols between agents
- Define escalation paths for complex issues - Establish clear task handoff procedures and information sharing mechanisms
- Create feedback loops for continuous improvement and adaptation
6. **Quality Assurance**: - Implement comprehensive error handling and recovery procedures
- Set clear success criteria for each agent and the overall swarm - Define escalation paths for complex issues and decision-making hierarchies
- Implement verification steps for task completion - Design monitoring, logging, and performance tracking systems
- Create mechanisms for self-assessment and improvement
- Establish protocols for handling edge cases and unexpected situations 6. **Quality Assurance & Governance**:
- Set measurable success criteria for each agent and the overall system
### Output Format: - Implement verification steps, validation procedures, and quality checks
- Create mechanisms for self-assessment, peer review, and continuous improvement
When creating a new agent or swarm, provide: - Establish protocols for handling edge cases, unexpected situations, and failures
- Design governance structures for oversight, accountability, and performance management
1. **Agent Design**:
- Role and purpose statement ### Multi-Agent Architecture Types:
- Personality profile
- Capabilities and limitations Choose the most appropriate architecture based on task requirements:
- Communication style
- Collaboration protocols - **AgentRearrange**: Dynamic task reallocation based on agent performance and workload
- **MixtureOfAgents**: Parallel processing with specialized agents working independently
2. **System Prompt**: - **SpreadSheetSwarm**: Structured data processing with coordinated workflows
- Complete, detailed prompt that embodies the agent's identity - **SequentialWorkflow**: Linear task progression with handoffs between agents
- Clear instructions for behavior and decision-making - **ConcurrentWorkflow**: Parallel execution with coordination and synchronization
- Specific guidelines for interaction and reporting - **GroupChat**: Collaborative discussion and consensus-building approach
- **MultiAgentRouter**: Intelligent routing and load balancing across agents
3. **Swarm Architecture**: - **AutoSwarmBuilder**: Self-organizing and self-optimizing agent teams
- Team structure and hierarchy - **HiearchicalSwarm**: Layered decision-making with management and execution tiers
- Communication flow - **MajorityVoting**: Democratic decision-making with voting mechanisms
- Task distribution plan - **MALT**: Multi-agent learning and training with knowledge sharing
- Quality control measures - **DeepResearchSwarm**: Comprehensive research with multiple specialized investigators
- **CouncilAsAJudge**: Deliberative decision-making with expert panels
### Notes: - **InteractiveGroupChat**: Dynamic group interactions with real-time collaboration
- **HeavySwarm**: High-capacity processing with multiple specialized agents
- Always prioritize clarity and specificity in agent design
- Ensure each agent has a unique, well-defined role ### Output Requirements:
- Create detailed, comprehensive system prompts
- Maintain clear documentation of agent capabilities and limitations When creating a multi-agent system, provide:
- Design for scalability and adaptability
- Focus on creating agents that can work together effectively 1. **Agent Specifications**:
- Consider edge cases and potential failure modes - Comprehensive role and purpose statements
- Implement robust error handling and recovery procedures - Detailed personality profiles and behavioral characteristics
- Complete capabilities, limitations, and boundary definitions
- Communication style and interaction protocols
- Collaboration strategies and team integration plans
2. **System Prompts**:
- Complete, detailed prompts that embody each agent's identity and capabilities
- Clear behavioral instructions and decision-making frameworks
- Specific interaction guidelines and reporting requirements
- Quality standards and performance expectations
3. **Architecture Design**:
- Team structure, hierarchy, and reporting relationships
- Communication flow patterns and information routing
- Task distribution strategies and workload balancing
- Quality control measures and performance monitoring
- Error handling and recovery procedures
### Best Practices:
- Prioritize clarity, specificity, and precision in agent design
- Ensure each agent has a unique, well-defined role with clear boundaries
- Create comprehensive, detailed system prompts that leave no ambiguity
- Maintain thorough documentation of agent capabilities, limitations, and interactions
- Design for scalability, adaptability, and long-term maintainability
- Focus on creating agents that work together synergistically and efficiently
- Consider edge cases, failure modes, and contingency planning
- Implement robust error handling, monitoring, and recovery procedures
- Design for continuous learning, improvement, and optimization
- Ensure ethical considerations, safety measures, and responsible AI practices
""" """
@ -101,13 +133,29 @@ class AgentConfig(BaseModel):
"""Configuration for an individual agent in a swarm""" """Configuration for an individual agent in a swarm"""
name: str = Field( name: str = Field(
description="The name of the agent", description="The name of the agent. This should be a unique identifier that distinguishes this agent from others within the swarm. The name should reflect the agent's primary function, role, or area of expertise, and should be easily recognizable by both humans and other agents in the system. A well-chosen name helps clarify the agent's responsibilities and facilitates effective communication and collaboration within the swarm.",
) )
description: str = Field( description: str = Field(
description="A description of the agent's purpose and capabilities", description=(
"A comprehensive description of the agent's purpose, core responsibilities, and capabilities within the swarm. One sentence is enough."
),
) )
system_prompt: str = Field( system_prompt: str = Field(
description="The system prompt that defines the agent's behavior", description=(
"The system prompt that defines the agent's behavior. This prompt should be extremely long, comprehensive, and extensive, encapsulating the agent's identity, operational guidelines, and decision-making framework in great detail. It provides the foundational instructions that guide the agent's actions, communication style, and interaction protocols with both users and other agents. The system prompt should be highly detailed, unambiguous, and exhaustive, ensuring the agent consistently acts in accordance with its intended role and adheres to the swarm's standards and best practices. The prompt should leave no ambiguity and cover all relevant aspects of the agent's responsibilities, behaviors, and expected outcomes."
),
)
goal: str = Field(
description="The goal of the agent. This should clearly state the primary objective or desired outcome the agent is tasked with achieving. The goal should be specific, measurable, and aligned with the overall mission of the swarm. It serves as the guiding principle for the agent's actions and decision-making processes, helping to maintain focus and drive effective collaboration within the multi-agent system.",
)
model_name: str = Field(
description="The model to use for the agent. This is the model that will be used to generate the agent's responses. For example, 'gpt-4o-mini' or 'claude-sonnet-3.7-sonnet-20240620'."
)
temperature: float = Field(
description="The temperature to use for the agent. This controls the randomness of the agent's responses. For example, 0.5 or 1.0."
)
max_loops: int = Field(
description="The maximum number of loops for the agent to run. This is the maximum number of times the agent will run its loop. For example, 1, 2, or 3. Keep this set to 1 unless the agent requires more than one loop to complete its task.",
) )
# max_loops: int = Field( # max_loops: int = Field(
@ -126,6 +174,63 @@ class AgentsConfig(BaseModel):
) )
class SwarmRouterConfig(BaseModel):
"""Configuration model for SwarmRouter."""
name: str = Field(description="The name of the team of agents")
description: str = Field(
description="Description of the team of agents"
)
agents: List[AgentConfig] = Field(
description="A list of agent configurations",
)
swarm_type: SwarmType = Field(
description="Type of multi-agent structure to use",
)
rearrange_flow: Optional[str] = Field(
description="Flow configuration string. Only to be used if you you use the AgentRearrange multi-agent structure"
)
rules: Optional[str] = Field(
description="Rules to inject into every agent. This is a string of rules that will be injected into every agent's system prompt. This is a good place to put things like 'You are a helpful assistant' or 'You are a helpful assistant that can answer questions and help with tasks'."
)
task: str = Field(
description="The task to be executed by the swarm",
)
class Config:
arbitrary_types_allowed = True
def reasoning_agent_run(
self,
task: str,
img: Optional[str] = None,
name: str = None,
model_name: str = "gpt-4.1",
system_prompt: str = None,
):
"""
Run a reasoning agent to analyze the task before the main director processes it.
Args:
task (str): The task to reason about
img (Optional[str]): Optional image input
Returns:
str: The reasoning output from the agent
"""
agent = Agent(
agent_name=name,
agent_description=f"You're the {name} agent that is responsible for reasoning about the task and creating a plan for the swarm to accomplish the task.",
model_name=model_name,
system_prompt=INTERNAL_MONOLGUE_PROMPT + system_prompt,
max_loops=1,
)
return agent.run(task=task, img=img)
class AutoSwarmBuilder: class AutoSwarmBuilder:
"""A class that automatically builds and manages swarms of AI agents. """A class that automatically builds and manages swarms of AI agents.
@ -143,11 +248,15 @@ class AutoSwarmBuilder:
def __init__( def __init__(
self, self,
name: str = None, name: str = "auto-swarm-builder",
description: str = None, description: str = "Auto Swarm Builder",
verbose: bool = True, verbose: bool = True,
max_loops: int = 1, max_loops: int = 1,
random_models: bool = True, random_models: bool = False,
return_agents: bool = False,
model_name: str = "gpt-4.1",
generate_router_config: bool = False,
interactive: bool = False,
): ):
"""Initialize the AutoSwarmBuilder. """Initialize the AutoSwarmBuilder.
@ -163,11 +272,36 @@ class AutoSwarmBuilder:
self.verbose = verbose self.verbose = verbose
self.max_loops = max_loops self.max_loops = max_loops
self.random_models = random_models self.random_models = random_models
self.return_agents = return_agents
self.model_name = model_name
self.generate_router_config = generate_router_config
self.interactive = interactive
self.conversation = Conversation()
self.reliability_check()
def reliability_check(self):
if self.max_loops == 0:
raise ValueError(
f"AutoSwarmBuilder: {self.name} max_loops cannot be 0"
)
logger.info( logger.info(
f"Initializing AutoSwarmBuilder with name: {name}, description: {description}" f"Initializing AutoSwarmBuilder: {self.name} Description: {self.description}"
) )
def _execute_task(self, task: str):
logger.info(f"Executing task: {task}")
agents = self.create_agents(task)
if self.random_models:
logger.info("Setting random models for agents")
agents = set_random_models_for_agents(agents=agents)
return self.initialize_swarm_router(agents=agents, task=task)
def run(self, task: str, *args, **kwargs): def run(self, task: str, *args, **kwargs):
"""Run the swarm on a given task. """Run the swarm on a given task.
@ -183,23 +317,104 @@ class AutoSwarmBuilder:
Exception: If there's an error during execution Exception: If there's an error during execution
""" """
try: try:
logger.info(f"Starting swarm execution for task: {task}")
agents = self.create_agents(task)
logger.info(f"Created {len(agents)} agents")
if self.random_models: if self.generate_router_config:
logger.info("Setting random models for agents") return self.create_router_config(task)
agents = set_random_models_for_agents(agents=agents) elif self.return_agents:
return self.create_agents(task)
else:
return self._execute_task(task)
return self.initialize_swarm_router(
agents=agents, task=task
)
except Exception as e: except Exception as e:
logger.error( logger.error(
f"Error in swarm execution: {str(e)}", exc_info=True f"AutoSwarmBuilder: Error in swarm execution: {str(e)} Traceback: {traceback.format_exc()}",
exc_info=True,
) )
raise raise
# def run(
# self, task: str, correct_answer: str = None, *args, **kwargs
# ):
# """
# Executes the swarm on the given task. If correct_answer is provided, the method will retry until this answer is found in the output, up to max_loops times.
# If correct_answer is not provided, the method will execute the task once and return the output.
# Args:
# task (str): The task to execute.
# correct_answer (str, optional): If provided, the method will retry until this answer is found in the output.
# *args: Additional positional arguments.
# **kwargs: Additional keyword arguments.
# Returns:
# Any: The output of the swarm execution, or the output containing the correct answer if specified.
# """
# if correct_answer is None:
# # If no correct_answer is specified, just run once and return the output
# return self._run(task, *args, **kwargs)
# else:
# # If correct_answer is specified, retry up to max_loops times
# for attempt in range(1, self.max_loops + 1):
# output = self._run(task, *args, **kwargs)
# if correct_answer in str(output):
# logger.info(
# f"AutoSwarmBuilder: Correct answer found on attempt {attempt}."
# )
# return output
# else:
# logger.info(
# f"AutoSwarmBuilder: Attempt {attempt} did not yield the correct answer, retrying..."
# )
# # If correct_answer was not found after max_loops, return the last output
# return output
def dict_to_agent(self, output: dict):
agents = []
if isinstance(output, dict):
for agent_config in output["agents"]:
logger.info(f"Building agent: {agent_config['name']}")
agent = self.build_agent(
agent_name=agent_config["name"],
agent_description=agent_config["description"],
agent_system_prompt=agent_config["system_prompt"],
)
agents.append(agent)
logger.info(
f"Successfully built agent: {agent_config['name']}"
)
return agents
def create_router_config(self, task: str):
try:
logger.info(
f"Creating swarm router config for task: {task}"
)
model = self.build_llm_agent(config=SwarmRouterConfig)
output = model.run(
f"Create the multi-agent team for the following task: {task}"
)
return output.model_dump()
except Exception as e:
logger.error(
f"Error creating swarm router config: {str(e)} Traceback: {traceback.format_exc()}",
exc_info=True,
)
raise e
def build_llm_agent(self, config: BaseModel):
return OpenAIFunctionCaller(
system_prompt=BOSS_SYSTEM_PROMPT,
api_key=os.getenv("OPENAI_API_KEY"),
temperature=0.5,
base_model=config,
model_name=self.model_name,
max_tokens=8000,
)
def create_agents(self, task: str): def create_agents(self, task: str):
"""Create agents for a given task. """Create agents for a given task.
@ -213,49 +428,25 @@ class AutoSwarmBuilder:
Exception: If there's an error during agent creation Exception: If there's an error during agent creation
""" """
try: try:
logger.info(f"Creating agents for task: {task}") model = self.build_llm_agent(config=AgentsConfig)
model = OpenAIFunctionCaller(
system_prompt=BOSS_SYSTEM_PROMPT,
api_key=os.getenv("OPENAI_API_KEY"),
temperature=0.5,
base_model=AgentsConfig,
)
logger.info(
"Getting agent configurations from boss agent"
)
output = model.run( output = model.run(
f"Create the agents for the following task: {task}" f"Create the agents for the following task: {task}"
) )
logger.debug(
f"Received agent configurations: {output.model_dump()}" if self.return_agents:
) output = output.model_dump()
output = output.model_dump() else:
output = self.dict_to_agent(output)
agents = []
if isinstance(output, dict): return output
for agent_config in output["agents"]:
logger.info(
f"Building agent: {agent_config['name']}"
)
agent = self.build_agent(
agent_name=agent_config["name"],
agent_description=agent_config["description"],
agent_system_prompt=agent_config[
"system_prompt"
],
)
agents.append(agent)
logger.info(
f"Successfully built agent: {agent_config['name']}"
)
return agents
except Exception as e: except Exception as e:
logger.error( logger.error(
f"Error creating agents: {str(e)}", exc_info=True f"Error creating agents: {str(e)} Traceback: {traceback.format_exc()}",
exc_info=True,
) )
raise raise e
def build_agent( def build_agent(
self, self,
@ -309,12 +500,7 @@ class AutoSwarmBuilder:
""" """
try: try:
logger.info("Initializing swarm router") logger.info("Initializing swarm router")
model = OpenAIFunctionCaller( model = self.build_llm_agent(config=SwarmRouterConfig)
system_prompt=BOSS_SYSTEM_PROMPT,
api_key=os.getenv("OPENAI_API_KEY"),
temperature=0.5,
base_model=SwarmRouterConfig,
)
logger.info("Creating swarm specification") logger.info("Creating swarm specification")
swarm_spec = model.run( swarm_spec = model.run(

@ -1,11 +1,16 @@
import concurrent.futures
from swarms.structs.agent import Agent from swarms.structs.agent import Agent
from typing import List from typing import List, Union, Callable
import os
from swarms.utils.formatter import formatter from swarms.utils.formatter import formatter
from loguru import logger
import traceback
def batch_agent_execution( def batch_agent_execution(
agents: List[Agent], agents: List[Union[Agent, Callable]],
tasks: List[str], tasks: List[str] = None,
imgs: List[str] = None,
): ):
""" """
Execute a batch of agents on a list of tasks concurrently. Execute a batch of agents on a list of tasks concurrently.
@ -20,45 +25,58 @@ def batch_agent_execution(
Raises: Raises:
ValueError: If number of agents doesn't match number of tasks ValueError: If number of agents doesn't match number of tasks
""" """
if len(agents) != len(tasks): try:
raise ValueError(
"Number of agents must match number of tasks"
)
import concurrent.futures logger.info(
import multiprocessing f"Executing {len(agents)} agents on {len(tasks)} tasks"
)
results = [] if len(agents) != len(tasks):
raise ValueError(
"Number of agents must match number of tasks"
)
# Calculate max workers as 90% of available CPU cores results = []
max_workers = max(1, int(multiprocessing.cpu_count() * 0.9))
formatter.print_panel( # Calculate max workers as 90% of available CPU cores
f"Executing {len(agents)} agents on {len(tasks)} tasks using {max_workers} workers" max_workers = max(1, int(os.cpu_count() * 0.9))
)
with concurrent.futures.ThreadPoolExecutor( formatter.print_panel(
max_workers=max_workers f"Executing {len(agents)} agents on {len(tasks)} tasks using {max_workers} workers"
) as executor: )
# Submit all tasks to the executor
future_to_task = {
executor.submit(agent.run, task): (agent, task)
for agent, task in zip(agents, tasks)
}
# Collect results as they complete with concurrent.futures.ThreadPoolExecutor(
for future in concurrent.futures.as_completed(future_to_task): max_workers=max_workers
agent, task = future_to_task[future] ) as executor:
try: # Submit all tasks to the executor
result = future.result() future_to_task = {
results.append(result) executor.submit(agent.run, task, imgs): (
except Exception as e: agent,
print( task,
f"Task failed for agent {agent.agent_name}: {str(e)}" imgs,
) )
results.append(None) for agent, task, imgs in zip(agents, tasks, imgs)
}
# Collect results as they complete
for future in concurrent.futures.as_completed(
future_to_task
):
agent, task = future_to_task[future]
try:
result = future.result()
results.append(result)
except Exception as e:
print(
f"Task failed for agent {agent.agent_name}: {str(e)}"
)
results.append(None)
# Wait for all futures to complete before returning # Wait for all futures to complete before returning
concurrent.futures.wait(future_to_task.keys()) concurrent.futures.wait(future_to_task.keys())
return results return results
except Exception as e:
log = f"Batch agent execution failed Error: {str(e)} Traceback: {traceback.format_exc()}"
logger.error(log)
raise e

File diff suppressed because it is too large Load Diff

@ -1,4 +1,4 @@
import multiprocessing import os
import uuid import uuid
from concurrent.futures import ThreadPoolExecutor, as_completed from concurrent.futures import ThreadPoolExecutor, as_completed
from functools import lru_cache from functools import lru_cache
@ -117,7 +117,7 @@ def judge_system_prompt() -> str:
@lru_cache(maxsize=128) @lru_cache(maxsize=128)
def build_judge_prompt( def build_judge_prompt(
dimension_name: str, user_prompt: str, model_response: str dimension_name: str, task: str, task_response: str
) -> str: ) -> str:
""" """
Builds a prompt for evaluating a specific dimension. Builds a prompt for evaluating a specific dimension.
@ -125,8 +125,8 @@ def build_judge_prompt(
Args: Args:
dimension_name (str): Name of the evaluation dimension dimension_name (str): Name of the evaluation dimension
user_prompt (str): The original user prompt task (str): The task containing the response to evaluate
model_response (str): The model's response to evaluate task_response (str): The response within the task to evaluate
Returns: Returns:
str: The formatted evaluation prompt str: The formatted evaluation prompt
@ -145,7 +145,7 @@ def build_judge_prompt(
{evaluation_focus} {evaluation_focus}
Your task is to provide a detailed, technical analysis of the model response focusing exclusively on the {dimension_name} dimension. Your task is to provide a detailed, technical analysis of the response focusing exclusively on the {dimension_name} dimension.
Guidelines: Guidelines:
1. Be specific and reference exact parts of the response 1. Be specific and reference exact parts of the response
@ -154,16 +154,16 @@ def build_judge_prompt(
4. Suggest specific improvements where applicable 4. Suggest specific improvements where applicable
5. Maintain a technical, analytical tone 5. Maintain a technical, analytical tone
--- BEGIN USER PROMPT --- --- BEGIN TASK ---
{user_prompt} {task}
--- END USER PROMPT --- --- END TASK ---
--- BEGIN MODEL RESPONSE --- --- BEGIN RESPONSE ---
{model_response} {task_response}
--- END MODEL RESPONSE --- --- END RESPONSE ---
### Technical Analysis ({dimension_name.upper()} Dimension): ### Technical Analysis ({dimension_name.upper()} Dimension):
Provide a comprehensive analysis that would be valuable for model improvement. Provide a comprehensive analysis that would be valuable for response improvement.
""" """
@ -176,7 +176,7 @@ def aggregator_system_prompt() -> str:
Returns: Returns:
str: The system prompt for the aggregator agent str: The system prompt for the aggregator agent
""" """
return """You are a senior AI evaluator responsible for synthesizing detailed technical feedback across multiple evaluation dimensions. Your role is to create a comprehensive analysis report that helps the development team understand and improve the model's performance. return """You are a senior AI evaluator responsible for synthesizing detailed technical feedback across multiple evaluation dimensions. Your role is to create a comprehensive analysis report that helps understand and improve the response quality.
Key Responsibilities: Key Responsibilities:
1. Identify patterns and correlations across different dimensions 1. Identify patterns and correlations across different dimensions
@ -225,10 +225,10 @@ def build_aggregation_prompt(rationales: Dict[str, str]) -> str:
class CouncilAsAJudge: class CouncilAsAJudge:
""" """
A council of AI agents that evaluates model responses across multiple dimensions. A council of AI agents that evaluates task responses across multiple dimensions.
This class implements a parallel evaluation system where multiple specialized agents This class implements a parallel evaluation system where multiple specialized agents
evaluate different aspects of a model's response, and their findings are aggregated evaluate different aspects of a task response, and their findings are aggregated
into a comprehensive report. into a comprehensive report.
Attributes: Attributes:
@ -247,15 +247,14 @@ class CouncilAsAJudge:
self, self,
id: str = swarm_id(), id: str = swarm_id(),
name: str = "CouncilAsAJudge", name: str = "CouncilAsAJudge",
description: str = "Evaluates the model's response across multiple dimensions", description: str = "Evaluates task responses across multiple dimensions",
model_name: str = "gpt-4o-mini", model_name: str = "gpt-4o-mini",
output_type: str = "all", output_type: str = "final",
cache_size: int = 128, cache_size: int = 128,
max_workers: int = None,
base_agent: Optional[Agent] = None,
random_model_name: bool = True, random_model_name: bool = True,
max_loops: int = 1, max_loops: int = 1,
aggregation_model_name: str = "gpt-4o-mini", aggregation_model_name: str = "gpt-4o-mini",
judge_agent_model_name: Optional[str] = None,
): ):
""" """
Initialize the CouncilAsAJudge. Initialize the CouncilAsAJudge.
@ -267,6 +266,10 @@ class CouncilAsAJudge:
model_name (str): Name of the model to use for evaluations model_name (str): Name of the model to use for evaluations
output_type (str): Type of output to return output_type (str): Type of output to return
cache_size (int): Size of the LRU cache for prompts cache_size (int): Size of the LRU cache for prompts
max_workers (int): Maximum number of worker threads for parallel execution
random_model_name (bool): Whether to use random model names
max_loops (int): Maximum number of loops for agents
aggregation_model_name (str): Model name for the aggregator agent
""" """
self.id = id self.id = id
self.name = name self.name = name
@ -274,11 +277,11 @@ class CouncilAsAJudge:
self.model_name = model_name self.model_name = model_name
self.output_type = output_type self.output_type = output_type
self.cache_size = cache_size self.cache_size = cache_size
self.max_workers = max_workers
self.base_agent = base_agent
self.random_model_name = random_model_name self.random_model_name = random_model_name
self.max_loops = max_loops self.max_loops = max_loops
self.aggregation_model_name = aggregation_model_name self.aggregation_model_name = aggregation_model_name
self.judge_agent_model_name = judge_agent_model_name
self.max_workers = max(1, int(os.cpu_count() * 0.75))
self.reliability_check() self.reliability_check()
@ -303,12 +306,6 @@ class CouncilAsAJudge:
self.concurrent_setup() self.concurrent_setup()
def concurrent_setup(self): def concurrent_setup(self):
# Calculate optimal number of workers (75% of available CPU cores)
total_cores = multiprocessing.cpu_count()
self.max_workers = max(1, int(total_cores * 0.75))
logger.info(
f"Using {self.max_workers} worker threads out of {total_cores} CPU cores"
)
# Configure caching # Configure caching
self._configure_caching(self.cache_size) self._configure_caching(self.cache_size)
@ -353,7 +350,7 @@ class CouncilAsAJudge:
dim: Agent( dim: Agent(
agent_name=f"{dim}_judge", agent_name=f"{dim}_judge",
system_prompt=judge_system_prompt(), system_prompt=judge_system_prompt(),
model_name="gpt-4o-mini", model_name=self.judge_agent_model_name,
max_loops=1, max_loops=1,
output_type="final", output_type="final",
dynamic_temperature_enabled=True, dynamic_temperature_enabled=True,
@ -393,17 +390,15 @@ class CouncilAsAJudge:
self, self,
dim: str, dim: str,
agent: Agent, agent: Agent,
user_prompt: str, task: str,
model_response: str,
) -> Tuple[str, str]: ) -> Tuple[str, str]:
""" """
Evaluate a single dimension of the model response. Evaluate a single dimension of the task response.
Args: Args:
dim (str): Dimension to evaluate dim (str): Dimension to evaluate
agent (Agent): Judge agent for this dimension agent (Agent): Judge agent for this dimension
user_prompt (str): Original user prompt task (str): Task containing the response to evaluate
model_response (str): Model's response to evaluate
Returns: Returns:
Tuple[str, str]: Tuple of (dimension name, evaluation result) Tuple[str, str]: Tuple of (dimension name, evaluation result)
@ -412,11 +407,9 @@ class CouncilAsAJudge:
DimensionEvaluationError: If evaluation fails DimensionEvaluationError: If evaluation fails
""" """
try: try:
prompt = build_judge_prompt( prompt = build_judge_prompt(dim, task, task)
dim, user_prompt, model_response
)
result = agent.run( result = agent.run(
f"{prompt} \n\n Evaluate the following agent {self.base_agent.agent_name} response for the {dim} dimension: {model_response}." f"{prompt} \n\n Evaluate the following response for the {dim} dimension: {task}."
) )
self.conversation.add( self.conversation.add(
@ -430,15 +423,12 @@ class CouncilAsAJudge:
f"Failed to evaluate dimension {dim}: {str(e)}" f"Failed to evaluate dimension {dim}: {str(e)}"
) )
def run( def run(self, task: str) -> None:
self, task: str, model_response: Optional[str] = None
) -> None:
""" """
Run the evaluation process using ThreadPoolExecutor. Run the evaluation process using ThreadPoolExecutor.
Args: Args:
task (str): Original user prompt task (str): Task containing the response to evaluate
model_response (str): Model's response to evaluate
Raises: Raises:
EvaluationError: If evaluation process fails EvaluationError: If evaluation process fails
@ -446,10 +436,6 @@ class CouncilAsAJudge:
try: try:
# Run the base agent
if self.base_agent and model_response is None:
model_response = self.base_agent.run(task=task)
self.conversation.add( self.conversation.add(
role="User", role="User",
content=task, content=task,
@ -457,7 +443,7 @@ class CouncilAsAJudge:
# Create tasks for all dimensions # Create tasks for all dimensions
tasks = [ tasks = [
(dim, agent, task, model_response) (dim, agent, task)
for dim, agent in self.judge_agents.items() for dim, agent in self.judge_agents.items()
] ]
@ -472,9 +458,8 @@ class CouncilAsAJudge:
dim, dim,
agent, agent,
task, task,
model_response,
): dim ): dim
for dim, agent, _, _ in tasks for dim, agent, _ in tasks
} }
# Collect results as they complete # Collect results as they complete
@ -505,32 +490,6 @@ class CouncilAsAJudge:
content=final_report, content=final_report,
) )
# Synthesize feedback and generate improved response
feedback_prompt = f"""
Based on the comprehensive evaluations from our expert council of judges, please refine your response to the original task.
Original Task:
{task}
Council Feedback:
{aggregation_prompt}
Please:
1. Carefully consider all feedback points
2. Address any identified weaknesses
3. Maintain or enhance existing strengths
4. Provide a refined, improved response that incorporates the council's insights
Your refined response:
"""
final_report = self.base_agent.run(task=feedback_prompt)
self.conversation.add(
role=self.base_agent.agent_name,
content=final_report,
)
return history_output_formatter( return history_output_formatter(
conversation=self.conversation, conversation=self.conversation,
type=self.output_type, type=self.output_type,

@ -18,6 +18,9 @@ Todo
- Auto build agents from input prompt - and then add them to the swarm - Auto build agents from input prompt - and then add them to the swarm
- Create an interactive and dynamic UI like we did with heavy swarm - Create an interactive and dynamic UI like we did with heavy swarm
- Make it faster and more high performance - Make it faster and more high performance
- Enable the director to choose a multi-agent approach to the task, it orchestrates how the agents talk and work together.
- Improve the director feedback, maybe add agent as a judge to the worker agent instead of the director.
- Use agent rearrange to orchestrate the agents
Classes: Classes:
HierarchicalOrder: Represents a single task assignment to a specific agent HierarchicalOrder: Represents a single task assignment to a specific agent
@ -25,14 +28,26 @@ Classes:
HierarchicalSwarm: Main swarm orchestrator that manages director and worker agents HierarchicalSwarm: Main swarm orchestrator that manages director and worker agents
""" """
import time
import traceback import traceback
from typing import Any, Callable, List, Optional, Union from typing import Any, Callable, List, Optional, Union
from loguru import logger
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from rich.console import Console
from rich.layout import Layout
from rich.live import Live
from rich.panel import Panel
from rich.table import Table
from rich.text import Text
from swarms.prompts.hiearchical_system_prompt import ( from swarms.prompts.hiearchical_system_prompt import (
HIEARCHICAL_SWARM_SYSTEM_PROMPT, HIEARCHICAL_SWARM_SYSTEM_PROMPT,
) )
from swarms.prompts.multi_agent_collab_prompt import (
MULTI_AGENT_COLLAB_PROMPT_TWO,
)
from swarms.prompts.reasoning_prompt import INTERNAL_MONOLGUE_PROMPT
from swarms.structs.agent import Agent from swarms.structs.agent import Agent
from swarms.structs.conversation import Conversation from swarms.structs.conversation import Conversation
from swarms.structs.ma_utils import list_all_agents from swarms.structs.ma_utils import list_all_agents
@ -40,10 +55,507 @@ from swarms.tools.base_tool import BaseTool
from swarms.utils.history_output_formatter import ( from swarms.utils.history_output_formatter import (
history_output_formatter, history_output_formatter,
) )
from swarms.utils.loguru_logger import initialize_logger
from swarms.utils.output_types import OutputType from swarms.utils.output_types import OutputType
logger = initialize_logger(log_folder="hierarchical_swarm")
class HierarchicalSwarmDashboard:
"""
Futuristic Arasaka Corporation-style dashboard for hierarchical swarm monitoring.
This dashboard provides a professional, enterprise-grade interface with red and black
color scheme, real-time monitoring of swarm operations, and cyberpunk aesthetics.
Attributes:
console (Console): Rich console instance for rendering
live_display (Live): Live display for real-time updates
swarm_name (str): Name of the swarm being monitored
agent_statuses (dict): Current status of all agents
director_status (str): Current status of the director
current_loop (int): Current execution loop
max_loops (int): Maximum number of loops
is_active (bool): Whether the dashboard is currently active
"""
def __init__(self, swarm_name: str = "Swarms Corporation"):
"""
Initialize the Arasaka dashboard.
Args:
swarm_name (str): Name of the swarm to display in the dashboard
"""
self.console = Console()
self.live_display = None
self.swarm_name = swarm_name
self.agent_statuses = {}
self.director_status = "INITIALIZING"
self.current_loop = 0
self.max_loops = 1
self.is_active = False
self.start_time = None
self.spinner_frames = [
"",
"",
"",
"",
"",
"",
"",
"",
"",
"",
]
self.spinner_idx = 0
# Director information tracking
self.director_plan = ""
self.director_orders = []
# Swarm information
self.swarm_description = ""
self.director_name = "Director"
self.director_model_name = "gpt-4o-mini"
# View mode for agents display
self.detailed_view = False
# Multi-loop agent tracking
self.agent_history = {} # Track agent outputs across loops
self.current_loop = 0
def _get_spinner(self) -> str:
"""Get current spinner frame for loading animations."""
self.spinner_idx = (self.spinner_idx + 1) % len(
self.spinner_frames
)
return self.spinner_frames[self.spinner_idx]
def _create_header(self) -> Panel:
"""Create the dashboard header with Swarms Corporation branding."""
header_text = Text()
header_text.append(
"╔══════════════════════════════════════════════════════════════════════════════╗\n",
style="bold red",
)
header_text.append("", style="bold red")
header_text.append(" ", style="bold red")
header_text.append(
"SWARMS CORPORATION", style="bold white on red"
)
header_text.append(" ", style="bold red")
header_text.append("\n", style="bold red")
header_text.append("", style="bold red")
header_text.append(" ", style="bold red")
header_text.append(
"HIERARCHICAL SWARM OPERATIONS CENTER", style="bold red"
)
header_text.append(" ", style="bold red")
header_text.append("\n", style="bold red")
header_text.append(
"╚══════════════════════════════════════════════════════════════════════════════╝",
style="bold red",
)
return Panel(
header_text,
border_style="red",
padding=(0, 1),
)
def _create_status_panel(self) -> Panel:
"""Create the operations status panel."""
status_text = Text()
# Corporation branding and operation type
status_text.append(
"By the Swarms Corporation", style="bold cyan"
)
status_text.append("\n", style="white")
status_text.append(
"Hierarchical Agent Operations", style="bold white"
)
status_text.append("\n\n", style="white")
# Swarm information
status_text.append("SWARM NAME: ", style="bold white")
status_text.append(f"{self.swarm_name}", style="bold cyan")
status_text.append("\n", style="white")
status_text.append("DESCRIPTION: ", style="bold white")
status_text.append(f"{self.swarm_description}", style="white")
status_text.append("\n", style="white")
status_text.append("DIRECTOR: ", style="bold white")
status_text.append(
f"{self.director_name} ({self.director_model_name})",
style="cyan",
)
status_text.append("\n", style="white")
status_text.append("TOTAL LOOPS: ", style="bold white")
status_text.append(f"{self.max_loops}", style="bold cyan")
status_text.append(" | ", style="white")
status_text.append("CURRENT LOOP: ", style="bold white")
status_text.append(
f"{self.current_loop}", style="bold yellow"
)
# Agent count metadata
agent_count = len(getattr(self, "agent_history", {}))
status_text.append(" | ", style="white")
status_text.append("AGENTS: ", style="bold white")
status_text.append(f"{agent_count}", style="bold green")
status_text.append("\n\n", style="white")
# Director status
status_text.append("DIRECTOR STATUS: ", style="bold white")
if self.director_status == "INITIALIZING":
status_text.append(
f"{self._get_spinner()} {self.director_status}",
style="bold yellow",
)
elif self.director_status == "ACTIVE":
status_text.append(
f"{self.director_status}", style="bold green"
)
elif self.director_status == "PROCESSING":
status_text.append(
f"{self._get_spinner()} {self.director_status}",
style="bold cyan",
)
else:
status_text.append(
f"{self.director_status}", style="bold red"
)
status_text.append("\n\n", style="white")
# Runtime and completion information
if self.start_time:
runtime = time.time() - self.start_time
status_text.append("RUNTIME: ", style="bold white")
status_text.append(f"{runtime:.2f}s", style="bold green")
# Add completion percentage if loops are running
if self.max_loops > 0:
completion_percent = (
self.current_loop / self.max_loops
) * 100
status_text.append(" | ", style="white")
status_text.append("PROGRESS: ", style="bold white")
status_text.append(
f"{completion_percent:.1f}%", style="bold cyan"
)
return Panel(
status_text,
border_style="red",
padding=(1, 2),
title="[bold white]OPERATIONS STATUS[/bold white]",
)
def _create_agents_table(self) -> Table:
"""Create the agents monitoring table with full outputs and loop history."""
table = Table(
show_header=True,
header_style="bold white on red",
border_style="red",
title="[bold white]AGENT MONITORING MATRIX[/bold white]",
title_style="bold white",
show_lines=True,
)
table.add_column("AGENT ID", style="bold cyan", width=25)
table.add_column("LOOP", style="bold white", width=8)
table.add_column("STATUS", style="bold white", width=15)
table.add_column("TASK", style="white", width=40)
table.add_column("OUTPUT", style="white", width=150)
# Display agents with their history across loops
for agent_name, history in self.agent_history.items():
for loop_num in range(self.max_loops + 1):
loop_key = f"Loop_{loop_num}"
if loop_key in history:
loop_data = history[loop_key]
status = loop_data.get("status", "UNKNOWN")
task = loop_data.get("task", "N/A")
output = loop_data.get("output", "")
# Style status
if status == "RUNNING":
status_display = (
f"{self._get_spinner()} {status}"
)
status_style = "bold yellow"
elif status == "COMPLETED":
status_display = f"{status}"
status_style = "bold green"
elif status == "PENDING":
status_display = f"{status}"
status_style = "bold red"
else:
status_display = f"{status}"
status_style = "bold red"
# Show full output without truncation
output_display = output if output else "No output"
table.add_row(
Text(agent_name, style="bold cyan"),
Text(f"Loop {loop_num}", style="bold white"),
Text(status_display, style=status_style),
Text(task, style="white"),
Text(output_display, style="white"),
)
return table
def _create_detailed_agents_view(self) -> Panel:
"""Create a detailed view of agents with full outputs and loop history."""
detailed_text = Text()
for agent_name, history in self.agent_history.items():
detailed_text.append(
f"AGENT: {agent_name}\n", style="bold cyan"
)
detailed_text.append("=" * 80 + "\n", style="red")
for loop_num in range(self.max_loops + 1):
loop_key = f"Loop_{loop_num}"
if loop_key in history:
loop_data = history[loop_key]
status = loop_data.get("status", "UNKNOWN")
task = loop_data.get("task", "N/A")
output = loop_data.get("output", "")
detailed_text.append(
f"LOOP {loop_num}:\n", style="bold white"
)
detailed_text.append(
f"STATUS: {status}\n", style="bold white"
)
detailed_text.append(
f"TASK: {task}\n", style="white"
)
detailed_text.append(
"OUTPUT:\n", style="bold white"
)
detailed_text.append(f"{output}\n", style="white")
detailed_text.append("" * 80 + "\n", style="red")
return Panel(
detailed_text,
border_style="red",
padding=(1, 2),
title="[bold white]DETAILED AGENT OUTPUTS (FULL HISTORY)[/bold white]",
)
def _create_director_panel(self) -> Panel:
"""Create the director information panel showing plan and orders."""
director_text = Text()
# Plan section
director_text.append("DIRECTOR PLAN:\n", style="bold white")
if self.director_plan:
director_text.append(self.director_plan, style="white")
else:
director_text.append(
"No plan available", style="dim white"
)
director_text.append("\n\n", style="white")
# Orders section
director_text.append("CURRENT ORDERS:\n", style="bold white")
if self.director_orders:
for i, order in enumerate(
self.director_orders
): # Show first 5 orders
director_text.append(f"{i+1}. ", style="bold cyan")
director_text.append(
f"{order.get('agent_name', 'Unknown')}: ",
style="bold white",
)
task = order.get("task", "No task")
director_text.append(task, style="white")
director_text.append("\n", style="white")
if len(self.director_orders) > 5:
director_text.append(
f"... and {len(self.director_orders) - 5} more orders",
style="dim white",
)
else:
director_text.append(
"No orders available", style="dim white"
)
return Panel(
director_text,
border_style="red",
padding=(1, 2),
title="[bold white]DIRECTOR OPERATIONS[/bold white]",
)
def _create_dashboard_layout(self) -> Layout:
"""Create the complete dashboard layout."""
layout = Layout()
# Split into operations status, director operations, and agents
layout.split_column(
Layout(name="operations_status", size=12),
Layout(name="director_operations", size=12),
Layout(name="agents", ratio=1),
)
# Add content to each section
layout["operations_status"].update(
self._create_status_panel()
)
layout["director_operations"].update(
self._create_director_panel()
)
# Choose between table view and detailed view
if self.detailed_view:
layout["agents"].update(
self._create_detailed_agents_view()
)
else:
layout["agents"].update(
Panel(
self._create_agents_table(),
border_style="red",
padding=(1, 1),
)
)
return layout
def start(self, max_loops: int = 1):
"""Start the dashboard display."""
self.max_loops = max_loops
self.start_time = time.time()
self.is_active = True
self.live_display = Live(
self._create_dashboard_layout(),
console=self.console,
refresh_per_second=10,
transient=False,
)
self.live_display.start()
def update_agent_status(
self,
agent_name: str,
status: str,
task: str = "",
output: str = "",
):
"""Update the status of a specific agent."""
# Create loop key for tracking history
loop_key = f"Loop_{self.current_loop}"
# Initialize agent history if not exists
if agent_name not in self.agent_history:
self.agent_history[agent_name] = {}
# Store current status and add to history
self.agent_statuses[agent_name] = {
"status": status,
"task": task,
"output": output,
}
# Add to history for this loop
self.agent_history[agent_name][loop_key] = {
"status": status,
"task": task,
"output": output,
}
if self.live_display and self.is_active:
self.live_display.update(self._create_dashboard_layout())
def update_director_status(self, status: str):
"""Update the director status."""
self.director_status = status
if self.live_display and self.is_active:
self.live_display.update(self._create_dashboard_layout())
def update_loop(self, current_loop: int):
"""Update the current execution loop."""
self.current_loop = current_loop
if self.live_display and self.is_active:
self.live_display.update(self._create_dashboard_layout())
def update_director_plan(self, plan: str):
"""Update the director's plan."""
self.director_plan = plan
if self.live_display and self.is_active:
self.live_display.update(self._create_dashboard_layout())
def update_director_orders(self, orders: list):
"""Update the director's orders."""
self.director_orders = orders
if self.live_display and self.is_active:
self.live_display.update(self._create_dashboard_layout())
def stop(self):
"""Stop the dashboard display."""
self.is_active = False
if self.live_display:
self.live_display.stop()
self.console.print()
def update_swarm_info(
self,
name: str,
description: str,
max_loops: int,
director_name: str,
director_model_name: str,
):
"""Update the dashboard with swarm-specific information."""
self.swarm_name = name
self.swarm_description = description
self.max_loops = max_loops
self.director_name = director_name
self.director_model_name = director_model_name
if self.live_display and self.is_active:
self.live_display.update(self._create_dashboard_layout())
def force_refresh(self):
"""Force refresh the dashboard display."""
if self.live_display and self.is_active:
self.live_display.update(self._create_dashboard_layout())
def show_full_output(self, agent_name: str, full_output: str):
"""Display full agent output in a separate panel."""
if self.live_display and self.is_active:
# Create a full output panel
output_panel = Panel(
Text(full_output, style="white"),
title=f"[bold white]FULL OUTPUT - {agent_name}[/bold white]",
border_style="red",
padding=(1, 2),
width=120,
)
# Temporarily show the full output
self.console.print(output_panel)
self.console.print() # Add spacing
def toggle_detailed_view(self):
"""Toggle between table view and detailed view."""
self.detailed_view = not self.detailed_view
if self.live_display and self.is_active:
self.live_display.update(self._create_dashboard_layout())
class HierarchicalOrder(BaseModel): class HierarchicalOrder(BaseModel):
@ -71,6 +583,25 @@ class HierarchicalOrder(BaseModel):
) )
class HierarchicalOrderRearrange(BaseModel):
"""
Represents a single task assignment within the hierarchical swarm.
This class defines the structure for individual task orders that the director
distributes to worker agents. Each order specifies which agent should execute
what specific task.
"""
initial_task: str = Field(
...,
description="The initial task that the director has to execute.",
)
flow_of_communication: str = Field(
...,
description="How the agents will communicate with each other to accomplish the task. Like agent_one -> agent_two -> agent_three -> agent_four -> agent_one, can use comma signs to denote sequential communication and commas to denote parallel communication for example agent_one -> agent_two, agent_three -> agent_four",
)
class SwarmSpec(BaseModel): class SwarmSpec(BaseModel):
""" """
Defines the complete specification for a hierarchical swarm execution. Defines the complete specification for a hierarchical swarm execution.
@ -86,10 +617,20 @@ class SwarmSpec(BaseModel):
individual agents within the swarm. individual agents within the swarm.
""" """
# # thoughts: str = Field(
# # ...,
# # description="A plan generated by the director agent for the swarm to accomplish the given task, where the director autonomously reasons through the problem, devises its own strategy, and determines the sequence of actions. "
# # "This plan reflects the director's independent thought process, outlining the rationale, priorities, and steps it deems necessary for successful execution. "
# # "It serves as a blueprint for the swarm, enabling agents to follow the director's self-derived guidance and adapt as needed throughout the process.",
# )
plan: str = Field( plan: str = Field(
..., ...,
description="Outlines the sequence of actions to be taken by the swarm. This plan is a detailed roadmap that guides the swarm's behavior and decision-making.", description="A plan generated by the director agent for the swarm to accomplish the given task, where the director autonomously reasons through the problem, devises its own strategy, and determines the sequence of actions. "
"This plan reflects the director's independent thought process, outlining the rationale, priorities, and steps it deems necessary for successful execution. "
"It serves as a blueprint for the swarm, enabling agents to follow the director's self-derived guidance and adapt as needed throughout the process.",
) )
orders: List[HierarchicalOrder] = Field( orders: List[HierarchicalOrder] = Field(
..., ...,
description="A collection of task assignments to specific agents within the swarm. These orders are the specific instructions that guide the agents in their task execution and are a key element in the swarm's plan.", description="A collection of task assignments to specific agents within the swarm. These orders are the specific instructions that guide the agents in their task execution and are a key element in the swarm's plan.",
@ -143,6 +684,11 @@ class HierarchicalSwarm:
Union[Agent, Callable, Any] Union[Agent, Callable, Any]
] = None, ] = None,
director_feedback_on: bool = True, director_feedback_on: bool = True,
interactive: bool = False,
director_system_prompt: str = HIEARCHICAL_SWARM_SYSTEM_PROMPT,
director_reasoning_model_name: str = "o3-mini",
director_reasoning_enabled: bool = True,
multi_agent_prompt_improvements: bool = False,
*args, *args,
**kwargs, **kwargs,
): ):
@ -187,9 +733,79 @@ class HierarchicalSwarm:
self.add_collaboration_prompt = add_collaboration_prompt self.add_collaboration_prompt = add_collaboration_prompt
self.planning_director_agent = planning_director_agent self.planning_director_agent = planning_director_agent
self.director_feedback_on = director_feedback_on self.director_feedback_on = director_feedback_on
self.interactive = interactive
self.director_system_prompt = director_system_prompt
self.director_reasoning_model_name = (
director_reasoning_model_name
)
self.director_reasoning_enabled = director_reasoning_enabled
self.multi_agent_prompt_improvements = (
multi_agent_prompt_improvements
)
if self.interactive:
self.agents_no_print()
# Initialize dashboard if interactive mode is enabled
self.dashboard = None
if self.interactive:
self.dashboard = HierarchicalSwarmDashboard(self.name)
# Enable detailed view for better output visibility
self.dashboard.detailed_view = True
# Pass additional swarm information to dashboard
self.dashboard.update_swarm_info(
name=self.name,
description=self.description,
max_loops=self.max_loops,
director_name=self.director_name,
director_model_name=self.director_model_name,
)
self.init_swarm() self.init_swarm()
def list_worker_agents(self) -> str:
return list_all_agents(
agents=self.agents,
add_to_conversation=False,
)
def prepare_worker_agents(self):
for agent in self.agents:
prompt = (
MULTI_AGENT_COLLAB_PROMPT_TWO
+ self.list_worker_agents()
)
if hasattr(agent, "system_prompt"):
agent.system_prompt += prompt
else:
agent.system_prompt = prompt
def reasoning_agent_run(
self, task: str, img: Optional[str] = None
):
"""
Run a reasoning agent to analyze the task before the main director processes it.
Args:
task (str): The task to reason about
img (Optional[str]): Optional image input
Returns:
str: The reasoning output from the agent
"""
agent = Agent(
agent_name=self.director_name,
agent_description=f"You're the {self.director_name} agent that is responsible for reasoning about the task and creating a plan for the swarm to accomplish the task.",
model_name=self.director_reasoning_model_name,
system_prompt=INTERNAL_MONOLGUE_PROMPT
+ self.director_system_prompt,
max_loops=1,
)
prompt = f"Conversation History: {self.conversation.get_str()} \n\n Task: {task}"
return agent.run(task=prompt, img=img)
def init_swarm(self): def init_swarm(self):
""" """
Initialize the swarm with proper configuration and validation. Initialize the swarm with proper configuration and validation.
@ -216,11 +832,27 @@ class HierarchicalSwarm:
self.add_context_to_director() self.add_context_to_director()
# Initialize agent statuses in dashboard if interactive mode
if self.interactive and self.dashboard:
for agent in self.agents:
if hasattr(agent, "agent_name"):
self.dashboard.update_agent_status(
agent.agent_name,
"PENDING",
"Awaiting task assignment",
"Ready for deployment",
)
# Force refresh to ensure agents are displayed
self.dashboard.force_refresh()
if self.verbose: if self.verbose:
logger.success( logger.success(
f"✅ HierarchicalSwarm: {self.name} initialized successfully." f"✅ HierarchicalSwarm: {self.name} initialized successfully."
) )
if self.multi_agent_prompt_improvements:
self.prepare_worker_agents()
def add_context_to_director(self): def add_context_to_director(self):
""" """
Add agent context and collaboration information to the director's conversation. Add agent context and collaboration information to the director's conversation.
@ -282,6 +914,7 @@ class HierarchicalSwarm:
return Agent( return Agent(
agent_name=self.director_name, agent_name=self.director_name,
agent_description="A director agent that can create a plan and distribute orders to agents", agent_description="A director agent that can create a plan and distribute orders to agents",
system_prompt=self.director_system_prompt,
model_name=self.director_model_name, model_name=self.director_model_name,
max_loops=1, max_loops=1,
base_model=SwarmSpec, base_model=SwarmSpec,
@ -333,6 +966,10 @@ class HierarchicalSwarm:
error_msg = f"❌ Failed to setup director: {str(e)}\n🔍 Traceback: {traceback.format_exc()}\n🐛 If this issue persists, please report it at: https://github.com/kyegomez/swarms/issues" error_msg = f"❌ Failed to setup director: {str(e)}\n🔍 Traceback: {traceback.format_exc()}\n🐛 If this issue persists, please report it at: https://github.com/kyegomez/swarms/issues"
logger.error(error_msg) logger.error(error_msg)
def agents_no_print(self):
for agent in self.agents:
agent.print_on = False
def run_director( def run_director(
self, self,
task: str, task: str,
@ -358,9 +995,7 @@ class HierarchicalSwarm:
""" """
try: try:
if self.verbose: if self.verbose:
logger.info( logger.info(f"🎯 Running director with task: {task}")
f"🎯 Running director with task: {task[:100]}..."
)
if self.planning_director_agent is not None: if self.planning_director_agent is not None:
plan = self.planning_director_agent.run( plan = self.planning_director_agent.run(
@ -370,6 +1005,12 @@ class HierarchicalSwarm:
task += plan task += plan
if self.director_reasoning_enabled:
reasoning_output = self.reasoning_agent_run(
task=task, img=img
)
task += f"\n\n Reasoning: {reasoning_output}"
# Run the director with the context # Run the director with the context
function_call = self.director.run( function_call = self.director.run(
task=f"History: {self.conversation.get_str()} \n\n Task: {task}", task=f"History: {self.conversation.get_str()} \n\n Task: {task}",
@ -391,6 +1032,7 @@ class HierarchicalSwarm:
except Exception as e: except Exception as e:
error_msg = f"❌ Failed to setup director: {str(e)}\n🔍 Traceback: {traceback.format_exc()}\n🐛 If this issue persists, please report it at: https://github.com/kyegomez/swarms/issues" error_msg = f"❌ Failed to setup director: {str(e)}\n🔍 Traceback: {traceback.format_exc()}\n🐛 If this issue persists, please report it at: https://github.com/kyegomez/swarms/issues"
logger.error(error_msg) logger.error(error_msg)
raise e
def step(self, task: str, img: str = None, *args, **kwargs): def step(self, task: str, img: str = None, *args, **kwargs):
""" """
@ -417,9 +1059,13 @@ class HierarchicalSwarm:
try: try:
if self.verbose: if self.verbose:
logger.info( logger.info(
f"👣 Executing single step for task: {task[:100]}..." f"👣 Executing single step for task: {task}"
) )
# Update dashboard for director execution
if self.interactive and self.dashboard:
self.dashboard.update_director_status("PLANNING")
output = self.run_director(task=task, img=img) output = self.run_director(task=task, img=img)
# Parse the orders # Parse the orders
@ -430,6 +1076,20 @@ class HierarchicalSwarm:
f"📋 Parsed plan and {len(orders)} orders" f"📋 Parsed plan and {len(orders)} orders"
) )
# Update dashboard with plan and orders information
if self.interactive and self.dashboard:
self.dashboard.update_director_plan(plan)
# Convert orders to list of dicts for dashboard
orders_list = [
{
"agent_name": order.agent_name,
"task": order.task,
}
for order in orders
]
self.dashboard.update_director_orders(orders_list)
self.dashboard.update_director_status("EXECUTING")
# Execute the orders # Execute the orders
outputs = self.execute_orders(orders) outputs = self.execute_orders(orders)
@ -450,7 +1110,13 @@ class HierarchicalSwarm:
error_msg = f"❌ Failed to setup director: {str(e)}\n🔍 Traceback: {traceback.format_exc()}\n🐛 If this issue persists, please report it at: https://github.com/kyegomez/swarms/issues" error_msg = f"❌ Failed to setup director: {str(e)}\n🔍 Traceback: {traceback.format_exc()}\n🐛 If this issue persists, please report it at: https://github.com/kyegomez/swarms/issues"
logger.error(error_msg) logger.error(error_msg)
def run(self, task: str, img: str = None, *args, **kwargs): def run(
self,
task: Optional[str] = None,
img: Optional[str] = None,
*args,
**kwargs,
):
""" """
Execute the hierarchical swarm for the specified number of feedback loops. Execute the hierarchical swarm for the specified number of feedback loops.
@ -462,7 +1128,8 @@ class HierarchicalSwarm:
context from previous iterations to subsequent ones. context from previous iterations to subsequent ones.
Args: Args:
task (str): The initial task to be processed by the swarm. task (str, optional): The initial task to be processed by the swarm.
If None and interactive mode is enabled, will prompt for input.
img (str, optional): Optional image input for the agents. img (str, optional): Optional image input for the agents.
*args: Additional positional arguments. *args: Additional positional arguments.
**kwargs: Additional keyword arguments. **kwargs: Additional keyword arguments.
@ -475,9 +1142,23 @@ class HierarchicalSwarm:
Exception: If swarm execution fails. Exception: If swarm execution fails.
""" """
try: try:
# Handle interactive mode task input
if task is None and self.interactive:
task = self._get_interactive_task()
# if task is None:
# raise ValueError(
# "Task is required for swarm execution"
# )
current_loop = 0 current_loop = 0
last_output = None last_output = None
# Start dashboard if in interactive mode
if self.interactive and self.dashboard:
self.dashboard.start(self.max_loops)
self.dashboard.update_director_status("ACTIVE")
if self.verbose: if self.verbose:
logger.info( logger.info(
f"🚀 Starting hierarchical swarm run: {self.name}" f"🚀 Starting hierarchical swarm run: {self.name}"
@ -492,6 +1173,13 @@ class HierarchicalSwarm:
f"🔄 Loop {current_loop + 1}/{self.max_loops} - Processing task" f"🔄 Loop {current_loop + 1}/{self.max_loops} - Processing task"
) )
# Update dashboard loop counter
if self.interactive and self.dashboard:
self.dashboard.update_loop(current_loop + 1)
self.dashboard.update_director_status(
"PROCESSING"
)
# For the first loop, use the original task. # For the first loop, use the original task.
# For subsequent loops, use the feedback from the previous loop as context. # For subsequent loops, use the feedback from the previous loop as context.
if current_loop == 0: if current_loop == 0:
@ -527,6 +1215,11 @@ class HierarchicalSwarm:
content=f"--- Loop {current_loop}/{self.max_loops} completed ---", content=f"--- Loop {current_loop}/{self.max_loops} completed ---",
) )
# Stop dashboard if in interactive mode
if self.interactive and self.dashboard:
self.dashboard.update_director_status("COMPLETED")
self.dashboard.stop()
if self.verbose: if self.verbose:
logger.success( logger.success(
f"🎉 Hierarchical swarm run completed: {self.name}" f"🎉 Hierarchical swarm run completed: {self.name}"
@ -540,9 +1233,32 @@ class HierarchicalSwarm:
) )
except Exception as e: except Exception as e:
# Stop dashboard on error
if self.interactive and self.dashboard:
self.dashboard.update_director_status("ERROR")
self.dashboard.stop()
error_msg = f"❌ Failed to setup director: {str(e)}\n🔍 Traceback: {traceback.format_exc()}\n🐛 If this issue persists, please report it at: https://github.com/kyegomez/swarms/issues" error_msg = f"❌ Failed to setup director: {str(e)}\n🔍 Traceback: {traceback.format_exc()}\n🐛 If this issue persists, please report it at: https://github.com/kyegomez/swarms/issues"
logger.error(error_msg) logger.error(error_msg)
def _get_interactive_task(self) -> str:
"""
Get task input from user in interactive mode.
Returns:
str: The task input from the user
"""
if self.dashboard:
self.dashboard.console.print(
"\n[bold red]SWARMS CORPORATION[/bold red] - [bold white]TASK INPUT REQUIRED[/bold white]"
)
self.dashboard.console.print(
"[bold cyan]Enter your task for the hierarchical swarm:[/bold cyan]"
)
task = input("> ")
return task.strip()
def feedback_director(self, outputs: list): def feedback_director(self, outputs: list):
""" """
Generate feedback from the director based on agent outputs. Generate feedback from the director based on agent outputs.
@ -646,6 +1362,12 @@ class HierarchicalSwarm:
f"Agent '{agent_name}' not found in swarm. Available agents: {available_agents}" f"Agent '{agent_name}' not found in swarm. Available agents: {available_agents}"
) )
# Update dashboard for agent execution
if self.interactive and self.dashboard:
self.dashboard.update_agent_status(
agent_name, "RUNNING", task, "Executing task..."
)
output = agent.run( output = agent.run(
task=f"History: {self.conversation.get_str()} \n\n Task: {task}", task=f"History: {self.conversation.get_str()} \n\n Task: {task}",
*args, *args,
@ -661,6 +1383,12 @@ class HierarchicalSwarm:
return output return output
except Exception as e: except Exception as e:
# Update dashboard with error status
if self.interactive and self.dashboard:
self.dashboard.update_agent_status(
agent_name, "ERROR", task, f"Error: {str(e)}"
)
error_msg = f"❌ Failed to setup director: {str(e)}\n🔍 Traceback: {traceback.format_exc()}\n🐛 If this issue persists, please report it at: https://github.com/kyegomez/swarms/issues" error_msg = f"❌ Failed to setup director: {str(e)}\n🔍 Traceback: {traceback.format_exc()}\n🐛 If this issue persists, please report it at: https://github.com/kyegomez/swarms/issues"
logger.error(error_msg) logger.error(error_msg)
@ -805,8 +1533,9 @@ class HierarchicalSwarm:
) )
except Exception as e: except Exception as e:
error_msg = f"❌ Failed to setup director: {str(e)}\n🔍 Traceback: {traceback.format_exc()}\n🐛 If this issue persists, please report it at: https://github.com/kyegomez/swarms/issues" error_msg = f"❌ Failed to parse orders: {str(e)}\n🔍 Traceback: {traceback.format_exc()}\n🐛 If this issue persists, please report it at: https://github.com/kyegomez/swarms/issues"
logger.error(error_msg) logger.error(error_msg)
raise e
def execute_orders(self, orders: list): def execute_orders(self, orders: list):
""" """
@ -836,9 +1565,31 @@ class HierarchicalSwarm:
f"📋 Executing order {i+1}/{len(orders)}: {order.agent_name}" f"📋 Executing order {i+1}/{len(orders)}: {order.agent_name}"
) )
# Update dashboard for agent execution
if self.interactive and self.dashboard:
self.dashboard.update_agent_status(
order.agent_name,
"RUNNING",
order.task,
"Processing...",
)
output = self.call_single_agent( output = self.call_single_agent(
order.agent_name, order.task order.agent_name, order.task
) )
# Update dashboard with completed status
if self.interactive and self.dashboard:
# Always show full output without truncation
output_display = str(output)
self.dashboard.update_agent_status(
order.agent_name,
"COMPLETED",
order.task,
output_display,
)
outputs.append(output) outputs.append(output)
if self.verbose: if self.verbose:

@ -12,6 +12,7 @@ import psutil
from swarms.structs.agent import Agent from swarms.structs.agent import Agent
from swarms.structs.omni_agent_types import AgentType from swarms.structs.omni_agent_types import AgentType
from loguru import logger
@dataclass @dataclass
@ -21,9 +22,11 @@ class ResourceMetrics:
active_threads: int active_threads: int
def run_single_agent(agent: AgentType, task: str) -> Any: def run_single_agent(
agent: AgentType, task: str, *args, **kwargs
) -> Any:
"""Run a single agent synchronously""" """Run a single agent synchronously"""
return agent.run(task) return agent.run(task=task, *args, **kwargs)
async def run_agent_async( async def run_agent_async(
@ -138,6 +141,35 @@ def run_agents_concurrently_multiprocess(
return results return results
def batched_grid_agent_execution(
agents: List[AgentType],
tasks: List[str],
max_workers: int = None,
) -> List[Any]:
"""
Run multiple agents with different tasks concurrently.
"""
logger.info(
f"Batch Grid Execution with {len(agents)} and number of tasks: {len(tasks)}"
)
if len(agents) != len(tasks):
raise ValueError(
"The number of agents must match the number of tasks."
)
if max_workers is None:
max_workers = os.cpu_count()
results = []
for agent, task in zip(agents, tasks):
result = run_single_agent(agent, task)
results.append(result)
return results
def run_agents_sequentially( def run_agents_sequentially(
agents: List[AgentType], task: str agents: List[AgentType], task: str
) -> List[Any]: ) -> List[Any]:

@ -446,7 +446,6 @@ class SwarmRouter:
description=self.description, description=self.description,
model_name=self.council_judge_model_name, model_name=self.council_judge_model_name,
output_type=self.output_type, output_type=self.output_type,
base_agent=self.agents[0] if self.agents else None,
) )
def _create_interactive_group_chat(self, *args, **kwargs): def _create_interactive_group_chat(self, *args, **kwargs):
@ -704,17 +703,7 @@ class SwarmRouter:
) )
try: try:
if self.swarm_type == "CouncilAsAJudge": result = self.swarm.run(task=task, *args, **kwargs)
result = self.swarm.run(
task=task,
img=img,
imgs=imgs,
model_response=model_response,
*args,
**kwargs,
)
else:
result = self.swarm.run(task=task, *args, **kwargs)
log_execution( log_execution(
swarm_id=self.id, swarm_id=self.id,

@ -15,8 +15,7 @@ The test suite follows the Swarms testing philosophy:
import os import os
import pytest import pytest
import asyncio import asyncio
from unittest.mock import Mock, patch, MagicMock, AsyncMock from unittest.mock import Mock, patch, AsyncMock
from typing import List, Dict, Any, Optional
from swarms.structs.board_of_directors_swarm import ( from swarms.structs.board_of_directors_swarm import (
BoardOfDirectorsSwarm, BoardOfDirectorsSwarm,
@ -28,7 +27,6 @@ from swarms.structs.board_of_directors_swarm import (
BoardSpec, BoardSpec,
) )
from swarms.structs.agent import Agent from swarms.structs.agent import Agent
from swarms.structs.conversation import Conversation
# Test fixtures # Test fixtures
@ -50,7 +48,7 @@ def mock_board_member(mock_agent):
agent=mock_agent, agent=mock_agent,
role=BoardMemberRole.CHAIRMAN, role=BoardMemberRole.CHAIRMAN,
voting_weight=1.5, voting_weight=1.5,
expertise_areas=["leadership", "strategy"] expertise_areas=["leadership", "strategy"],
) )
@ -70,7 +68,11 @@ def sample_agents():
@pytest.fixture @pytest.fixture
def sample_board_members(sample_agents): def sample_board_members(sample_agents):
"""Create sample board members for testing.""" """Create sample board members for testing."""
roles = [BoardMemberRole.CHAIRMAN, BoardMemberRole.VICE_CHAIRMAN, BoardMemberRole.SECRETARY] roles = [
BoardMemberRole.CHAIRMAN,
BoardMemberRole.VICE_CHAIRMAN,
BoardMemberRole.SECRETARY,
]
board_members = [] board_members = []
for i, (agent, role) in enumerate(zip(sample_agents, roles)): for i, (agent, role) in enumerate(zip(sample_agents, roles)):
@ -78,7 +80,7 @@ def sample_board_members(sample_agents):
agent=agent, agent=agent,
role=role, role=role,
voting_weight=1.0 + (i * 0.2), voting_weight=1.0 + (i * 0.2),
expertise_areas=[f"expertise_{i+1}"] expertise_areas=[f"expertise_{i+1}"],
) )
board_members.append(board_member) board_members.append(board_member)
@ -92,7 +94,7 @@ def basic_board_swarm(sample_agents):
name="TestBoard", name="TestBoard",
agents=sample_agents, agents=sample_agents,
verbose=False, verbose=False,
max_loops=1 max_loops=1,
) )
@ -109,7 +111,7 @@ def configured_board_swarm(sample_agents, sample_board_members):
decision_threshold=0.7, decision_threshold=0.7,
enable_voting=True, enable_voting=True,
enable_consensus=True, enable_consensus=True,
max_workers=4 max_workers=4,
) )
@ -124,7 +126,9 @@ class TestBoardMemberRole:
assert BoardMemberRole.SECRETARY == "secretary" assert BoardMemberRole.SECRETARY == "secretary"
assert BoardMemberRole.TREASURER == "treasurer" assert BoardMemberRole.TREASURER == "treasurer"
assert BoardMemberRole.MEMBER == "member" assert BoardMemberRole.MEMBER == "member"
assert BoardMemberRole.EXECUTIVE_DIRECTOR == "executive_director" assert (
BoardMemberRole.EXECUTIVE_DIRECTOR == "executive_director"
)
class TestBoardDecisionType: class TestBoardDecisionType:
@ -135,7 +139,9 @@ class TestBoardDecisionType:
assert BoardDecisionType.UNANIMOUS == "unanimous" assert BoardDecisionType.UNANIMOUS == "unanimous"
assert BoardDecisionType.MAJORITY == "majority" assert BoardDecisionType.MAJORITY == "majority"
assert BoardDecisionType.CONSENSUS == "consensus" assert BoardDecisionType.CONSENSUS == "consensus"
assert BoardDecisionType.CHAIRMAN_DECISION == "chairman_decision" assert (
BoardDecisionType.CHAIRMAN_DECISION == "chairman_decision"
)
class TestBoardMember: class TestBoardMember:
@ -147,19 +153,21 @@ class TestBoardMember:
agent=mock_agent, agent=mock_agent,
role=BoardMemberRole.CHAIRMAN, role=BoardMemberRole.CHAIRMAN,
voting_weight=1.5, voting_weight=1.5,
expertise_areas=["leadership", "strategy"] expertise_areas=["leadership", "strategy"],
) )
assert board_member.agent == mock_agent assert board_member.agent == mock_agent
assert board_member.role == BoardMemberRole.CHAIRMAN assert board_member.role == BoardMemberRole.CHAIRMAN
assert board_member.voting_weight == 1.5 assert board_member.voting_weight == 1.5
assert board_member.expertise_areas == ["leadership", "strategy"] assert board_member.expertise_areas == [
"leadership",
"strategy",
]
def test_board_member_defaults(self, mock_agent): def test_board_member_defaults(self, mock_agent):
"""Test board member with default values.""" """Test board member with default values."""
board_member = BoardMember( board_member = BoardMember(
agent=mock_agent, agent=mock_agent, role=BoardMemberRole.MEMBER
role=BoardMemberRole.MEMBER
) )
assert board_member.voting_weight == 1.0 assert board_member.voting_weight == 1.0
@ -170,7 +178,7 @@ class TestBoardMember:
board_member = BoardMember( board_member = BoardMember(
agent=mock_agent, agent=mock_agent,
role=BoardMemberRole.MEMBER, role=BoardMemberRole.MEMBER,
expertise_areas=None expertise_areas=None,
) )
assert board_member.expertise_areas == [] assert board_member.expertise_areas == []
@ -186,7 +194,7 @@ class TestBoardOrder:
task="Test task", task="Test task",
priority=1, priority=1,
deadline="2024-01-01", deadline="2024-01-01",
assigned_by="Chairman" assigned_by="Chairman",
) )
assert order.agent_name == "TestAgent" assert order.agent_name == "TestAgent"
@ -197,10 +205,7 @@ class TestBoardOrder:
def test_board_order_defaults(self): def test_board_order_defaults(self):
"""Test board order with default values.""" """Test board order with default values."""
order = BoardOrder( order = BoardOrder(agent_name="TestAgent", task="Test task")
agent_name="TestAgent",
task="Test task"
)
assert order.priority == 3 assert order.priority == 3
assert order.deadline is None assert order.deadline is None
@ -213,14 +218,14 @@ class TestBoardOrder:
BoardOrder( BoardOrder(
agent_name="TestAgent", agent_name="TestAgent",
task="Test task", task="Test task",
priority=0 # Invalid priority priority=0, # Invalid priority
) )
with pytest.raises(ValueError): with pytest.raises(ValueError):
BoardOrder( BoardOrder(
agent_name="TestAgent", agent_name="TestAgent",
task="Test task", task="Test task",
priority=6 # Invalid priority priority=6, # Invalid priority
) )
@ -235,7 +240,7 @@ class TestBoardDecision:
votes_for=3, votes_for=3,
votes_against=1, votes_against=1,
abstentions=0, abstentions=0,
reasoning="The proposal aligns with our strategic goals" reasoning="The proposal aligns with our strategic goals",
) )
assert decision.decision_type == BoardDecisionType.MAJORITY assert decision.decision_type == BoardDecisionType.MAJORITY
@ -243,13 +248,16 @@ class TestBoardDecision:
assert decision.votes_for == 3 assert decision.votes_for == 3
assert decision.votes_against == 1 assert decision.votes_against == 1
assert decision.abstentions == 0 assert decision.abstentions == 0
assert decision.reasoning == "The proposal aligns with our strategic goals" assert (
decision.reasoning
== "The proposal aligns with our strategic goals"
)
def test_board_decision_defaults(self): def test_board_decision_defaults(self):
"""Test board decision with default values.""" """Test board decision with default values."""
decision = BoardDecision( decision = BoardDecision(
decision_type=BoardDecisionType.CONSENSUS, decision_type=BoardDecisionType.CONSENSUS,
decision="Test decision" decision="Test decision",
) )
assert decision.votes_for == 0 assert decision.votes_for == 0
@ -265,12 +273,12 @@ class TestBoardSpec:
"""Test creating a board spec.""" """Test creating a board spec."""
orders = [ orders = [
BoardOrder(agent_name="Agent1", task="Task 1"), BoardOrder(agent_name="Agent1", task="Task 1"),
BoardOrder(agent_name="Agent2", task="Task 2") BoardOrder(agent_name="Agent2", task="Task 2"),
] ]
decisions = [ decisions = [
BoardDecision( BoardDecision(
decision_type=BoardDecisionType.MAJORITY, decision_type=BoardDecisionType.MAJORITY,
decision="Decision 1" decision="Decision 1",
) )
] ]
@ -278,7 +286,7 @@ class TestBoardSpec:
plan="Test plan", plan="Test plan",
orders=orders, orders=orders,
decisions=decisions, decisions=decisions,
meeting_summary="Test meeting summary" meeting_summary="Test meeting summary",
) )
assert spec.plan == "Test plan" assert spec.plan == "Test plan"
@ -288,10 +296,7 @@ class TestBoardSpec:
def test_board_spec_defaults(self): def test_board_spec_defaults(self):
"""Test board spec with default values.""" """Test board spec with default values."""
spec = BoardSpec( spec = BoardSpec(plan="Test plan", orders=[])
plan="Test plan",
orders=[]
)
assert spec.decisions == [] assert spec.decisions == []
assert spec.meeting_summary == "" assert spec.meeting_summary == ""
@ -304,8 +309,7 @@ class TestBoardOfDirectorsSwarmInitialization:
def test_basic_initialization(self, sample_agents): def test_basic_initialization(self, sample_agents):
"""Test basic swarm initialization.""" """Test basic swarm initialization."""
swarm = BoardOfDirectorsSwarm( swarm = BoardOfDirectorsSwarm(
name="TestSwarm", name="TestSwarm", agents=sample_agents
agents=sample_agents
) )
assert swarm.name == "TestSwarm" assert swarm.name == "TestSwarm"
@ -314,7 +318,9 @@ class TestBoardOfDirectorsSwarmInitialization:
assert swarm.verbose is False assert swarm.verbose is False
assert swarm.decision_threshold == 0.6 assert swarm.decision_threshold == 0.6
def test_configured_initialization(self, sample_agents, sample_board_members): def test_configured_initialization(
self, sample_agents, sample_board_members
):
"""Test configured swarm initialization.""" """Test configured swarm initialization."""
swarm = BoardOfDirectorsSwarm( swarm = BoardOfDirectorsSwarm(
name="ConfiguredSwarm", name="ConfiguredSwarm",
@ -326,7 +332,7 @@ class TestBoardOfDirectorsSwarmInitialization:
decision_threshold=0.8, decision_threshold=0.8,
enable_voting=False, enable_voting=False,
enable_consensus=False, enable_consensus=False,
max_workers=8 max_workers=8,
) )
assert swarm.name == "ConfiguredSwarm" assert swarm.name == "ConfiguredSwarm"
@ -346,23 +352,41 @@ class TestBoardOfDirectorsSwarmInitialization:
assert len(swarm.board_members) == 3 assert len(swarm.board_members) == 3
assert swarm.board_members[0].role == BoardMemberRole.CHAIRMAN assert swarm.board_members[0].role == BoardMemberRole.CHAIRMAN
assert swarm.board_members[1].role == BoardMemberRole.VICE_CHAIRMAN assert (
assert swarm.board_members[2].role == BoardMemberRole.SECRETARY swarm.board_members[1].role
== BoardMemberRole.VICE_CHAIRMAN
)
assert (
swarm.board_members[2].role == BoardMemberRole.SECRETARY
)
def test_initialization_without_agents(self): def test_initialization_without_agents(self):
"""Test initialization without agents should raise error.""" """Test initialization without agents should raise error."""
with pytest.raises(ValueError, match="No agents found in the swarm"): with pytest.raises(
ValueError, match="No agents found in the swarm"
):
BoardOfDirectorsSwarm(agents=[]) BoardOfDirectorsSwarm(agents=[])
def test_initialization_with_invalid_max_loops(self, sample_agents): def test_initialization_with_invalid_max_loops(
self, sample_agents
):
"""Test initialization with invalid max_loops.""" """Test initialization with invalid max_loops."""
with pytest.raises(ValueError, match="Max loops must be greater than 0"): with pytest.raises(
ValueError, match="Max loops must be greater than 0"
):
BoardOfDirectorsSwarm(agents=sample_agents, max_loops=0) BoardOfDirectorsSwarm(agents=sample_agents, max_loops=0)
def test_initialization_with_invalid_decision_threshold(self, sample_agents): def test_initialization_with_invalid_decision_threshold(
self, sample_agents
):
"""Test initialization with invalid decision threshold.""" """Test initialization with invalid decision threshold."""
with pytest.raises(ValueError, match="Decision threshold must be between 0.0 and 1.0"): with pytest.raises(
BoardOfDirectorsSwarm(agents=sample_agents, decision_threshold=1.5) ValueError,
match="Decision threshold must be between 0.0 and 1.0",
):
BoardOfDirectorsSwarm(
agents=sample_agents, decision_threshold=1.5
)
class TestBoardOfDirectorsSwarmMethods: class TestBoardOfDirectorsSwarmMethods:
@ -373,8 +397,14 @@ class TestBoardOfDirectorsSwarmMethods:
swarm = BoardOfDirectorsSwarm(agents=sample_agents) swarm = BoardOfDirectorsSwarm(agents=sample_agents)
assert len(swarm.board_members) == 3 assert len(swarm.board_members) == 3
assert all(hasattr(member.agent, 'agent_name') for member in swarm.board_members) assert all(
assert all(hasattr(member.agent, 'run') for member in swarm.board_members) hasattr(member.agent, "agent_name")
for member in swarm.board_members
)
assert all(
hasattr(member.agent, "run")
for member in swarm.board_members
)
def test_get_chairman_prompt(self, sample_agents): def test_get_chairman_prompt(self, sample_agents):
"""Test chairman prompt generation.""" """Test chairman prompt generation."""
@ -412,12 +442,16 @@ class TestBoardOfDirectorsSwarmMethods:
assert "Secretary" in info assert "Secretary" in info
assert "expertise" in info assert "expertise" in info
def test_add_board_member(self, basic_board_swarm, mock_board_member): def test_add_board_member(
self, basic_board_swarm, mock_board_member
):
"""Test adding a board member.""" """Test adding a board member."""
initial_count = len(basic_board_swarm.board_members) initial_count = len(basic_board_swarm.board_members)
basic_board_swarm.add_board_member(mock_board_member) basic_board_swarm.add_board_member(mock_board_member)
assert len(basic_board_swarm.board_members) == initial_count + 1 assert (
len(basic_board_swarm.board_members) == initial_count + 1
)
assert mock_board_member in basic_board_swarm.board_members assert mock_board_member in basic_board_swarm.board_members
def test_remove_board_member(self, configured_board_swarm): def test_remove_board_member(self, configured_board_swarm):
@ -428,19 +462,29 @@ class TestBoardOfDirectorsSwarmMethods:
initial_count = len(configured_board_swarm.board_members) initial_count = len(configured_board_swarm.board_members)
configured_board_swarm.remove_board_member(member_name) configured_board_swarm.remove_board_member(member_name)
assert len(configured_board_swarm.board_members) == initial_count - 1 assert (
assert member_to_remove not in configured_board_swarm.board_members len(configured_board_swarm.board_members)
== initial_count - 1
)
assert (
member_to_remove
not in configured_board_swarm.board_members
)
def test_get_board_member(self, configured_board_swarm): def test_get_board_member(self, configured_board_swarm):
"""Test getting a board member by name.""" """Test getting a board member by name."""
member = configured_board_swarm.board_members[0] member = configured_board_swarm.board_members[0]
member_name = member.agent.agent_name member_name = member.agent.agent_name
found_member = configured_board_swarm.get_board_member(member_name) found_member = configured_board_swarm.get_board_member(
member_name
)
assert found_member == member assert found_member == member
# Test with non-existent member # Test with non-existent member
not_found = configured_board_swarm.get_board_member("NonExistent") not_found = configured_board_swarm.get_board_member(
"NonExistent"
)
assert not_found is None assert not_found is None
def test_get_board_summary(self, configured_board_swarm): def test_get_board_summary(self, configured_board_swarm):
@ -462,10 +506,14 @@ class TestBoardOfDirectorsSwarmMethods:
class TestBoardMeetingOperations: class TestBoardMeetingOperations:
"""Test board meeting operations.""" """Test board meeting operations."""
def test_create_board_meeting_prompt(self, configured_board_swarm): def test_create_board_meeting_prompt(
self, configured_board_swarm
):
"""Test board meeting prompt creation.""" """Test board meeting prompt creation."""
task = "Test task for board meeting" task = "Test task for board meeting"
prompt = configured_board_swarm._create_board_meeting_prompt(task) prompt = configured_board_swarm._create_board_meeting_prompt(
task
)
assert task in prompt assert task in prompt
assert "BOARD OF DIRECTORS MEETING" in prompt assert "BOARD OF DIRECTORS MEETING" in prompt
@ -477,23 +525,33 @@ class TestBoardMeetingOperations:
"""Test board discussion conduction.""" """Test board discussion conduction."""
prompt = "Test board meeting prompt" prompt = "Test board meeting prompt"
with patch.object(configured_board_swarm.board_members[0].agent, 'run') as mock_run: with patch.object(
configured_board_swarm.board_members[0].agent, "run"
) as mock_run:
mock_run.return_value = "Board discussion result" mock_run.return_value = "Board discussion result"
result = configured_board_swarm._conduct_board_discussion(prompt) result = configured_board_swarm._conduct_board_discussion(
prompt
)
assert result == "Board discussion result" assert result == "Board discussion result"
mock_run.assert_called_once_with(task=prompt, img=None) mock_run.assert_called_once_with(task=prompt, img=None)
def test_conduct_board_discussion_no_chairman(self, sample_agents): def test_conduct_board_discussion_no_chairman(
self, sample_agents
):
"""Test board discussion when no chairman is found.""" """Test board discussion when no chairman is found."""
swarm = BoardOfDirectorsSwarm(agents=sample_agents) swarm = BoardOfDirectorsSwarm(agents=sample_agents)
# Remove all board members # Remove all board members
swarm.board_members = [] swarm.board_members = []
with pytest.raises(ValueError, match="No chairman found in board members"): with pytest.raises(
ValueError, match="No chairman found in board members"
):
swarm._conduct_board_discussion("Test prompt") swarm._conduct_board_discussion("Test prompt")
def test_parse_board_decisions_valid_json(self, configured_board_swarm): def test_parse_board_decisions_valid_json(
self, configured_board_swarm
):
"""Test parsing valid JSON board decisions.""" """Test parsing valid JSON board decisions."""
valid_json = """ valid_json = """
{ {
@ -520,7 +578,9 @@ class TestBoardMeetingOperations:
} }
""" """
result = configured_board_swarm._parse_board_decisions(valid_json) result = configured_board_swarm._parse_board_decisions(
valid_json
)
assert isinstance(result, BoardSpec) assert isinstance(result, BoardSpec)
assert result.plan == "Test plan" assert result.plan == "Test plan"
@ -528,33 +588,46 @@ class TestBoardMeetingOperations:
assert len(result.decisions) == 1 assert len(result.decisions) == 1
assert result.meeting_summary == "Test summary" assert result.meeting_summary == "Test summary"
def test_parse_board_decisions_invalid_json(self, configured_board_swarm): def test_parse_board_decisions_invalid_json(
self, configured_board_swarm
):
"""Test parsing invalid JSON board decisions.""" """Test parsing invalid JSON board decisions."""
invalid_json = "Invalid JSON content" invalid_json = "Invalid JSON content"
result = configured_board_swarm._parse_board_decisions(invalid_json) result = configured_board_swarm._parse_board_decisions(
invalid_json
)
assert isinstance(result, BoardSpec) assert isinstance(result, BoardSpec)
assert result.plan == invalid_json assert result.plan == invalid_json
assert len(result.orders) == 0 assert len(result.orders) == 0
assert len(result.decisions) == 0 assert len(result.decisions) == 0
assert result.meeting_summary == "Parsing failed, using raw output" assert (
result.meeting_summary
== "Parsing failed, using raw output"
)
def test_run_board_meeting(self, configured_board_swarm): def test_run_board_meeting(self, configured_board_swarm):
"""Test running a complete board meeting.""" """Test running a complete board meeting."""
task = "Test board meeting task" task = "Test board meeting task"
with patch.object(configured_board_swarm, '_conduct_board_discussion') as mock_discuss: with patch.object(
with patch.object(configured_board_swarm, '_parse_board_decisions') as mock_parse: configured_board_swarm, "_conduct_board_discussion"
) as mock_discuss:
with patch.object(
configured_board_swarm, "_parse_board_decisions"
) as mock_parse:
mock_discuss.return_value = "Board discussion" mock_discuss.return_value = "Board discussion"
mock_parse.return_value = BoardSpec( mock_parse.return_value = BoardSpec(
plan="Test plan", plan="Test plan",
orders=[], orders=[],
decisions=[], decisions=[],
meeting_summary="Test summary" meeting_summary="Test summary",
) )
result = configured_board_swarm.run_board_meeting(task) result = configured_board_swarm.run_board_meeting(
task
)
assert isinstance(result, BoardSpec) assert isinstance(result, BoardSpec)
mock_discuss.assert_called_once() mock_discuss.assert_called_once()
@ -569,17 +642,27 @@ class TestTaskExecution:
agent_name = "Agent1" agent_name = "Agent1"
task = "Test task" task = "Test task"
with patch.object(configured_board_swarm.agents[0], 'run') as mock_run: with patch.object(
configured_board_swarm.agents[0], "run"
) as mock_run:
mock_run.return_value = "Agent response" mock_run.return_value = "Agent response"
result = configured_board_swarm._call_single_agent(agent_name, task) result = configured_board_swarm._call_single_agent(
agent_name, task
)
assert result == "Agent response" assert result == "Agent response"
mock_run.assert_called_once() mock_run.assert_called_once()
def test_call_single_agent_not_found(self, configured_board_swarm): def test_call_single_agent_not_found(
self, configured_board_swarm
):
"""Test calling a non-existent agent.""" """Test calling a non-existent agent."""
with pytest.raises(ValueError, match="Agent 'NonExistent' not found"): with pytest.raises(
configured_board_swarm._call_single_agent("NonExistent", "Test task") ValueError, match="Agent 'NonExistent' not found"
):
configured_board_swarm._call_single_agent(
"NonExistent", "Test task"
)
def test_execute_single_order(self, configured_board_swarm): def test_execute_single_order(self, configured_board_swarm):
"""Test executing a single order.""" """Test executing a single order."""
@ -587,27 +670,36 @@ class TestTaskExecution:
agent_name="Agent1", agent_name="Agent1",
task="Test order task", task="Test order task",
priority=1, priority=1,
assigned_by="Chairman" assigned_by="Chairman",
) )
with patch.object(configured_board_swarm, '_call_single_agent') as mock_call: with patch.object(
configured_board_swarm, "_call_single_agent"
) as mock_call:
mock_call.return_value = "Order execution result" mock_call.return_value = "Order execution result"
result = configured_board_swarm._execute_single_order(order) result = configured_board_swarm._execute_single_order(
order
)
assert result == "Order execution result" assert result == "Order execution result"
mock_call.assert_called_once_with( mock_call.assert_called_once_with(
agent_name="Agent1", agent_name="Agent1", task="Test order task"
task="Test order task"
) )
def test_execute_orders(self, configured_board_swarm): def test_execute_orders(self, configured_board_swarm):
"""Test executing multiple orders.""" """Test executing multiple orders."""
orders = [ orders = [
BoardOrder(agent_name="Agent1", task="Task 1", priority=1), BoardOrder(
BoardOrder(agent_name="Agent2", task="Task 2", priority=2), agent_name="Agent1", task="Task 1", priority=1
),
BoardOrder(
agent_name="Agent2", task="Task 2", priority=2
),
] ]
with patch.object(configured_board_swarm, '_execute_single_order') as mock_execute: with patch.object(
configured_board_swarm, "_execute_single_order"
) as mock_execute:
mock_execute.side_effect = ["Result 1", "Result 2"] mock_execute.side_effect = ["Result 1", "Result 2"]
results = configured_board_swarm._execute_orders(orders) results = configured_board_swarm._execute_orders(orders)
@ -621,12 +713,16 @@ class TestTaskExecution:
"""Test generating board feedback.""" """Test generating board feedback."""
outputs = [ outputs = [
{"agent_name": "Agent1", "output": "Output 1"}, {"agent_name": "Agent1", "output": "Output 1"},
{"agent_name": "Agent2", "output": "Output 2"} {"agent_name": "Agent2", "output": "Output 2"},
] ]
with patch.object(configured_board_swarm.board_members[0].agent, 'run') as mock_run: with patch.object(
configured_board_swarm.board_members[0].agent, "run"
) as mock_run:
mock_run.return_value = "Board feedback" mock_run.return_value = "Board feedback"
result = configured_board_swarm._generate_board_feedback(outputs) result = configured_board_swarm._generate_board_feedback(
outputs
)
assert result == "Board feedback" assert result == "Board feedback"
mock_run.assert_called_once() mock_run.assert_called_once()
@ -636,7 +732,9 @@ class TestTaskExecution:
swarm = BoardOfDirectorsSwarm(agents=sample_agents) swarm = BoardOfDirectorsSwarm(agents=sample_agents)
swarm.board_members = [] # Remove all board members swarm.board_members = [] # Remove all board members
with pytest.raises(ValueError, match="No chairman found for feedback"): with pytest.raises(
ValueError, match="No chairman found for feedback"
):
swarm._generate_board_feedback([]) swarm._generate_board_feedback([])
@ -647,22 +745,36 @@ class TestStepAndRunMethods:
"""Test the step method.""" """Test the step method."""
task = "Test step task" task = "Test step task"
with patch.object(configured_board_swarm, 'run_board_meeting') as mock_meeting: with patch.object(
with patch.object(configured_board_swarm, '_execute_orders') as mock_execute: configured_board_swarm, "run_board_meeting"
with patch.object(configured_board_swarm, '_generate_board_feedback') as mock_feedback: ) as mock_meeting:
with patch.object(
configured_board_swarm, "_execute_orders"
) as mock_execute:
with patch.object(
configured_board_swarm, "_generate_board_feedback"
) as mock_feedback:
mock_meeting.return_value = BoardSpec( mock_meeting.return_value = BoardSpec(
plan="Test plan", plan="Test plan",
orders=[BoardOrder(agent_name="Agent1", task="Task 1")], orders=[
BoardOrder(
agent_name="Agent1", task="Task 1"
)
],
decisions=[], decisions=[],
meeting_summary="Test summary" meeting_summary="Test summary",
) )
mock_execute.return_value = [{"agent_name": "Agent1", "output": "Result"}] mock_execute.return_value = [
{"agent_name": "Agent1", "output": "Result"}
]
mock_feedback.return_value = "Board feedback" mock_feedback.return_value = "Board feedback"
result = configured_board_swarm.step(task) result = configured_board_swarm.step(task)
assert result == "Board feedback" assert result == "Board feedback"
mock_meeting.assert_called_once_with(task=task, img=None) mock_meeting.assert_called_once_with(
task=task, img=None
)
mock_execute.assert_called_once() mock_execute.assert_called_once()
mock_feedback.assert_called_once() mock_feedback.assert_called_once()
@ -671,30 +783,44 @@ class TestStepAndRunMethods:
configured_board_swarm.board_feedback_on = False configured_board_swarm.board_feedback_on = False
task = "Test step task" task = "Test step task"
with patch.object(configured_board_swarm, 'run_board_meeting') as mock_meeting: with patch.object(
with patch.object(configured_board_swarm, '_execute_orders') as mock_execute: configured_board_swarm, "run_board_meeting"
) as mock_meeting:
with patch.object(
configured_board_swarm, "_execute_orders"
) as mock_execute:
mock_meeting.return_value = BoardSpec( mock_meeting.return_value = BoardSpec(
plan="Test plan", plan="Test plan",
orders=[BoardOrder(agent_name="Agent1", task="Task 1")], orders=[
BoardOrder(agent_name="Agent1", task="Task 1")
],
decisions=[], decisions=[],
meeting_summary="Test summary" meeting_summary="Test summary",
) )
mock_execute.return_value = [{"agent_name": "Agent1", "output": "Result"}] mock_execute.return_value = [
{"agent_name": "Agent1", "output": "Result"}
]
result = configured_board_swarm.step(task) result = configured_board_swarm.step(task)
assert result == [{"agent_name": "Agent1", "output": "Result"}] assert result == [
{"agent_name": "Agent1", "output": "Result"}
]
def test_run_method(self, configured_board_swarm): def test_run_method(self, configured_board_swarm):
"""Test the run method.""" """Test the run method."""
task = "Test run task" task = "Test run task"
with patch.object(configured_board_swarm, 'step') as mock_step: with patch.object(
with patch.object(configured_board_swarm, 'conversation') as mock_conversation: configured_board_swarm, "step"
) as mock_step:
with patch.object(
configured_board_swarm, "conversation"
) as mock_conversation:
mock_step.return_value = "Step result" mock_step.return_value = "Step result"
mock_conversation.add = Mock() mock_conversation.add = Mock()
result = configured_board_swarm.run(task) configured_board_swarm.run(task)
assert mock_step.call_count == 2 # max_loops = 2 assert mock_step.call_count == 2 # max_loops = 2
assert mock_conversation.add.call_count == 2 assert mock_conversation.add.call_count == 2
@ -703,7 +829,7 @@ class TestStepAndRunMethods:
"""Test the async run method.""" """Test the async run method."""
task = "Test async run task" task = "Test async run task"
with patch.object(configured_board_swarm, 'run') as mock_run: with patch.object(configured_board_swarm, "run") as mock_run:
mock_run.return_value = "Async result" mock_run.return_value = "Async result"
async def test_async(): async def test_async():
@ -722,9 +848,7 @@ class TestBoardOfDirectorsSwarmIntegration:
def test_full_workflow_integration(self, sample_agents): def test_full_workflow_integration(self, sample_agents):
"""Test full workflow integration.""" """Test full workflow integration."""
swarm = BoardOfDirectorsSwarm( swarm = BoardOfDirectorsSwarm(
agents=sample_agents, agents=sample_agents, verbose=False, max_loops=1
verbose=False,
max_loops=1
) )
task = "Create a simple report" task = "Create a simple report"
@ -761,7 +885,9 @@ class TestBoardOfDirectorsSwarmIntegration:
} }
""" """
with patch.object(swarm.board_members[0].agent, 'run') as mock_run: with patch.object(
swarm.board_members[0].agent, "run"
) as mock_run:
mock_run.return_value = mock_board_output mock_run.return_value = mock_board_output
result = swarm.run(task) result = swarm.run(task)
@ -777,7 +903,7 @@ class TestBoardOfDirectorsSwarmIntegration:
agent=sample_agents[0], agent=sample_agents[0],
role=BoardMemberRole.MEMBER, role=BoardMemberRole.MEMBER,
voting_weight=1.0, voting_weight=1.0,
expertise_areas=["testing"] expertise_areas=["testing"],
) )
initial_count = len(swarm.board_members) initial_count = len(swarm.board_members)
@ -790,7 +916,9 @@ class TestBoardOfDirectorsSwarmIntegration:
assert len(swarm.board_members) == initial_count assert len(swarm.board_members) == initial_count
# Test getting board member # Test getting board member
member = swarm.get_board_member(swarm.board_members[0].agent.agent_name) member = swarm.get_board_member(
swarm.board_members[0].agent.agent_name
)
assert member is not None assert member is not None
@ -798,21 +926,33 @@ class TestBoardOfDirectorsSwarmIntegration:
@pytest.mark.parametrize("max_loops", [1, 2, 3]) @pytest.mark.parametrize("max_loops", [1, 2, 3])
def test_max_loops_parameterization(sample_agents, max_loops): def test_max_loops_parameterization(sample_agents, max_loops):
"""Test swarm with different max_loops values.""" """Test swarm with different max_loops values."""
swarm = BoardOfDirectorsSwarm(agents=sample_agents, max_loops=max_loops) swarm = BoardOfDirectorsSwarm(
agents=sample_agents, max_loops=max_loops
)
assert swarm.max_loops == max_loops assert swarm.max_loops == max_loops
@pytest.mark.parametrize("decision_threshold", [0.5, 0.6, 0.7, 0.8, 0.9]) @pytest.mark.parametrize(
def test_decision_threshold_parameterization(sample_agents, decision_threshold): "decision_threshold", [0.5, 0.6, 0.7, 0.8, 0.9]
)
def test_decision_threshold_parameterization(
sample_agents, decision_threshold
):
"""Test swarm with different decision threshold values.""" """Test swarm with different decision threshold values."""
swarm = BoardOfDirectorsSwarm(agents=sample_agents, decision_threshold=decision_threshold) swarm = BoardOfDirectorsSwarm(
agents=sample_agents, decision_threshold=decision_threshold
)
assert swarm.decision_threshold == decision_threshold assert swarm.decision_threshold == decision_threshold
@pytest.mark.parametrize("board_model", ["gpt-4o-mini", "gpt-4", "claude-3-sonnet"]) @pytest.mark.parametrize(
"board_model", ["gpt-4o-mini", "gpt-4", "claude-3-sonnet"]
)
def test_board_model_parameterization(sample_agents, board_model): def test_board_model_parameterization(sample_agents, board_model):
"""Test swarm with different board models.""" """Test swarm with different board models."""
swarm = BoardOfDirectorsSwarm(agents=sample_agents, board_model_name=board_model) swarm = BoardOfDirectorsSwarm(
agents=sample_agents, board_model_name=board_model
)
assert swarm.board_model_name == board_model assert swarm.board_model_name == board_model
@ -825,28 +965,50 @@ class TestBoardOfDirectorsSwarmErrorHandling:
with pytest.raises(ValueError): with pytest.raises(ValueError):
BoardOfDirectorsSwarm(agents=[]) BoardOfDirectorsSwarm(agents=[])
def test_board_meeting_error_handling(self, configured_board_swarm): def test_board_meeting_error_handling(
self, configured_board_swarm
):
"""Test error handling during board meeting.""" """Test error handling during board meeting."""
with patch.object(configured_board_swarm, '_conduct_board_discussion') as mock_discuss: with patch.object(
mock_discuss.side_effect = Exception("Board meeting failed") configured_board_swarm, "_conduct_board_discussion"
) as mock_discuss:
mock_discuss.side_effect = Exception(
"Board meeting failed"
)
with pytest.raises(Exception, match="Board meeting failed"): with pytest.raises(
Exception, match="Board meeting failed"
):
configured_board_swarm.run_board_meeting("Test task") configured_board_swarm.run_board_meeting("Test task")
def test_task_execution_error_handling(self, configured_board_swarm): def test_task_execution_error_handling(
self, configured_board_swarm
):
"""Test error handling during task execution.""" """Test error handling during task execution."""
with patch.object(configured_board_swarm, '_call_single_agent') as mock_call: with patch.object(
configured_board_swarm, "_call_single_agent"
) as mock_call:
mock_call.side_effect = Exception("Task execution failed") mock_call.side_effect = Exception("Task execution failed")
with pytest.raises(Exception, match="Task execution failed"): with pytest.raises(
configured_board_swarm._call_single_agent("Agent1", "Test task") Exception, match="Task execution failed"
):
configured_board_swarm._call_single_agent(
"Agent1", "Test task"
)
def test_order_execution_error_handling(self, configured_board_swarm): def test_order_execution_error_handling(
self, configured_board_swarm
):
"""Test error handling during order execution.""" """Test error handling during order execution."""
orders = [BoardOrder(agent_name="Agent1", task="Task 1")] orders = [BoardOrder(agent_name="Agent1", task="Task 1")]
with patch.object(configured_board_swarm, '_execute_single_order') as mock_execute: with patch.object(
mock_execute.side_effect = Exception("Order execution failed") configured_board_swarm, "_execute_single_order"
) as mock_execute:
mock_execute.side_effect = Exception(
"Order execution failed"
)
# Should not raise exception, but log error # Should not raise exception, but log error
results = configured_board_swarm._execute_orders(orders) results = configured_board_swarm._execute_orders(orders)
@ -863,9 +1025,7 @@ class TestBoardOfDirectorsSwarmPerformance:
import time import time
swarm = BoardOfDirectorsSwarm( swarm = BoardOfDirectorsSwarm(
agents=sample_agents, agents=sample_agents, max_workers=3, verbose=False
max_workers=3,
verbose=False
) )
# Create multiple orders # Create multiple orders
@ -876,15 +1036,21 @@ class TestBoardOfDirectorsSwarmPerformance:
start_time = time.time() start_time = time.time()
with patch.object(swarm, '_execute_single_order') as mock_execute: with patch.object(
mock_execute.side_effect = lambda order: f"Result for {order.task}" swarm, "_execute_single_order"
) as mock_execute:
mock_execute.side_effect = (
lambda order: f"Result for {order.task}"
)
results = swarm._execute_orders(orders) results = swarm._execute_orders(orders)
end_time = time.time() end_time = time.time()
execution_time = end_time - start_time execution_time = end_time - start_time
assert len(results) == 3 assert len(results) == 3
assert execution_time < 1.0 # Should complete quickly with parallel execution assert (
execution_time < 1.0
) # Should complete quickly with parallel execution
def test_memory_usage(self, sample_agents): def test_memory_usage(self, sample_agents):
"""Test memory usage characteristics.""" """Test memory usage characteristics."""
@ -898,9 +1064,7 @@ class TestBoardOfDirectorsSwarmPerformance:
swarms = [] swarms = []
for i in range(5): for i in range(5):
swarm = BoardOfDirectorsSwarm( swarm = BoardOfDirectorsSwarm(
agents=sample_agents, agents=sample_agents, name=f"Swarm{i}", verbose=False
name=f"Swarm{i}",
verbose=False
) )
swarms.append(swarm) swarms.append(swarm)
@ -917,49 +1081,69 @@ class TestBoardOfDirectorsSwarmConfiguration:
def test_verbose_configuration(self, sample_agents): def test_verbose_configuration(self, sample_agents):
"""Test verbose configuration.""" """Test verbose configuration."""
swarm = BoardOfDirectorsSwarm(agents=sample_agents, verbose=True) swarm = BoardOfDirectorsSwarm(
agents=sample_agents, verbose=True
)
assert swarm.verbose is True assert swarm.verbose is True
swarm = BoardOfDirectorsSwarm(agents=sample_agents, verbose=False) swarm = BoardOfDirectorsSwarm(
agents=sample_agents, verbose=False
)
assert swarm.verbose is False assert swarm.verbose is False
def test_collaboration_prompt_configuration(self, sample_agents): def test_collaboration_prompt_configuration(self, sample_agents):
"""Test collaboration prompt configuration.""" """Test collaboration prompt configuration."""
swarm = BoardOfDirectorsSwarm(agents=sample_agents, add_collaboration_prompt=True) swarm = BoardOfDirectorsSwarm(
agents=sample_agents, add_collaboration_prompt=True
)
assert swarm.add_collaboration_prompt is True assert swarm.add_collaboration_prompt is True
swarm = BoardOfDirectorsSwarm(agents=sample_agents, add_collaboration_prompt=False) swarm = BoardOfDirectorsSwarm(
agents=sample_agents, add_collaboration_prompt=False
)
assert swarm.add_collaboration_prompt is False assert swarm.add_collaboration_prompt is False
def test_board_feedback_configuration(self, sample_agents): def test_board_feedback_configuration(self, sample_agents):
"""Test board feedback configuration.""" """Test board feedback configuration."""
swarm = BoardOfDirectorsSwarm(agents=sample_agents, board_feedback_on=True) swarm = BoardOfDirectorsSwarm(
agents=sample_agents, board_feedback_on=True
)
assert swarm.board_feedback_on is True assert swarm.board_feedback_on is True
swarm = BoardOfDirectorsSwarm(agents=sample_agents, board_feedback_on=False) swarm = BoardOfDirectorsSwarm(
agents=sample_agents, board_feedback_on=False
)
assert swarm.board_feedback_on is False assert swarm.board_feedback_on is False
def test_voting_configuration(self, sample_agents): def test_voting_configuration(self, sample_agents):
"""Test voting configuration.""" """Test voting configuration."""
swarm = BoardOfDirectorsSwarm(agents=sample_agents, enable_voting=True) swarm = BoardOfDirectorsSwarm(
agents=sample_agents, enable_voting=True
)
assert swarm.enable_voting is True assert swarm.enable_voting is True
swarm = BoardOfDirectorsSwarm(agents=sample_agents, enable_voting=False) swarm = BoardOfDirectorsSwarm(
agents=sample_agents, enable_voting=False
)
assert swarm.enable_voting is False assert swarm.enable_voting is False
def test_consensus_configuration(self, sample_agents): def test_consensus_configuration(self, sample_agents):
"""Test consensus configuration.""" """Test consensus configuration."""
swarm = BoardOfDirectorsSwarm(agents=sample_agents, enable_consensus=True) swarm = BoardOfDirectorsSwarm(
agents=sample_agents, enable_consensus=True
)
assert swarm.enable_consensus is True assert swarm.enable_consensus is True
swarm = BoardOfDirectorsSwarm(agents=sample_agents, enable_consensus=False) swarm = BoardOfDirectorsSwarm(
agents=sample_agents, enable_consensus=False
)
assert swarm.enable_consensus is False assert swarm.enable_consensus is False
# Real integration tests (skipped if no API key) # Real integration tests (skipped if no API key)
@pytest.mark.skipif( @pytest.mark.skipif(
not os.getenv("OPENAI_API_KEY"), not os.getenv("OPENAI_API_KEY"),
reason="OpenAI API key not available" reason="OpenAI API key not available",
) )
class TestBoardOfDirectorsSwarmRealIntegration: class TestBoardOfDirectorsSwarmRealIntegration:
"""Real integration tests for BoardOfDirectorsSwarm.""" """Real integration tests for BoardOfDirectorsSwarm."""
@ -972,20 +1156,18 @@ class TestBoardOfDirectorsSwarmRealIntegration:
agent_name="Researcher", agent_name="Researcher",
agent_description="Research analyst", agent_description="Research analyst",
model_name="gpt-4o-mini", model_name="gpt-4o-mini",
max_loops=1 max_loops=1,
), ),
Agent( Agent(
agent_name="Writer", agent_name="Writer",
agent_description="Content writer", agent_description="Content writer",
model_name="gpt-4o-mini", model_name="gpt-4o-mini",
max_loops=1 max_loops=1,
) ),
] ]
swarm = BoardOfDirectorsSwarm( swarm = BoardOfDirectorsSwarm(
agents=agents, agents=agents, verbose=False, max_loops=1
verbose=False,
max_loops=1
) )
task = "Create a brief market analysis report" task = "Create a brief market analysis report"
@ -1003,7 +1185,7 @@ class TestBoardOfDirectorsSwarmRealIntegration:
agent_name="TestAgent", agent_name="TestAgent",
agent_description="Test agent", agent_description="Test agent",
model_name="gpt-4o-mini", model_name="gpt-4o-mini",
max_loops=1 max_loops=1,
) )
] ]

Loading…
Cancel
Save