diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index 129c4eda..c321de28 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -314,6 +314,12 @@ nav: - VLLM: "swarms/examples/vllm_integration.md" - Llama4: "swarms/examples/llama4.md" + - Agent Examples: + - Basic Agent: "swarms/examples/basic_agent.md" + - Agents with Callable Tools: "swarms/examples/agent_with_tools.md" + # - Agent With MCP Integration: "swarms/examples/agent_with_mcp.md" + + - Swarms Tools: - Agent with Yahoo Finance: "swarms/examples/yahoo_finance.md" - Twitter Agents: "swarms_tools/twitter.md" @@ -322,12 +328,12 @@ nav: - Agent with HTX + CoinGecko Function Calling: "swarms/examples/swarms_tools_htx_gecko.md" - Lumo: "swarms/examples/lumo.md" - Quant Crypto Agent: "swarms/examples/quant_crypto_agent.md" + - Multi-Agent Collaboration: - Unique Swarms: "swarms/examples/unique_swarms.md" - Swarms DAO: "swarms/examples/swarms_dao.md" - Hybrid Hierarchical-Cluster Swarm Example: "swarms/examples/hhcs_examples.md" - Group Chat Example: "swarms/examples/groupchat_example.md" - - Meme Agent Builder: "swarms/examples/meme_agents.md" - Sequential Workflow Example: "swarms/examples/sequential_example.md" - ConcurrentWorkflow with VLLM Agents: "swarms/examples/vllm.md" - External Agents: diff --git a/docs/swarms/examples/agent_with_tools.md b/docs/swarms/examples/agent_with_tools.md new file mode 100644 index 00000000..35e06bd8 --- /dev/null +++ b/docs/swarms/examples/agent_with_tools.md @@ -0,0 +1,646 @@ +# Basic Agent Example + +This tutorial demonstrates how to create and use tools (callables) with the Swarms framework. Tools are Python functions that your agent can call to perform specific tasks, interact with external services, or process data. We'll show you how to build well-structured tools and integrate them with your agent. + +## Prerequisites + +- Python 3.7+ + +- OpenAI API key + +- Swarms library + +## Building Tools for Your Agent + +Tools are functions that your agent can use to interact with external services, process data, or perform specific tasks. Here's a guide on how to build effective tools for your agent: + +### Tool Structure Best Practices + +1. **Type Hints**: Always use type hints to specify input and output types + +2. **Docstrings**: Include comprehensive docstrings with description, args, returns, and examples + +3. **Error Handling**: Implement proper error handling and return consistent JSON responses + +4. **Rate Limiting**: Include rate limiting when dealing with APIs + +5. **Input Validation**: Validate input parameters before processing + +### Example Tool Template + +Here's a template for creating a well-structured tool: + +```python +from typing import Optional, Dict, Any +import json + +def example_tool(param1: str, param2: Optional[int] = None) -> str: + """ + Brief description of what the tool does. + + Args: + param1 (str): Description of first parameter + param2 (Optional[int]): Description of optional parameter + + Returns: + str: JSON formatted string containing the result + + Raises: + ValueError: Description of when this error occurs + RequestException: Description of when this error occurs + + Example: + >>> result = example_tool("test", 123) + >>> print(result) + {"status": "success", "data": {"key": "value"}} + """ + try: + # Input validation + if not isinstance(param1, str): + raise ValueError("param1 must be a string") + + # Main logic + result: Dict[str, Any] = { + "status": "success", + "data": { + "param1": param1, + "param2": param2 + } + } + + # Return JSON string + return json.dumps(result, indent=2) + + except ValueError as e: + return json.dumps({"error": f"Validation error: {str(e)}"}) + except Exception as e: + return json.dumps({"error": f"Unexpected error: {str(e)}"}) +``` + +### Building API Integration Tools + +When building tools that interact with external APIs: + +1. **API Client Setup**: + +```python +def get_api_data(endpoint: str, params: Dict[str, Any]) -> str: + """ + Generic API data fetcher with proper error handling. + + Args: + endpoint (str): API endpoint to call + params (Dict[str, Any]): Query parameters + + Returns: + str: JSON formatted response + """ + try: + response = requests.get( + endpoint, + params=params, + timeout=10 + ) + response.raise_for_status() + return json.dumps(response.json(), indent=2) + except requests.RequestException as e: + return json.dumps({"error": f"API error: {str(e)}"}) +``` + + + +### Data Processing Tools + +Example of a tool that processes data: + +```python +from typing import List, Dict +import pandas as pd + +def process_market_data(prices: List[float], window: int = 14) -> str: + """ + Calculate technical indicators from price data. + + Args: + prices (List[float]): List of historical prices + window (int): Rolling window size for calculations + + Returns: + str: JSON formatted string with calculated indicators + + Example: + >>> prices = [100, 101, 99, 102, 98, 103] + >>> result = process_market_data(prices, window=3) + >>> print(result) + {"sma": 101.0, "volatility": 2.1} + """ + try: + df = pd.DataFrame({"price": prices}) + + results: Dict[str, float] = { + "sma": df["price"].rolling(window).mean().iloc[-1], + "volatility": df["price"].rolling(window).std().iloc[-1] + } + + return json.dumps(results, indent=2) + + except Exception as e: + return json.dumps({"error": f"Processing error: {str(e)}"}) +``` + +### Adding Tools to Your Agent + +Once you've created your tools, add them to your agent like this: + +```python +agent = Agent( + agent_name="Your-Agent", + agent_description="Description of your agent", + system_prompt="System prompt for your agent", + tools=[ + example_tool, + get_api_data, + rate_limited_api_call, + process_market_data + ] +) +``` + +## Tutorial Steps + +1. First, install the latest version of Swarms: + +```bash +pip3 install -U swarms +``` + +2. Set up your environment variables in a `.env` file: + +```plaintext +OPENAI_API_KEY="your-api-key-here" +WORKSPACE_DIR="agent_workspace" +``` + +3. Create a new Python file and customize your agent with the following parameters: + - `agent_name`: A unique identifier for your agent + + - `agent_description`: A detailed description of your agent's capabilities + + - `system_prompt`: The core instructions that define your agent's behavior + + - `model_name`: The GPT model to use + + - Additional configuration options for temperature and output format + +4. Run the example code below: + + + +```python +import json +import requests +from swarms import Agent +from typing import List +import time + + +def get_coin_price(coin_id: str, vs_currency: str) -> str: + """ + Get the current price of a specific cryptocurrency. + + Args: + coin_id (str): The CoinGecko ID of the cryptocurrency (e.g., 'bitcoin', 'ethereum') + vs_currency (str, optional): The target currency. Defaults to "usd". + + Returns: + str: JSON formatted string containing the coin's current price and market data + + Raises: + requests.RequestException: If the API request fails + + Example: + >>> result = get_coin_price("bitcoin") + >>> print(result) + {"bitcoin": {"usd": 45000, "usd_market_cap": 850000000000, ...}} + """ + try: + url = "https://api.coingecko.com/api/v3/simple/price" + params = { + "ids": coin_id, + "vs_currencies": vs_currency, + "include_market_cap": True, + "include_24hr_vol": True, + "include_24hr_change": True, + "include_last_updated_at": True, + } + + response = requests.get(url, params=params, timeout=10) + response.raise_for_status() + + data = response.json() + return json.dumps(data, indent=2) + + except requests.RequestException as e: + return json.dumps( + { + "error": f"Failed to fetch price for {coin_id}: {str(e)}" + } + ) + except Exception as e: + return json.dumps({"error": f"Unexpected error: {str(e)}"}) + + +def get_top_cryptocurrencies(limit: int, vs_currency: str) -> str: + """ + Fetch the top cryptocurrencies by market capitalization. + + Args: + limit (int, optional): Number of coins to retrieve (1-250). Defaults to 10. + vs_currency (str, optional): The target currency. Defaults to "usd". + + Returns: + str: JSON formatted string containing top cryptocurrencies with detailed market data + + Raises: + requests.RequestException: If the API request fails + ValueError: If limit is not between 1 and 250 + + Example: + >>> result = get_top_cryptocurrencies(5) + >>> print(result) + [{"id": "bitcoin", "name": "Bitcoin", "current_price": 45000, ...}] + """ + try: + if not 1 <= limit <= 250: + raise ValueError("Limit must be between 1 and 250") + + url = "https://api.coingecko.com/api/v3/coins/markets" + params = { + "vs_currency": vs_currency, + "order": "market_cap_desc", + "per_page": limit, + "page": 1, + "sparkline": False, + "price_change_percentage": "24h,7d", + } + + response = requests.get(url, params=params, timeout=10) + response.raise_for_status() + + data = response.json() + + # Simplify the data structure for better readability + simplified_data = [] + for coin in data: + simplified_data.append( + { + "id": coin.get("id"), + "symbol": coin.get("symbol"), + "name": coin.get("name"), + "current_price": coin.get("current_price"), + "market_cap": coin.get("market_cap"), + "market_cap_rank": coin.get("market_cap_rank"), + "total_volume": coin.get("total_volume"), + "price_change_24h": coin.get( + "price_change_percentage_24h" + ), + "price_change_7d": coin.get( + "price_change_percentage_7d_in_currency" + ), + "last_updated": coin.get("last_updated"), + } + ) + + return json.dumps(simplified_data, indent=2) + + except (requests.RequestException, ValueError) as e: + return json.dumps( + { + "error": f"Failed to fetch top cryptocurrencies: {str(e)}" + } + ) + except Exception as e: + return json.dumps({"error": f"Unexpected error: {str(e)}"}) + + +def search_cryptocurrencies(query: str) -> str: + """ + Search for cryptocurrencies by name or symbol. + + Args: + query (str): The search term (coin name or symbol) + + Returns: + str: JSON formatted string containing search results with coin details + + Raises: + requests.RequestException: If the API request fails + + Example: + >>> result = search_cryptocurrencies("ethereum") + >>> print(result) + {"coins": [{"id": "ethereum", "name": "Ethereum", "symbol": "eth", ...}]} + """ + try: + url = "https://api.coingecko.com/api/v3/search" + params = {"query": query} + + response = requests.get(url, params=params, timeout=10) + response.raise_for_status() + + data = response.json() + + # Extract and format the results + result = { + "coins": data.get("coins", [])[ + :10 + ], # Limit to top 10 results + "query": query, + "total_results": len(data.get("coins", [])), + } + + return json.dumps(result, indent=2) + + except requests.RequestException as e: + return json.dumps( + {"error": f'Failed to search for "{query}": {str(e)}'} + ) + except Exception as e: + return json.dumps({"error": f"Unexpected error: {str(e)}"}) + + +def get_jupiter_quote( + input_mint: str, + output_mint: str, + amount: float, + slippage: float = 0.5, +) -> str: + """ + Get a quote for token swaps using Jupiter Protocol on Solana. + + Args: + input_mint (str): Input token mint address + output_mint (str): Output token mint address + amount (float): Amount of input tokens to swap + slippage (float, optional): Slippage tolerance percentage. Defaults to 0.5. + + Returns: + str: JSON formatted string containing the swap quote details + + Example: + >>> result = get_jupiter_quote("SOL_MINT_ADDRESS", "USDC_MINT_ADDRESS", 1.0) + >>> print(result) + {"inputAmount": "1000000000", "outputAmount": "22.5", "route": [...]} + """ + try: + url = "https://lite-api.jup.ag/swap/v1/quote" + params = { + "inputMint": input_mint, + "outputMint": output_mint, + "amount": str(int(amount * 1e9)), # Convert to lamports + "slippageBps": int(slippage * 100), + } + + response = requests.get(url, params=params, timeout=10) + response.raise_for_status() + return json.dumps(response.json(), indent=2) + + except requests.RequestException as e: + return json.dumps( + {"error": f"Failed to get Jupiter quote: {str(e)}"} + ) + except Exception as e: + return json.dumps({"error": f"Unexpected error: {str(e)}"}) + + +def get_htx_market_data(symbol: str) -> str: + """ + Get market data for a trading pair from HTX exchange. + + Args: + symbol (str): Trading pair symbol (e.g., 'btcusdt', 'ethusdt') + + Returns: + str: JSON formatted string containing market data + + Example: + >>> result = get_htx_market_data("btcusdt") + >>> print(result) + {"symbol": "btcusdt", "price": "45000", "volume": "1000000", ...} + """ + try: + url = "https://api.htx.com/market/detail/merged" + params = {"symbol": symbol.lower()} + + response = requests.get(url, params=params, timeout=10) + response.raise_for_status() + return json.dumps(response.json(), indent=2) + + except requests.RequestException as e: + return json.dumps( + {"error": f"Failed to fetch HTX market data: {str(e)}"} + ) + except Exception as e: + return json.dumps({"error": f"Unexpected error: {str(e)}"}) + + +def get_token_historical_data( + token_id: str, days: int = 30, vs_currency: str = "usd" +) -> str: + """ + Get historical price and market data for a cryptocurrency. + + Args: + token_id (str): The CoinGecko ID of the cryptocurrency + days (int, optional): Number of days of historical data. Defaults to 30. + vs_currency (str, optional): The target currency. Defaults to "usd". + + Returns: + str: JSON formatted string containing historical price and market data + + Example: + >>> result = get_token_historical_data("bitcoin", 7) + >>> print(result) + {"prices": [[timestamp, price], ...], "market_caps": [...], "volumes": [...]} + """ + try: + url = f"https://api.coingecko.com/api/v3/coins/{token_id}/market_chart" + params = { + "vs_currency": vs_currency, + "days": days, + "interval": "daily", + } + + response = requests.get(url, params=params, timeout=10) + response.raise_for_status() + return json.dumps(response.json(), indent=2) + + except requests.RequestException as e: + return json.dumps( + {"error": f"Failed to fetch historical data: {str(e)}"} + ) + except Exception as e: + return json.dumps({"error": f"Unexpected error: {str(e)}"}) + + +def get_defi_stats() -> str: + """ + Get global DeFi statistics including TVL, trading volumes, and dominance. + + Returns: + str: JSON formatted string containing global DeFi statistics + + Example: + >>> result = get_defi_stats() + >>> print(result) + {"total_value_locked": 50000000000, "defi_dominance": 15.5, ...} + """ + try: + url = "https://api.coingecko.com/api/v3/global/decentralized_finance_defi" + response = requests.get(url, timeout=10) + response.raise_for_status() + return json.dumps(response.json(), indent=2) + + except requests.RequestException as e: + return json.dumps( + {"error": f"Failed to fetch DeFi stats: {str(e)}"} + ) + except Exception as e: + return json.dumps({"error": f"Unexpected error: {str(e)}"}) + + +def get_jupiter_tokens() -> str: + """ + Get list of tokens supported by Jupiter Protocol on Solana. + + Returns: + str: JSON formatted string containing supported tokens + + Example: + >>> result = get_jupiter_tokens() + >>> print(result) + {"tokens": [{"symbol": "SOL", "mint": "...", "decimals": 9}, ...]} + """ + try: + url = "https://lite-api.jup.ag/tokens/v1/mints/tradable" + response = requests.get(url, timeout=10) + response.raise_for_status() + return json.dumps(response.json(), indent=2) + + except requests.RequestException as e: + return json.dumps( + {"error": f"Failed to fetch Jupiter tokens: {str(e)}"} + ) + except Exception as e: + return json.dumps({"error": f"Unexpected error: {str(e)}"}) + + +def get_htx_trading_pairs() -> str: + """ + Get list of all trading pairs available on HTX exchange. + + Returns: + str: JSON formatted string containing trading pairs information + + Example: + >>> result = get_htx_trading_pairs() + >>> print(result) + {"symbols": [{"symbol": "btcusdt", "state": "online", "type": "spot"}, ...]} + """ + try: + url = "https://api.htx.com/v1/common/symbols" + response = requests.get(url, timeout=10) + response.raise_for_status() + return json.dumps(response.json(), indent=2) + + except requests.RequestException as e: + return json.dumps( + {"error": f"Failed to fetch HTX trading pairs: {str(e)}"} + ) + except Exception as e: + return json.dumps({"error": f"Unexpected error: {str(e)}"}) + + +def get_market_sentiment(coin_ids: List[str]) -> str: + """ + Get market sentiment data including social metrics and developer activity. + + Args: + coin_ids (List[str]): List of CoinGecko coin IDs + + Returns: + str: JSON formatted string containing market sentiment data + + Example: + >>> result = get_market_sentiment(["bitcoin", "ethereum"]) + >>> print(result) + {"bitcoin": {"sentiment_score": 75, "social_volume": 15000, ...}, ...} + """ + try: + sentiment_data = {} + for coin_id in coin_ids: + url = f"https://api.coingecko.com/api/v3/coins/{coin_id}" + params = { + "localization": False, + "tickers": False, + "market_data": False, + "community_data": True, + "developer_data": True, + } + + response = requests.get(url, params=params, timeout=10) + response.raise_for_status() + data = response.json() + + sentiment_data[coin_id] = { + "community_score": data.get("community_score"), + "developer_score": data.get("developer_score"), + "public_interest_score": data.get( + "public_interest_score" + ), + "community_data": data.get("community_data"), + "developer_data": data.get("developer_data"), + } + + # Rate limiting to avoid API restrictions + time.sleep(0.6) + + return json.dumps(sentiment_data, indent=2) + + except requests.RequestException as e: + return json.dumps( + {"error": f"Failed to fetch market sentiment: {str(e)}"} + ) + except Exception as e: + return json.dumps({"error": f"Unexpected error: {str(e)}"}) + + +# Initialize the agent with expanded tools +agent = Agent( + agent_name="Financial-Analysis-Agent", + agent_description="Advanced financial advisor agent with comprehensive cryptocurrency market analysis capabilities across multiple platforms including Jupiter Protocol and HTX", + system_prompt="You are an advanced financial advisor agent with access to real-time cryptocurrency data from multiple sources including CoinGecko, Jupiter Protocol, and HTX. You can help users analyze market trends, check prices, find trading opportunities, perform swaps, and get detailed market insights. Always provide accurate, up-to-date information and explain market data in an easy-to-understand way.", + max_loops=1, + max_tokens=4096, + model_name="gpt-4o-mini", + dynamic_temperature_enabled=True, + output_type="all", + tools=[ + get_coin_price, + get_top_cryptocurrencies, + search_cryptocurrencies, + get_jupiter_quote, + get_htx_market_data, + get_token_historical_data, + get_defi_stats, + get_jupiter_tokens, + get_htx_trading_pairs, + get_market_sentiment, + ], + # Upload your tools to the tools parameter here! +) + +# agent.run("Use defi stats to find the best defi project to invest in") +agent.run("Get the market sentiment for bitcoin") +# Automatically executes any number and combination of tools you have uploaded to the tools parameter! +``` diff --git a/docs/swarms/examples/basic_agent.md b/docs/swarms/examples/basic_agent.md new file mode 100644 index 00000000..87d10ddf --- /dev/null +++ b/docs/swarms/examples/basic_agent.md @@ -0,0 +1,107 @@ +# Basic Agent Example + +This example demonstrates how to create and configure a sophisticated AI agent using the Swarms framework. In this tutorial, we'll build a Quantitative Trading Agent that can analyze financial markets and provide investment insights. The agent is powered by GPT models and can be customized for various financial analysis tasks. + +## Prerequisites + +- Python 3.7+ + +- OpenAI API key + +- Swarms library + +## Tutorial Steps + +1. First, install the latest version of Swarms: + +```bash +pip3 install -U swarms +``` + +2. Set up your environment variables in a `.env` file: + +```plaintext +OPENAI_API_KEY="your-api-key-here" +WORKSPACE_DIR="agent_workspace" +``` + +3. Create a new Python file and customize your agent with the following parameters: + - `agent_name`: A unique identifier for your agent + + - `agent_description`: A detailed description of your agent's capabilities + + - `system_prompt`: The core instructions that define your agent's behavior + + - `model_name`: The GPT model to use + + - Additional configuration options for temperature and output format + +4. Run the example code below: + + +## Code + +```python +import time +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.""", + max_loops=1, + model_name="gpt-4o-mini", + dynamic_temperature_enabled=True, + output_type="json", + safety_prompt_on=True, +) + +out = agent.run("What are the best top 3 etfs for gold coverage?") + +time.sleep(10) +print(out) +``` + +## Example Output + +The agent will return a JSON response containing recommendations for gold ETFs based on the query. + +## Customization + +You can modify the system prompt and agent parameters to create specialized agents for different use cases: + +| Use Case | Description | +|----------|-------------| +| Market Analysis | Analyze market trends, patterns, and indicators to identify trading opportunities | +| Portfolio Management | Optimize asset allocation and rebalancing strategies | +| Risk Assessment | Evaluate and mitigate potential risks in trading strategies | +| Trading Strategy Development | Design and implement algorithmic trading strategies | \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index be9afd13..12ca9b74 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "swarms" -version = "7.8.5" +version = "7.8.6" description = "Swarms - TGSC" license = "MIT" authors = ["Kye Gomez "] diff --git a/swarms/structs/__init__.py b/swarms/structs/__init__.py index 53181f32..cc49a1fd 100644 --- a/swarms/structs/__init__.py +++ b/swarms/structs/__init__.py @@ -1,10 +1,13 @@ from swarms.structs.agent import Agent from swarms.structs.agent_builder import AgentsBuilder +from swarms.structs.auto_swarm_builder import AutoSwarmBuilder from swarms.structs.base_structure import BaseStructure from swarms.structs.base_swarm import BaseSwarm from swarms.structs.base_workflow import BaseWorkflow +from swarms.structs.batch_agent_execution import batch_agent_execution from swarms.structs.concurrent_workflow import ConcurrentWorkflow from swarms.structs.conversation import Conversation +from swarms.structs.council_judge import CouncilAsAJudge from swarms.structs.de_hallucination_swarm import DeHallucinationSwarm from swarms.structs.deep_research_swarm import DeepResearchSwarm from swarms.structs.graph_workflow import ( @@ -20,6 +23,11 @@ from swarms.structs.groupchat import ( from swarms.structs.hybrid_hiearchical_peer_swarm import ( HybridHierarchicalClusterSwarm, ) +from swarms.structs.ma_blocks import ( + aggregate, + find_agent_by_name, + run_agent, +) from swarms.structs.majority_voting import ( MajorityVoting, majority_voting, @@ -34,6 +42,8 @@ from swarms.structs.mixture_of_agents import MixtureOfAgents from swarms.structs.model_router import ModelRouter from swarms.structs.multi_agent_collab import MultiAgentCollaboration from swarms.structs.multi_agent_exec import ( + get_agents_info, + get_swarms_info, run_agent_with_timeout, run_agents_concurrently, run_agents_concurrently_async, @@ -43,8 +53,6 @@ from swarms.structs.multi_agent_exec import ( run_agents_with_resource_monitoring, run_agents_with_tasks_concurrently, run_single_agent, - get_agents_info, - get_swarms_info, ) from swarms.structs.multi_agent_router import MultiAgentRouter from swarms.structs.rearrange import AgentRearrange, rearrange @@ -76,11 +84,6 @@ from swarms.structs.swarming_architectures import ( staircase_swarm, star_swarm, ) -from swarms.structs.auto_swarm_builder import AutoSwarmBuilder -from swarms.structs.council_judge import CouncilAsAJudge -from swarms.structs.batch_agent_execution import batch_agent_execution -from swarms.structs.ma_blocks import aggregate - __all__ = [ "Agent", @@ -151,4 +154,6 @@ __all__ = [ "CouncilAsAJudge", "batch_agent_execution", "aggregate", + "find_agent_by_name", + "run_agent", ] diff --git a/swarms/structs/dynamic_conversational_swarm.py b/swarms/structs/dynamic_conversational_swarm.py index 896950f5..158036b6 100644 --- a/swarms/structs/dynamic_conversational_swarm.py +++ b/swarms/structs/dynamic_conversational_swarm.py @@ -3,6 +3,7 @@ import random from swarms.structs.agent import Agent from typing import List from swarms.structs.conversation import Conversation +from swarms.structs.ma_blocks import find_agent_by_name from swarms.utils.history_output_formatter import ( history_output_formatter, ) @@ -84,14 +85,22 @@ class DynamicConversationalSwarm: except json.JSONDecodeError: raise ValueError("Invalid JSON string") - def find_agent_by_name(self, agent_name: str) -> Agent: - for agent in self.agents: - if agent.name == agent_name: - return agent - raise ValueError(f"Agent with name {agent_name} not found") - def run_agent(self, agent_name: str, task: str) -> str: - agent = self.find_agent_by_name(agent_name) + """ + Run a specific agent with a given task. + + Args: + agent_name (str): The name of the agent to run + task (str): The task to execute + + Returns: + str: The agent's response to the task + + Raises: + ValueError: If agent is not found + RuntimeError: If there's an error running the agent + """ + agent = find_agent_by_name(agents=self.agents, agent_name=agent_name) return agent.run(task) def fetch_random_agent_name(self) -> str: diff --git a/swarms/structs/ma_blocks.py b/swarms/structs/ma_blocks.py index 60b4a56a..4565ce31 100644 --- a/swarms/structs/ma_blocks.py +++ b/swarms/structs/ma_blocks.py @@ -1,3 +1,4 @@ +from typing import Union from swarms.structs.agent import Agent from typing import List, Callable from swarms.structs.conversation import Conversation @@ -82,3 +83,77 @@ def aggregate( return history_output_formatter( conversation=conversation, type=type ) + + +def run_agent( + agent: Agent, + task: str, + type: HistoryOutputType = "all", + *args, + **kwargs, +): + """ + Run an agent on a task. + + Args: + agent (Agent): The agent to run + task (str): The task to run the agent on + type (HistoryOutputType, optional): The type of history output. Defaults to "all". + *args: Variable length argument list + **kwargs: Arbitrary keyword arguments + + Returns: + Any: The result of running the agent + + Raises: + ValueError: If agent or task is None + TypeError: If agent is not an instance of Agent + """ + if agent is None: + raise ValueError("Agent cannot be None") + + if task is None: + raise ValueError("Task cannot be None") + + if not isinstance(agent, Agent): + raise TypeError("Agent must be an instance of Agent") + + try: + return agent.run(task=task, *args, **kwargs) + except Exception as e: + raise RuntimeError(f"Error running agent: {str(e)}") + + + +def find_agent_by_name(agents: List[Union[Agent, Callable]], agent_name: str) -> Agent: + """ + Find an agent by its name in a list of agents. + + Args: + agents (List[Union[Agent, Callable]]): List of agents to search through + agent_name (str): Name of the agent to find + + Returns: + Agent: The found agent + + Raises: + ValueError: If agents list is empty or agent not found + TypeError: If agent_name is not a string + """ + if not agents: + raise ValueError("Agents list cannot be empty") + + if not isinstance(agent_name, str): + raise TypeError("Agent name must be a string") + + if not agent_name.strip(): + raise ValueError("Agent name cannot be empty or whitespace") + + try: + for agent in agents: + if hasattr(agent, 'name') and agent.name == agent_name: + return agent + raise ValueError(f"Agent with name '{agent_name}' not found") + except Exception as e: + raise RuntimeError(f"Error finding agent: {str(e)}") + diff --git a/text_multi_agent_concurrency.py b/text_multi_agent_concurrency.py index 10efd469..f779eacd 100644 --- a/text_multi_agent_concurrency.py +++ b/text_multi_agent_concurrency.py @@ -29,8 +29,10 @@ agents = [ ), ] -aggregate( +out = aggregate( workers=agents, task="What is the best sector to invest in?", type="all", ) + +print(out)