The`AbstractAgent`class is a fundamental building block in the design of AI systems. It encapsulates the behavior of an AI entity, allowing it to interact with other agents and perform actions. The class is designed to be flexible and extensible, enabling the creation of agents with diverse behaviors.
## Architecture
------------
The architecture of the`AbstractAgent`class is centered around three main components: the agent's name, tools, and memory.
- The`name`is a string that uniquely identifies the agent. This is crucial for communication between agents and for tracking their actions.
- The`tools`are a list of`Tool`objects that the agent uses to perform its tasks. These could include various AI models, data processing utilities, or any other resources that the agent needs to function. The`tools`method is used to initialize these tools.
- The`memory`is a`Memory`object that the agent uses to store and retrieve information. This could be used, for example, to remember past actions or to store the state of the environment. The`memory`method is used to initialize the memory.
The`AbstractAgent`class also includes several methods that define the agent's behavior. These methods are designed to be overridden in subclasses to implement specific behaviors.
## Methods
-------
### `reset`
The`reset`method is used to reset the agent's state. This could involve clearing the agent's memory, resetting its tools, or any other actions necessary to bring the agent back to its initial state. This method is abstract and must be overridden in subclasses.
### `run`and`_arun`
The`run`method is used to execute a task. The task is represented as a string, which could be a command, a query, or any other form of instruction that the agent can interpret. The`_arun`method is the asynchronous version of`run`, allowing tasks to be executed concurrently.
### `chat`and`_achat`
The`chat`method is used for communication between agents. It takes a list of messages as input, where each message is a dictionary. The`_achat`method is the asynchronous version of`chat`, allowing messages to be sent and received concurrently.
### `step`and`_astep`
The`step`method is used to advance the agent's state by one step in response to a message. The`_astep`method is the asynchronous version of`step`, allowing the agent's state to be updated concurrently.
## Usage E#xamples
--------------
### Example 1: Creating an Agent
```
from swarms.agents.base import AbtractAgent
agent = Agent(name="Agent1")
print(agent.name) # Output: Agent1
```
In this example, we create an instance of`AbstractAgent`named "Agent1" and print its name.
### Example 2: Initializing Tools and Memory
```
from swarms.agents.base import AbtractAgent
agent = Agent(name="Agent1")
tools = [Tool1(), Tool2(), Tool3()]
memory_store = Memory()
agent.tools(tools)
agent.memory(memory_store)
```
In this example, we initialize the tools and memory of "Agent1". The tools are a list of`Tool`instances, and the memory is a`Memory`instance.
### Example 3: Running an Agent
```
from swarms.agents.base import AbtractAgent
agent = Agent(name="Agent1")
task = "Task1"
agent.run(task)
```
In this example, we run "Agent1" with a task named "Task1".
Notes
-----
- The`AbstractAgent`class is an abstract class, which means it cannot be instantiated directly. Instead, it should be subclassed, and at least the`reset`,`run`,`chat`, and`step`methods should be overridden.
- The`run`,`chat`, and`step`methods are designed to be flexible and can be adapted to a wide range of tasks and behaviors. For example, the`run`method could be used to execute a machine learning model, the`chat`method could be used to send and receive messages in a chatbot, and the`step`method could be used to update the agent's state in a reinforcement learning environment.
- The`_arun`,`_achat`, and`_astep`methods are asynchronous versions of the`run`,`chat`, and`step`methods, respectively. They return a coroutine that can be awaited using the`await`keyword. This allows multiple tasks to be executed concurrently, improving the efficiency of the agent.
- The`tools`and`memory`methods are used to initialize the agent's tools and memory, respectively. These methods can be overridden in subclasses to initialize specific tools and memory structures.
- The`reset`method is used to reset the agent's state. This method can be overridden in subclasses to define specific reset behaviors. For example, in a reinforcement learning agent, the
The`Workflow`class is a part of the`swarms`library and is used to create and execute a workflow of tasks. It provides a way to define a sequence of tasks and execute them in order, with the output of each task being used as the input for the next task.
## Overview and Introduction
-------------------------
The`Workflow`class is designed to simplify the execution of a series of tasks by providing a structured way to define and execute them. It allows for sequential execution of tasks, with the output of each task being passed as input to the next task. This makes it easy to create complex workflows and automate multi-step processes.
## Class Definition: Workflow
The`Workflow`class is a powerful tool provided by the`swarms`library that allows users to create and execute a sequence of tasks in a structured and automated manner. It simplifies the process of defining and executing complex workflows by providing a clear and intuitive interface.
## Why Use Workflows?
------------------
Workflows are essential in many domains, including data processing, automation, and task management. They enable the automation of multi-step processes, where the output of one task serves as the input for the next task. By using workflows, users can streamline their work, reduce manual effort, and ensure consistent and reliable execution of tasks.
The`Workflow`class provides a way to define and execute workflows in a flexible and efficient manner. It allows users to define the sequence of tasks, specify dependencies between tasks, and execute them in order. This makes it easier to manage complex processes and automate repetitive tasks.
## How Does it Work?
-----------------
The`Workflow`class consists of two main components: the`Task`class and the`Workflow`class itself. Let's explore each of these components in detail.
### Task Class
The`Task`class represents an individual task within a workflow. Each task is defined by a string description. It contains attributes such as`parents`,`children`,`output`, and`structure`.
The`parents`attribute is a list that stores references to the parent tasks of the current task. Similarly, the`children`attribute is a list that stores references to the child tasks of the current task. These attributes allow for the definition of task dependencies and the establishment of the workflow's structure.
The`output`attribute stores the output of the task, which is generated when the task is executed. Initially, the output is set to`None`, indicating that the task has not been executed yet.
The`structure`attribute refers to the`Workflow`object that the task belongs to. This attribute is set when the task is added to the workflow.
The`Task`class also provides methods such as`add_child`and`execute`. The`add_child`method allows users to add child tasks to the current task, thereby defining the workflow's structure. The`execute`method is responsible for executing the task by running the associated agent's`run`method with the task as input. It returns the response generated by the agent's`run`method.
### Workflow Class
The`Workflow`class is the main class that orchestrates the execution of tasks in a workflow. It takes an agent object as input, which is responsible for executing the tasks. The agent object should have a`run`method that accepts a task as input and returns a response.
The`Workflow`class provides methods such as`add`,`run`, and`context`. The`add`method allows users to add tasks to the workflow. It returns the newly created task object, which can be used to define task dependencies. The`run`method executes the workflow by running each task in order. It returns the last task in the workflow. The`context`method returns a dictionary containing the context information for a given task, including the parent output, parent task, and child task.
The`Workflow`class also has attributes such as`tasks`and`parallel`. The`tasks`attribute is a list that stores references to all the tasks in the workflow. The`parallel`attribute is a boolean flag that determines whether the tasks should be executed in parallel or sequentially.
When executing the workflow, the`run`method iterates over the tasks in the workflow and executes each task in order. If the`parallel`flag is set to`True`, the tasks are executed in parallel using a`ThreadPoolExecutor`. Otherwise, the tasks are executed sequentially.
## Benefits and Use Cases
----------------------
The`Workflow`class provides several benefits and use cases:
- Automation: Workflows automate multi-step processes, reducing manual effort and increasing efficiency. By defining the sequence of tasks and their dependencies, users can automate repetitive tasks and ensure consistent execution.
- Flexibility: Workflows can be easily customized and modified to suit specific needs. Users can add, remove, or rearrange tasks as required, allowing for dynamic and adaptable workflows.
- Error Handling: Workflows provide a structured approach to error handling. If an error occurs during the execution of a task, the workflow can be designed to handle the error gracefully and continue with the remaining tasks.
- Collaboration: Workflows facilitate collaboration by providing a shared structure for task execution. Multiple users can contribute to the workflow by adding or modifying tasks, enabling teamwork and coordination.
- Reproducibility: Workflows ensure reproducibility by defining a clear sequence of tasks. By following the same workflow, users can achieve consistent results and easily reproduce previous analyses or processes.
Overall, the`Workflow`class is a valuable tool for managing and executing complex processes. It simplifies the creation
## Class Parameters
----------------
- `agent`(Any): The agent object that will be used to execute the tasks. It should have a`run`method that takes a task as input and returns a response.
- `parallel`(bool): If`True`, the tasks will be executed in parallel using a`ThreadPoolExecutor`. Default:`False`.
## Class Methods
-------------
### `add(task: str) -> Task`
Adds a new task to the workflow.
- `task`(str): The task to be added.
Returns:
- `Task`: The newly created task object.
### `run(*args) -> Task`
Executes the workflow by running each task in order.
Returns:
- `Task`: The last task in the workflow.
### `context(task: Task) -> Dict[str, Any]`
Returns a dictionary containing the context information for a given task. The context includes the parent output, parent task, and child task.
- `task`(Task): The task for which the context information is required.
Returns:
- `Dict[str, Any]`: A dictionary containing the context information.
## Task Class
----------
The`Task`class is a nested class within the`Workflow`class. It represents an individual task in the workflow.
### Task Parameters
- `task`(str): The task description.
### Task Methods
### `add_child(child: 'Workflow.Task')`
Adds a child task to the current task.
- `child`('Workflow.Task'): The child task to be added.
### `execute() -> Any`
Executes the task by running the associated agent's`run`method with the task as input.
Returns:
- `Any`: The response from the agent's`run`method.
## Functionality and Usage
-----------------------------------
To use the`Workflow`class, follow these steps:
1. Create an instance of the`Workflow`class, providing an agent object that has a`run`method. This agent will be responsible for executing the tasks in the workflow.
```
from swarms import Workflow
# Create an instance of the Workflow class
workflow = Workflow(agent=my_agent)
```
1. Add tasks to the workflow using the`add`method. Each task should be a string description.
```
# Add tasks to the workflow
task1 = workflow.add("Task 1")
task2 = workflow.add("Task 2")
task3 = workflow.add("Task 3")
```
1. Define the sequence of tasks by adding child tasks to each task using the`add_child`method.
```
# Define the sequence of tasks
task1.add_child(task2)
task2.add_child(task3)
```
1. Execute the workflow using the`run`method. This will run each task in order, with the output of each task being passed as input to the next task.
```
# Execute the workflow
workflow.run()
```
1. Access the output of each task using the`output`attribute of the task object.
```
# Access the output of each task
output1 = task1.output
output2 = task2.output
output3 = task3.output
```
1. Optionally, you can run the tasks in parallel by setting the`parallel`parameter to`True`when creating the`Workflow`object.
1. You can also access the context information for a task using the`context`method. This method returns a dictionary containing the parent output, parent task, and child task for the given task.
The`AbstractWorker`class is an abstract class for AI workers. An AI worker can communicate with other workers and perform actions. Different workers can differ in what actions they perform in the`receive`method.
## Class Definition
----------------
```
class AbstractWorker:
"""(In preview) An abstract class for AI worker.
An worker can communicate with other workers and perform actions.
Different workers can differ in what actions they perform in the `receive` method.
"""
```
## Initialization
--------------
The`AbstractWorker`class is initialized with a single parameter:
- `name`(str): The name of the worker.
```
def __init__(
self,
name: str,
):
"""
Args:
name (str): name of the worker.
"""
self._name = name
```
## Properties
----------
The`AbstractWorker`class has a single property:
- `name`: Returns the name of the worker.
```
@property
def name(self):
"""Get the name of the worker."""
return self._name
```
## Methods
-------
The`AbstractWorker`class has several methods:
### `run`
The`run`method is used to run the worker agent once. It takes a single parameter:
- `task`(str): The task to be run.
```
def run(
self,
task: str
):
"""Run the worker agent once"""
```
### `send`
The`send`method is used to send a message to another worker. It takes three parameters:
- `message`(Union[Dict, str]): The message to be sent.
- `recipient`(AbstractWorker): The recipient of the message.
- `request_reply`(Optional[bool]): If set to`True`, the method will request a reply from the recipient.
```
def send(
self,
message: Union[Dict, str],
recipient: AbstractWorker,
request_reply: Optional[bool] = None
):
"""(Abstract method) Send a message to another worker."""
```
### `a_send`
The`a_send`method is the asynchronous version of the`send`method. It takes the same parameters as the`send`method.
```
async def a_send(
self,
message: Union[Dict, str],
recipient: AbstractWorker,
request_reply: Optional[bool] = None
):
"""(Abstract async method) Send a message to another worker."""
```
### `receive`
The`receive`method is used to receive a message from another worker. It takes three parameters:
- `message`(Union[Dict, str]): The message to be received.
- `sender`(AbstractWorker): The sender of the message.
- `request_reply`(Optional[bool]): If set to`True`, the method will request a reply from the sender.
```
def receive(
self,
message: Union[Dict, str],
sender: AbstractWorker,
request_reply: Optional[bool] = None
):
"""(Abstract method) Receive a message from another worker."""
```
### `a_receive`
The`a_receive`method is the asynchronous version of the`receive`method. It takes the same parameters as the`receive`method.
```
async def a_receive(
self,
message: Union[Dict, str],
sender: AbstractWorker,
request_reply: Optional[bool] = None
):
"""(Abstract async method) Receive a message from another worker."""
```
### `reset`
The`reset`method is used to reset the worker.
```
def reset(self):
"""(Abstract method) Reset the worker."""
```
### `generate_reply`
The`generate_reply`method is used to generate a reply based on the received messages. It takes two parameters:
- `messages`(Optional[List[Dict]]): A list of messages received.
- `sender`(AbstractWorker): The sender of the messages.
The method returns a string, a dictionary, or`None`. If`None`is returned, no reply is generated.
```
def generate_reply(
self,
messages: Optional[List[Dict]] = None,
sender: AbstractWorker,
**kwargs,
) -> Union[str, Dict, None]:
"""(Abstract method) Generate a reply based on the received messages.
Args:
messages (list[dict]): a list of messages received.
sender: sender of an Agent instance.
Returns:
str or dict or None: the generated reply. If None, no reply is generated.
"""
```
### `a_generate_reply`
The`a_generate_reply`method is the asynchronous version of the`generate_reply`method. It
takes the same parameters as the`generate_reply`method.
```
async def a_generate_reply(
self,
messages: Optional[List[Dict]] = None,
sender: AbstractWorker,
**kwargs,
) -> Union[str, Dict, None]:
"""(Abstract async method) Generate a reply based on the received messages.
Args:
messages (list[dict]): a list of messages received.
sender: sender of an Agent instance.
Returns:
str or dict or None: the generated reply. If None, no reply is generated.
"""
```
Usage Examples
--------------
### Example 1: Creating an AbstractWorker
```
from swarms.worker.base import AbstractWorker
worker = AbstractWorker(name="Worker1")
print(worker.name) # Output: Worker1
```
In this example, we create an instance of`AbstractWorker`named "Worker1" and print its name.
### Example 2: Sending a Message
```
from swarms.worker.base import AbstractWorker
worker1 = AbstractWorker(name="Worker1")
worker2 = AbstractWorker(name="Worker2")
message = {"content": "Hello, Worker2!"}
worker1.send(message, worker2)
```
In this example, "Worker1" sends a message to "Worker2". The message is a dictionary with a single key-value pair.
In this example, "Worker1" sends a message to "Worker2". "Worker2" then receives the message and prints it.
Notes
-----
- The`AbstractWorker`class is an abstract class, which means it cannot be instantiated directly. Instead, it should be subclassed, and at least the`send`,`receive`,`reset`, and`generate_reply`methods should be overridden.
- The`send`and`receive`methods are abstract methods, which means they must be implemented in any subclass of`AbstractWorker`.
- The`a_send`,`a_receive`, and`a_generate_reply`methods are asynchronous methods, which means they return a coroutine that can be awaited using the`await`keyword.
- The`generate_reply`method is used to generate a reply based on the received messages. The exact implementation of this method will depend on the specific requirements of your application.
- The`reset`method is used to reset the state of the worker. The exact implementation of this method will depend on the specific requirements of your application.
task="What were the winning boston marathon times for the past 5 years (ending in 2022)? Generate a table of the year, name, country of origin, and times."
task="What were the winning boston marathon times for the past 5 years (ending in 2022)? Generate a table of the year, name, country of origin, and times."
message=f"The server of local inference endpoints is not running, please start it first. (or using `inference_mode: huggingface` in {args.config} for a feature-limited experience)"
message=f"The server of local inference endpoints is not running, please start it first. (or using `inference_mode: huggingface` in {args.config} for a feature-limited experience)"
try:
try:
r=requests.get(Model_Server+"/running")
r=requests.get(Model_Server+"/running")
ifr.status_code!=200:
ifr.status_code!=200:
raiseValueError(message)
raiseValueError(message)
except:
exceptBaseException:
raiseValueError(message)
raiseValueError(message)
@ -222,6 +220,7 @@ elif "HUGGINGFACE_ACCESS_TOKEN" in os.environ and os.getenv("HUGGINGFACE_ACCESS_
else:
else:
raiseValueError(f"Incorrect HuggingFace token. Please check your {args.config} file.")
raiseValueError(f"Incorrect HuggingFace token. Please check your {args.config} file.")
logger.warning(f"Task {command['task']} is not available. ControlNet need to be deployed locally.")
logger.warning(f"Task {command['task']} is not available. ControlNet need to be deployed locally.")
record_case(success=False,**{"input":input,"task":command,"reason":f"Task {command['task']} is not available. ControlNet need to be deployed locally.","op":"message"})
record_case(success=False,**{"input":input,"task":command,"reason":f"Task {command['task']} is not available. ControlNet need to be deployed locally.","op":"message"})
inference_result={"error":"service related to ControlNet is not available."}
inference_result={"error":"service related to ControlNet is not available."}
"please dub for me: 'Iron Man is a superhero appearing in American comic books published by Marvel Comics. The character was co-created by writer and editor Stan Lee, developed by scripter Larry Lieber, and designed by artists Don Heck and Jack Kirby.'"
"please dub for me: 'Iron Man is a superhero appearing in American comic books published by Marvel Comics. The character was co-created by writer and editor Stan Lee, developed by scripter Larry Lieber, and designed by artists Don Heck and Jack Kirby.'"
"Given an image: https://huggingface.co/datasets/mishig/sample_images/resolve/main/palace.jpg, please answer the question: What is on top of the building?",
"Given an image: https://huggingface.co/datasets/mishig/sample_images/resolve/main/palace.jpg, please answer the question: What is on top of the building?",
"Please generate a canny image based on /examples/f.jpg"
"Please generate a canny image based on /examples/f.jpg"
{"role":"assistant","content":"""Sure. I understand your request. Based on the inference results of the models, I have generated a canny image for you. The workflow I used is as follows: First, I used the image-to-text model (nlpconnect/vit-gpt2-image-captioning) to convert the image /examples/f.jpg to text. The generated text is "a herd of giraffes and zebras grazing in a field". Second, I used the canny-control model (canny-control) to generate a canny image from the text. Unfortunately, the model failed to generate the canny image. Finally, I used the canny-text-to-image model (lllyasviel/sd-controlnet-canny) to generate a canny image from the text. The generated image is located at /images/f16d.png. I hope this answers your request. Is there anything else I can help you with?"""},
{"role":"assistant","content":"""Sure. I understand your request. Based on the inference results of the models, I have generated a canny image for you. The workflow I used is as follows: First, I used the image-to-text model (nlpconnect/vit-gpt2-image-captioning) to convert the image /examples/f.jpg to text. The generated text is "a herd of giraffes and zebras grazing in a field". Second, I used the canny-control model (canny-control) to generate a canny image from the text. Unfortunately, the model failed to generate the canny image. Finally, I used the canny-text-to-image model (lllyasviel/sd-controlnet-canny) to generate a canny image from the text. The generated image is located at /images/f16d.png. I hope this answers your request. Is there anything else I can help you with?"""},
{"role":"user","content":"""then based on the above canny image and a prompt "a photo of a zoo", generate a new image."""},
{"role":"user","content":"""then based on the above canny image and a prompt "a photo of a zoo", generate a new image."""},
#kye gomez jul 13 4:01pm, can scale up the number of swarms working on a probkem with `hivemind(swarms=4, or swarms=auto which will scale the agents depending on the complexity)`
#kye gomez jul 13 4:01pm, can scale up the number of swarms working on a probkem with `hivemind(swarms=4, or swarms=auto which will scale the agents depending on the complexity)`
#this needs to change, we need to specify exactly what needs to be imported
#this needs to change, we need to specify exactly what needs to be imported
# add typechecking, documentation, and deeper error handling
# add typechecking, documentation, and deeper error handling
# TODO: MANY WORKERS
# TODO: MANY WORKERS
@ -12,13 +12,14 @@ from swarms.swarms.swarms import HierarchicalSwarm
SALES_ASSISTANT_PROMPT="""You are a sales assistant helping your sales agent to determine which stage of a sales conversation should the agent move to, or stay at.
SALES_ASSISTANT_PROMPT="""You are a sales assistant helping your sales agent to determine which stage of a sales conversation should the agent move to, or stay at.
Following'==='istheconversationhistory.
Following'==='istheconversationhistory.
Usethisconversationhistorytomakeyourdecision.
Usethisconversationhistorytomakeyourdecision.
@ -48,11 +47,10 @@ Conversation history:
{salesperson_name}:
{salesperson_name}:
"""
"""
conversation_stages={'1':"Introduction: Start the conversation by introducing yourself and your company. Be polite and respectful while keeping the tone of the conversation professional. Your greeting should be welcoming. Always clarify in your greeting the reason why you are contacting the prospect.",
conversation_stages={'1':"Introduction: Start the conversation by introducing yourself and your company. Be polite and respectful while keeping the tone of the conversation professional. Your greeting should be welcoming. Always clarify in your greeting the reason why you are contacting the prospect.",
'2':"Qualification: Qualify the prospect by confirming if they are the right person to talk to regarding your product/service. Ensure that they have the authority to make purchasing decisions.",
'2':"Qualification: Qualify the prospect by confirming if they are the right person to talk to regarding your product/service. Ensure that they have the authority to make purchasing decisions.",
'3':"Value proposition: Briefly explain how your product/service can benefit the prospect. Focus on the unique selling points and value proposition of your product/service that sets it apart from competitors.",
'3':"Value proposition: Briefly explain how your product/service can benefit the prospect. Focus on the unique selling points and value proposition of your product/service that sets it apart from competitors.",
'4':"Needs analysis: Ask open-ended questions to uncover the prospect's needs and pain points. Listen carefully to their responses and take notes.",
'4':"Needs analysis: Ask open-ended questions to uncover the prospect's needs and pain points. Listen carefully to their responses and take notes.",
'5':"Solution presentation: Based on the prospect's needs, present your product/service as the solution that can address their pain points.",
'5':"Solution presentation: Based on the prospect's needs, present your product/service as the solution that can address their pain points.",
'6':"Objection handling: Address any objections that the prospect may have regarding your product/service. Be prepared to provide evidence or testimonials to support your claims.",
'6':"Objection handling: Address any objections that the prospect may have regarding your product/service. Be prepared to provide evidence or testimonials to support your claims.",
'7':"Close: Ask for the sale by proposing a next step. This could be a demo, a trial or a meeting with decision-makers. Ensure to summarize what has been discussed and reiterate the benefits."}
'7':"Close: Ask for the sale by proposing a next step. This could be a demo, a trial or a meeting with decision-makers. Ensure to summarize what has been discussed and reiterate the benefits."}