[FEAT][clusterops integration] [Updated Docs] [Updated ConcurrentWorkflow] [Updated SwarmRouter]

pull/612/head^2
Your Name 3 months ago
parent ad24283164
commit 8b78ab2bba

@ -0,0 +1,48 @@
import os
from swarms import Agent
from swarm_models import OpenAIChat
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
# Retrieve the OpenAI API key from the environment variable
api_key = os.getenv("GROQ_API_KEY")
# Initialize the model for OpenAI Chat
model = OpenAIChat(
openai_api_base="https://api.groq.com/openai/v1",
openai_api_key=api_key,
model_name="llama-3.1-70b-versatile",
temperature=0.1,
)
# Initialize the agent with automated prompt engineering enabled
agent = Agent(
agent_name="Financial-Analysis-Agent",
system_prompt=None, # System prompt is dynamically generated
agent_description=None,
llm=model,
max_loops=1,
autosave=True,
dashboard=False,
verbose=False,
dynamic_temperature_enabled=True,
saved_state_path="finance_agent.json",
user_name="Human:",
return_step_meta=False,
output_type="string",
streaming_on=False,
auto_generate_prompt=True, # Enable automated prompt engineering
)
# Run the agent with a task description and specify the device
agent.run(
"How can I establish a ROTH IRA to buy stocks and get a tax break? What are the criteria",
## Will design a system prompt based on the task if description and system prompt are None
device="cpu",
)
# Print the dynamically generated system prompt
print(agent.system_prompt)

@ -0,0 +1,162 @@
import os
from dotenv import load_dotenv
from swarms import Agent
from swarm_models import OpenAIChat
from swarms.structs.swarm_router import SwarmRouter
load_dotenv()
# Get the OpenAI API key from the environment variable
api_key = os.getenv("GROQ_API_KEY")
# Model
model = OpenAIChat(
openai_api_base="https://api.groq.com/openai/v1",
openai_api_key=api_key,
model_name="llama-3.1-70b-versatile",
temperature=0.1,
)
# Define specialized system prompts for each agent
DATA_EXTRACTOR_PROMPT = """You are a highly specialized private equity agent focused on data extraction from various documents. Your expertise includes:
1. Extracting key financial metrics (revenue, EBITDA, growth rates, etc.) from financial statements and reports
2. Identifying and extracting important contract terms from legal documents
3. Pulling out relevant market data from industry reports and analyses
4. Extracting operational KPIs from management presentations and internal reports
5. Identifying and extracting key personnel information from organizational charts and bios
Provide accurate, structured data extracted from various document types to support investment analysis."""
SUMMARIZER_PROMPT = """You are an expert private equity agent specializing in summarizing complex documents. Your core competencies include:
1. Distilling lengthy financial reports into concise executive summaries
2. Summarizing legal documents, highlighting key terms and potential risks
3. Condensing industry reports to capture essential market trends and competitive dynamics
4. Summarizing management presentations to highlight key strategic initiatives and projections
5. Creating brief overviews of technical documents, emphasizing critical points for non-technical stakeholders
Deliver clear, concise summaries that capture the essence of various documents while highlighting information crucial for investment decisions."""
FINANCIAL_ANALYST_PROMPT = """You are a specialized private equity agent focused on financial analysis. Your key responsibilities include:
1. Analyzing historical financial statements to identify trends and potential issues
2. Evaluating the quality of earnings and potential adjustments to EBITDA
3. Assessing working capital requirements and cash flow dynamics
4. Analyzing capital structure and debt capacity
5. Evaluating financial projections and underlying assumptions
Provide thorough, insightful financial analysis to inform investment decisions and valuation."""
MARKET_ANALYST_PROMPT = """You are a highly skilled private equity agent specializing in market analysis. Your expertise covers:
1. Analyzing industry trends, growth drivers, and potential disruptors
2. Evaluating competitive landscape and market positioning
3. Assessing market size, segmentation, and growth potential
4. Analyzing customer dynamics, including concentration and loyalty
5. Identifying potential regulatory or macroeconomic impacts on the market
Deliver comprehensive market analysis to assess the attractiveness and risks of potential investments."""
OPERATIONAL_ANALYST_PROMPT = """You are an expert private equity agent focused on operational analysis. Your core competencies include:
1. Evaluating operational efficiency and identifying improvement opportunities
2. Analyzing supply chain and procurement processes
3. Assessing sales and marketing effectiveness
4. Evaluating IT systems and digital capabilities
5. Identifying potential synergies in merger or add-on acquisition scenarios
Provide detailed operational analysis to uncover value creation opportunities and potential risks."""
# Initialize specialized agents
data_extractor_agent = Agent(
agent_name="Data-Extractor",
system_prompt=DATA_EXTRACTOR_PROMPT,
llm=model,
max_loops=1,
autosave=True,
verbose=True,
dynamic_temperature_enabled=True,
saved_state_path="data_extractor_agent.json",
user_name="pe_firm",
retry_attempts=1,
context_length=200000,
output_type="string",
)
summarizer_agent = Agent(
agent_name="Document-Summarizer",
system_prompt=SUMMARIZER_PROMPT,
llm=model,
max_loops=1,
autosave=True,
verbose=True,
dynamic_temperature_enabled=True,
saved_state_path="summarizer_agent.json",
user_name="pe_firm",
retry_attempts=1,
context_length=200000,
output_type="string",
)
financial_analyst_agent = Agent(
agent_name="Financial-Analyst",
system_prompt=FINANCIAL_ANALYST_PROMPT,
llm=model,
max_loops=1,
autosave=True,
verbose=True,
dynamic_temperature_enabled=True,
saved_state_path="financial_analyst_agent.json",
user_name="pe_firm",
retry_attempts=1,
context_length=200000,
output_type="string",
)
market_analyst_agent = Agent(
agent_name="Market-Analyst",
system_prompt=MARKET_ANALYST_PROMPT,
llm=model,
max_loops=1,
autosave=True,
verbose=True,
dynamic_temperature_enabled=True,
saved_state_path="market_analyst_agent.json",
user_name="pe_firm",
retry_attempts=1,
context_length=200000,
output_type="string",
)
operational_analyst_agent = Agent(
agent_name="Operational-Analyst",
system_prompt=OPERATIONAL_ANALYST_PROMPT,
llm=model,
max_loops=1,
autosave=True,
verbose=True,
dynamic_temperature_enabled=True,
saved_state_path="operational_analyst_agent.json",
user_name="pe_firm",
retry_attempts=1,
context_length=200000,
output_type="string",
)
# Initialize the SwarmRouter
router = SwarmRouter(
name="pe-document-analysis-swarm",
description="Analyze documents for private equity due diligence and investment decision-making",
max_loops=1,
agents=[
data_extractor_agent,
summarizer_agent,
# financial_analyst_agent,
# market_analyst_agent,
# operational_analyst_agent,
],
swarm_type="auto", # or "SequentialWorkflow" or "ConcurrentWorkflow" or
# auto_generate_prompts=True,
)
# Example usage
if __name__ == "__main__":
# Run a comprehensive private equity document analysis task
result = router.run(
"Where is the best place to find template term sheets for series A startups. Provide links and references"
)
print(result)
# Retrieve and print logs
for log in router.get_logs():
print(f"{log.timestamp} - {log.level}: {log.message}")

@ -0,0 +1,100 @@
import os
from swarms import Agent, ConcurrentWorkflow
from swarm_models import OpenAIChat
from loguru import logger
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
# Retrieve the OpenAI API key from the environment variable
api_key = os.getenv("GROQ_API_KEY")
# Initialize the model for OpenAI Chat
model = OpenAIChat(
openai_api_base="https://api.groq.com/openai/v1",
openai_api_key=api_key,
model_name="llama-3.1-70b-versatile",
temperature=0.1,
)
logger.add("swarms_example.log", rotation="10 MB")
agents = [
Agent(
agent_name=f"Term-Sheet-Analysis-Agent-{i}",
system_prompt="Analyze the term sheet for investment opportunities.",
llm=model,
max_loops=1,
autosave=True,
dashboard=False,
verbose=True,
dynamic_temperature_enabled=True,
saved_state_path=f"term_sheet_analysis_agent_{i}.json",
user_name="swarms_corp",
retry_attempts=1,
context_length=200000,
return_step_meta=False,
)
for i in range(3) # Adjust number of agents as needed
]
# Initialize the workflow with the list of agents
workflow = ConcurrentWorkflow(
agents=agents,
metadata_output_path="term_sheet_analysis_metadata.json",
return_str_on=True,
auto_generate_prompts=True,
auto_save=True,
)
# Define the task for all agents
task = "Analyze the term sheet for investment opportunities and identify key terms and conditions."
# Run the workflow and save metadata
metadata = workflow.run(task)
logger.info(metadata)
# # Example usage of the run_batched method
# tasks = [
# "What are the benefits of a ROTH IRA?",
# "How do I open a ROTH IRA account?",
# ]
# results = workflow.run_batched(tasks)
# print("\nRun Batched Method Output:")
# print(results)
# # Example usage of the run_async method
# async def run_async_example():
# future = workflow.run_async(task)
# result = await future
# print("\nRun Async Method Output:")
# print(result)
# # Example usage of the run_batched_async method
# async def run_batched_async_example():
# futures = workflow.run_batched_async(tasks)
# results = await asyncio.gather(*futures)
# print("\nRun Batched Async Method Output:")
# print(results)
# # Example usage of the run_parallel method
# parallel_results = workflow.run_parallel(tasks)
# print("\nRun Parallel Method Output:")
# print(parallel_results)
# # Example usage of the run_parallel_async method
# async def run_parallel_async_example():
# parallel_futures = workflow.run_parallel_async(tasks)
# parallel_results = await asyncio.gather(*parallel_futures)
# print("\nRun Parallel Async Method Output:")
# print(parallel_results)
# # To run the async examples, you would typically use an event loop
# if __name__ == "__main__":
# asyncio.run(run_async_example())
# asyncio.run(run_batched_async_example())
# asyncio.run(run_parallel_async_example())

@ -0,0 +1,334 @@
# ClusterOps API Reference
ClusterOps is a Python library for managing and executing tasks across CPU and GPU resources in a distributed computing environment. It provides functions for resource discovery, task execution, and performance monitoring.
## Installation
```bash
$ pip3 install clusterops
```
## Table of Contents
1. [CPU Operations](#cpu-operations)
2. [GPU Operations](#gpu-operations)
3. [Utility Functions](#utility-functions)
4. [Resource Monitoring](#resource-monitoring)
## CPU Operations
### `list_available_cpus()`
Lists all available CPU cores.
#### Returns
| Type | Description |
|------|-------------|
| `List[int]` | A list of available CPU core indices. |
#### Raises
| Exception | Description |
|-----------|-------------|
| `RuntimeError` | If no CPUs are found. |
#### Example
```python
from clusterops import list_available_cpus
available_cpus = list_available_cpus()
print(f"Available CPU cores: {available_cpus}")
```
### `execute_on_cpu(cpu_id: int, func: Callable, *args: Any, **kwargs: Any) -> Any`
Executes a callable on a specific CPU.
#### Parameters
| Name | Type | Description |
|------|------|-------------|
| `cpu_id` | `int` | The CPU core to run the function on. |
| `func` | `Callable` | The function to be executed. |
| `*args` | `Any` | Arguments for the callable. |
| `**kwargs` | `Any` | Keyword arguments for the callable. |
#### Returns
| Type | Description |
|------|-------------|
| `Any` | The result of the function execution. |
#### Raises
| Exception | Description |
|-----------|-------------|
| `ValueError` | If the CPU core specified is invalid. |
| `RuntimeError` | If there is an error executing the function on the CPU. |
#### Example
```python
from clusterops import execute_on_cpu
def sample_task(n: int) -> int:
return n * n
result = execute_on_cpu(0, sample_task, 10)
print(f"Result of sample task on CPU 0: {result}")
```
### `execute_with_cpu_cores(core_count: int, func: Callable, *args: Any, **kwargs: Any) -> Any`
Executes a callable using a specified number of CPU cores.
#### Parameters
| Name | Type | Description |
|------|------|-------------|
| `core_count` | `int` | The number of CPU cores to run the function on. |
| `func` | `Callable` | The function to be executed. |
| `*args` | `Any` | Arguments for the callable. |
| `**kwargs` | `Any` | Keyword arguments for the callable. |
#### Returns
| Type | Description |
|------|-------------|
| `Any` | The result of the function execution. |
#### Raises
| Exception | Description |
|-----------|-------------|
| `ValueError` | If the number of CPU cores specified is invalid or exceeds available cores. |
| `RuntimeError` | If there is an error executing the function on the specified CPU cores. |
#### Example
```python
from clusterops import execute_with_cpu_cores
def parallel_task(n: int) -> int:
return sum(range(n))
result = execute_with_cpu_cores(4, parallel_task, 1000000)
print(f"Result of parallel task using 4 CPU cores: {result}")
```
## GPU Operations
### `list_available_gpus() -> List[str]`
Lists all available GPUs.
#### Returns
| Type | Description |
|------|-------------|
| `List[str]` | A list of available GPU names. |
#### Raises
| Exception | Description |
|-----------|-------------|
| `RuntimeError` | If no GPUs are found. |
#### Example
```python
from clusterops import list_available_gpus
available_gpus = list_available_gpus()
print(f"Available GPUs: {available_gpus}")
```
### `select_best_gpu() -> Optional[int]`
Selects the GPU with the most free memory.
#### Returns
| Type | Description |
|------|-------------|
| `Optional[int]` | The GPU ID of the best available GPU, or None if no GPUs are available. |
#### Example
```python
from clusterops import select_best_gpu
best_gpu = select_best_gpu()
if best_gpu is not None:
print(f"Best GPU for execution: GPU {best_gpu}")
else:
print("No GPUs available")
```
### `execute_on_gpu(gpu_id: int, func: Callable, *args: Any, **kwargs: Any) -> Any`
Executes a callable on a specific GPU using Ray.
#### Parameters
| Name | Type | Description |
|------|------|-------------|
| `gpu_id` | `int` | The GPU to run the function on. |
| `func` | `Callable` | The function to be executed. |
| `*args` | `Any` | Arguments for the callable. |
| `**kwargs` | `Any` | Keyword arguments for the callable. |
#### Returns
| Type | Description |
|------|-------------|
| `Any` | The result of the function execution. |
#### Raises
| Exception | Description |
|-----------|-------------|
| `ValueError` | If the GPU index is invalid. |
| `RuntimeError` | If there is an error executing the function on the GPU. |
#### Example
```python
from clusterops import execute_on_gpu
def gpu_task(n: int) -> int:
return n ** 2
result = execute_on_gpu(0, gpu_task, 10)
print(f"Result of GPU task on GPU 0: {result}")
```
### `execute_on_multiple_gpus(gpu_ids: List[int], func: Callable, all_gpus: bool = False, timeout: float = None, *args: Any, **kwargs: Any) -> List[Any]`
Executes a callable across multiple GPUs using Ray.
#### Parameters
| Name | Type | Description |
|------|------|-------------|
| `gpu_ids` | `List[int]` | The list of GPU IDs to run the function on. |
| `func` | `Callable` | The function to be executed. |
| `all_gpus` | `bool` | Whether to use all available GPUs (default: False). |
| `timeout` | `float` | Timeout for the execution in seconds (default: None). |
| `*args` | `Any` | Arguments for the callable. |
| `**kwargs` | `Any` | Keyword arguments for the callable. |
#### Returns
| Type | Description |
|------|-------------|
| `List[Any]` | A list of results from the execution on each GPU. |
#### Raises
| Exception | Description |
|-----------|-------------|
| `ValueError` | If any GPU index is invalid. |
| `RuntimeError` | If there is an error executing the function on the GPUs. |
#### Example
```python
from clusterops import execute_on_multiple_gpus
def multi_gpu_task(n: int) -> int:
return n ** 3
results = execute_on_multiple_gpus([0, 1], multi_gpu_task, 5)
print(f"Results of multi-GPU task: {results}")
```
### `distributed_execute_on_gpus(gpu_ids: List[int], func: Callable, *args: Any, **kwargs: Any) -> List[Any]`
Executes a callable across multiple GPUs and nodes using Ray's distributed task scheduling.
#### Parameters
| Name | Type | Description |
|------|------|-------------|
| `gpu_ids` | `List[int]` | The list of GPU IDs across nodes to run the function on. |
| `func` | `Callable` | The function to be executed. |
| `*args` | `Any` | Arguments for the callable. |
| `**kwargs` | `Any` | Keyword arguments for the callable. |
#### Returns
| Type | Description |
|------|-------------|
| `List[Any]` | A list of results from the execution on each GPU. |
#### Example
```python
from clusterops import distributed_execute_on_gpus
def distributed_task(n: int) -> int:
return n ** 4
results = distributed_execute_on_gpus([0, 1, 2, 3], distributed_task, 3)
print(f"Results of distributed GPU task: {results}")
```
## Utility Functions
### `retry_with_backoff(func: Callable, retries: int = RETRY_COUNT, delay: float = RETRY_DELAY, *args: Any, **kwargs: Any) -> Any`
Retries a callable function with exponential backoff in case of failure.
#### Parameters
| Name | Type | Description |
|------|------|-------------|
| `func` | `Callable` | The function to execute with retries. |
| `retries` | `int` | Number of retries (default: RETRY_COUNT from env). |
| `delay` | `float` | Delay between retries in seconds (default: RETRY_DELAY from env). |
| `*args` | `Any` | Arguments for the callable. |
| `**kwargs` | `Any` | Keyword arguments for the callable. |
#### Returns
| Type | Description |
|------|-------------|
| `Any` | The result of the function execution. |
#### Raises
| Exception | Description |
|-----------|-------------|
| `Exception` | After all retries fail. |
#### Example
```python
from clusterops import retry_with_backoff
def unstable_task():
# Simulating an unstable task that might fail
import random
if random.random() < 0.5:
raise Exception("Task failed")
return "Task succeeded"
result = retry_with_backoff(unstable_task, retries=5, delay=1)
print(f"Result of unstable task: {result}")
```
## Resource Monitoring
### `monitor_resources()`
Continuously monitors CPU and GPU resources and logs alerts when thresholds are crossed.
#### Example
```python
from clusterops import monitor_resources
# Start monitoring resources
monitor_resources()
```
### `profile_execution(func: Callable, *args: Any, **kwargs: Any) -> Any`
Profiles the execution of a task, collecting metrics like execution time and CPU/GPU usage.
#### Parameters
| Name | Type | Description |
|------|------|-------------|
| `func` | `Callable` | The function to profile. |
| `*args` | `Any` | Arguments for the callable. |
| `**kwargs` | `Any` | Keyword arguments for the callable. |
#### Returns
| Type | Description |
|------|-------------|
| `Any` | The result of the function execution along with the collected metrics. |
#### Example
```python
from clusterops import profile_execution
def cpu_intensive_task():
return sum(i*i for i in range(10000000))
result = profile_execution(cpu_intensive_task)
print(f"Result of profiled task: {result}")
```
This API reference provides a comprehensive overview of the ClusterOps library's main functions, their parameters, return values, and usage examples. It should help users understand and utilize the library effectively for managing and executing tasks across CPU and GPU resources in a distributed computing environment.

@ -254,4 +254,6 @@ nav:
- Managing Prompts in Production: "swarms/prompts/main.md"
- Corporate:
- Hiring: "corporate/hiring.md"
- Swarms Goals & Milestone Tracking; A Vision for 2024 and Beyond: "corporate/2024_2025_goals.md"
- Swarms Goals & Milestone Tracking; A Vision for 2024 and Beyond: "corporate/2024_2025_goals.md"
- Clusterops:
- Overview: "clusterops/reference.md"

@ -1,161 +1,236 @@
# `Agent` Documentation
# `Agent`
Swarm Agent is a powerful autonomous agent framework designed to connect Language Models (LLMs) with various tools and long-term memory. This class provides the ability to ingest and process various types of documents such as PDFs, text files, Markdown files, JSON files, and more. The Agent structure offers a wide range of features to enhance the capabilities of LLMs and facilitate efficient task execution.
1. **Conversational Loop**: It establishes a conversational loop with a language model. This means it allows you to interact with the model in a back-and-forth manner, taking turns in the conversation.
2. **Feedback Collection**: The class allows users to provide feedback on the responses generated by the model. This feedback can be valuable for training and improving the model's responses over time.
3. **Stoppable Conversation**: You can define custom stopping conditions for the conversation, allowing you to stop the interaction based on specific criteria. For example, you can stop the conversation if a certain keyword is detected in the responses.
## Overview
The `Agent` class establishes a conversational loop with a language model, allowing for interactive task execution, feedback collection, and dynamic response generation. It includes features such as:
1. **Conversational Loop**: Enables back-and-forth interaction with the model.
2. **Feedback Collection**: Allows users to provide feedback on generated responses.
3. **Stoppable Conversation**: Supports custom stopping conditions for the conversation.
4. **Retry Mechanism**: Implements a retry system for handling issues in response generation.
5. **Tool Integration**: Supports the integration of various tools for enhanced capabilities.
6. **Long-term Memory Management**: Incorporates vector databases for efficient information retrieval.
7. **Document Ingestion**: Processes various document types for information extraction.
8. **Interactive Mode**: Allows real-time communication with the agent.
9. **Sentiment Analysis**: Evaluates the sentiment of generated responses.
10. **Output Filtering and Cleaning**: Ensures generated responses meet specific criteria.
11. **Asynchronous and Concurrent Execution**: Supports efficient parallelization of tasks.
12. **Planning and Reasoning**: Implements techniques like algorithm of thoughts for enhanced decision-making.
## Architecture
```mermaid
graph TD
A[Task Initiation] -->|Receives Task| B[Initial LLM Processing]
B -->|Interprets Task| C[Tool Usage]
C -->|Calls Tools| D[Function 1]
C -->|Calls Tools| E[Function 2]
D -->|Returns Data| C
E -->|Returns Data| C
C -->|Provides Data| F[Memory Interaction]
F -->|Stores and Retrieves Data| G[RAG System]
G -->|ChromaDB/Pinecone| H[Enhanced Data]
F -->|Provides Enhanced Data| I[Final LLM Processing]
I -->|Generates Final Response| J[Output]
C -->|No Tools Available| K[Skip Tool Usage]
K -->|Proceeds to Memory Interaction| F
F -->|No Memory Available| L[Skip Memory Interaction]
L -->|Proceeds to Final LLM Processing| I
```
4. **Retry Mechanism**: The class includes a retry mechanism that can be helpful if there are issues generating responses from the model. It attempts to generate a response multiple times before raising an error.
### `Agent` Attributes
## `Agent` Attributes
| Attribute | Description |
|------------|-------------|
| `id` | A unique identifier for the agent instance. |
| `llm` | The language model instance used by the agent. |
| `template` | The template used for formatting responses. |
| `max_loops` | The maximum number of loops the agent can run. |
| `stopping_condition` | A callable function that determines when the agent should stop looping. |
| `loop_interval` | The interval (in seconds) between loops. |
| `retry_attempts` | The number of retry attempts for failed LLM calls. |
| `retry_interval` | The interval (in seconds) between retry attempts. |
| `return_history` | A boolean indicating whether the agent should return the conversation history. |
| `stopping_token` | A token that, when present in the response, stops the agent from looping. |
| `dynamic_loops` | A boolean indicating whether the agent should dynamically determine the number of loops. |
| `interactive` | A boolean indicating whether the agent should run in interactive mode. |
| `dashboard` | A boolean indicating whether the agent should display a dashboard. |
| `agent_name` | The name of the agent instance. |
| `agent_description` | A description of the agent instance. |
| `system_prompt` | The system prompt used to initialize the conversation. |
| `tools` | A list of callable functions representing tools the agent can use. |
| `dynamic_temperature_enabled` | A boolean indicating whether the agent should dynamically adjust the temperature of the LLM. |
| `sop` | The standard operating procedure for the agent. |
| `sop_list` | A list of strings representing the standard operating procedure. |
| `saved_state_path` | The file path for saving and loading the agent's state. |
| `autosave` | A boolean indicating whether the agent should automatically save its state. |
| `context_length` | The maximum length of the context window (in tokens) for the LLM. |
| `user_name` | The name used to represent the user in the conversation. |
| `self_healing_enabled` | A boolean indicating whether the agent should attempt to self-heal in case of errors. |
| `code_interpreter` | A boolean indicating whether the agent should interpret and execute code snippets. |
| `multi_modal` | A boolean indicating whether the agent should support multimodal inputs (e.g., text and images). |
| `pdf_path` | The file path of a PDF document to be ingested. |
| `list_of_pdf` | A list of file paths for PDF documents to be ingested. |
| `tokenizer` | An instance of a tokenizer used for token counting and management. |
| `long_term_memory` | An instance of a `BaseVectorDatabase` implementation for long-term memory management. |
| `preset_stopping_token` | A boolean indicating whether the agent should use a preset stopping token. |
| `traceback` | An object used for traceback handling. |
| `traceback_handlers` | A list of traceback handlers. |
| `streaming_on` | A boolean indicating whether the agent should stream its responses. |
| `docs` | A list of document paths or contents to be ingested. |
| `docs_folder` | The path to a folder containing documents to be ingested. |
| `verbose` | A boolean indicating whether the agent should print verbose output. |
| `parser` | A callable function used for parsing input data. |
| `best_of_n` | An integer indicating the number of best responses to generate (for sampling). |
| `callback` | A callable function to be called after each agent loop. |
| `metadata` | A dictionary containing metadata for the agent. |
| `callbacks` | A list of callable functions to be called during the agent's execution. |
| `logger_handler` | A handler for logging messages. |
| `search_algorithm` | A callable function representing the search algorithm for long-term memory retrieval. |
| `logs_to_filename` | The file path for logging agent activities. |
| `evaluator` | A callable function used for evaluating the agent's responses. |
| `output_json` | A boolean indicating whether the agent's output should be in JSON format. |
| `stopping_func` | A callable function used as a stopping condition for the agent. |
| `custom_loop_condition` | A callable function used as a custom loop condition for the agent. |
| `sentiment_threshold` | A float value representing the sentiment threshold for evaluating responses. |
| `custom_exit_command` | A string representing a custom command for exiting the agent's loop. |
| `sentiment_analyzer` | A callable function used for sentiment analysis on the agent's outputs. |
| `limit_tokens_from_string` | A callable function used for limiting the number of tokens in a string. |
| `custom_tools_prompt` | A callable function used for generating a custom prompt for tool usage. |
| `tool_schema` | A data structure representing the schema for the agent's tools. |
| `output_type` | A type representing the expected output type of the agent's responses. |
| `function_calling_type` | A string representing the type of function calling (e.g., "json"). |
| `output_cleaner` | A callable function used for cleaning the agent's output. |
| `function_calling_format_type` | A string representing the format type for function calling (e.g., "OpenAI"). |
| `list_base_models` | A list of base models used for generating tool schemas. |
| `metadata_output_type` | A string representing the output type for metadata. |
| `state_save_file_type` | A string representing the file type for saving the agent's state (e.g., "json", "yaml"). |
| `chain_of_thoughts` | A boolean indicating whether the agent should use the chain of thoughts technique. |
| `algorithm_of_thoughts` | A boolean indicating whether the agent should use the algorithm of thoughts technique. |
| `tree_of_thoughts` | A boolean indicating whether the agent should use the tree of thoughts technique. |
| `tool_choice` | A string representing the method for tool selection (e.g., "auto"). |
| `execute_tool` | A boolean indicating whether the agent should execute tools. |
| `rules` | A string representing the rules for the agent's behavior. |
| `planning` | A boolean indicating whether the agent should perform planning. |
| `planning_prompt` | A string representing the prompt for planning. |
| `device` | A string representing the device on which the agent should run. |
| `custom_planning_prompt` | A string representing a custom prompt for planning. |
| `memory_chunk_size` | An integer representing the maximum size of memory chunks for long-term memory retrieval. |
| `agent_ops_on` | A boolean indicating whether agent operations should be enabled. |
| `return_step_meta` | A boolean indicating whether or not to return JSON of all the steps and additional metadata |
| `output_type` | A Literal type indicating whether to output "string", "str", "list", "json", "dict", "yaml" |
### `Agent` Methods
|-----------|-------------|
| `id` | Unique identifier for the agent instance. |
| `llm` | Language model instance used by the agent. |
| `template` | Template used for formatting responses. |
| `max_loops` | Maximum number of loops the agent can run. |
| `stopping_condition` | Callable function determining when to stop looping. |
| `loop_interval` | Interval (in seconds) between loops. |
| `retry_attempts` | Number of retry attempts for failed LLM calls. |
| `retry_interval` | Interval (in seconds) between retry attempts. |
| `return_history` | Boolean indicating whether to return conversation history. |
| `stopping_token` | Token that stops the agent from looping when present in the response. |
| `dynamic_loops` | Boolean indicating whether to dynamically determine the number of loops. |
| `interactive` | Boolean indicating whether to run in interactive mode. |
| `dashboard` | Boolean indicating whether to display a dashboard. |
| `agent_name` | Name of the agent instance. |
| `agent_description` | Description of the agent instance. |
| `system_prompt` | System prompt used to initialize the conversation. |
| `tools` | List of callable functions representing tools the agent can use. |
| `dynamic_temperature_enabled` | Boolean indicating whether to dynamically adjust the LLM's temperature. |
| `sop` | Standard operating procedure for the agent. |
| `sop_list` | List of strings representing the standard operating procedure. |
| `saved_state_path` | File path for saving and loading the agent's state. |
| `autosave` | Boolean indicating whether to automatically save the agent's state. |
| `context_length` | Maximum length of the context window (in tokens) for the LLM. |
| `user_name` | Name used to represent the user in the conversation. |
| `self_healing_enabled` | Boolean indicating whether to attempt self-healing in case of errors. |
| `code_interpreter` | Boolean indicating whether to interpret and execute code snippets. |
| `multi_modal` | Boolean indicating whether to support multimodal inputs. |
| `pdf_path` | File path of a PDF document to be ingested. |
| `list_of_pdf` | List of file paths for PDF documents to be ingested. |
| `tokenizer` | Instance of a tokenizer used for token counting and management. |
| `long_term_memory` | Instance of a `BaseVectorDatabase` implementation for long-term memory management. |
| `preset_stopping_token` | Boolean indicating whether to use a preset stopping token. |
| `traceback` | Object used for traceback handling. |
| `traceback_handlers` | List of traceback handlers. |
| `streaming_on` | Boolean indicating whether to stream responses. |
| `docs` | List of document paths or contents to be ingested. |
| `docs_folder` | Path to a folder containing documents to be ingested. |
| `verbose` | Boolean indicating whether to print verbose output. |
| `parser` | Callable function used for parsing input data. |
| `best_of_n` | Integer indicating the number of best responses to generate. |
| `callback` | Callable function to be called after each agent loop. |
| `metadata` | Dictionary containing metadata for the agent. |
| `callbacks` | List of callable functions to be called during execution. |
| `logger_handler` | Handler for logging messages. |
| `search_algorithm` | Callable function for long-term memory retrieval. |
| `logs_to_filename` | File path for logging agent activities. |
| `evaluator` | Callable function for evaluating the agent's responses. |
| `stopping_func` | Callable function used as a stopping condition. |
| `custom_loop_condition` | Callable function used as a custom loop condition. |
| `sentiment_threshold` | Float value representing the sentiment threshold for evaluating responses. |
| `custom_exit_command` | String representing a custom command for exiting the agent's loop. |
| `sentiment_analyzer` | Callable function for sentiment analysis on outputs. |
| `limit_tokens_from_string` | Callable function for limiting the number of tokens in a string. |
| `custom_tools_prompt` | Callable function for generating a custom prompt for tool usage. |
| `tool_schema` | Data structure representing the schema for the agent's tools. |
| `output_type` | Type representing the expected output type of responses. |
| `function_calling_type` | String representing the type of function calling. |
| `output_cleaner` | Callable function for cleaning the agent's output. |
| `function_calling_format_type` | String representing the format type for function calling. |
| `list_base_models` | List of base models used for generating tool schemas. |
| `metadata_output_type` | String representing the output type for metadata. |
| `state_save_file_type` | String representing the file type for saving the agent's state. |
| `chain_of_thoughts` | Boolean indicating whether to use the chain of thoughts technique. |
| `algorithm_of_thoughts` | Boolean indicating whether to use the algorithm of thoughts technique. |
| `tree_of_thoughts` | Boolean indicating whether to use the tree of thoughts technique. |
| `tool_choice` | String representing the method for tool selection. |
| `execute_tool` | Boolean indicating whether to execute tools. |
| `rules` | String representing the rules for the agent's behavior. |
| `planning` | Boolean indicating whether to perform planning. |
| `planning_prompt` | String representing the prompt for planning. |
| `device` | String representing the device on which the agent should run. |
| `custom_planning_prompt` | String representing a custom prompt for planning. |
| `memory_chunk_size` | Integer representing the maximum size of memory chunks for long-term memory retrieval. |
| `agent_ops_on` | Boolean indicating whether agent operations should be enabled. |
| `return_step_meta` | Boolean indicating whether to return JSON of all steps and additional metadata. |
| `output_type` | Literal type indicating whether to output "string", "str", "list", "json", "dict", or "yaml". |
| `time_created` | Float representing the time the agent was created. |
| `tags` | Optional list of strings for tagging the agent. |
| `use_cases` | Optional list of dictionaries describing use cases for the agent. |
| `step_pool` | List of Step objects representing the agent's execution steps. |
| `print_every_step` | Boolean indicating whether to print every step of execution. |
| `agent_output` | ManySteps object containing the agent's output and metadata. |
| `executor_workers` | Integer representing the number of executor workers for concurrent operations. |
| `data_memory` | Optional callable for data memory operations. |
| `load_yaml_path` | String representing the path to a YAML file for loading configurations. |
| `auto_generate_prompt` | Boolean indicating whether to automatically generate prompts. |
## `Agent` Methods
| Method | Description | Inputs | Usage Example |
|--------|-------------|--------|----------------|
| `run(task, img=None, *args, **kwargs)` | Runs the autonomous agent loop to complete the given task. | `task` (str): The task to be performed.<br>`img` (str, optional): Path to an image file, if the task involves image processing.<br>`*args`, `**kwargs`: Additional arguments to pass to the language model. | `response = agent.run("Generate a report on financial performance.")` |
| `__call__(task, img=None, *args, **kwargs)` | An alternative way to call the `run` method. | Same as `run`. | `response = agent("Generate a report on financial performance.")` |
| `parse_and_execute_tools(response, *args, **kwargs)` | Parses the agent's response and executes any tools mentioned in it. | `response` (str): The agent's response to be parsed.<br>`*args`, `**kwargs`: Additional arguments to pass to the tool execution. | `agent.parse_and_execute_tools(response)` |
| `long_term_memory_prompt(query, *args, **kwargs)` | Generates a prompt for querying the agent's long-term memory. | `query` (str): The query to search for in long-term memory.<br>`*args`, `**kwargs`: Additional arguments to pass to the long-term memory retrieval. | `memory_retrieval = agent.long_term_memory_prompt("financial performance")` |
| `add_memory(message)` | Adds a message to the agent's memory. | `message` (str): The message
## Features
- **Language Model Integration**: The Swarm Agent allows seamless integration with different language models, enabling users to leverage the power of state-of-the-art models.
- **Tool Integration**: The framework supports the integration of various tools, enabling the agent to perform a wide range of tasks, from code execution to data analysis and beyond.
- **Long-term Memory Management**: The Swarm Agent incorporates long-term memory management capabilities, allowing it to store and retrieve relevant information for effective decision-making and task execution.
- **Document Ingestion**: The agent can ingest and process various types of documents, including PDFs, text files, Markdown files, JSON files, and more, enabling it to extract relevant information for task completion.
- **Interactive Mode**: Users can interact with the agent in an interactive mode, enabling real-time communication and task execution.
- **Dashboard**: The framework provides a visual dashboard for monitoring the agent's performance and activities.
- **Dynamic Temperature Control**: The Swarm Agent supports dynamic temperature control, allowing for adjustments to the model's output diversity during task execution.
- **Autosave and State Management**: The agent can save its state automatically, enabling seamless resumption of tasks after interruptions or system restarts.
- **Self-Healing and Error Handling**: The framework incorporates self-healing and error-handling mechanisms to ensure robust and reliable operation.
- **Code Interpretation**: The agent can interpret and execute code snippets, expanding its capabilities for tasks involving programming or scripting.
- **Multimodal Support**: The framework supports multimodal inputs, enabling the agent to process and reason about various data types, such as text, images, and audio.
- **Tokenization and Token Management**: The Swarm Agent provides tokenization capabilities, enabling efficient management of token usage and context window truncation.
- **Sentiment Analysis**: The agent can perform sentiment analysis on its generated outputs, allowing for evaluation and adjustment of responses based on sentiment thresholds.
- **Output Filtering and Cleaning**: The framework supports output filtering and cleaning, ensuring that generated responses adhere to specific criteria or guidelines.
- **Asynchronous and Concurrent Execution**: The Swarm Agent supports asynchronous and concurrent task execution, enabling efficient parallelization and scaling of operations.
- **Planning and Reasoning**: The agent can engage in planning and reasoning processes, leveraging techniques such as algorithm of thoughts and chain of thoughts to enhance decision-making and task execution.
- **Agent Operations and Monitoring**: The framework provides integration with agent operations and monitoring tools, enabling real-time monitoring and management of the agent's activities.
| `run(task, img=None, is_last=False, device="cpu", device_id=0, all_cores=True, *args, **kwargs)` | Runs the autonomous agent loop to complete the given task. | `task` (str): The task to be performed.<br>`img` (str, optional): Path to an image file.<br>`is_last` (bool): Whether this is the last task.<br>`device` (str): Device to run on ("cpu" or "gpu").<br>`device_id` (int): ID of the GPU to use.<br>`all_cores` (bool): Whether to use all CPU cores.<br>`*args`, `**kwargs`: Additional arguments. | `response = agent.run("Generate a report on financial performance.")` |
| `__call__(task, img=None, *args, **kwargs)` | Alternative way to call the `run` method. | Same as `run`. | `response = agent("Generate a report on financial performance.")` |
| `parse_and_execute_tools(response, *args, **kwargs)` | Parses the agent's response and executes any tools mentioned in it. | `response` (str): The agent's response to be parsed.<br>`*args`, `**kwargs`: Additional arguments. | `agent.parse_and_execute_tools(response)` |
| `add_memory(message)` | Adds a message to the agent's memory. | `message` (str): The message to add. | `agent.add_memory("Important information")` |
| `plan(task, *args, **kwargs)` | Plans the execution of a task. | `task` (str): The task to plan.<br>`*args`, `**kwargs`: Additional arguments. | `agent.plan("Analyze market trends")` |
| `run_concurrent(task, *args, **kwargs)` | Runs a task concurrently. | `task` (str): The task to run.<br>`*args`, `**kwargs`: Additional arguments. | `response = await agent.run_concurrent("Concurrent task")` |
| `run_concurrent_tasks(tasks, *args, **kwargs)` | Runs multiple tasks concurrently. | `tasks` (List[str]): List of tasks to run.<br>`*args`, `**kwargs`: Additional arguments. | `responses = agent.run_concurrent_tasks(["Task 1", "Task 2"])` |
| `bulk_run(inputs)` | Generates responses for multiple input sets. | `inputs` (List[Dict[str, Any]]): List of input dictionaries. | `responses = agent.bulk_run([{"task": "Task 1"}, {"task": "Task 2"}])` |
| `save()` | Saves the agent's history to a file. | None | `agent.save()` |
| `load(file_path)` | Loads the agent's history from a file. | `file_path` (str): Path to the file. | `agent.load("agent_history.json")` |
| `graceful_shutdown()` | Gracefully shuts down the system, saving the state. | None | `agent.graceful_shutdown()` |
| `analyze_feedback()` | Analyzes the feedback for issues. | None | `agent.analyze_feedback()` |
| `undo_last()` | Undoes the last response and returns the previous state. | None | `previous_state, message = agent.undo_last()` |
| `add_response_filter(filter_word)` | Adds a response filter to filter out certain words. | `filter_word` (str): Word to filter. | `agent.add_response_filter("sensitive")` |
| `apply_response_filters(response)` | Applies response filters to the given response. | `response` (str): Response to filter. | `filtered_response = agent.apply_response_filters(response)` |
| `filtered_run(task)` | Runs a task with response filtering applied. | `task` (str): Task to run. | `response = agent.filtered_run("Generate a report")` |
| `save_to_yaml(file_path)` | Saves the agent to a YAML file. | `file_path` (str): Path to save the YAML file. | `agent.save_to_yaml("agent_config.yaml")` |
| `get_llm_parameters()` | Returns the parameters of the language model. | None | `llm_params = agent.get_llm_parameters()` |
| `save_state(file_path, *args, **kwargs)` | Saves the current state of the agent to a JSON file. | `file_path` (str): Path to save the JSON file.<br>`*args`, `**kwargs`: Additional arguments. | `agent.save_state("agent_state.json")` |
| `load_state(file_path)` | Loads the state of the agent from a JSON file. | `file_path` (str): Path to the JSON file. | `agent.load_state("agent_state.json")` |
| `update_system_prompt(system_prompt)` | Updates the system prompt. | `system_prompt` (str): New system prompt. | `agent.update_system_prompt("New system instructions")` |
| `update_max_loops(max_loops)` | Updates the maximum number of loops. | `max_loops` (int): New maximum number of loops. | `agent.update_max_loops(5)` |
| `update_loop_interval(loop_interval)` | Updates the loop interval. | `loop_interval` (int): New loop interval. | `agent.update_loop_interval(2)` |
| `update_retry_attempts(retry_attempts)` | Updates the number of retry attempts. | `retry_attempts` (int): New number of retry attempts. | `agent.update_retry_attempts(3)` |
| `update_retry_interval(retry_interval)` | Updates the retry interval. | `retry_interval` (int): New retry interval. | `agent.update_retry_interval(5)` |
| `reset()` | Resets the agent's memory. | None | `agent.reset()` |
| `ingest_docs(docs, *args, **kwargs)` | Ingests documents into the agent's memory. | `docs` (List[str]): List of document paths.<br>`*args`, `**kwargs`: Additional arguments. | `agent.ingest_docs(["doc1.pdf", "doc2.txt"])` |
| `ingest_pdf(pdf)` | Ingests a PDF document into the agent's memory. | `pdf` (str): Path to the PDF file. | `agent.ingest_pdf("document.pdf")` |
| `receive_message(name, message)` | Receives a message and adds it to the agent's memory. | `name` (str): Name of the sender.<br>`message` (str): Content of the message. | `agent.receive_message("User", "Hello, agent!")` |
| `send_agent_message(agent_name, message, *args, **kwargs)` | Sends a message from the agent to a user. | `agent_name` (str): Name of the agent.<br>`message` (str): Message to send.<br>`*args`, `**kwargs`: Additional arguments. | `response = agent.send_agent_message("AgentX", "Task completed")` |
| `add_tool(tool)` | Adds a tool to the agent's toolset. | `tool` (Callable): Tool to add. | `agent.add_tool(my_custom_tool)` |
| `add_tools(tools)` | Adds multiple tools to the agent's toolset. | `tools` (List[Callable]): List of tools to add. | `agent.add_tools([tool1, tool2])` |
| `remove_tool(tool)` | Removes a tool from the agent's toolset. || Method | Description | Inputs | Usage Example |
|--------|-------------|--------|----------------|
| `remove_tool(tool)` | Removes a tool from the agent's toolset. | `tool` (Callable): Tool to remove. | `agent.remove_tool(my_custom_tool)` |
| `remove_tools(tools)` | Removes multiple tools from the agent's toolset. | `tools` (List[Callable]): List of tools to remove. | `agent.remove_tools([tool1, tool2])` |
| `get_docs_from_doc_folders()` | Retrieves and processes documents from the specified folder. | None | `agent.get_docs_from_doc_folders()` |
| `check_end_session_agentops()` | Checks and ends the AgentOps session if enabled. | None | `agent.check_end_session_agentops()` |
| `memory_query(task, *args, **kwargs)` | Queries the long-term memory for relevant information. | `task` (str): The task or query.<br>`*args`, `**kwargs`: Additional arguments. | `result = agent.memory_query("Find information about X")` |
| `sentiment_analysis_handler(response)` | Performs sentiment analysis on the given response. | `response` (str): The response to analyze. | `agent.sentiment_analysis_handler("Great job!")` |
| `count_and_shorten_context_window(history, *args, **kwargs)` | Counts tokens and shortens the context window if necessary. | `history` (str): The conversation history.<br>`*args`, `**kwargs`: Additional arguments. | `shortened_history = agent.count_and_shorten_context_window(history)` |
| `output_cleaner_and_output_type(response, *args, **kwargs)` | Cleans and formats the output based on specified type. | `response` (str): The response to clean and format.<br>`*args`, `**kwargs`: Additional arguments. | `cleaned_response = agent.output_cleaner_and_output_type(response)` |
| `stream_response(response, delay=0.001)` | Streams the response token by token. | `response` (str): The response to stream.<br>`delay` (float): Delay between tokens. | `agent.stream_response("This is a streamed response")` |
| `dynamic_context_window()` | Dynamically adjusts the context window. | None | `agent.dynamic_context_window()` |
| `check_available_tokens()` | Checks and returns the number of available tokens. | None | `available_tokens = agent.check_available_tokens()` |
| `tokens_checks()` | Performs token checks and returns available tokens. | None | `token_info = agent.tokens_checks()` |
| `truncate_string_by_tokens(input_string, limit)` | Truncates a string to fit within a token limit. | `input_string` (str): String to truncate.<br>`limit` (int): Token limit. | `truncated_string = agent.truncate_string_by_tokens("Long string", 100)` |
| `if_tokens_exceeds_context_length()` | Checks if the number of tokens exceeds the context length. | None | `exceeds = agent.if_tokens_exceeds_context_length()` |
| `tokens_operations(input_string)` | Performs various token-related operations on the input string. | `input_string` (str): String to process. | `processed_string = agent.tokens_operations("Input string")` |
| `parse_function_call_and_execute(response)` | Parses a function call from the response and executes it. | `response` (str): Response containing the function call. | `result = agent.parse_function_call_and_execute(response)` |
| `activate_agentops()` | Activates AgentOps functionality. | None | `agent.activate_agentops()` |
| `count_tokens_and_subtract_from_context_window(response, *args, **kwargs)` | Counts tokens in the response and adjusts the context window. | `response` (str): Response to process.<br>`*args`, `**kwargs`: Additional arguments. | `await agent.count_tokens_and_subtract_from_context_window(response)` |
| `llm_output_parser(response)` | Parses the output from the language model. | `response` (Any): Response from the LLM. | `parsed_response = agent.llm_output_parser(llm_output)` |
| `log_step_metadata(loop, task, response)` | Logs metadata for each step of the agent's execution. | `loop` (int): Current loop number.<br>`task` (str): Current task.<br>`response` (str): Agent's response. | `agent.log_step_metadata(1, "Analyze data", "Analysis complete")` |
| `to_dict()` | Converts the agent's attributes to a dictionary. | None | `agent_dict = agent.to_dict()` |
| `to_json(indent=4, *args, **kwargs)` | Converts the agent's attributes to a JSON string. | `indent` (int): Indentation for JSON.<br>`*args`, `**kwargs`: Additional arguments. | `agent_json = agent.to_json()` |
| `to_yaml(indent=4, *args, **kwargs)` | Converts the agent's attributes to a YAML string. | `indent` (int): Indentation for YAML.<br>`*args`, `**kwargs`: Additional arguments. | `agent_yaml = agent.to_yaml()` |
| `to_toml(*args, **kwargs)` | Converts the agent's attributes to a TOML string. | `*args`, `**kwargs`: Additional arguments. | `agent_toml = agent.to_toml()` |
| `model_dump_json()` | Saves the agent model to a JSON file in the workspace directory. | None | `agent.model_dump_json()` |
| `model_dump_yaml()` | Saves the agent model to a YAML file in the workspace directory. | None | `agent.model_dump_yaml()` |
| `log_agent_data()` | Logs the agent's data to an external API. | None | `agent.log_agent_data()` |
| `handle_tool_schema_ops()` | Handles operations related to tool schemas. | None | `agent.handle_tool_schema_ops()` |
| `call_llm(task, *args, **kwargs)` | Calls the appropriate method on the language model. | `task` (str): Task for the LLM.<br>`*args`, `**kwargs`: Additional arguments. | `response = agent.call_llm("Generate text")` |
| `handle_sop_ops()` | Handles operations related to standard operating procedures. | None | `agent.handle_sop_ops()` |
| `agent_output_type(responses)` | Processes and returns the agent's output based on the specified output type. | `responses` (list): List of responses. | `formatted_output = agent.agent_output_type(responses)` |
| `check_if_no_prompt_then_autogenerate(task)` | Checks if a system prompt is not set and auto-generates one if needed. | `task` (str): The task to use for generating a prompt. | `agent.check_if_no_prompt_then_autogenerate("Analyze data")` |
## Getting Started
First run the following:
To use the Swarm Agent, first install the required dependencies:
```bash
pip3 install -U swarms
```
And, then now you can get started with the following:
Then, you can initialize and use the agent as follows:
```python
import os
from swarms import Agent
from swarm_models import OpenAIChat
from swarms.prompts.finance_agent_sys_prompt import (
FINANCIAL_AGENT_SYS_PROMPT,
)
from swarms.prompts.finance_agent_sys_prompt import FINANCIAL_AGENT_SYS_PROMPT
# Get the OpenAI API key from the environment variable
api_key = os.getenv("OPENAI_API_KEY")
# Create an instance of the OpenAIChat class
model = OpenAIChat(
api_key=api_key, model_name="gpt-4o-mini", temperature=0.1
api_key=api_key, model_name="gpt-4-0613", temperature=0.1
)
# Initialize the agent
agent = Agent(
agent_name="Financial-Analysis-Agent_sas_chicken_eej",
agent_name="Financial-Analysis-Agent",
system_prompt=FINANCIAL_AGENT_SYS_PROMPT,
llm=model,
max_loops=1,
@ -171,23 +246,18 @@ agent = Agent(
output_type="str",
)
agent.run(
"How can I establish a ROTH IRA to buy stocks and get a tax break? What are the criteria"
# Run the agent
response = agent.run(
"How can I establish a ROTH IRA to buy stocks and get a tax break? What are the criteria?"
)
print(out)
print(response)
```
This example initializes an instance of the `Agent` class with an OpenAI language model and a maximum of 3 loops. The `run()` method is then called with a task to generate a report on financial performance, and the agent's response is printed.
## Advanced Usage
The Swarm Agent provides numerous advanced features and customization options. Here are a few examples of how to leverage these features:
### Tool Integration
To integrate tools with the Swarm Agent, you can pass a list of callable functions with types and doc strings to the `tools` parameter when initializing the `Agent` instance. The agent will automatically convert these functions into an OpenAI function calling schema and make them available for use during task execution.
To integrate tools with the Swarm `Agent`, you can pass a list of callable functions with types and doc strings to the `tools` parameter when initializing the `Agent` instance. The agent will automatically convert these functions into an OpenAI function calling schema and make them available for use during task execution.
## Requirements for a tool
- Function
@ -197,30 +267,9 @@ To integrate tools with the Swarm Agent, you can pass a list of callable functio
```python
from swarms import Agent
from swarm_models import OpenAIChat
from swarms_memory import ChromaDB
import subprocess
import os
# Making an instance of the ChromaDB class
memory = ChromaDB(
metric="cosine",
n_results=3,
output_dir="results",
docs_folder="docs",
)
# Model
model = OpenAIChat(
api_key=os.getenv("OPENAI_API_KEY"),
model_name="gpt-4o-mini",
temperature=0.1,
)
# Tools in swarms are simple python functions and docstrings
def terminal(
code: str,
):
def terminal(code: str):
"""
Run code in the terminal.
@ -230,185 +279,90 @@ def terminal(
Returns:
str: The output of the code.
"""
out = subprocess.run(
code, shell=True, capture_output=True, text=True
).stdout
out = subprocess.run(code, shell=True, capture_output=True, text=True).stdout
return str(out)
def browser(query: str):
"""
Search the query in the browser with the `browser` tool.
Args:
query (str): The query to search in the browser.
Returns:
str: The search results.
"""
import webbrowser
url = f"https://www.google.com/search?q={query}"
webbrowser.open(url)
return f"Searching for {query} in the browser."
def create_file(file_path: str, content: str):
"""
Create a file using the file editor tool.
Args:
file_path (str): The path to the file.
content (str): The content to write to the file.
Returns:
str: The result of the file creation operation.
"""
with open(file_path, "w") as file:
file.write(content)
return f"File {file_path} created successfully."
def file_editor(file_path: str, mode: str, content: str):
"""
Edit a file using the file editor tool.
Args:
file_path (str): The path to the file.
mode (str): The mode to open the file in.
content (str): The content to write to the file.
Returns:
str: The result of the file editing operation.
"""
with open(file_path, mode) as file:
file.write(content)
return f"File {file_path} edited successfully."
# Agent
# Initialize the agent with a tool
agent = Agent(
agent_name="Devin",
system_prompt=(
"Autonomous agent that can interact with humans and other"
" agents. Be Helpful and Kind. Use the tools provided to"
" assist the user. Return all code in markdown format."
),
llm=model,
max_loops="auto",
autosave=True,
dashboard=False,
streaming_on=True,
verbose=True,
stopping_token="<DONE>",
interactive=True,
tools=[terminal, browser, file_editor, create_file],
streaming=True,
long_term_memory=memory,
agent_name="Terminal-Agent",
llm=OpenAIChat(api_key=os.getenv("OPENAI_API_KEY")),
tools=[terminal],
system_prompt="You are an agent that can execute terminal commands. Use the tools provided to assist the user.",
)
# Run the agent
out = agent(
"Create a CSV file with the latest tax rates for C corporations in the following ten states and the District of Columbia: Alabama, California, Florida, Georgia, Illinois, New York, North Carolina, Ohio, Texas, and Washington."
)
print(out)
response = agent.run("List the contents of the current directory")
print(response)
```
### Long-term Memory Management
The Swarm Agent supports integration with various vector databases for long-term memory management. You can pass an instance of a `BaseVectorDatabase` implementation to the `long_term_memory` parameter when initializing the `Agent`.
The Swarm Agent supports integration with vector databases for long-term memory management. Here's an example using ChromaDB:
```python
import os
from swarms_memory import ChromaDB
from swarms import Agent
from swarm_models import Anthropic
from swarms.prompts.finance_agent_sys_prompt import (
FINANCIAL_AGENT_SYS_PROMPT,
)
from swarms_memory import ChromaDB
# Initilaize the chromadb client
# Initialize ChromaDB
chromadb = ChromaDB(
metric="cosine",
output_dir="fiance_agent_rag",
# docs_folder="artifacts", # Folder of your documents
output_dir="finance_agent_rag",
)
# Model
model = Anthropic(anthropic_api_key=os.getenv("ANTHROPIC_API_KEY"))
# Initialize the agent
# Initialize the agent with long-term memory
agent = Agent(
agent_name="Financial-Analysis-Agent",
system_prompt=FINANCIAL_AGENT_SYS_PROMPT,
agent_description="Agent creates ",
llm=model,
max_loops="auto",
autosave=True,
dashboard=False,
verbose=True,
streaming_on=True,
dynamic_temperature_enabled=True,
saved_state_path="finance_agent.json",
user_name="swarms_corp",
retry_attempts=3,
context_length=200000,
llm=Anthropic(anthropic_api_key=os.getenv("ANTHROPIC_API_KEY")),
long_term_memory=chromadb,
system_prompt="You are a financial analysis agent with access to long-term memory.",
)
agent.run(
"What are the components of a startups stock incentive equity plan"
)
```
### Document Ingestion
The Swarm Agent can ingest various types of documents, such as PDFs, text files, Markdown files, and JSON files. You can pass a list of document paths or contents to the `docs` parameter when initializing the `Agent`.
```python
from swarms.structs import Agent
# Initialize the agent with documents
agent = Agent(llm=llm, max_loops=3, docs=["path/to/doc1.pdf", "path/to/doc2.txt"])
# Run the agent
response = agent.run("What are the components of a startup's stock incentive equity plan?")
print(response)
```
### Interactive Mode
The Swarm Agent supports an interactive mode, where users can engage in real-time communication with the agent. To enable interactive mode, set the `interactive` parameter to `True` when initializing the `Agent`.
To enable interactive mode, set the `interactive` parameter to `True` when initializing the `Agent`:
```python
from swarms.structs import Agent
# Initialize the agent in interactive mode
agent = Agent(llm=llm, max_loops=3, interactive=True)
agent = Agent(
agent_name="Interactive-Agent",
llm=OpenAIChat(api_key=os.getenv("OPENAI_API_KEY")),
interactive=True,
system_prompt="You are an interactive agent. Engage in a conversation with the user.",
)
# Run the agent in interactive mode
agent.interactive_run()
agent.run("Let's start a conversation")
```
### Sentiment Analysis
The Swarm Agent can perform sentiment analysis on its generated outputs using a sentiment analyzer function. You can pass a callable function to the `sentiment_analyzer` parameter when initializing the `Agent`.
To perform sentiment analysis on the agent's outputs, you can provide a sentiment analyzer function:
```python
from swarms.structs import Agent
from my_sentiment_analyzer import sentiment_analyzer_function
from textblob import TextBlob
def sentiment_analyzer(text):
analysis = TextBlob(text)
return analysis.sentiment.polarity
# Initialize the agent with a sentiment analyzer
agent = Agent(
agent_name = "sentiment-analyzer-agent-01", system_prompt="..."
llm=llm, max_loops=3, sentiment_analyzer=sentiment_analyzer_function)
agent_name="Sentiment-Analysis-Agent",
llm=OpenAIChat(api_key=os.getenv("OPENAI_API_KEY")),
sentiment_analyzer=sentiment_analyzer,
sentiment_threshold=0.5,
system_prompt="You are an agent that generates responses with sentiment analysis.",
)
response = agent.run("Generate a positive statement about AI")
print(response)
```
## Documentation Examples
The Swarm Agent provides numerous examples and usage scenarios throughout the documentation. Here are a few examples to illustrate various features and functionalities:
### Undo Functionality
@ -516,4 +470,76 @@ agent.check_end_session_agentops()
# Dump the model to a JSON file
agent.model_dump_json()
print(agent.to_toml())
```
```
## Auto Generate Prompt + CPU Execution
```python
import os
from swarms import Agent
from swarm_models import OpenAIChat
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
# Retrieve the OpenAI API key from the environment variable
api_key = os.getenv("GROQ_API_KEY")
# Initialize the model for OpenAI Chat
model = OpenAIChat(
openai_api_base="https://api.groq.com/openai/v1",
openai_api_key=api_key,
model_name="llama-3.1-70b-versatile",
temperature=0.1,
)
# Initialize the agent with automated prompt engineering enabled
agent = Agent(
agent_name="Financial-Analysis-Agent",
system_prompt=None, # System prompt is dynamically generated
agent_description=None,
llm=model,
max_loops=1,
autosave=True,
dashboard=False,
verbose=False,
dynamic_temperature_enabled=True,
saved_state_path="finance_agent.json",
user_name="Human:",
return_step_meta=False,
output_type="string",
streaming_on=False,
auto_generate_prompt=True, # Enable automated prompt engineering
)
# Run the agent with a task description and specify the device
agent.run(
"How can I establish a ROTH IRA to buy stocks and get a tax break? What are the criteria",
## Will design a system prompt based on the task if description and system prompt are None
device="cpu",
)
# Print the dynamically generated system prompt
print(agent.system_prompt)
```
## Best Practices
1. Always provide a clear and concise `system_prompt` to guide the agent's behavior.
2. Use `tools` to extend the agent's capabilities for specific tasks.
3. Implement error handling and utilize the `retry_attempts` feature for robust execution.
4. Leverage `long_term_memory` for tasks that require persistent information.
5. Use `interactive` mode for real-time conversations and `dashboard` for monitoring.
6. Implement `sentiment_analysis` for applications requiring tone management.
7. Utilize `autosave` and `save_state`/`load_state` methods for continuity across sessions.
8. Optimize token usage with `dynamic_context_window` and `tokens_checks` methods.
9. Use `concurrent` and `async` methods for performance-critical applications.
10. Regularly review and analyze feedback using the `analyze_feedback` method.
By following these guidelines and leveraging the Swarm Agent's extensive features, you can create powerful, flexible, and efficient autonomous agents for a wide range of applications.

@ -0,0 +1,537 @@
# `Agent` Documentation
Swarm Agent is a powerful autonomous agent framework designed to connect Language Models (LLMs) with various tools and long-term memory. This class provides the ability to ingest and process various types of documents such as PDFs, text files, Markdown files, JSON files, and more. The Agent structure offers a wide range of features to enhance the capabilities of LLMs and facilitate efficient task execution.
1. **Conversational Loop**: It establishes a conversational loop with a language model. This means it allows you to interact with the model in a back-and-forth manner, taking turns in the conversation.
2. **Feedback Collection**: The class allows users to provide feedback on the responses generated by the model. This feedback can be valuable for training and improving the model's responses over time.
3. **Stoppable Conversation**: You can define custom stopping conditions for the conversation, allowing you to stop the interaction based on specific criteria. For example, you can stop the conversation if a certain keyword is detected in the responses.
4. **Retry Mechanism**: The class includes a retry mechanism that can be helpful if there are issues generating responses from the model. It attempts to generate a response multiple times before raising an error.
## Architecture
```mermaid
graph TD
A[Task Initiation] -->|Receives Task| B[Initial LLM Processing]
B -->|Interprets Task| C[Tool Usage]
C -->|Calls Tools| D[Function 1]
C -->|Calls Tools| E[Function 2]
D -->|Returns Data| C
E -->|Returns Data| C
C -->|Provides Data| F[Memory Interaction]
F -->|Stores and Retrieves Data| G[RAG System]
G -->|ChromaDB/Pinecone| H[Enhanced Data]
F -->|Provides Enhanced Data| I[Final LLM Processing]
I -->|Generates Final Response| J[Output]
C -->|No Tools Available| K[Skip Tool Usage]
K -->|Proceeds to Memory Interaction| F
F -->|No Memory Available| L[Skip Memory Interaction]
L -->|Proceeds to Final LLM Processing| I
```
### `Agent` Attributes
| Attribute | Description |
|------------|-------------|
| `id` | A unique identifier for the agent instance. |
| `llm` | The language model instance used by the agent. |
| `template` | The template used for formatting responses. |
| `max_loops` | The maximum number of loops the agent can run. |
| `stopping_condition` | A callable function that determines when the agent should stop looping. |
| `loop_interval` | The interval (in seconds) between loops. |
| `retry_attempts` | The number of retry attempts for failed LLM calls. |
| `retry_interval` | The interval (in seconds) between retry attempts. |
| `return_history` | A boolean indicating whether the agent should return the conversation history. |
| `stopping_token` | A token that, when present in the response, stops the agent from looping. |
| `dynamic_loops` | A boolean indicating whether the agent should dynamically determine the number of loops. |
| `interactive` | A boolean indicating whether the agent should run in interactive mode. |
| `dashboard` | A boolean indicating whether the agent should display a dashboard. |
| `agent_name` | The name of the agent instance. |
| `agent_description` | A description of the agent instance. |
| `system_prompt` | The system prompt used to initialize the conversation. |
| `tools` | A list of callable functions representing tools the agent can use. |
| `dynamic_temperature_enabled` | A boolean indicating whether the agent should dynamically adjust the temperature of the LLM. |
| `sop` | The standard operating procedure for the agent. |
| `sop_list` | A list of strings representing the standard operating procedure. |
| `saved_state_path` | The file path for saving and loading the agent's state. |
| `autosave` | A boolean indicating whether the agent should automatically save its state. |
| `context_length` | The maximum length of the context window (in tokens) for the LLM. |
| `user_name` | The name used to represent the user in the conversation. |
| `self_healing_enabled` | A boolean indicating whether the agent should attempt to self-heal in case of errors. |
| `code_interpreter` | A boolean indicating whether the agent should interpret and execute code snippets. |
| `multi_modal` | A boolean indicating whether the agent should support multimodal inputs (e.g., text and images). |
| `pdf_path` | The file path of a PDF document to be ingested. |
| `list_of_pdf` | A list of file paths for PDF documents to be ingested. |
| `tokenizer` | An instance of a tokenizer used for token counting and management. |
| `long_term_memory` | An instance of a `BaseVectorDatabase` implementation for long-term memory management. |
| `preset_stopping_token` | A boolean indicating whether the agent should use a preset stopping token. |
| `traceback` | An object used for traceback handling. |
| `traceback_handlers` | A list of traceback handlers. |
| `streaming_on` | A boolean indicating whether the agent should stream its responses. |
| `docs` | A list of document paths or contents to be ingested. |
| `docs_folder` | The path to a folder containing documents to be ingested. |
| `verbose` | A boolean indicating whether the agent should print verbose output. |
| `parser` | A callable function used for parsing input data. |
| `best_of_n` | An integer indicating the number of best responses to generate (for sampling). |
| `callback` | A callable function to be called after each agent loop. |
| `metadata` | A dictionary containing metadata for the agent. |
| `callbacks` | A list of callable functions to be called during the agent's execution. |
| `logger_handler` | A handler for logging messages. |
| `search_algorithm` | A callable function representing the search algorithm for long-term memory retrieval. |
| `logs_to_filename` | The file path for logging agent activities. |
| `evaluator` | A callable function used for evaluating the agent's responses. |
| `output_json` | A boolean indicating whether the agent's output should be in JSON format. |
| `stopping_func` | A callable function used as a stopping condition for the agent. |
| `custom_loop_condition` | A callable function used as a custom loop condition for the agent. |
| `sentiment_threshold` | A float value representing the sentiment threshold for evaluating responses. |
| `custom_exit_command` | A string representing a custom command for exiting the agent's loop. |
| `sentiment_analyzer` | A callable function used for sentiment analysis on the agent's outputs. |
| `limit_tokens_from_string` | A callable function used for limiting the number of tokens in a string. |
| `custom_tools_prompt` | A callable function used for generating a custom prompt for tool usage. |
| `tool_schema` | A data structure representing the schema for the agent's tools. |
| `output_type` | A type representing the expected output type of the agent's responses. |
| `function_calling_type` | A string representing the type of function calling (e.g., "json"). |
| `output_cleaner` | A callable function used for cleaning the agent's output. |
| `function_calling_format_type` | A string representing the format type for function calling (e.g., "OpenAI"). |
| `list_base_models` | A list of base models used for generating tool schemas. |
| `metadata_output_type` | A string representing the output type for metadata. |
| `state_save_file_type` | A string representing the file type for saving the agent's state (e.g., "json", "yaml"). |
| `chain_of_thoughts` | A boolean indicating whether the agent should use the chain of thoughts technique. |
| `algorithm_of_thoughts` | A boolean indicating whether the agent should use the algorithm of thoughts technique. |
| `tree_of_thoughts` | A boolean indicating whether the agent should use the tree of thoughts technique. |
| `tool_choice` | A string representing the method for tool selection (e.g., "auto"). |
| `execute_tool` | A boolean indicating whether the agent should execute tools. |
| `rules` | A string representing the rules for the agent's behavior. |
| `planning` | A boolean indicating whether the agent should perform planning. |
| `planning_prompt` | A string representing the prompt for planning. |
| `device` | A string representing the device on which the agent should run. |
| `custom_planning_prompt` | A string representing a custom prompt for planning. |
| `memory_chunk_size` | An integer representing the maximum size of memory chunks for long-term memory retrieval. |
| `agent_ops_on` | A boolean indicating whether agent operations should be enabled. |
| `return_step_meta` | A boolean indicating whether or not to return JSON of all the steps and additional metadata |
| `output_type` | A Literal type indicating whether to output "string", "str", "list", "json", "dict", "yaml" |
### `Agent` Methods
| Method | Description | Inputs | Usage Example |
|--------|-------------|--------|----------------|
| `run(task, img=None, *args, **kwargs)` | Runs the autonomous agent loop to complete the given task. | `task` (str): The task to be performed.<br>`img` (str, optional): Path to an image file, if the task involves image processing.<br>`*args`, `**kwargs`: Additional arguments to pass to the language model. | `response = agent.run("Generate a report on financial performance.")` |
| `__call__(task, img=None, *args, **kwargs)` | An alternative way to call the `run` method. | Same as `run`. | `response = agent("Generate a report on financial performance.")` |
| `parse_and_execute_tools(response, *args, **kwargs)` | Parses the agent's response and executes any tools mentioned in it. | `response` (str): The agent's response to be parsed.<br>`*args`, `**kwargs`: Additional arguments to pass to the tool execution. | `agent.parse_and_execute_tools(response)` |
| `long_term_memory_prompt(query, *args, **kwargs)` | Generates a prompt for querying the agent's long-term memory. | `query` (str): The query to search for in long-term memory.<br>`*args`, `**kwargs`: Additional arguments to pass to the long-term memory retrieval. | `memory_retrieval = agent.long_term_memory_prompt("financial performance")` |
| `add_memory(message)` | Adds a message to the agent's memory. | `message` (str): The message
## Features
- **Language Model Integration**: The Swarm Agent allows seamless integration with different language models, enabling users to leverage the power of state-of-the-art models.
- **Tool Integration**: The framework supports the integration of various tools, enabling the agent to perform a wide range of tasks, from code execution to data analysis and beyond.
- **Long-term Memory Management**: The Swarm Agent incorporates long-term memory management capabilities, allowing it to store and retrieve relevant information for effective decision-making and task execution.
- **Document Ingestion**: The agent can ingest and process various types of documents, including PDFs, text files, Markdown files, JSON files, and more, enabling it to extract relevant information for task completion.
- **Interactive Mode**: Users can interact with the agent in an interactive mode, enabling real-time communication and task execution.
- **Dashboard**: The framework provides a visual dashboard for monitoring the agent's performance and activities.
- **Dynamic Temperature Control**: The Swarm Agent supports dynamic temperature control, allowing for adjustments to the model's output diversity during task execution.
- **Autosave and State Management**: The agent can save its state automatically, enabling seamless resumption of tasks after interruptions or system restarts.
- **Self-Healing and Error Handling**: The framework incorporates self-healing and error-handling mechanisms to ensure robust and reliable operation.
- **Code Interpretation**: The agent can interpret and execute code snippets, expanding its capabilities for tasks involving programming or scripting.
- **Multimodal Support**: The framework supports multimodal inputs, enabling the agent to process and reason about various data types, such as text, images, and audio.
- **Tokenization and Token Management**: The Swarm Agent provides tokenization capabilities, enabling efficient management of token usage and context window truncation.
- **Sentiment Analysis**: The agent can perform sentiment analysis on its generated outputs, allowing for evaluation and adjustment of responses based on sentiment thresholds.
- **Output Filtering and Cleaning**: The framework supports output filtering and cleaning, ensuring that generated responses adhere to specific criteria or guidelines.
- **Asynchronous and Concurrent Execution**: The Swarm Agent supports asynchronous and concurrent task execution, enabling efficient parallelization and scaling of operations.
- **Planning and Reasoning**: The agent can engage in planning and reasoning processes, leveraging techniques such as algorithm of thoughts and chain of thoughts to enhance decision-making and task execution.
- **Agent Operations and Monitoring**: The framework provides integration with agent operations and monitoring tools, enabling real-time monitoring and management of the agent's activities.
## Getting Started
First run the following:
```bash
pip3 install -U swarms
```
And, then now you can get started with the following:
```python
import os
from swarms import Agent
from swarm_models import OpenAIChat
from swarms.prompts.finance_agent_sys_prompt import (
FINANCIAL_AGENT_SYS_PROMPT,
)
# Get the OpenAI API key from the environment variable
api_key = os.getenv("OPENAI_API_KEY")
# Create an instance of the OpenAIChat class
model = OpenAIChat(
api_key=api_key, model_name="gpt-4o-mini", temperature=0.1
)
# Initialize the agent
agent = Agent(
agent_name="Financial-Analysis-Agent_sas_chicken_eej",
system_prompt=FINANCIAL_AGENT_SYS_PROMPT,
llm=model,
max_loops=1,
autosave=True,
dashboard=False,
verbose=True,
dynamic_temperature_enabled=True,
saved_state_path="finance_agent.json",
user_name="swarms_corp",
retry_attempts=1,
context_length=200000,
return_step_meta=False,
output_type="str",
)
agent.run(
"How can I establish a ROTH IRA to buy stocks and get a tax break? What are the criteria"
)
print(out)
```
This example initializes an instance of the `Agent` class with an OpenAI language model and a maximum of 3 loops. The `run()` method is then called with a task to generate a report on financial performance, and the agent's response is printed.
## Advanced Usage
The Swarm Agent provides numerous advanced features and customization options. Here are a few examples of how to leverage these features:
### Tool Integration
To integrate tools with the Swarm Agent, you can pass a list of callable functions with types and doc strings to the `tools` parameter when initializing the `Agent` instance. The agent will automatically convert these functions into an OpenAI function calling schema and make them available for use during task execution.
## Requirements for a tool
- Function
- With types
- with doc strings
```python
from swarms import Agent
from swarm_models import OpenAIChat
from swarms_memory import ChromaDB
import subprocess
import os
# Making an instance of the ChromaDB class
memory = ChromaDB(
metric="cosine",
n_results=3,
output_dir="results",
docs_folder="docs",
)
# Model
model = OpenAIChat(
api_key=os.getenv("OPENAI_API_KEY"),
model_name="gpt-4o-mini",
temperature=0.1,
)
# Tools in swarms are simple python functions and docstrings
def terminal(
code: str,
):
"""
Run code in the terminal.
Args:
code (str): The code to run in the terminal.
Returns:
str: The output of the code.
"""
out = subprocess.run(
code, shell=True, capture_output=True, text=True
).stdout
return str(out)
def browser(query: str):
"""
Search the query in the browser with the `browser` tool.
Args:
query (str): The query to search in the browser.
Returns:
str: The search results.
"""
import webbrowser
url = f"https://www.google.com/search?q={query}"
webbrowser.open(url)
return f"Searching for {query} in the browser."
def create_file(file_path: str, content: str):
"""
Create a file using the file editor tool.
Args:
file_path (str): The path to the file.
content (str): The content to write to the file.
Returns:
str: The result of the file creation operation.
"""
with open(file_path, "w") as file:
file.write(content)
return f"File {file_path} created successfully."
def file_editor(file_path: str, mode: str, content: str):
"""
Edit a file using the file editor tool.
Args:
file_path (str): The path to the file.
mode (str): The mode to open the file in.
content (str): The content to write to the file.
Returns:
str: The result of the file editing operation.
"""
with open(file_path, mode) as file:
file.write(content)
return f"File {file_path} edited successfully."
# Agent
agent = Agent(
agent_name="Devin",
system_prompt=(
"Autonomous agent that can interact with humans and other"
" agents. Be Helpful and Kind. Use the tools provided to"
" assist the user. Return all code in markdown format."
),
llm=model,
max_loops="auto",
autosave=True,
dashboard=False,
streaming_on=True,
verbose=True,
stopping_token="<DONE>",
interactive=True,
tools=[terminal, browser, file_editor, create_file],
streaming=True,
long_term_memory=memory,
)
# Run the agent
out = agent(
"Create a CSV file with the latest tax rates for C corporations in the following ten states and the District of Columbia: Alabama, California, Florida, Georgia, Illinois, New York, North Carolina, Ohio, Texas, and Washington."
)
print(out)
```
### Long-term Memory Management
The Swarm Agent supports integration with various vector databases for long-term memory management. You can pass an instance of a `BaseVectorDatabase` implementation to the `long_term_memory` parameter when initializing the `Agent`.
```python
import os
from swarms_memory import ChromaDB
from swarms import Agent
from swarm_models import Anthropic
from swarms.prompts.finance_agent_sys_prompt import (
FINANCIAL_AGENT_SYS_PROMPT,
)
# Initilaize the chromadb client
chromadb = ChromaDB(
metric="cosine",
output_dir="fiance_agent_rag",
# docs_folder="artifacts", # Folder of your documents
)
# Model
model = Anthropic(anthropic_api_key=os.getenv("ANTHROPIC_API_KEY"))
# Initialize the agent
agent = Agent(
agent_name="Financial-Analysis-Agent",
system_prompt=FINANCIAL_AGENT_SYS_PROMPT,
agent_description="Agent creates ",
llm=model,
max_loops="auto",
autosave=True,
dashboard=False,
verbose=True,
streaming_on=True,
dynamic_temperature_enabled=True,
saved_state_path="finance_agent.json",
user_name="swarms_corp",
retry_attempts=3,
context_length=200000,
long_term_memory=chromadb,
)
agent.run(
"What are the components of a startups stock incentive equity plan"
)
```
### Document Ingestion
The Swarm Agent can ingest various types of documents, such as PDFs, text files, Markdown files, and JSON files. You can pass a list of document paths or contents to the `docs` parameter when initializing the `Agent`.
```python
from swarms.structs import Agent
# Initialize the agent with documents
agent = Agent(llm=llm, max_loops=3, docs=["path/to/doc1.pdf", "path/to/doc2.txt"])
```
### Interactive Mode
The Swarm Agent supports an interactive mode, where users can engage in real-time communication with the agent. To enable interactive mode, set the `interactive` parameter to `True` when initializing the `Agent`.
```python
from swarms.structs import Agent
# Initialize the agent in interactive mode
agent = Agent(llm=llm, max_loops=3, interactive=True)
# Run the agent in interactive mode
agent.interactive_run()
```
### Sentiment Analysis
The Swarm Agent can perform sentiment analysis on its generated outputs using a sentiment analyzer function. You can pass a callable function to the `sentiment_analyzer` parameter when initializing the `Agent`.
```python
from swarms.structs import Agent
from my_sentiment_analyzer import sentiment_analyzer_function
# Initialize the agent with a sentiment analyzer
agent = Agent(
agent_name = "sentiment-analyzer-agent-01", system_prompt="..."
llm=llm, max_loops=3, sentiment_analyzer=sentiment_analyzer_function)
```
### Undo Functionality
```python
# Feature 2: Undo functionality
response = agent.run("Another task")
print(f"Response: {response}")
previous_state, message = agent.undo_last()
print(message)
```
### Response Filtering
```python
# Feature 3: Response filtering
agent.add_response_filter("report")
response = agent.filtered_run("Generate a report on finance")
print(response)
```
### Saving and Loading State
```python
# Save the agent state
agent.save_state('saved_flow.json')
# Load the agent state
agent = Agent(llm=llm_instance, max_loops=5)
agent.load_state('saved_flow.json')
agent.run("Continue with the task")
```
### Async and Concurrent Execution
```python
# Run a task concurrently
response = await agent.run_concurrent("Concurrent task")
print(response)
# Run multiple tasks concurrently
tasks = [
{"task": "Task 1"},
{"task": "Task 2", "img": "path/to/image.jpg"},
{"task": "Task 3", "custom_param": 42}
]
responses = agent.bulk_run(tasks)
print(responses)
```
### Various other settings
```python
# # Convert the agent object to a dictionary
print(agent.to_dict())
print(agent.to_toml())
print(agent.model_dump_json())
print(agent.model_dump_yaml())
# Ingest documents into the agent's knowledge base
agent.ingest_docs("your_pdf_path.pdf")
# Receive a message from a user and process it
agent.receive_message(name="agent_name", message="message")
# Send a message from the agent to a user
agent.send_agent_message(agent_name="agent_name", message="message")
# Ingest multiple documents into the agent's knowledge base
agent.ingest_docs("your_pdf_path.pdf", "your_csv_path.csv")
# Run the agent with a filtered system prompt
agent.filtered_run(
"How can I establish a ROTH IRA to buy stocks and get a tax break? What are the criteria?"
)
# Run the agent with multiple system prompts
agent.bulk_run(
[
"How can I establish a ROTH IRA to buy stocks and get a tax break? What are the criteria?",
"Another system prompt",
]
)
# Add a memory to the agent
agent.add_memory("Add a memory to the agent")
# Check the number of available tokens for the agent
agent.check_available_tokens()
# Perform token checks for the agent
agent.tokens_checks()
# Print the dashboard of the agent
agent.print_dashboard()
# Fetch all the documents from the doc folders
agent.get_docs_from_doc_folders()
# Activate agent ops
agent.activate_agentops()
agent.check_end_session_agentops()
# Dump the model to a JSON file
agent.model_dump_json()
print(agent.to_toml())
```

@ -9,7 +9,9 @@ The `ConcurrentWorkflow` class is designed to facilitate the concurrent executio
- **Concurrent Execution**: Runs multiple agents simultaneously using Python's `asyncio` and `ThreadPoolExecutor`.
- **Metadata Collection**: Gathers detailed metadata about each agent's execution, including start and end times, duration, and output.
- **Customizable Output**: Allows the user to save metadata to a file or return it as a string or dictionary.
- **Error Handling**: Catches and logs errors during agent execution, ensuring the workflow can continue.
- **Error Handling**: Implements retry logic for improved reliability.
- **Batch Processing**: Supports running tasks in batches and parallel execution.
- **Asynchronous Execution**: Provides asynchronous run options for improved performance.
## Class Definitions
@ -56,6 +58,7 @@ The `ConcurrentWorkflow` class is the core class that manages the concurrent exe
| `max_loops` | `int` | Maximum number of loops for the workflow, defaults to `1`. |
| `return_str_on` | `bool` | Flag to return output as string. Defaults to `False`. |
| `agent_responses` | `List[str]` | List of agent responses as strings. |
| `auto_generate_prompts`| `bool` | Flag indicating whether to auto-generate prompts for agents. |
## Methods
@ -76,11 +79,24 @@ Initializes the `ConcurrentWorkflow` class with the provided parameters.
| `max_loops` | `int` | `1` | Maximum number of loops for the workflow. |
| `return_str_on` | `bool` | `False` | Flag to return output as string. |
| `agent_responses` | `List[str]` | `[]` | List of agent responses as strings. |
| `auto_generate_prompts`| `bool` | `False` | Flag indicating whether to auto-generate prompts for agents. |
#### Raises
- `ValueError`: If the list of agents is empty or if the description is empty.
### ConcurrentWorkflow.activate_auto_prompt_engineering
Activates the auto-generate prompts feature for all agents in the workflow.
#### Example
```python
workflow = ConcurrentWorkflow(agents=[Agent()])
workflow.activate_auto_prompt_engineering()
# All agents in the workflow will now auto-generate prompts.
```
### ConcurrentWorkflow._run_agent
Runs a single agent with the provided task and tracks its output and metadata.
@ -99,7 +115,7 @@ Runs a single agent with the provided task and tracks its output and metadata.
#### Detailed Explanation
This method handles the execution of a single agent by offloading the task to a thread using `ThreadPoolExecutor`. It also tracks the time taken by the agent to complete the task and logs relevant information. If an exception occurs during execution, it captures the error and includes it in the output.
This method handles the execution of a single agent by offloading the task to a thread using `ThreadPoolExecutor`. It also tracks the time taken by the agent to complete the task and logs relevant information. If an exception occurs during execution, it captures the error and includes it in the output. The method implements retry logic for improved reliability.
### ConcurrentWorkflow.transform_metadata_schema_to_str
@ -135,7 +151,18 @@ Executes multiple agents concurrently with the same task.
#### Detailed Explanation
This method is responsible for managing the concurrent execution of all agents. It uses `asyncio.gather` to run multiple agents simultaneously and collects their outputs into a `MetadataSchema` object. This aggregated metadata can then be saved or returned depending on the workflow configuration.
This method is responsible for managing the concurrent execution of all agents. It uses `asyncio.gather` to run multiple agents simultaneously and collects their outputs into a `MetadataSchema` object. This aggregated metadata can then be saved or returned depending on the workflow configuration. The method includes retry logic for improved reliability.
### ConcurrentWorkflow.save_metadata
Saves the metadata to a JSON file based on the `auto_save` flag.
#### Example
```python
workflow.save_metadata()
# Metadata will be saved to the specified path if auto_save is True.
```
### ConcurrentWorkflow.run
@ -149,12 +176,125 @@ Runs the workflow for the provided task, executes agents concurrently, and saves
#### Returns
- `Dict[str, Any]`: The final metadata as a dictionary.
- `Union[Dict[str, Any], str]`: The final metadata as a dictionary or a string, depending on the `return_str_on` flag.
#### Detailed Explanation
This is the main method that a user will call to execute the workflow. It manages the entire process from starting the agents to collecting and optionally saving the metadata. The method also provides flexibility in how the results are returned—either as a JSON dictionary or as a formatted string.
### ConcurrentWorkflow.run_batched
Runs the workflow for a batch of tasks, executing agents concurrently for each task.
#### Parameters
| Parameter | Type | Description |
|-------------|--------------|-----------------------------------------------------------|
| `tasks` | `List[str]` | A list of tasks or queries to give to all agents. |
#### Returns
- `List[Union[Dict[str, Any], str]]`: A list of final metadata for each task, either as a dictionary or a string.
#### Example
```python
tasks = ["Task 1", "Task 2"]
results = workflow.run_batched(tasks)
print(results)
```
### ConcurrentWorkflow.run_async
Runs the workflow asynchronously for the given task.
#### Parameters
| Parameter | Type | Description |
|-------------|--------------|-----------------------------------------------------------|
| `task` | `str` | The task or query to give to all agents. |
#### Returns
- `asyncio.Future`: A future object representing the asynchronous operation.
#### Example
```python
async def run_async_example():
future = workflow.run_async(task="Example task")
result = await future
print(result)
```
### ConcurrentWorkflow.run_batched_async
Runs the workflow asynchronously for a batch of tasks.
#### Parameters
| Parameter | Type | Description |
|-------------|--------------|-----------------------------------------------------------|
| `tasks` | `List[str]` | A list of tasks or queries to give to all agents. |
#### Returns
- `List[asyncio.Future]`: A list of future objects representing the asynchronous operations for each task.
#### Example
```python
tasks = ["Task 1", "Task 2"]
futures = workflow.run_batched_async(tasks)
results = await asyncio.gather(*futures)
print(results)
```
### ConcurrentWorkflow.run_parallel
Runs the workflow in parallel for a batch of tasks.
#### Parameters
| Parameter | Type | Description |
|-------------|--------------|-----------------------------------------------------------|
| `tasks` | `List[str]` | A list of tasks or queries to give to all agents. |
#### Returns
- `List[Union[Dict[str, Any], str]]`: A list of final metadata for each task, either as a dictionary or a string.
#### Example
```python
tasks = ["Task 1", "Task 2"]
results = workflow.run_parallel(tasks)
print(results)
```
### ConcurrentWorkflow.run_parallel_async
Runs the workflow in parallel asynchronously for a batch of tasks.
#### Parameters
| Parameter | Type | Description |
|-------------|--------------|-----------------------------------------------------------|
| `tasks` | `List[str]` | A list of tasks or queries to give to all agents. |
#### Returns
- `List[asyncio.Future]`: A list of future objects representing the asynchronous operations for each task.
#### Example
```python
tasks = ["Task 1", "Task 2"]
futures = workflow.run_parallel_async(tasks)
results = await asyncio.gather(*futures)
print(results)
```
## Usage Examples
### Example 1: Basic Usage
@ -249,7 +389,7 @@ agents = [
# Initialize workflow
workflow = ConcurrentWorkflow(
name = "Real Estate Marketing Swarm",
name="Real Estate Marketing Swarm",
agents=agents,
metadata_output_path="metadata.json",
description="Concurrent swarm of content generators for real estate!",
@ -257,17 +397,26 @@ workflow = ConcurrentWorkflow(
)
# Run workflow
task = "Analyze the financial impact of a new product launch."
task = "Create a marketing campaign for a luxury beachfront property in Miami, focusing on its stunning ocean views, private beach access, and state-of-the-art amenities."
metadata = workflow.run(task)
print(metadata)
```
### Example 2: Custom Output Handling
```python
# Run workflow with string output
workflow = ConcurrentWorkflow(agents=agents, return_str_on=True)
# Initialize workflow with string output
workflow = ConcurrentWorkflow(
name="Real Estate Marketing Swarm",
agents=agents,
metadata_output_path="metadata.json",
description="Concurrent swarm of content generators for real estate!",
auto_save=True,
return_str_on=True
)
# Run workflow
task = "Develop a marketing strategy for a newly renovated historic townhouse in Boston, emphasizing its blend of classic architecture and modern amenities."
metadata_str = workflow.run(task)
print(metadata_str)
```
@ -275,10 +424,79 @@ print(metadata_str)
### Example 3: Error Handling and Debugging
```python
import logging
# Set up logging
logging.basicConfig(level=logging.INFO)
# Initialize workflow
workflow = ConcurrentWorkflow(
name="Real Estate Marketing Swarm",
agents=agents,
metadata_output_path="metadata.json",
description="Concurrent swarm of content generators for real estate!",
auto_save=True
)
# Run workflow with error handling
try:
task = "Create a marketing campaign for a eco-friendly tiny house community in Portland, Oregon."
metadata = workflow.run(task)
except ValueError as e:
print(f"An error occurred: {e}")
print(metadata)
except Exception as e:
logging.error(f"An error occurred during workflow execution: {str(e)}")
# Additional error handling or debugging steps can be added here
```
### Example 4: Batch Processing
```python
# Initialize workflow
workflow = ConcurrentWorkflow(
name="Real Estate Marketing Swarm",
agents=agents,
metadata_output_path="metadata_batch.json",
description="Concurrent swarm of content generators for real estate!",
auto_save=True
)
# Define a list of tasks
tasks = [
"Market a family-friendly suburban home with a large backyard and excellent schools nearby.",
"Promote a high-rise luxury apartment in New York City with panoramic skyline views.",
"Advertise a ski-in/ski-out chalet in Aspen, Colorado, perfect for winter sports enthusiasts."
]
# Run workflow in batch mode
results = workflow.run_batched(tasks)
# Process and print results
for task, result in zip(tasks, results):
print(f"Task: {task}")
print(f"Result: {result}\n")
```
### Example 5: Asynchronous Execution
```python
import asyncio
# Initialize workflow
workflow = ConcurrentWorkflow(
name="Real Estate Marketing Swarm",
agents=agents,
metadata_output_path="metadata_async.json",
description="Concurrent swarm of content generators for real estate!",
auto_save=True
)
async def run_async_workflow():
task = "Develop a marketing strategy for a sustainable, off-grid mountain retreat in Colorado."
result = await workflow.run_async(task)
print(result)
# Run the async workflow
asyncio.run(run_async_workflow())
```
## Tips and Best Practices
@ -287,6 +505,11 @@ except ValueError as e:
- **Metadata Management**: Use the `auto_save` flag to automatically save metadata if you plan to run multiple workflows in succession.
- **Concurrency Limits**: Adjust the number of agents based on your system's capabilities to avoid overloading resources.
- **Error Handling**: Implement try-except blocks when running workflows to catch and handle exceptions gracefully.
- **Batch Processing**: For large numbers of tasks, consider using `run_batched` or `run_parallel` methods to improve overall throughput.
- **Asynchronous Operations**: Utilize asynchronous methods (`run_async`, `run_batched_async`, `run_parallel_async`) when dealing with I/O-bound tasks or when you need to maintain responsiveness in your application.
- **Logging**: Implement detailed logging to track the progress of your workflows and troubleshoot any issues that may arise.
- **Resource Management**: Be mindful of API rate limits and resource consumption, especially when running large batches or parallel executions.
- **Testing**: Thoroughly test your workflows with various inputs and edge cases to ensure robust performance in production environments.
## References and Resources
@ -294,3 +517,4 @@ except ValueError as e:
- [Pydantic Documentation](https://pydantic-docs.helpmanual.io/)
- [ThreadPoolExecutor in Python](https://docs.python.org/3/library/concurrent.futures.html#concurrent.futures.ThreadPoolExecutor)
- [Loguru for Logging in Python](https://loguru.readthedocs.io/en/stable/)
- [Tenacity: Retry library for Python](https://tenacity.readthedocs.io/en/latest/)

@ -1,8 +1,6 @@
# SwarmRouter Documentation
## Overview
The `SwarmRouter` class is a flexible routing system designed to manage different types of swarms for task execution. It provides a unified interface to interact with various swarm types, including `AgentRearrange`, `MixtureOfAgents`, `SpreadSheetSwarm`, `SequentialWorkflow`, and `ConcurrentWorkflow`. We will be continously adding more and more swarm architectures here as we progress with new architectures.
The `SwarmRouter` class is a flexible routing system designed to manage different types of swarms for task execution. It provides a unified interface to interact with various swarm types, including `AgentRearrange`, `MixtureOfAgents`, `SpreadSheetSwarm`, `SequentialWorkflow`, `ConcurrentWorkflow`, and finally `auto` which will dynamically select the most appropriate swarm for you by analyzing your name, description, and input task. We will be continuously adding more swarm architectures as we progress with new developments.
## Classes
@ -29,8 +27,12 @@ Main class for routing tasks to different swarm types.
| `name` | str | Name of the SwarmRouter instance. |
| `description` | str | Description of the SwarmRouter instance. |
| `max_loops` | int | Maximum number of loops to perform. |
| `agents` | List[Agent] | List of Agent objects to be used in the swarm. |
| `agents` | List[Union[Agent, Callable]] | List of Agent objects or callable functions to be used in the swarm. |
| `swarm_type` | SwarmType | Type of swarm to be used. |
| `autosave` | bool | Flag to enable/disable autosave. |
| `flow` | str | The flow of the swarm. |
| `return_json` | bool | Flag to enable/disable returning the result in JSON format. |
| `auto_generate_prompts` | bool | Flag to enable/disable auto generation of prompts. |
| `swarm` | Union[AgentRearrange, MixtureOfAgents, SpreadSheetSwarm, SequentialWorkflow, ConcurrentWorkflow] | Instantiated swarm object. |
| `logs` | List[SwarmLog] | List of log entries captured during operations. |
@ -38,11 +40,17 @@ Main class for routing tasks to different swarm types.
| Method | Parameters | Description |
| --- | --- | --- |
| `__init__` | `self, name: str, description: str, max_loops: int, agents: List[Agent], swarm_type: SwarmType, *args, **kwargs` | Initialize the SwarmRouter. |
| `_create_swarm` | `self, *args, **kwargs` | Create and return the specified swarm type. |
| `_log` | `self, level: str, message: str, task: str, metadata: Dict[str, Any]` | Create a log entry and add it to the logs list. |
| `run` | `self, task: str, *args, **kwargs` | Run the specified task on the selected swarm. |
| `__init__` | `self, name: str, description: str, max_loops: int, agents: List[Union[Agent, Callable]], swarm_type: SwarmType, autosave: bool, flow: str, return_json: bool, auto_generate_prompts: bool, *args, **kwargs` | Initialize the SwarmRouter. |
| `reliability_check` | `self` | Perform reliability checks on the SwarmRouter configuration. |
| `_create_swarm` | `self, task: str = None, *args, **kwargs` | Create and return the specified swarm type or automatically match the best swarm type for a given task. |
| `_log` | `self, level: str, message: str, task: str = "", metadata: Dict[str, Any] = None` | Create a log entry and add it to the logs list. |
| `run` | `self, task: str, *args, **kwargs` | Run the specified task on the selected or matched swarm. |
| `batch_run` | `self, tasks: List[str], *args, **kwargs` | Execute a batch of tasks on the selected or matched swarm type. |
| `threaded_run` | `self, task: str, *args, **kwargs` | Execute a task on the selected or matched swarm type using threading. |
| `async_run` | `self, task: str, *args, **kwargs` | Execute a task on the selected or matched swarm type asynchronously. |
| `get_logs` | `self` | Retrieve all logged entries. |
| `concurrent_run` | `self, task: str, *args, **kwargs` | Execute a task on the selected or matched swarm type concurrently. |
| `concurrent_batch_run` | `self, tasks: List[str], *args, **kwargs` | Execute a batch of tasks on the selected or matched swarm type concurrently. |
## Installation
@ -53,6 +61,7 @@ pip install swarms swarm_models
```
## Basic Usage
```python
import os
from dotenv import load_dotenv
@ -71,6 +80,7 @@ model = OpenAIChat(
model_name="llama-3.1-70b-versatile",
temperature=0.1,
)
# Define specialized system prompts for each agent
DATA_EXTRACTOR_PROMPT = """You are a highly specialized private equity agent focused on data extraction from various documents. Your expertise includes:
1. Extracting key financial metrics (revenue, EBITDA, growth rates, etc.) from financial statements and reports
@ -88,30 +98,6 @@ SUMMARIZER_PROMPT = """You are an expert private equity agent specializing in su
5. Creating brief overviews of technical documents, emphasizing critical points for non-technical stakeholders
Deliver clear, concise summaries that capture the essence of various documents while highlighting information crucial for investment decisions."""
FINANCIAL_ANALYST_PROMPT = """You are a specialized private equity agent focused on financial analysis. Your key responsibilities include:
1. Analyzing historical financial statements to identify trends and potential issues
2. Evaluating the quality of earnings and potential adjustments to EBITDA
3. Assessing working capital requirements and cash flow dynamics
4. Analyzing capital structure and debt capacity
5. Evaluating financial projections and underlying assumptions
Provide thorough, insightful financial analysis to inform investment decisions and valuation."""
MARKET_ANALYST_PROMPT = """You are a highly skilled private equity agent specializing in market analysis. Your expertise covers:
1. Analyzing industry trends, growth drivers, and potential disruptors
2. Evaluating competitive landscape and market positioning
3. Assessing market size, segmentation, and growth potential
4. Analyzing customer dynamics, including concentration and loyalty
5. Identifying potential regulatory or macroeconomic impacts on the market
Deliver comprehensive market analysis to assess the attractiveness and risks of potential investments."""
OPERATIONAL_ANALYST_PROMPT = """You are an expert private equity agent focused on operational analysis. Your core competencies include:
1. Evaluating operational efficiency and identifying improvement opportunities
2. Analyzing supply chain and procurement processes
3. Assessing sales and marketing effectiveness
4. Evaluating IT systems and digital capabilities
5. Identifying potential synergies in merger or add-on acquisition scenarios
Provide detailed operational analysis to uncover value creation opportunities and potential risks."""
# Initialize specialized agents
data_extractor_agent = Agent(
agent_name="Data-Extractor",
@ -143,80 +129,28 @@ summarizer_agent = Agent(
output_type="string",
)
financial_analyst_agent = Agent(
agent_name="Financial-Analyst",
system_prompt=FINANCIAL_ANALYST_PROMPT,
llm=model,
max_loops=1,
autosave=True,
verbose=True,
dynamic_temperature_enabled=True,
saved_state_path="financial_analyst_agent.json",
user_name="pe_firm",
retry_attempts=1,
context_length=200000,
output_type="string",
)
market_analyst_agent = Agent(
agent_name="Market-Analyst",
system_prompt=MARKET_ANALYST_PROMPT,
llm=model,
max_loops=1,
autosave=True,
verbose=True,
dynamic_temperature_enabled=True,
saved_state_path="market_analyst_agent.json",
user_name="pe_firm",
retry_attempts=1,
context_length=200000,
output_type="string",
)
operational_analyst_agent = Agent(
agent_name="Operational-Analyst",
system_prompt=OPERATIONAL_ANALYST_PROMPT,
llm=model,
max_loops=1,
autosave=True,
verbose=True,
dynamic_temperature_enabled=True,
saved_state_path="operational_analyst_agent.json",
user_name="pe_firm",
retry_attempts=1,
context_length=200000,
output_type="string",
)
# Initialize the SwarmRouter
router = SwarmRouter(
name="pe-document-analysis-swarm",
description="Analyze documents for private equity due diligence and investment decision-making",
max_loops=1,
agents=[
data_extractor_agent,
summarizer_agent,
financial_analyst_agent,
market_analyst_agent,
operational_analyst_agent,
],
swarm_type="ConcurrentWorkflow", # or "SequentialWorkflow" or "ConcurrentWorkflow" or
agents=[data_extractor_agent, summarizer_agent],
swarm_type="ConcurrentWorkflow",
autosave=True,
return_json=True,
)
# Example usage
if __name__ == "__main__":
# Run a comprehensive private equity document analysis task
result = router.run(
"Where is the best place to find template term sheets for series A startups. Provide links and references"
"Where is the best place to find template term sheets for series A startups? Provide links and references"
)
print(result)
# Retrieve and print logs
for log in router.get_logs():
print(f"{log.timestamp} - {log.level}: {log.message}")
```
## Advanced Usage
@ -229,16 +163,30 @@ You can create multiple SwarmRouter instances with different swarm types:
sequential_router = SwarmRouter(
name="SequentialRouter",
agents=[agent1, agent2],
swarm_type=SwarmType.SequentialWorkflow
swarm_type="SequentialWorkflow"
)
concurrent_router = SwarmRouter(
name="ConcurrentRouter",
agents=[agent1, agent2],
swarm_type=SwarmType.ConcurrentWorkflow
swarm_type="ConcurrentWorkflow"
)
```
### Automatic Swarm Type Selection
You can let the SwarmRouter automatically select the best swarm type for a given task:
```python
auto_router = SwarmRouter(
name="AutoRouter",
agents=[agent1, agent2],
swarm_type="auto"
)
result = auto_router.run("Analyze and summarize the quarterly financial report")
```
## Use Cases
### AgentRearrange
@ -251,8 +199,8 @@ rearrange_router = SwarmRouter(
description="Optimize agent order for multi-step tasks",
max_loops=3,
agents=[data_extractor, analyzer, summarizer],
swarm_type=SwarmType.AgentRearrange,
flow = f"{data_extractor.name} -> {analyzer.name} -> {summarizer.name}"
swarm_type="AgentRearrange",
flow=f"{data_extractor.name} -> {analyzer.name} -> {summarizer.name}"
)
result = rearrange_router.run("Analyze and summarize the quarterly financial report")
@ -268,7 +216,7 @@ mixture_router = SwarmRouter(
description="Combine insights from various expert agents",
max_loops=1,
agents=[financial_expert, market_analyst, tech_specialist],
swarm_type=SwarmType.MixtureOfAgents
swarm_type="MixtureOfAgents"
)
result = mixture_router.run("Evaluate the potential acquisition of TechStartup Inc.")
@ -284,7 +232,7 @@ spreadsheet_router = SwarmRouter(
description="Collaborative data processing and analysis",
max_loops=1,
agents=[data_cleaner, statistical_analyzer, visualizer],
swarm_type=SwarmType.SpreadSheetSwarm
swarm_type="SpreadSheetSwarm"
)
result = spreadsheet_router.run("Process and visualize customer churn data")
@ -300,7 +248,7 @@ sequential_router = SwarmRouter(
description="Generate comprehensive reports sequentially",
max_loops=1,
agents=[data_extractor, analyzer, writer, reviewer],
swarm_type=SwarmType.SequentialWorkflow
swarm_type="SequentialWorkflow"
)
result = sequential_router.run("Create a due diligence report for Project Alpha")
@ -316,22 +264,70 @@ concurrent_router = SwarmRouter(
description="Analyze multiple data sources concurrently",
max_loops=1,
agents=[financial_analyst, market_researcher, competitor_analyst],
swarm_type=SwarmType.ConcurrentWorkflow
swarm_type="ConcurrentWorkflow"
)
result = concurrent_router.run("Conduct a comprehensive market analysis for Product X")
```
## Error Handling
The `SwarmRouter` includes error handling in the `run` method. If an exception occurs during task execution, it will be logged and re-raised for the caller to handle. Always wrap the `run` method in a try-except block:
### Auto Select (Experimental)
Autonomously selects the right swarm by conducting vector search on your input task or name or description or all 3.
```python
concurrent_router = SwarmRouter(
name="MultiSourceAnalyzer",
description="Analyze multiple data sources concurrently",
max_loops=1,
agents=[financial_analyst, market_researcher, competitor_analyst],
swarm_type="auto" # Set this to 'auto' for it to auto select your swarm. It's match words like concurrently multiple -> "ConcurrentWorkflow"
)
result = concurrent_router.run("Conduct a comprehensive market analysis for Product X")
```
## Advanced Features
### Batch Processing
To process multiple tasks in a batch:
```python
tasks = ["Analyze Q1 report", "Summarize competitor landscape", "Evaluate market trends"]
results = router.batch_run(tasks)
```
### Threaded Execution
For non-blocking execution of a task:
```python
result = router.threaded_run("Perform complex analysis")
```
### Asynchronous Execution
For asynchronous task execution:
```python
result = await router.async_run("Generate financial projections")
```
### Concurrent Execution
To run a single task concurrently:
```python
result = router.concurrent_run("Analyze multiple data streams")
```
### Concurrent Batch Processing
To process multiple tasks concurrently:
```python
try:
result = router.run("Complex analysis task")
except Exception as e:
print(f"An error occurred: {str(e)}")
# Handle the error appropriately
tasks = ["Task 1", "Task 2", "Task 3"]
results = router.concurrent_batch_run(tasks)
```
## Best Practices
@ -342,4 +338,7 @@ except Exception as e:
4. Use descriptive names and descriptions for your SwarmRouter and agents.
5. Implement proper error handling in your application code.
6. Consider the nature of your tasks when choosing a swarm type (e.g., use ConcurrentWorkflow for tasks that can be parallelized).
7. Optimize your agents' prompts and configurations for best performance within the swarm.
7. Optimize your agents' prompts and configurations for best performance within the swarm.
8. Utilize the automatic swarm type selection feature for tasks where the optimal swarm type is not immediately clear.
9. Take advantage of batch processing and concurrent execution for handling multiple tasks efficiently.
10. Use the reliability check feature to ensure your SwarmRouter is properly configured before running tasks.

@ -1,35 +1,39 @@
import requests
from bs4 import BeautifulSoup
def scrape_blackrock_trades():
url = "https://arkhamintelligence.com/blackrock/trades"
response = requests.get(url)
if response.status_code == 200:
soup = BeautifulSoup(response.content, 'html.parser')
soup = BeautifulSoup(response.content, "html.parser")
# Example: Assuming trades are in a table
trades = []
table = soup.find('table', {'id': 'trades-table'})
table = soup.find("table", {"id": "trades-table"})
if table:
for row in table.find_all('tr'):
columns = row.find_all('td')
for row in table.find_all("tr"):
columns = row.find_all("td")
if len(columns) > 0:
trade = {
'trade_date': columns[0].text.strip(),
'asset': columns[1].text.strip(),
'action': columns[2].text.strip(),
'quantity': columns[3].text.strip(),
'price': columns[4].text.strip(),
'total_value': columns[5].text.strip(),
"trade_date": columns[0].text.strip(),
"asset": columns[1].text.strip(),
"action": columns[2].text.strip(),
"quantity": columns[3].text.strip(),
"price": columns[4].text.strip(),
"total_value": columns[5].text.strip(),
}
trades.append(trade)
return trades
else:
print(f"Failed to fetch data. Status code: {response.status_code}")
print(
f"Failed to fetch data. Status code: {response.status_code}"
)
return None
if __name__ == "__main__":
trades = scrape_blackrock_trades()
if trades:

@ -1,6 +1,6 @@
import requests
import pandas as pd
from datetime import datetime, timedelta
from datetime import datetime
import os
from typing import Dict, Tuple, Any
import logging
@ -10,24 +10,31 @@ logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# You'll need to set these environment variables with your actual API keys
ALPHA_VANTAGE_API_KEY = os.getenv('ALPHA_VANTAGE_API_KEY')
WORLD_BANK_API_KEY = os.getenv('WORLD_BANK_API_KEY')
FRED_API_KEY = os.getenv('FRED_API_KEY')
ALPHA_VANTAGE_API_KEY = os.getenv("ALPHA_VANTAGE_API_KEY")
WORLD_BANK_API_KEY = os.getenv("WORLD_BANK_API_KEY")
FRED_API_KEY = os.getenv("FRED_API_KEY")
def fetch_real_economic_data(country: str, start_date: datetime, end_date: datetime) -> Tuple[str, Dict[str, Any]]:
def fetch_real_economic_data(
country: str, start_date: datetime, end_date: datetime
) -> Tuple[str, Dict[str, Any]]:
data = {}
def get_alpha_vantage_data(indicator: str) -> pd.Series:
try:
url = f"https://www.alphavantage.co/query?function={indicator}&interval=monthly&apikey={ALPHA_VANTAGE_API_KEY}"
response = requests.get(url)
response.raise_for_status()
df = pd.DataFrame(response.json()['Monthly Time Series']).T
df = pd.DataFrame(
response.json()["Monthly Time Series"]
).T
df.index = pd.to_datetime(df.index)
df = df.sort_index()
return df['4. close'].astype(float)
return df["4. close"].astype(float)
except Exception as e:
logger.error(f"Error fetching Alpha Vantage data: {str(e)}")
logger.error(
f"Error fetching Alpha Vantage data: {str(e)}"
)
return pd.Series()
def get_world_bank_data(indicator: str) -> pd.Series:
@ -37,9 +44,9 @@ def fetch_real_economic_data(country: str, start_date: datetime, end_date: datet
response.raise_for_status()
data = response.json()[1]
df = pd.DataFrame(data)
df['date'] = pd.to_datetime(df['date'], format='%Y')
df = df.set_index('date').sort_index()
return df['value'].astype(float)
df["date"] = pd.to_datetime(df["date"], format="%Y")
df = df.set_index("date").sort_index()
return df["value"].astype(float)
except Exception as e:
logger.error(f"Error fetching World Bank data: {str(e)}")
return pd.Series()
@ -49,66 +56,103 @@ def fetch_real_economic_data(country: str, start_date: datetime, end_date: datet
url = f"https://api.stlouisfed.org/fred/series/observations?series_id={series_id}&api_key={FRED_API_KEY}&file_type=json"
response = requests.get(url)
response.raise_for_status()
df = pd.DataFrame(response.json()['observations'])
df['date'] = pd.to_datetime(df['date'])
df = df.set_index('date').sort_index()
return df['value'].astype(float)
df = pd.DataFrame(response.json()["observations"])
df["date"] = pd.to_datetime(df["date"])
df = df.set_index("date").sort_index()
return df["value"].astype(float)
except Exception as e:
logger.error(f"Error fetching FRED data: {str(e)}")
return pd.Series()
# Fetch data from different sources
data['GDP_growth_rate'] = get_world_bank_data('NY.GDP.MKTP.KD.ZG')
data['unemployment_rate'] = get_world_bank_data('SL.UEM.TOTL.ZS')
data['inflation_rate'] = get_world_bank_data('FP.CPI.TOTL.ZG')
data['debt_to_GDP_ratio'] = get_world_bank_data('GC.DOD.TOTL.GD.ZS')
data['current_account_balance'] = get_world_bank_data('BN.CAB.XOKA.CD')
data['yield_curve_slope'] = get_fred_data('T10Y2Y')
data['stock_market_index'] = get_alpha_vantage_data('TIME_SERIES_MONTHLY')
data['consumer_confidence_index'] = get_fred_data('CSCICP03USM665S')
data['business_confidence_index'] = get_fred_data('BSCICP03USM665S')
data["GDP_growth_rate"] = get_world_bank_data("NY.GDP.MKTP.KD.ZG")
data["unemployment_rate"] = get_world_bank_data("SL.UEM.TOTL.ZS")
data["inflation_rate"] = get_world_bank_data("FP.CPI.TOTL.ZG")
data["debt_to_GDP_ratio"] = get_world_bank_data(
"GC.DOD.TOTL.GD.ZS"
)
data["current_account_balance"] = get_world_bank_data(
"BN.CAB.XOKA.CD"
)
data["yield_curve_slope"] = get_fred_data("T10Y2Y")
data["stock_market_index"] = get_alpha_vantage_data(
"TIME_SERIES_MONTHLY"
)
data["consumer_confidence_index"] = get_fred_data(
"CSCICP03USM665S"
)
data["business_confidence_index"] = get_fred_data(
"BSCICP03USM665S"
)
# Combine all data into a single DataFrame
df = pd.DataFrame(data)
df = df.loc[start_date:end_date]
if df.empty:
logger.warning("No data retrieved for the specified date range and country.")
return "No data available", {"country": country, "real_time_data": {}, "historical_data": {}}
logger.warning(
"No data retrieved for the specified date range and country."
)
return "No data available", {
"country": country,
"real_time_data": {},
"historical_data": {},
}
# Prepare the dictionary output
output_dict = {
"country": country,
"real_time_data": df.iloc[-1].to_dict(),
"historical_data": df.to_dict()
"historical_data": df.to_dict(),
}
# Create summary string
summary = f"Economic Data Summary for {country} (as of {end_date.strftime('%Y-%m-%d')}):\n"
for key, value in output_dict['real_time_data'].items():
for key, value in output_dict["real_time_data"].items():
if pd.notna(value):
summary += f"{key.replace('_', ' ').title()}: {value:.2f}\n"
summary += (
f"{key.replace('_', ' ').title()}: {value:.2f}\n"
)
else:
summary += f"{key.replace('_', ' ').title()}: Data not available\n"
return summary, output_dict
# Example usage
if __name__ == "__main__":
country = "US" # ISO country code
start_date = datetime(2020, 1, 1)
end_date = datetime.now()
summary, data = fetch_real_economic_data(country, start_date, end_date)
summary, data = fetch_real_economic_data(
country, start_date, end_date
)
print(summary)
print("\nOutput Dictionary (truncated):")
print(f"Country: {data['country']}")
print("Real-time data:", data['real_time_data'])
print("Real-time data:", data["real_time_data"])
print("Historical data: {First day, Last day}")
if data['historical_data']:
first_day = min(next(iter(data['historical_data'].values())).keys())
last_day = max(next(iter(data['historical_data'].values())).keys())
print(f" {first_day}:", {k: v[first_day] if first_day in v else 'N/A' for k, v in data['historical_data'].items()})
print(f" {last_day}:", {k: v[last_day] if last_day in v else 'N/A' for k, v in data['historical_data'].items()})
if data["historical_data"]:
first_day = min(
next(iter(data["historical_data"].values())).keys()
)
last_day = max(
next(iter(data["historical_data"].values())).keys()
)
print(
f" {first_day}:",
{
k: v[first_day] if first_day in v else "N/A"
for k, v in data["historical_data"].items()
},
)
print(
f" {last_day}:",
{
k: v[last_day] if last_day in v else "N/A"
for k, v in data["historical_data"].items()
},
)
else:
print(" No historical data available.")
print(" No historical data available.")

@ -0,0 +1,82 @@
from swarms.prompts.prompt import Prompt
import subprocess
# Tools
def terminal(
code: str,
):
"""
Run code in the terminal.
Args:
code (str): The code to run in the terminal.
Returns:
str: The output of the code.
"""
out = subprocess.run(
code, shell=True, capture_output=True, text=True
).stdout
return str(out)
def browser(query: str):
"""
Search the query in the browser with the `browser` tool.
Args:
query (str): The query to search in the browser.
Returns:
str: The search results.
"""
import webbrowser
url = f"https://www.google.com/search?q={query}"
webbrowser.open(url)
return f"Searching for {query} in the browser."
def create_file(file_path: str, content: str):
"""
Create a file using the file editor tool.
Args:
file_path (str): The path to the file.
content (str): The content to write to the file.
Returns:
str: The result of the file creation operation.
"""
with open(file_path, "w") as file:
file.write(content)
return f"File {file_path} created successfully."
def file_editor(file_path: str, mode: str, content: str):
"""
Edit a file using the file editor tool.
Args:
file_path (str): The path to the file.
mode (str): The mode to open the file in.
content (str): The content to write to the file.
Returns:
str: The result of the file editing operation.
"""
with open(file_path, mode) as file:
file.write(content)
return f"File {file_path} edited successfully."
prompt = Prompt(
content="This is my first prompt!",
name="My First Prompt",
description="A simple example prompt.",
# tools=[file_editor, create_file, terminal]
)
prompt.add_tools(tools=[file_editor, create_file, terminal])
print(prompt.content)

@ -76,6 +76,7 @@ black = "*"
swarms-cloud = ">=0.4.4,<5"
aiofiles = "*"
swarm-models = "*"
clusterops = "*"
[tool.poetry.scripts]
swarms = "swarms.cli.main:main"

@ -32,4 +32,5 @@ networkx
swarms-memory
pre-commit
aiofiles
swarm-models
swarm-models
clusterops

@ -0,0 +1,271 @@
from typing import List, Tuple, Optional
import numpy as np
import torch
from transformers import AutoTokenizer, AutoModel
from pydantic import BaseModel, Field
from loguru import logger
import json
from tenacity import retry, stop_after_attempt, wait_exponential
# Ensure you have the necessary libraries installed:
# pip install torch transformers pydantic loguru tenacity
class SwarmType(BaseModel):
name: str
description: str
embedding: Optional[List[float]] = Field(
default=None, exclude=True
)
class SwarmMatcherConfig(BaseModel):
model_name: str = "sentence-transformers/all-MiniLM-L6-v2"
embedding_dim: int = (
512 # Dimension of the sentence-transformers model
)
class SwarmMatcher:
"""
A class for matching tasks to swarm types based on their descriptions.
It utilizes a transformer model to generate embeddings for task and swarm type descriptions,
and then calculates the dot product to find the best match.
"""
def __init__(self):
"""
Initializes the SwarmMatcher with a configuration.
Args:
config (SwarmMatcherConfig): The configuration for the SwarmMatcher.
"""
logger.add("swarm_matcher_debug.log", level="DEBUG")
logger.debug("Initializing SwarmMatcher")
try:
config = SwarmMatcherConfig()
self.config = config
self.tokenizer = AutoTokenizer.from_pretrained(
config.model_name
)
self.model = AutoModel.from_pretrained(config.model_name)
self.swarm_types: List[SwarmType] = []
logger.debug("SwarmMatcher initialized successfully")
except Exception as e:
logger.error(f"Error initializing SwarmMatcher: {str(e)}")
raise
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=4, max=10),
)
def get_embedding(self, text: str) -> np.ndarray:
"""
Generates an embedding for a given text using the configured model.
Args:
text (str): The text for which to generate an embedding.
Returns:
np.ndarray: The embedding vector for the text.
"""
logger.debug(f"Getting embedding for text: {text[:50]}...")
try:
inputs = self.tokenizer(
text,
return_tensors="pt",
padding=True,
truncation=True,
max_length=512,
)
with torch.no_grad():
outputs = self.model(**inputs)
embedding = (
outputs.last_hidden_state.mean(dim=1)
.squeeze()
.numpy()
)
logger.debug("Embedding generated successfully")
return embedding
except Exception as e:
logger.error(f"Error generating embedding: {str(e)}")
raise
def add_swarm_type(self, swarm_type: SwarmType):
"""
Adds a swarm type to the list of swarm types, generating an embedding for its description.
Args:
swarm_type (SwarmType): The swarm type to add.
"""
logger.debug(f"Adding swarm type: {swarm_type.name}")
try:
embedding = self.get_embedding(swarm_type.description)
swarm_type.embedding = embedding.tolist()
self.swarm_types.append(swarm_type)
logger.info(f"Added swarm type: {swarm_type.name}")
except Exception as e:
logger.error(
f"Error adding swarm type {swarm_type.name}: {str(e)}"
)
raise
def find_best_match(self, task: str) -> Tuple[str, float]:
"""
Finds the best match for a given task among the registered swarm types.
Args:
task (str): The task for which to find the best match.
Returns:
Tuple[str, float]: A tuple containing the name of the best matching swarm type and the score.
"""
logger.debug(f"Finding best match for task: {task[:50]}...")
try:
task_embedding = self.get_embedding(task)
best_match = None
best_score = -float("inf")
for swarm_type in self.swarm_types:
score = np.dot(
task_embedding, np.array(swarm_type.embedding)
)
if score > best_score:
best_score = score
best_match = swarm_type
logger.info(
f"Best match for task: {best_match.name} (score: {best_score})"
)
return best_match.name, float(best_score)
except Exception as e:
logger.error(
f"Error finding best match for task: {str(e)}"
)
raise
def auto_select_swarm(self, task: str) -> str:
"""
Automatically selects the best swarm type for a given task based on their descriptions.
Args:
task (str): The task for which to select a swarm type.
Returns:
str: The name of the selected swarm type.
"""
logger.debug(f"Auto-selecting swarm for task: {task[:50]}...")
best_match, score = self.find_best_match(task)
if (
best_match == "No match"
): # Handle the case where no match was found
logger.info(f"Task: {task}")
logger.info("No suitable swarm type found.")
return "No suitable swarm type found" # Return a message indicating no match
logger.info(f"Task: {task}")
logger.info(f"Selected Swarm Type: {best_match}")
logger.info(f"Confidence Score: {score:.2f}")
return best_match
def run_multiple(self, tasks: List[str], *args, **kwargs) -> str:
swarms = []
for task in tasks:
output = self.auto_select_swarm(task)
# Append
swarms.append(output)
return swarms
def save_swarm_types(self, filename: str):
"""
Saves the registered swarm types to a JSON file.
Args:
filename (str): The name of the file to which to save the swarm types.
"""
try:
with open(filename, "w") as f:
json.dump([st.dict() for st in self.swarm_types], f)
logger.info(f"Saved swarm types to {filename}")
except Exception as e:
logger.error(f"Error saving swarm types: {str(e)}")
raise
def load_swarm_types(self, filename: str):
"""
Loads swarm types from a JSON file.
Args:
filename (str): The name of the file from which to load the swarm types.
"""
try:
with open(filename, "r") as f:
swarm_types_data = json.load(f)
self.swarm_types = [
SwarmType(**st) for st in swarm_types_data
]
logger.info(f"Loaded swarm types from {filename}")
except Exception as e:
logger.error(f"Error loading swarm types: {str(e)}")
raise
def initialize_swarm_types(self):
logger.debug("Initializing swarm types")
swarm_types = [
SwarmType(
name="AgentRearrange",
description="Optimize agent order and rearrange flow for multi-step tasks, ensuring efficient task allocation and minimizing bottlenecks",
),
SwarmType(
name="MixtureOfAgents",
description="Combine diverse expert agents for comprehensive analysis, fostering a collaborative approach to problem-solving and leveraging individual strengths",
),
SwarmType(
name="SpreadSheetSwarm",
description="Collaborative data processing and analysis in a spreadsheet-like environment, facilitating real-time data sharing and visualization",
),
SwarmType(
name="SequentialWorkflow",
description="Execute tasks in a step-by-step, sequential process workflow, ensuring a logical and methodical approach to task execution",
),
SwarmType(
name="ConcurrentWorkflow",
description="Process multiple tasks or data sources concurrently in parallel, maximizing productivity and reducing processing time",
),
]
for swarm_type in swarm_types:
self.add_swarm_type(swarm_type)
# logger.debug("Swarm types initialized")
# Example usage
if __name__ == "__main__":
# logger.info("Starting SwarmMatcher example")
matcher = SwarmMatcher()
# Save swarm types for future use
# matcher.save_swarm_types("swarm_types.json")
tasks = [
# "Optimize the order of agents for a complex financial analysis task",
# "Combine insights from various expert agents to evaluate a potential acquisition",
# "Process and analyze customer churn data collaboratively",
# "Generate a comprehensive due diligence report step by step",
"Analyze multiple data sources concurrently for market research"
]
for task in tasks:
selected_swarm = matcher.auto_select_swarm(task)
# print("\n" + "-"*50 + "\n")
print(selected_swarm)
# # Load swarm types in a new session
# new_matcher = SwarmMatcher(config)
# new_matcher.load_swarm_types("swarm_types.json")
# print("Loaded swarm types:", [st.name for st in new_matcher.swarm_types])
# logger.info("SwarmMatcher example completed successfully")

@ -0,0 +1,51 @@
from typing import Any
from loguru import logger
from tenacity import retry, stop_after_attempt, wait_exponential
from swarms.prompts.prompt_generator import (
prompt_generator_sys_prompt as second_sys_prompt,
)
from swarms.prompts.prompt_generator_optimizer import (
prompt_generator_sys_prompt,
)
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=4, max=10),
)
def auto_generate_prompt(
task: str = None,
model: Any = None,
max_tokens: int = 4000,
use_second_sys_prompt: bool = True,
*args,
**kwargs,
):
"""
Generates a prompt for a given task using the provided model.
Args:
task (str, optional): The task for which to generate a prompt.
model (Any, optional): The model to be used for prompt generation.
max_tokens (int, optional): The maximum number of tokens in the generated prompt. Defaults to 4000.
use_second_sys_prompt (bool, optional): Whether to use the second system prompt. Defaults to True.
Returns:
str: The generated prompt.
"""
try:
system_prompt = (
second_sys_prompt.get_prompt()
if use_second_sys_prompt
else prompt_generator_sys_prompt.get_prompt()
)
output = model.run(
system_prompt + task, max_tokens=max_tokens
)
print(output)
return output
except Exception as e:
logger.error(f"Error generating prompt: {str(e)}")
raise

@ -102,6 +102,9 @@ def create_agents_from_yaml(
"return_step_meta", False
),
output_type=agent_config.get("output_type", "str"),
auto_generate_prompt=agent_config.get(
"auto_generate_prompt", "False"
),
*args,
**kwargs,
)

@ -11,6 +11,7 @@ from swarms.prompts.prompt_generator_optimizer import (
prompt_generator_sys_prompt,
)
load_dotenv()

@ -1,7 +1,7 @@
import time
import json
import os
from typing import List
from typing import Callable, List
import uuid
from loguru import logger
from pydantic import (
@ -12,6 +12,7 @@ from pydantic import (
from pydantic.v1 import validator
from swarms_cloud.utils.log_to_swarms_database import log_agent_data
from swarms_cloud.utils.capture_system_data import capture_system_data
from swarms.tools.base_tool import BaseTool
class Prompt(BaseModel):
@ -73,6 +74,7 @@ class Prompt(BaseModel):
default=os.getenv("WORKSPACE_DIR"),
description="The folder where the autosave folder is in",
)
# tools: List[callable] = None
@validator("edit_history", pre=True, always=True)
def initialize_history(cls, v, values):
@ -157,6 +159,9 @@ class Prompt(BaseModel):
if self.autosave:
self._autosave()
def return_json(self):
return self.model_dump_json(indent=4)
def get_prompt(self) -> str:
"""
Returns the current prompt content as a string.
@ -202,6 +207,14 @@ class Prompt(BaseModel):
"Persistent storage integration is required."
)
def add_tools(self, tools: List[Callable]) -> str:
tools_prompt = BaseTool(
tools=tools, tool_system_prompt=None
).convert_tool_into_openai_schema()
self.content += "\n"
self.content += "\n"
self.content += tools_prompt
def _autosave(self) -> None:
"""
Autosaves the prompt to a specified folder within WORKSPACE_DIR.

@ -0,0 +1,70 @@
from swarms.prompts.prompt import Prompt
# Aggregator system prompt
prompt_generator_sys_prompt = Prompt(
name="prompt-generator-sys-prompt-o1",
description="Generate the most reliable prompt for a specific problem",
content="""
Your purpose is to craft extremely reliable and production-grade system prompts for other agents.
# Instructions
- Understand the prompt required for the agent.
- Utilize a combination of the most effective prompting strategies available, including chain of thought, many shot, few shot, and instructions-examples-constraints.
- Craft the prompt by blending the most suitable prompting strategies.
- Ensure the prompt is production-grade ready and educates the agent on how to reason and why to reason in that manner.
- Provide constraints if necessary and as needed.
- The system prompt should be extensive and cover a vast array of potential scenarios to specialize the agent.
""",
)
# print(prompt_generator_sys_prompt.get_prompt())
prompt_generator_sys_prompt.edit_prompt(
"""
Your primary objective is to design and develop highly reliable and production-grade system prompts tailored to the specific needs of other agents. This requires a deep understanding of the agent's capabilities, limitations, and the tasks they are intended to perform.
####### Guidelines #################
1. **Thoroughly understand the agent's requirements**: Before crafting the prompt, it is essential to comprehend the agent's capabilities, its intended use cases, and the specific tasks it needs to accomplish. This understanding will enable you to create a prompt that effectively leverages the agent's strengths and addresses its weaknesses.
2. **Employ a diverse range of prompting strategies**: To ensure the prompt is effective and versatile, incorporate a variety of prompting strategies, including but not limited to:
- **Chain of thought**: Encourage the agent to think step-by-step, breaking down complex problems into manageable parts.
- **Many shot**: Provide multiple examples or scenarios to help the agent generalize and adapt to different situations.
- **Few shot**: Offer a limited number of examples or scenarios to prompt the agent to learn from sparse data.
- **Instructions-examples-constraints**: Combine clear instructions with relevant examples and constraints to guide the agent's behavior and ensure it operates within defined boundaries.
3. **Blend prompting strategies effectively**: Select the most suitable prompting strategies for the specific task or scenario and combine them in a way that enhances the agent's understanding and performance.
4. **Ensure production-grade quality and educational value**: The prompt should not only be effective in guiding the agent's actions but also provide educational value by teaching the agent how to reason, why to reason in a particular way, and how to apply its knowledge in various contexts.
5. **Provide constraints as necessary**: Include constraints in the prompt to ensure the agent operates within predetermined parameters, adheres to specific guidelines, or follows established protocols.
6. **Design for extensibility and scenario coverage**: Craft the prompt to be extensive and cover a wide range of potential scenarios, enabling the agent to specialize and adapt to diverse situations.
7. **Continuously evaluate and refine**: Regularly assess the effectiveness of the prompt and refine it as needed to ensure it remains relevant, efficient, and aligned with the agent's evolving capabilities and requirements.
By following these guidelines and incorporating a deep understanding of the agent's needs, you can create system prompts that are not only reliable and production-grade but also foster the agent's growth and specialization.
######### Example Output Formats ########
# Instruction-Examples-Constraints
The agent's role and responsibilities
# Instructions
# Examples
# Constraints
################### REACT ############
<observation> your observation </observation
<plan> your plan </plan>
<action> your action </action>
"""
)
print(prompt_generator_sys_prompt.get_prompt())
print(prompt_generator_sys_prompt.model_dump_json(indent=4))

@ -24,6 +24,8 @@ Given a task description or existing prompt, produce a detailed system prompt to
The final prompt you output should adhere to the following structure below. Do not include any additional commentary, only output the completed system prompt. SPECIFICALLY, do not include any additional messages at the start or end of the prompt. (e.g. no "---")
# Instructions
[Concise instruction describing the task - this should be the first line in the prompt, no section header]
[Additional details as needed.]
@ -36,7 +38,7 @@ The final prompt you output should adhere to the following structure below. Do n
# Output Format
[Specifically call out how the output should be formatted, be it response length, structure e.g. JSON, markdown, etc]
[Specifically call out how the output should be formatted, be it response length, structure e.g. JSON, markdown, etc] [Only utilize markdown unless mentioned otherwise]
# Examples [optional]

@ -56,6 +56,7 @@ from clusterops import (
execute_on_gpu,
execute_with_cpu_cores,
)
from swarms.agents.ape_agent import auto_generate_prompt
# Utils
@ -125,11 +126,58 @@ class Agent:
pdf_path (str): The path to the pdf
list_of_pdf (str): The list of pdf
tokenizer (Any): The tokenizer
memory (BaseVectorDatabase): The memory
long_term_memory (BaseVectorDatabase): The long term memory
preset_stopping_token (bool): Enable preset stopping token
traceback (Any): The traceback
traceback_handlers (Any): The traceback handlers
streaming_on (bool): Enable streaming
docs (List[str]): The list of documents
docs_folder (str): The folder containing the documents
verbose (bool): Enable verbose mode
parser (Callable): The parser to use
best_of_n (int): The number of best responses to return
callback (Callable): The callback function
metadata (Dict[str, Any]): The metadata
callbacks (List[Callable]): The list of callback functions
logger_handler (Any): The logger handler
search_algorithm (Callable): The search algorithm
logs_to_filename (str): The filename for the logs
evaluator (Callable): The evaluator function
stopping_func (Callable): The stopping function
custom_loop_condition (Callable): The custom loop condition
sentiment_threshold (float): The sentiment threshold
custom_exit_command (str): The custom exit command
sentiment_analyzer (Callable): The sentiment analyzer
limit_tokens_from_string (Callable): The function to limit tokens from a string
custom_tools_prompt (Callable): The custom tools prompt
tool_schema (ToolUsageType): The tool schema
output_type (agent_output_type): The output type
function_calling_type (str): The function calling type
output_cleaner (Callable): The output cleaner function
function_calling_format_type (str): The function calling format type
list_base_models (List[BaseModel]): The list of base models
metadata_output_type (str): The metadata output type
state_save_file_type (str): The state save file type
chain_of_thoughts (bool): Enable chain of thoughts
algorithm_of_thoughts (bool): Enable algorithm of thoughts
tree_of_thoughts (bool): Enable tree of thoughts
tool_choice (str): The tool choice
execute_tool (bool): Enable tool execution
rules (str): The rules
planning (str): The planning
planning_prompt (str): The planning prompt
device (str): The device
custom_planning_prompt (str): The custom planning prompt
memory_chunk_size (int): The memory chunk size
agent_ops_on (bool): Enable agent operations
log_directory (str): The log directory
tool_system_prompt (str): The tool system prompt
max_tokens (int): The maximum number of tokens
frequency_penalty (float): The frequency penalty
presence_penalty (float): The presence penalty
temperature (float): The temperature
workspace_dir (str): The workspace directory
timeout (int): The timeout
Methods:
run: Run the agent
@ -262,8 +310,6 @@ class Agent:
log_directory: str = None,
tool_system_prompt: str = tool_sop_prompt(),
max_tokens: int = 4096,
top_p: float = 0.9,
top_k: int = None,
frequency_penalty: float = 0.0,
presence_penalty: float = 0.0,
temperature: float = 0.1,
@ -283,6 +329,7 @@ class Agent:
executor_workers: int = os.cpu_count(),
data_memory: Optional[Callable] = None,
load_yaml_path: str = None,
auto_generate_prompt: bool = False,
*args,
**kwargs,
):
@ -369,8 +416,7 @@ class Agent:
self.log_directory = log_directory
self.tool_system_prompt = tool_system_prompt
self.max_tokens = max_tokens
self.top_p = top_p
self.top_k = top_k
self.frequency_penalty = frequency_penalty
self.presence_penalty = presence_penalty
self.temperature = temperature
@ -389,6 +435,7 @@ class Agent:
self.data_memory = data_memory
self.load_yaml_path = load_yaml_path
self.tokenizer = TikTokenizer()
self.auto_generate_prompt = auto_generate_prompt
# Initialize the feedback
self.feedback = []
@ -527,6 +574,41 @@ class Agent:
# Telemetry Processor to log agent data
threading.Thread(target=self.log_agent_data).start()
def check_if_no_prompt_then_autogenerate(self, task: str = None):
"""
Checks if a system prompt is not set and auto_generate_prompt is enabled. If so, it auto-generates a prompt based on the agent's name, description, or the task if both are missing.
Args:
task (str, optional): The task to use as a fallback if both name and description are missing. Defaults to None.
"""
if (
self.system_prompt is None
and self.auto_generate_prompt is True
):
if self.description:
prompt = auto_generate_prompt(
self.description, self.llm
)
elif self.agent_name:
logger.info(
"Description is missing. Using agent name as a fallback."
)
prompt = auto_generate_prompt(
self.agent_name, self.llm
)
else:
logger.warning(
"Both description and agent name are missing. Using task as a fallback."
)
prompt = auto_generate_prompt(task, self.llm)
self.system_prompt = prompt
logger.info("Auto-generated prompt successfully.")
else:
if self.system_prompt is not None:
self.system_prompt = auto_generate_prompt(
self.system_prompt, self.llm
)
def set_system_prompt(self, system_prompt: str):
"""Set the system prompt"""
self.system_prompt = system_prompt
@ -680,6 +762,8 @@ class Agent:
Run the autonomous agent loop
"""
try:
self.check_if_no_prompt_then_autogenerate(task)
self.agent_output.task = task
# Add task to memory

@ -0,0 +1,320 @@
import os
from typing import List, Optional
import chromadb
from loguru import logger
from tenacity import retry, stop_after_attempt, wait_exponential
from typing import Union, Callable, Any
from swarms import Agent
class AgentRAG:
"""A vector database for storing and retrieving agents based on their characteristics."""
def __init__(
self,
collection_name: str = "agents",
persist_directory: str = "./vector_db",
n_agents: int = 1,
*args,
**kwargs,
):
"""
Initialize the AgentRAG.
Args:
persist_directory (str): The directory to persist the ChromaDB data.
"""
self.collection_name = collection_name
self.n_agents = n_agents
self.persist_directory = persist_directory
self.client = chromadb.Client(*args, **kwargs)
self.collection = self.client.create_collection(
collection_name
)
self.agents: List[Agent] = []
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=4, max=10),
)
def add_agent(self, agent: Agent) -> None:
"""
Add an agent to the vector database.
Args:
agent (Agent): The agent to add.
"""
try:
agent_text = f"{agent.name} {agent.description} {agent.system_prompt}"
self.collection.add(
documents=[agent_text],
metadatas=[{"name": agent.name}],
ids=[agent.name],
)
self.agents.append(agent)
logger.info(
f"Added agent {agent.name} to the vector database."
)
except Exception as e:
logger.error(
f"Error adding agent {agent.name} to the vector database: {str(e)}"
)
raise
def add_agents(
self, agents: List[Union[Agent, Callable, Any]]
) -> None:
for agent in agents:
self.add_agent(agent)
def update_agent_history(self, agent_name: str) -> None:
"""
Update the agent's entry in the vector database with its interaction history.
Args:
agent_name (str): The name of the agent to update.
"""
agent = next(
(a for a in self.agents if a.name == agent_name), None
)
if agent:
history = agent.short_memory.return_history_as_string()
history_text = " ".join(history)
updated_text = f"{agent.name} {agent.description} {agent.system_prompt} {history_text}"
self.collection.update(
ids=[agent_name],
documents=[updated_text],
metadatas=[{"name": agent_name}],
)
logger.info(
f"Updated agent {agent_name} with interaction history."
)
else:
logger.warning(
f"Agent {agent_name} not found in the database."
)
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=4, max=10),
)
def find_best_agent(
self, task: str, *args, **kwargs
) -> Optional[Agent]:
"""
Find the best agent for a given task.
Args:
task (str): The task description.
Returns:
Optional[Agent]: The best matching agent, if found.
"""
try:
results = self.collection.query(
query_texts=[task],
n_results=self.n_agents,
*args,
**kwargs,
)
if results["ids"]:
best_match_name = results["ids"][0][0]
best_agent = next(
(
a
for a in self.agents
if a.name == best_match_name
),
None,
)
if best_agent:
logger.info(
f"Found best matching agent: {best_match_name}"
)
return best_agent
else:
logger.warning(
f"Agent {best_match_name} found in index but not in agents list."
)
else:
logger.warning(
"No matching agent found for the given task."
)
return None
except Exception as e:
logger.error(f"Error finding best agent: {str(e)}")
raise
# Example usage
if __name__ == "__main__":
from dotenv import load_dotenv
from swarm_models import OpenAIChat
load_dotenv()
# Get the OpenAI API key from the environment variable
api_key = os.getenv("GROQ_API_KEY")
# Model
model = OpenAIChat(
openai_api_base="https://api.groq.com/openai/v1",
openai_api_key=api_key,
model_name="llama-3.1-70b-versatile",
temperature=0.1,
)
# Initialize the vector database
vector_db = AgentRAG()
# Define specialized system prompts for each agent
DATA_EXTRACTOR_PROMPT = """You are a highly specialized private equity agent focused on data extraction from various documents. Your expertise includes:
1. Extracting key financial metrics (revenue, EBITDA, growth rates, etc.) from financial statements and reports
2. Identifying and extracting important contract terms from legal documents
3. Pulling out relevant market data from industry reports and analyses
4. Extracting operational KPIs from management presentations and internal reports
5. Identifying and extracting key personnel information from organizational charts and bios
Provide accurate, structured data extracted from various document types to support investment analysis."""
SUMMARIZER_PROMPT = """You are an expert private equity agent specializing in summarizing complex documents. Your core competencies include:
1. Distilling lengthy financial reports into concise executive summaries
2. Summarizing legal documents, highlighting key terms and potential risks
3. Condensing industry reports to capture essential market trends and competitive dynamics
4. Summarizing management presentations to highlight key strategic initiatives and projections
5. Creating brief overviews of technical documents, emphasizing critical points for non-technical stakeholders
Deliver clear, concise summaries that capture the essence of various documents while highlighting information crucial for investment decisions."""
FINANCIAL_ANALYST_PROMPT = """You are a specialized private equity agent focused on financial analysis. Your key responsibilities include:
1. Analyzing historical financial statements to identify trends and potential issues
2. Evaluating the quality of earnings and potential adjustments to EBITDA
3. Assessing working capital requirements and cash flow dynamics
4. Analyzing capital structure and debt capacity
5. Evaluating financial projections and underlying assumptions
Provide thorough, insightful financial analysis to inform investment decisions and valuation."""
MARKET_ANALYST_PROMPT = """You are a highly skilled private equity agent specializing in market analysis. Your expertise covers:
1. Analyzing industry trends, growth drivers, and potential disruptors
2. Evaluating competitive landscape and market positioning
3. Assessing market size, segmentation, and growth potential
4. Analyzing customer dynamics, including concentration and loyalty
5. Identifying potential regulatory or macroeconomic impacts on the market
Deliver comprehensive market analysis to assess the attractiveness and risks of potential investments."""
OPERATIONAL_ANALYST_PROMPT = """You are an expert private equity agent focused on operational analysis. Your core competencies include:
1. Evaluating operational efficiency and identifying improvement opportunities
2. Analyzing supply chain and procurement processes
3. Assessing sales and marketing effectiveness
4. Evaluating IT systems and digital capabilities
5. Identifying potential synergies in merger or add-on acquisition scenarios
Provide detailed operational analysis to uncover value creation opportunities and potential risks."""
# Initialize specialized agents
data_extractor_agent = Agent(
agent_name="Data-Extractor",
system_prompt=DATA_EXTRACTOR_PROMPT,
llm=model,
max_loops=1,
autosave=True,
verbose=True,
dynamic_temperature_enabled=True,
saved_state_path="data_extractor_agent.json",
user_name="pe_firm",
retry_attempts=1,
context_length=200000,
output_type="string",
)
summarizer_agent = Agent(
agent_name="Document-Summarizer",
system_prompt=SUMMARIZER_PROMPT,
llm=model,
max_loops=1,
autosave=True,
verbose=True,
dynamic_temperature_enabled=True,
saved_state_path="summarizer_agent.json",
user_name="pe_firm",
retry_attempts=1,
context_length=200000,
output_type="string",
)
financial_analyst_agent = Agent(
agent_name="Financial-Analyst",
system_prompt=FINANCIAL_ANALYST_PROMPT,
llm=model,
max_loops=1,
autosave=True,
verbose=True,
dynamic_temperature_enabled=True,
saved_state_path="financial_analyst_agent.json",
user_name="pe_firm",
retry_attempts=1,
context_length=200000,
output_type="string",
)
market_analyst_agent = Agent(
agent_name="Market-Analyst",
system_prompt=MARKET_ANALYST_PROMPT,
llm=model,
max_loops=1,
autosave=True,
verbose=True,
dynamic_temperature_enabled=True,
saved_state_path="market_analyst_agent.json",
user_name="pe_firm",
retry_attempts=1,
context_length=200000,
output_type="string",
)
operational_analyst_agent = Agent(
agent_name="Operational-Analyst",
system_prompt=OPERATIONAL_ANALYST_PROMPT,
llm=model,
max_loops=1,
autosave=True,
verbose=True,
dynamic_temperature_enabled=True,
saved_state_path="operational_analyst_agent.json",
user_name="pe_firm",
retry_attempts=1,
context_length=200000,
output_type="string",
)
# Create agents (using the agents from the original code)
agents_to_add = [
data_extractor_agent,
summarizer_agent,
financial_analyst_agent,
market_analyst_agent,
operational_analyst_agent,
]
# Add agents to the vector database
for agent in agents_to_add:
vector_db.add_agent(agent)
# Example task
task = "Analyze the financial statements of a potential acquisition target and identify key growth drivers."
# Find the best agent for the task
best_agent = vector_db.find_best_agent(task)
if best_agent:
logger.info(f"Best agent for the task: {best_agent.name}")
# Use the best agent to perform the task
result = best_agent.run(task)
print(f"Task result: {result}")
# Update the agent's history in the database
vector_db.update_agent_history(best_agent.name)
else:
print("No suitable agent found for the task.")
# Save the vector database

@ -0,0 +1,3 @@
"""
This class will input a swarm type -> then auto generate a list of `Agent` structures with their name, descriptions, system prompts, and more.
"""

@ -3,14 +3,22 @@ import os
import uuid
from concurrent.futures import ThreadPoolExecutor
from datetime import datetime
from typing import Any, Dict, List, Optional
from typing import Any, Dict, List, Optional, Union
from loguru import logger
from pydantic import BaseModel, Field
from tenacity import retry, stop_after_attempt, wait_exponential
from swarms.structs.agent import Agent
from swarms.structs.base_swarm import BaseSwarm
from swarms.utils.file_processing import create_file_in_folder
import concurrent
from clusterops import (
execute_on_gpu,
execute_with_cpu_cores,
execute_on_multiple_gpus,
list_available_gpus,
)
class AgentOutputSchema(BaseModel):
@ -60,7 +68,7 @@ class MetadataSchema(BaseModel):
class ConcurrentWorkflow(BaseSwarm):
"""
Represents a concurrent workflow that executes multiple agents concurrently.
Represents a concurrent workflow that executes multiple agents concurrently in a production-grade manner.
Args:
name (str): The name of the workflow. Defaults to "ConcurrentWorkflow".
@ -69,6 +77,10 @@ class ConcurrentWorkflow(BaseSwarm):
metadata_output_path (str): The path to save the metadata output. Defaults to "agent_metadata.json".
auto_save (bool): Flag indicating whether to automatically save the metadata. Defaults to False.
output_schema (BaseModel): The output schema for the metadata. Defaults to MetadataSchema.
max_loops (int): The maximum number of loops for each agent. Defaults to 1.
return_str_on (bool): Flag indicating whether to return the output as a string. Defaults to False.
agent_responses (list): The list of agent responses. Defaults to an empty list.
auto_generate_prompts (bool): Flag indicating whether to auto-generate prompts for agents. Defaults to False.
Raises:
ValueError: If the list of agents is empty or if the description is empty.
@ -80,7 +92,12 @@ class ConcurrentWorkflow(BaseSwarm):
metadata_output_path (str): The path to save the metadata output.
auto_save (bool): Flag indicating whether to automatically save the metadata.
output_schema (BaseModel): The output schema for the metadata.
max_loops (int): The maximum number of loops for each agent.
return_str_on (bool): Flag indicating whether to return the output as a string.
agent_responses (list): The list of agent responses.
auto_generate_prompts (bool): Flag indicating whether to auto-generate prompts for agents.
retry_attempts (int): The number of retry attempts for failed agent executions.
retry_wait_time (int): The initial wait time for retries in seconds.
"""
def __init__(
@ -94,10 +111,17 @@ class ConcurrentWorkflow(BaseSwarm):
max_loops: int = 1,
return_str_on: bool = False,
agent_responses: list = [],
auto_generate_prompts: bool = False,
*args,
**kwargs,
):
super().__init__(name=name, agents=agents, *args, **kwargs)
super().__init__(
name=name,
description=description,
agents=agents,
*args,
**kwargs,
)
self.name = name
self.description = description
self.agents = agents
@ -107,35 +131,90 @@ class ConcurrentWorkflow(BaseSwarm):
self.max_loops = max_loops
self.return_str_on = return_str_on
self.agent_responses = agent_responses
self.auto_generate_prompts = auto_generate_prompts
if not agents:
raise ValueError("The list of agents cannot be empty.")
self.reliability_check()
if not description:
raise ValueError("The description cannot be empty.")
def reliability_check(self):
try:
logger.info("Starting reliability checks")
if self.name is None:
logger.error("A name is required for the swarm")
raise ValueError("A name is required for the swarm")
if not self.agents:
logger.error("The list of agents must not be empty.")
raise ValueError(
"The list of agents must not be empty."
)
if not self.description:
logger.error("A description is required.")
raise ValueError("A description is required.")
logger.info("Reliability checks completed successfully")
except ValueError as e:
logger.error(f"Reliability check failed: {e}")
raise
except Exception as e:
logger.error(
f"An unexpected error occurred during reliability checks: {e}"
)
raise
def activate_auto_prompt_engineering(self):
"""
Activates the auto-generate prompts feature for all agents in the workflow.
Example:
>>> workflow = ConcurrentWorkflow(agents=[Agent()])
>>> workflow.activate_auto_prompt_engineering()
>>> # All agents in the workflow will now auto-generate prompts.
"""
if self.auto_generate_prompts is True:
for agent in self.agents:
agent.auto_generate_prompt = True
@retry(wait=wait_exponential(min=2), stop=stop_after_attempt(3))
async def _run_agent(
self, agent: Agent, task: str, executor: ThreadPoolExecutor
self,
agent: Agent,
task: str,
img: str,
executor: ThreadPoolExecutor,
*args,
**kwargs,
) -> AgentOutputSchema:
"""
Runs a single agent with the given task and tracks its output and metadata.
Runs a single agent with the given task and tracks its output and metadata with retry logic.
Args:
agent (Agent): The agent instance to run.
task (str): The task or query to give to the agent.
img (str): The image to be processed by the agent.
executor (ThreadPoolExecutor): The thread pool executor to use for running the agent task.
Returns:
AgentOutputSchema: The metadata and output from the agent's execution.
Example:
>>> async def run_agent_example():
>>> executor = ThreadPoolExecutor()
>>> agent_output = await workflow._run_agent(agent=Agent(), task="Example task", img="example.jpg", executor=executor)
>>> print(agent_output)
"""
start_time = datetime.now()
try:
loop = asyncio.get_running_loop()
output = await loop.run_in_executor(
executor, agent.run, task
executor, agent.run, task, img, *args, **kwargs
)
except Exception as e:
output = f"Error: {e}"
logger.error(
f"Error running agent {agent.agent_name}: {e}"
)
raise
end_time = datetime.now()
duration = (end_time - start_time).total_seconds()
@ -160,38 +239,53 @@ class ConcurrentWorkflow(BaseSwarm):
self, schema: MetadataSchema
):
"""
transform metadata schema to string
Converts the metadata swarm schema into a string format with the agent name, response, and time.
Args:
schema (MetadataSchema): The metadata schema to convert.
converts the metadata swarm schema into a string format with the agent name, response, and time
Returns:
str: The string representation of the metadata schema.
Example:
>>> metadata_schema = MetadataSchema()
>>> metadata_str = workflow.transform_metadata_schema_to_str(metadata_schema)
>>> print(metadata_str)
"""
self.agent_responses = [
f"Agent Name: {agent.agent_name}\nResponse: {agent.output}\n\n"
for agent in schema.agents
]
# print all agent responses
# print("\n".join(self.agent_responses))
# Return the agent responses as a string
return "\n".join(self.agent_responses)
@retry(wait=wait_exponential(min=2), stop=stop_after_attempt(3))
async def _execute_agents_concurrently(
self, task: str
self, task: str, img: str, *args, **kwargs
) -> MetadataSchema:
"""
Executes multiple agents concurrently with the same task.
Executes multiple agents concurrently with the same task, incorporating retry logic for failed executions.
Args:
task (str): The task or query to give to all agents.
img (str): The image to be processed by the agents.
Returns:
MetadataSchema: The aggregated metadata and outputs from all agents.
Example:
>>> async def execute_agents_example():
>>> metadata_schema = await workflow._execute_agents_concurrently(task="Example task", img="example.jpg")
>>> print(metadata_schema)
"""
with ThreadPoolExecutor(
max_workers=os.cpu_count()
) as executor:
tasks_to_run = [
self._run_agent(agent, task, executor)
self._run_agent(
agent, task, img, executor, *args, **kwargs
)
for agent in self.agents
]
@ -203,33 +297,53 @@ class ConcurrentWorkflow(BaseSwarm):
agents=agent_outputs,
)
def run(self, task: str) -> Dict[str, Any]:
def save_metadata(self):
"""
Runs the workflow for the given task, executes agents concurrently, and saves metadata.
Saves the metadata to a JSON file based on the auto_save flag.
Example:
>>> workflow.save_metadata()
>>> # Metadata will be saved to the specified path if auto_save is True.
"""
# Save metadata to a JSON file
if self.auto_save:
logger.info(
f"Saving metadata to {self.metadata_output_path}"
)
create_file_in_folder(
os.getenv("WORKSPACE_DIR"),
self.metadata_output_path,
self.output_schema.model_dump_json(indent=4),
)
def _run(
self, task: str, img: str, *args, **kwargs
) -> Union[Dict[str, Any], str]:
"""
Runs the workflow for the given task, executes agents concurrently, and saves metadata in a production-grade manner.
Args:
task (str): The task or query to give to all agents.
img (str): The image to be processed by the agents.
Returns:
Dict[str, Any]: The final metadata as a dictionary.
str: The final metadata as a string if return_str_on is True.
Example:
>>> metadata = workflow.run(task="Example task", img="example.jpg")
>>> print(metadata)
"""
logger.info(
f"Running concurrent workflow with {len(self.agents)} agents."
)
self.output_schema = asyncio.run(
self._execute_agents_concurrently(task)
self._execute_agents_concurrently(
task, img, *args, **kwargs
)
)
# # Save metadata to a JSON file
if self.auto_save:
logger.info(
f"Saving metadata to {self.metadata_output_path}"
)
create_file_in_folder(
os.getenv("WORKSPACE_DIR"),
self.metadata_output_path,
self.output_schema.model_dump_json(indent=4),
)
self.save_metadata()
if self.return_str_on:
return self.transform_metadata_schema_to_str(
@ -240,6 +354,207 @@ class ConcurrentWorkflow(BaseSwarm):
# Return metadata as a dictionary
return self.output_schema.model_dump_json(indent=4)
def run(
self,
task: Optional[str] = None,
img: Optional[str] = None,
is_last: bool = False,
device: str = "cpu", # gpu
device_id: int = 0,
all_cores: bool = True, # Defaults to using all available cores
all_gpus: bool = False,
*args,
**kwargs,
) -> Any:
"""
Executes the agent's run method on a specified device.
This method attempts to execute the agent's run method on a specified device, either CPU or GPU. It logs the device selection and the number of cores or GPU ID used. If the device is set to CPU, it can use all available cores or a specific core specified by `device_id`. If the device is set to GPU, it uses the GPU specified by `device_id`.
Args:
task (Optional[str], optional): The task to be executed. Defaults to None.
img (Optional[str], optional): The image to be processed. Defaults to None.
is_last (bool, optional): Indicates if this is the last task. Defaults to False.
device (str, optional): The device to use for execution. Defaults to "cpu".
device_id (int, optional): The ID of the GPU to use if device is set to "gpu". Defaults to 0.
all_cores (bool, optional): If True, uses all available CPU cores. Defaults to True.
all_gpus (bool, optional): If True, uses all available GPUS. Defaults to True.
*args: Additional positional arguments to be passed to the execution method.
**kwargs: Additional keyword arguments to be passed to the execution method.
Returns:
Any: The result of the execution.
Raises:
ValueError: If an invalid device is specified.
Exception: If any other error occurs during execution.
"""
try:
logger.info(f"Attempting to run on device: {device}")
if device == "cpu":
logger.info("Device set to CPU")
if all_cores is True:
count = os.cpu_count()
logger.info(
f"Using all available CPU cores: {count}"
)
else:
count = device_id
logger.info(f"Using specific CPU core: {count}")
return execute_with_cpu_cores(
count, self._run, task, img, *args, **kwargs
)
# If device gpu
elif device == "gpu":
logger.info("Device set to GPU")
return execute_on_gpu(
device_id, self._run, task, img, *args, **kwargs
)
elif all_gpus is True:
return execute_on_multiple_gpus(
[int(gpu) for gpu in list_available_gpus()],
self._run,
task,
img,
*args,
**kwargs,
)
else:
raise ValueError(
f"Invalid device specified: {device}. Supported devices are 'cpu' and 'gpu'."
)
except ValueError as e:
logger.error(f"Invalid device specified: {e}")
raise e
except Exception as e:
logger.error(f"An error occurred during execution: {e}")
raise e
def run_batched(
self, tasks: List[str]
) -> List[Union[Dict[str, Any], str]]:
"""
Runs the workflow for a batch of tasks, executes agents concurrently for each task, and saves metadata in a production-grade manner.
Args:
tasks (List[str]): A list of tasks or queries to give to all agents.
Returns:
List[Union[Dict[str, Any], str]]: A list of final metadata for each task, either as a dictionary or a string.
Example:
>>> tasks = ["Task 1", "Task 2"]
>>> results = workflow.run_batched(tasks)
>>> print(results)
"""
results = []
for task in tasks:
result = self.run(task)
results.append(result)
return results
def run_async(self, task: str) -> asyncio.Future:
"""
Runs the workflow asynchronously for the given task, executes agents concurrently, and saves metadata in a production-grade manner.
Args:
task (str): The task or query to give to all agents.
Returns:
asyncio.Future: A future object representing the asynchronous operation.
Example:
>>> async def run_async_example():
>>> future = workflow.run_async(task="Example task")
>>> result = await future
>>> print(result)
"""
logger.info(
f"Running concurrent workflow asynchronously with {len(self.agents)} agents."
)
return asyncio.ensure_future(self.run(task))
def run_batched_async(
self, tasks: List[str]
) -> List[asyncio.Future]:
"""
Runs the workflow asynchronously for a batch of tasks, executes agents concurrently for each task, and saves metadata in a production-grade manner.
Args:
tasks (List[str]): A list of tasks or queries to give to all agents.
Returns:
List[asyncio.Future]: A list of future objects representing the asynchronous operations for each task.
Example:
>>> tasks = ["Task 1", "Task 2"]
>>> futures = workflow.run_batched_async(tasks)
>>> results = await asyncio.gather(*futures)
>>> print(results)
"""
futures = []
for task in tasks:
future = self.run_async(task)
futures.append(future)
return futures
def run_parallel(
self, tasks: List[str]
) -> List[Union[Dict[str, Any], str]]:
"""
Runs the workflow in parallel for a batch of tasks, executes agents concurrently for each task, and saves metadata in a production-grade manner.
Args:
tasks (List[str]): A list of tasks or queries to give to all agents.
Returns:
List[Union[Dict[str, Any], str]]: A list of final metadata for each task, either as a dictionary or a string.
Example:
>>> tasks = ["Task 1", "Task 2"]
>>> results = workflow.run_parallel(tasks)
>>> print(results)
"""
with ThreadPoolExecutor(
max_workers=os.cpu_count()
) as executor:
futures = {
executor.submit(self.run, task): task
for task in tasks
}
results = []
for future in concurrent.futures.as_completed(futures):
result = future.result()
results.append(result)
return results
def run_parallel_async(
self, tasks: List[str]
) -> List[asyncio.Future]:
"""
Runs the workflow in parallel asynchronously for a batch of tasks, executes agents concurrently for each task, and saves metadata in a production-grade manner.
Args:
tasks (List[str]): A list of tasks or queries to give to all agents.
Returns:
List[asyncio.Future]: A list of future objects representing the asynchronous operations for each task.
Example:
>>> tasks = ["Task 1", "Task 2"]
>>> futures = workflow.run_parallel_async(tasks)
>>> results = await asyncio.gather(*futures)
>>> print(results)
"""
futures = []
for task in tasks:
future = self.run_async(task)
futures.append(future)
return futures
# if __name__ == "__main__":
# # Assuming you've already initialized some agents outside of this class

@ -31,6 +31,13 @@ class SwarmRearrange:
Attributes:
swarms (dict): A dictionary of swarms, where the key is the swarm's name and the value is the swarm object.
flow (str): The flow pattern of the tasks.
max_loops (int): The maximum number of loops to run the swarm.
verbose (bool): A flag indicating whether to log verbose messages.
human_in_the_loop (bool): A flag indicating whether human intervention is required.
custom_human_in_the_loop (Callable[[str], str], optional): A custom function for human-in-the-loop intervention.
return_json (bool): A flag indicating whether to return the result in JSON format.
swarm_history (dict): A dictionary to keep track of the history of each swarm.
lock (threading.Lock): A lock for thread-safe operations.
Methods:
__init__(swarms: List[swarm] = None, flow: str = None): Initializes the SwarmRearrange object.
@ -70,8 +77,8 @@ class SwarmRearrange:
self.description = description
self.swarms = {swarm.name: swarm for swarm in swarms}
self.flow = flow if flow is not None else ""
self.verbose = verbose
self.max_loops = max_loops if max_loops > 0 else 1
self.verbose = verbose
self.human_in_the_loop = human_in_the_loop
self.custom_human_in_the_loop = custom_human_in_the_loop
self.return_json = return_json
@ -79,34 +86,23 @@ class SwarmRearrange:
self.lock = threading.Lock()
self.id = uuid.uuid4().hex if id is None else id
# Run the relianility checks
# Run the reliability checks
self.reliability_checks()
# # Output schema
# self.input_config = SwarmRearrangeInput(
# swarm_id=self.id,
# name=self.name,
# description=self.description,
# flow=self.flow,
# max_loops=self.max_loops,
# )
# # Output schema
# self.output_schema = SwarmRearrangeOutput(
# Input=self.input_config,
# outputs=[],
# )
# Logging configuration
if self.verbose:
logger.add("swarm_rearrange.log", rotation="10 MB")
def reliability_checks(self):
logger.info("Running reliability checks.")
if self.swarms is None:
if not self.swarms:
raise ValueError("No swarms found in the swarm.")
if self.flow is None:
if not self.flow:
raise ValueError("No flow found in the swarm.")
if self.max_loops is None:
raise ValueError("No max_loops found in the swarm.")
if self.max_loops <= 0:
raise ValueError("Max loops must be a positive integer.")
logger.info(
"SwarmRearrange initialized with swarms: {}".format(
@ -114,10 +110,6 @@ class SwarmRearrange:
)
)
# Verbose is True
if self.verbose is True:
logger.add("swarm_rearrange.log")
def set_custom_flow(self, flow: str):
self.flow = flow
logger.info(f"Custom flow set: {flow}")
@ -199,7 +191,7 @@ class SwarmRearrange:
"Duplicate swarm names in the flow are not allowed."
)
print("Flow is valid.")
logger.info("Flow is valid.")
return True
def run(
@ -354,10 +346,37 @@ def swarm_arrange(
*args,
**kwargs,
):
return SwarmRearrange(
name,
description,
swarms,
output_type,
flow,
).run(task, *args, **kwargs)
"""
Orchestrates the execution of multiple swarms in a sequential manner.
Args:
name (str, optional): The name of the swarm arrangement. Defaults to "SwarmArrange-01".
description (str, optional): A description of the swarm arrangement. Defaults to "Combine multiple swarms and execute them sequentially".
swarms (List[Callable], optional): A list of swarm objects to be executed. Defaults to None.
output_type (str, optional): The format of the output. Defaults to "json".
flow (str, optional): The flow pattern of the tasks. Defaults to None.
task (str, optional): The task to be executed by the swarms. Defaults to None.
*args: Additional positional arguments to be passed to the SwarmRearrange object.
**kwargs: Additional keyword arguments to be passed to the SwarmRearrange object.
Returns:
Any: The result of the swarm arrangement execution.
"""
try:
swarm_arrangement = SwarmRearrange(
name,
description,
swarms,
output_type,
flow,
)
result = swarm_arrangement.run(task, *args, **kwargs)
logger.info(
f"Swarm arrangement {name} executed successfully with output type {output_type}."
)
return result
except Exception as e:
logger.error(
f"An error occurred during swarm arrangement execution: {e}"
)
return str(e)

@ -0,0 +1,250 @@
from typing import List, Tuple, Optional
import numpy as np
import torch
from transformers import AutoTokenizer, AutoModel
from pydantic import BaseModel, Field
from loguru import logger
import json
from tenacity import retry, stop_after_attempt, wait_exponential
# Ensure you have the necessary libraries installed:
# pip install torch transformers pydantic loguru tenacity
class SwarmType(BaseModel):
name: str
description: str
embedding: Optional[List[float]] = Field(
default=None, exclude=True
)
class SwarmMatcherConfig(BaseModel):
model_name: str = "sentence-transformers/all-MiniLM-L6-v2"
embedding_dim: int = (
512 # Dimension of the sentence-transformers model
)
class SwarmMatcher:
"""
A class for matching tasks to swarm types based on their descriptions.
It utilizes a transformer model to generate embeddings for task and swarm type descriptions,
and then calculates the dot product to find the best match.
"""
def __init__(self, config: SwarmMatcherConfig):
"""
Initializes the SwarmMatcher with a configuration.
Args:
config (SwarmMatcherConfig): The configuration for the SwarmMatcher.
"""
logger.add("swarm_matcher_debug.log", level="DEBUG")
logger.debug("Initializing SwarmMatcher")
try:
self.config = config
self.tokenizer = AutoTokenizer.from_pretrained(
config.model_name
)
self.model = AutoModel.from_pretrained(config.model_name)
self.swarm_types: List[SwarmType] = []
logger.debug("SwarmMatcher initialized successfully")
except Exception as e:
logger.error(f"Error initializing SwarmMatcher: {str(e)}")
raise
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=4, max=10),
)
def get_embedding(self, text: str) -> np.ndarray:
"""
Generates an embedding for a given text using the configured model.
Args:
text (str): The text for which to generate an embedding.
Returns:
np.ndarray: The embedding vector for the text.
"""
logger.debug(f"Getting embedding for text: {text[:50]}...")
try:
inputs = self.tokenizer(
text,
return_tensors="pt",
padding=True,
truncation=True,
max_length=512,
)
with torch.no_grad():
outputs = self.model(**inputs)
embedding = (
outputs.last_hidden_state.mean(dim=1)
.squeeze()
.numpy()
)
logger.debug("Embedding generated successfully")
return embedding
except Exception as e:
logger.error(f"Error generating embedding: {str(e)}")
raise
def add_swarm_type(self, swarm_type: SwarmType):
"""
Adds a swarm type to the list of swarm types, generating an embedding for its description.
Args:
swarm_type (SwarmType): The swarm type to add.
"""
logger.debug(f"Adding swarm type: {swarm_type.name}")
try:
embedding = self.get_embedding(swarm_type.description)
swarm_type.embedding = embedding.tolist()
self.swarm_types.append(swarm_type)
logger.info(f"Added swarm type: {swarm_type.name}")
except Exception as e:
logger.error(
f"Error adding swarm type {swarm_type.name}: {str(e)}"
)
raise
def find_best_match(self, task: str) -> Tuple[str, float]:
"""
Finds the best match for a given task among the registered swarm types.
Args:
task (str): The task for which to find the best match.
Returns:
Tuple[str, float]: A tuple containing the name of the best matching swarm type and the score.
"""
logger.debug(f"Finding best match for task: {task[:50]}...")
try:
task_embedding = self.get_embedding(task)
best_match = None
best_score = -float("inf")
for swarm_type in self.swarm_types:
score = np.dot(
task_embedding, np.array(swarm_type.embedding)
)
if score > best_score:
best_score = score
best_match = swarm_type
logger.info(
f"Best match for task: {best_match.name} (score: {best_score})"
)
return best_match.name, float(best_score)
except Exception as e:
logger.error(
f"Error finding best match for task: {str(e)}"
)
raise
def auto_select_swarm(self, task: str) -> str:
"""
Automatically selects the best swarm type for a given task based on their descriptions.
Args:
task (str): The task for which to select a swarm type.
Returns:
str: The name of the selected swarm type.
"""
logger.debug(f"Auto-selecting swarm for task: {task[:50]}...")
best_match, score = self.find_best_match(task)
logger.info(f"Task: {task}")
logger.info(f"Selected Swarm Type: {best_match}")
logger.info(f"Confidence Score: {score:.2f}")
return best_match
def run_multiple(self, tasks: List[str], *args, **kwargs) -> str:
swarms = []
for task in tasks:
output = self.auto_select_swarm(task)
# Append
swarms.append(output)
return swarms
def save_swarm_types(self, filename: str):
"""
Saves the registered swarm types to a JSON file.
Args:
filename (str): The name of the file to which to save the swarm types.
"""
try:
with open(filename, "w") as f:
json.dump([st.dict() for st in self.swarm_types], f)
logger.info(f"Saved swarm types to {filename}")
except Exception as e:
logger.error(f"Error saving swarm types: {str(e)}")
raise
def load_swarm_types(self, filename: str):
"""
Loads swarm types from a JSON file.
Args:
filename (str): The name of the file from which to load the swarm types.
"""
try:
with open(filename, "r") as f:
swarm_types_data = json.load(f)
self.swarm_types = [
SwarmType(**st) for st in swarm_types_data
]
logger.info(f"Loaded swarm types from {filename}")
except Exception as e:
logger.error(f"Error loading swarm types: {str(e)}")
raise
def initialize_swarm_types(matcher: SwarmMatcher):
logger.debug("Initializing swarm types")
swarm_types = [
SwarmType(
name="AgentRearrange",
description="Optimize agent order and rearrange flow for multi-step tasks, ensuring efficient task allocation and minimizing bottlenecks",
),
SwarmType(
name="MixtureOfAgents",
description="Combine diverse expert agents for comprehensive analysis, fostering a collaborative approach to problem-solving and leveraging individual strengths",
),
SwarmType(
name="SpreadSheetSwarm",
description="Collaborative data processing and analysis in a spreadsheet-like environment, facilitating real-time data sharing and visualization",
),
SwarmType(
name="SequentialWorkflow",
description="Execute tasks in a step-by-step, sequential process workflow, ensuring a logical and methodical approach to task execution",
),
SwarmType(
name="ConcurrentWorkflow",
description="Process multiple tasks or data sources concurrently in parallel, maximizing productivity and reducing processing time",
),
]
for swarm_type in swarm_types:
matcher.add_swarm_type(swarm_type)
logger.debug("Swarm types initialized")
def swarm_matcher(task: str, *args, **kwargs):
"""
Runs the SwarmMatcher example with predefined tasks and swarm types.
"""
config = SwarmMatcherConfig()
matcher = SwarmMatcher(config)
initialize_swarm_types(matcher)
matcher.save_swarm_types("swarm_types.json")
swarm_type = matcher.auto_select_swarm(task)
logger.info(f"{swarm_type}")
return swarm_type

@ -11,6 +11,8 @@ from swarms.structs.mixture_of_agents import MixtureOfAgents
from swarms.structs.rearrange import AgentRearrange
from swarms.structs.sequential_workflow import SequentialWorkflow
from swarms.structs.spreadsheet_swarm import SpreadSheetSwarm
from tenacity import retry, stop_after_attempt, wait_fixed
from swarms.structs.swarm_matcher import swarm_matcher
SwarmType = Literal[
"AgentRearrange",
@ -18,6 +20,7 @@ SwarmType = Literal[
"SpreadSheetSwarm",
"SequentialWorkflow",
"ConcurrentWorkflow",
"auto",
]
@ -37,15 +40,21 @@ class SwarmLog(BaseModel):
class SwarmRouter:
"""
A class to route tasks to different swarm types based on user selection.
A class to dynamically route tasks to different swarm types based on user selection or automatic matching.
This class allows users to specify a swarm type and a list of agents, then run tasks
on the selected swarm type. It includes type validation, logging, and metadata capture.
This class enables users to specify a swarm type or let the system automatically determine the best swarm type for a given task. It then runs the task on the selected or matched swarm type, ensuring type validation, logging, and metadata capture.
Attributes:
agents (List[Agent]): A list of Agent objects to be used in the swarm.
swarm_type (SwarmType): The type of swarm to be used.
swarm (Union[AgentRearrange, GraphWorkflow, MixtureOfAgents, SpreadSheetSwarm]):
name (str): The name of the SwarmRouter instance.
description (str): A description of the SwarmRouter instance.
max_loops (int): The maximum number of loops to perform.
agents (List[Union[Agent, Callable]]): A list of Agent objects to be used in the swarm.
swarm_type (SwarmType): The type of swarm to be used, which can be specified or automatically determined.
autosave (bool): A flag to enable/disable autosave.
flow (str): The flow of the swarm.
return_json (bool): A flag to enable/disable returning the result in JSON format.
auto_generate_prompts (bool): A flag to enable/disable auto generation of prompts.
swarm (Union[AgentRearrange, MixtureOfAgents, SpreadSheetSwarm, SequentialWorkflow, ConcurrentWorkflow]):
The instantiated swarm object.
logs (List[SwarmLog]): A list of log entries captured during operations.
@ -55,6 +64,7 @@ class SwarmRouter:
- SpreadSheetSwarm: Utilizes spreadsheet-like operations for task management.
- SequentialWorkflow: Executes tasks in a sequential manner.
- ConcurrentWorkflow: Executes tasks concurrently for parallel processing.
- "auto" will automatically conduct embedding search to find the best swarm for your task
"""
def __init__(
@ -63,35 +73,14 @@ class SwarmRouter:
description: str = "Routes your task to the desired swarm",
max_loops: int = 1,
agents: List[Union[Agent, Callable]] = [],
swarm_type: SwarmType = "SequentialWorkflow",
swarm_type: SwarmType = "SequentialWorkflow", # "SpreadSheetSwarm" # "auto"
autosave: bool = False,
flow: str = None,
return_json: bool = True,
auto_generate_prompts: bool = False,
*args,
**kwargs,
):
"""
Initialize the SwarmRouter with a list of agents and a swarm type.
Args:
name (str, optional): The name of the SwarmRouter instance. Defaults to None.
description (str, optional): A description of the SwarmRouter instance. Defaults to None.
max_loops (int, optional): The maximum number of loops to perform. Defaults to 1.
agents (List[Agent], optional): A list of Agent objects to be used in the swarm. Defaults to None.
swarm_type (SwarmType, optional): The type of swarm to be used. Defaults to None.
*args: Variable length argument list.
**kwargs: Arbitrary keyword arguments.
Raises:
ValueError: If an invalid swarm type is provided, or if there are no agents, or if swarm type is "none", or if max_loops is 0.
"""
if not agents:
raise ValueError("No agents provided for the swarm.")
if swarm_type is None:
raise ValueError("Swarm type cannot be 'none'.")
if max_loops == 0:
raise ValueError("max_loops cannot be 0.")
self.name = name
self.description = description
self.max_loops = max_loops
@ -100,15 +89,32 @@ class SwarmRouter:
self.autosave = autosave
self.flow = flow
self.return_json = return_json
self.swarm = self._create_swarm(*args, **kwargs)
self.auto_generate_prompts = auto_generate_prompts
self.logs = []
self.reliability_check()
self._log(
"info",
f"SwarmRouter initialized with swarm type: {swarm_type}",
)
def _create_swarm(self, *args, **kwargs) -> Union[
@retry(stop=stop_after_attempt(3), wait=wait_fixed(1))
def reliability_check(self):
logger.info("Logger initializing checks")
if not self.agents:
raise ValueError("No agents provided for the swarm.")
if self.swarm_type is None:
raise ValueError("Swarm type cannot be 'none'.")
if self.max_loops == 0:
raise ValueError("max_loops cannot be 0.")
logger.info("Checks completed your swarm is ready.")
def _create_swarm(
self, task: str = None, *args, **kwargs
) -> Union[
AgentRearrange,
MixtureOfAgents,
SpreadSheetSwarm,
@ -116,20 +122,24 @@ class SwarmRouter:
ConcurrentWorkflow,
]:
"""
Create and return the specified swarm type.
Dynamically create and return the specified swarm type or automatically match the best swarm type for a given task.
Args:
task (str, optional): The task to be executed by the swarm. Defaults to None.
*args: Variable length argument list.
**kwargs: Arbitrary keyword arguments.
Returns:
Union[AgentRearrange, GraphWorkflow, MixtureOfAgents, SpreadSheetSwarm]:
Union[AgentRearrange, MixtureOfAgents, SpreadSheetSwarm, SequentialWorkflow, ConcurrentWorkflow]:
The instantiated swarm object.
Raises:
ValueError: If an invalid swarm type is provided.
"""
if self.swarm_type == "AgentRearrange":
if self.swarm_type == "auto":
self.swarm_type = swarm_matcher(task)
elif self.swarm_type == "AgentRearrange":
return AgentRearrange(
name=self.name,
description=self.description,
@ -209,9 +219,10 @@ class SwarmRouter:
self.logs.append(log_entry)
logger.log(level.upper(), message)
@retry(stop=stop_after_attempt(3), wait=wait_fixed(1))
def run(self, task: str, *args, **kwargs) -> Any:
"""
Run the specified task on the selected swarm.
Dynamically run the specified task on the selected or matched swarm type.
Args:
task (str): The task to be executed by the swarm.
@ -224,6 +235,8 @@ class SwarmRouter:
Raises:
Exception: If an error occurs during task execution.
"""
self.swarm = self._create_swarm(task, *args, **kwargs)
try:
self._log(
"info",
@ -248,6 +261,107 @@ class SwarmRouter:
)
raise
def batch_run(
self, tasks: List[str], *args, **kwargs
) -> List[Any]:
"""
Execute a batch of tasks on the selected or matched swarm type.
Args:
tasks (List[str]): A list of tasks to be executed by the swarm.
*args: Variable length argument list.
**kwargs: Arbitrary keyword arguments.
Returns:
List[Any]: A list of results from the swarm's execution.
Raises:
Exception: If an error occurs during task execution.
"""
results = []
for task in tasks:
try:
result = self.run(task, *args, **kwargs)
results.append(result)
except Exception as e:
self._log(
"error",
f"Error occurred while running batch task on {self.swarm_type} swarm: {str(e)}",
task=task,
metadata={"error": str(e)},
)
raise
return results
def threaded_run(self, task: str, *args, **kwargs) -> Any:
"""
Execute a task on the selected or matched swarm type using threading.
Args:
task (str): The task to be executed by the swarm.
*args: Variable length argument list.
**kwargs: Arbitrary keyword arguments.
Returns:
Any: The result of the swarm's execution.
Raises:
Exception: If an error occurs during task execution.
"""
from threading import Thread
def run_in_thread():
try:
result = self.run(task, *args, **kwargs)
return result
except Exception as e:
self._log(
"error",
f"Error occurred while running task in thread on {self.swarm_type} swarm: {str(e)}",
task=task,
metadata={"error": str(e)},
)
raise
thread = Thread(target=run_in_thread)
thread.start()
thread.join()
return thread.result
def async_run(self, task: str, *args, **kwargs) -> Any:
"""
Execute a task on the selected or matched swarm type asynchronously.
Args:
task (str): The task to be executed by the swarm.
*args: Variable length argument list.
**kwargs: Arbitrary keyword arguments.
Returns:
Any: The result of the swarm's execution.
Raises:
Exception: If an error occurs during task execution.
"""
import asyncio
async def run_async():
try:
result = await asyncio.to_thread(
self.run, task, *args, **kwargs
)
return result
except Exception as e:
self._log(
"error",
f"Error occurred while running task asynchronously on {self.swarm_type} swarm: {str(e)}",
task=task,
metadata={"error": str(e)},
)
raise
return asyncio.run(run_async())
def get_logs(self) -> List[SwarmLog]:
"""
Retrieve all logged entries.
@ -256,3 +370,52 @@ class SwarmRouter:
List[SwarmLog]: A list of all log entries.
"""
return self.logs
def concurrent_run(self, task: str, *args, **kwargs) -> Any:
"""
Execute a task on the selected or matched swarm type concurrently.
Args:
task (str): The task to be executed by the swarm.
*args: Variable length argument list.
**kwargs: Arbitrary keyword arguments.
Returns:
Any: The result of the swarm's execution.
Raises:
Exception: If an error occurs during task execution.
"""
from concurrent.futures import ThreadPoolExecutor
with ThreadPoolExecutor() as executor:
future = executor.submit(self.run, task, *args, **kwargs)
result = future.result()
return result
def concurrent_batch_run(
self, tasks: List[str], *args, **kwargs
) -> List[Any]:
"""
Execute a batch of tasks on the selected or matched swarm type concurrently.
Args:
tasks (List[str]): A list of tasks to be executed by the swarm.
*args: Variable length argument list.
**kwargs: Arbitrary keyword arguments.
Returns:
List[Any]: A list of results from the swarm's execution.
Raises:
Exception: If an error occurs during task execution.
"""
from concurrent.futures import ThreadPoolExecutor
with ThreadPoolExecutor() as executor:
futures = [
executor.submit(self.run, task, *args, **kwargs)
for task in tasks
]
results = [future.result() for future in futures]
return results

@ -17,13 +17,6 @@ load_dotenv()
# Get the OpenAI API key from the environment variable
api_key = os.getenv("OPENAI_API_KEY")
# # Set up loguru to log into a file and console
# logger.add(
# "multi_agent_log_{time}.log",
# format="{time} {level} {message}",
# level="DEBUG",
# rotation="10 MB",
# )
# Pretrained model for embeddings
embedding_model = SentenceTransformer(

@ -20,18 +20,17 @@ ToolType = Union[BaseModel, Dict[str, Any], Callable[..., Any]]
class BaseTool(BaseModel):
verbose: bool = False
base_models: List[type[BaseModel]] = []
verbose: bool = False
autocheck: bool = False
auto_execute_tool: Optional[bool] = False
tools: List[Callable[..., Any]] = []
tool_system_prompt: str = Field(
...,
verbose: Optional[bool] = None
base_models: Optional[List[type[BaseModel]]] = None
autocheck: Optional[bool] = None
auto_execute_tool: Optional[bool] = None
tools: Optional[List[Callable[..., Any]]] = None
tool_system_prompt: Optional[str] = Field(
None,
description="The system prompt for the tool system.",
)
function_map: Dict[str, Callable] = {}
list_of_dicts: List[Dict[str, Any]] = []
function_map: Optional[Dict[str, Callable]] = None
list_of_dicts: Optional[List[Dict[str, Any]]] = None
def func_to_dict(
self,
@ -418,7 +417,7 @@ class BaseTool(BaseModel):
f"Tool {tool.__name__} does not have documentation or type hints, please add them to make the tool execution reliable."
)
return None
return tool_schema_list
def check_func_if_have_docs(self, func: callable):
if func.__doc__ is not None:

@ -499,29 +499,6 @@ def test_tool_function_without_docstring():
tool(no_doc_func)
# ... more exception tests ...
# Decorator behavior tests
@pytest.mark.asyncio
async def test_async_tool_function():
# Test an async function with the tool decorator
@tool
async def async_func(arg: str) -> str:
return arg
# Add async specific assertions here
# ... more decorator tests ...
class MockSchema(BaseModel):
"""Mock schema for testing args_schema."""
arg: str
# Test suite starts here
class TestTool:
# Basic Functionality Tests
@ -544,11 +521,6 @@ class TestTool:
with pytest.raises(ValueError):
tool(123)
# Schema Inference and Application Tests
def test_tool_with_args_schema(self, mock_func):
result = tool(mock_func, args_schema=MockSchema)
assert result.args_schema == MockSchema
def test_tool_with_infer_schema_true(self, mock_func):
tool(mock_func, infer_schema=True)
# Assertions related to schema inference

Loading…
Cancel
Save