[REFACTOR][SequentialWorkflow] [Agent] [FEATS][AsyncWorkflow] [BUFG][ConcurrentWorkflow] [MISC][DOCS]
parent
e06cdd5fbb
commit
a4c4c3b943
@ -0,0 +1,124 @@
|
|||||||
|
# swarms.agents
|
||||||
|
|
||||||
|
## 1. Introduction
|
||||||
|
|
||||||
|
`AbstractAgent` is an abstract class that serves as a foundation for implementing AI agents. An agent is an entity that can communicate with other agents and perform actions. The `AbstractAgent` class allows for customization in the implementation of the `receive` method, enabling different agents to define unique actions for receiving and processing messages.
|
||||||
|
|
||||||
|
`AbstractAgent` provides capabilities for managing tools and accessing memory, and has methods for running, chatting, and stepping through communication with other agents.
|
||||||
|
|
||||||
|
## 2. Class Definition
|
||||||
|
|
||||||
|
```python
|
||||||
|
class AbstractAgent:
|
||||||
|
"""An abstract class for AI agent.
|
||||||
|
|
||||||
|
An agent can communicate with other agents and perform actions.
|
||||||
|
Different agents can differ in what actions they perform in the `receive` method.
|
||||||
|
|
||||||
|
Agents are full and completed:
|
||||||
|
|
||||||
|
Agents = llm + tools + memory
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, name: str):
|
||||||
|
"""
|
||||||
|
Args:
|
||||||
|
name (str): name of the agent.
|
||||||
|
"""
|
||||||
|
self._name = name
|
||||||
|
|
||||||
|
@property
|
||||||
|
def name(self):
|
||||||
|
"""Get the name of the agent."""
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
def tools(self, tools):
|
||||||
|
"""init tools"""
|
||||||
|
|
||||||
|
def memory(self, memory_store):
|
||||||
|
"""init memory"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
"""(Abstract method) Reset the agent."""
|
||||||
|
|
||||||
|
def run(self, task: str):
|
||||||
|
"""Run the agent once"""
|
||||||
|
|
||||||
|
def _arun(self, taks: str):
|
||||||
|
"""Run Async run"""
|
||||||
|
|
||||||
|
def chat(self, messages: List[Dict]):
|
||||||
|
"""Chat with the agent"""
|
||||||
|
|
||||||
|
def _achat(self, messages: List[Dict]):
|
||||||
|
"""Asynchronous Chat"""
|
||||||
|
|
||||||
|
def step(self, message: str):
|
||||||
|
"""Step through the agent"""
|
||||||
|
|
||||||
|
def _astep(self, message: str):
|
||||||
|
"""Asynchronous step"""
|
||||||
|
```
|
||||||
|
|
||||||
|
## 3. Functionality and Usage
|
||||||
|
|
||||||
|
The `AbstractAgent` class represents a generic AI agent and provides a set of methods to interact with it.
|
||||||
|
|
||||||
|
To create an instance of an agent, the `name` of the agent should be specified.
|
||||||
|
|
||||||
|
### Core Methods
|
||||||
|
|
||||||
|
#### 1. `reset`
|
||||||
|
|
||||||
|
The `reset` method allows the agent to be reset to its initial state.
|
||||||
|
|
||||||
|
```python
|
||||||
|
agent.reset()
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. `run`
|
||||||
|
|
||||||
|
The `run` method allows the agent to perform a specific task.
|
||||||
|
|
||||||
|
```python
|
||||||
|
agent.run('some_task')
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. `chat`
|
||||||
|
|
||||||
|
The `chat` method enables communication with the agent through a series of messages.
|
||||||
|
|
||||||
|
```python
|
||||||
|
messages = [{'id': 1, 'text': 'Hello, agent!'}, {'id': 2, 'text': 'How are you?'}]
|
||||||
|
agent.chat(messages)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4. `step`
|
||||||
|
|
||||||
|
The `step` method allows the agent to process a single message.
|
||||||
|
|
||||||
|
```python
|
||||||
|
agent.step('Hello, agent!')
|
||||||
|
```
|
||||||
|
|
||||||
|
### Asynchronous Methods
|
||||||
|
|
||||||
|
The class also provides asynchronous variants of the core methods.
|
||||||
|
|
||||||
|
### Additional Functionality
|
||||||
|
|
||||||
|
Additional functionalities for agent initialization and management of tools and memory are also provided.
|
||||||
|
|
||||||
|
```python
|
||||||
|
agent.tools(some_tools)
|
||||||
|
agent.memory(some_memory_store)
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. Additional Information and Tips
|
||||||
|
|
||||||
|
When implementing a new agent using the `AbstractAgent` class, ensure that the `receive` method is overridden to define the specific behavior of the agent upon receiving messages.
|
||||||
|
|
||||||
|
## 5. References and Resources
|
||||||
|
|
||||||
|
For further exploration and understanding of AI agents and agent communication, refer to the relevant literature and research on this topic.
|
@ -0,0 +1,120 @@
|
|||||||
|
# The Module/Class Name: Message
|
||||||
|
|
||||||
|
In the swarms.agents framework, the class `Message` is used to represent a message with timestamp and optional metadata.
|
||||||
|
|
||||||
|
## Overview and Introduction
|
||||||
|
|
||||||
|
The `Message` class is a fundamental component that enables the representation of messages within an agent system. Messages contain essential information such as the sender, content, timestamp, and optional metadata.
|
||||||
|
|
||||||
|
## Class Definition
|
||||||
|
|
||||||
|
### Constructor: `__init__`
|
||||||
|
|
||||||
|
The constructor of the `Message` class takes three parameters:
|
||||||
|
|
||||||
|
1. `sender` (str): The sender of the message.
|
||||||
|
2. `content` (str): The content of the message.
|
||||||
|
3. `metadata` (dict or None): Optional metadata associated with the message.
|
||||||
|
|
||||||
|
### Methods
|
||||||
|
|
||||||
|
1. `__repr__(self)`: Returns a string representation of the `Message` object, including the timestamp, sender, and content.
|
||||||
|
|
||||||
|
```python
|
||||||
|
class Message:
|
||||||
|
"""
|
||||||
|
Represents a message with timestamp and optional metadata.
|
||||||
|
|
||||||
|
Usage
|
||||||
|
--------------
|
||||||
|
mes = Message(
|
||||||
|
sender = "Kye",
|
||||||
|
content = "message"
|
||||||
|
)
|
||||||
|
|
||||||
|
print(mes)
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, sender, content, metadata=None):
|
||||||
|
self.timestamp = datetime.datetime.now()
|
||||||
|
self.sender = sender
|
||||||
|
self.content = content
|
||||||
|
self.metadata = metadata or {}
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
"""
|
||||||
|
__repr__ represents the string representation of the Message object.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
(str) A string containing the timestamp, sender, and content of the message.
|
||||||
|
"""
|
||||||
|
return f"{self.timestamp} - {self.sender}: {self.content}"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Functionality and Usage
|
||||||
|
|
||||||
|
The `Message` class represents a message in the agent system. Upon initialization, the `timestamp` is set to the current date and time, and the `metadata` is set to an empty dictionary if no metadata is provided.
|
||||||
|
|
||||||
|
### Usage Example 1
|
||||||
|
|
||||||
|
Creating a `Message` object and displaying its string representation.
|
||||||
|
|
||||||
|
```python
|
||||||
|
mes = Message(
|
||||||
|
sender = "Kye",
|
||||||
|
content = "Hello! How are you?"
|
||||||
|
)
|
||||||
|
|
||||||
|
print(mes)
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
```
|
||||||
|
2023-09-20 13:45:00 - Kye: Hello! How are you?
|
||||||
|
```
|
||||||
|
|
||||||
|
### Usage Example 2
|
||||||
|
|
||||||
|
Creating a `Message` object with metadata.
|
||||||
|
|
||||||
|
```python
|
||||||
|
metadata = {"priority": "high", "category": "urgent"}
|
||||||
|
mes_with_metadata = Message(
|
||||||
|
sender = "Alice",
|
||||||
|
content = "Important update",
|
||||||
|
metadata = metadata
|
||||||
|
)
|
||||||
|
|
||||||
|
print(mes_with_metadata)
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
```
|
||||||
|
2023-09-20 13:46:00 - Alice: Important update
|
||||||
|
```
|
||||||
|
|
||||||
|
### Usage Example 3
|
||||||
|
|
||||||
|
Creating a `Message` object without providing metadata.
|
||||||
|
|
||||||
|
```python
|
||||||
|
mes_no_metadata = Message(
|
||||||
|
sender = "Bob",
|
||||||
|
content = "Reminder: Meeting at 2PM"
|
||||||
|
)
|
||||||
|
|
||||||
|
print(mes_no_metadata)
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
```
|
||||||
|
2023-09-20 13:47:00 - Bob: Reminder: Meeting at 2PM
|
||||||
|
```
|
||||||
|
|
||||||
|
## Additional Information and Tips
|
||||||
|
|
||||||
|
When creating a new `Message` object, ensure that the required parameters `sender` and `content` are provided. The `timestamp` will automatically be assigned the current date and time. Optional `metadata` can be included to provide additional context or information associated with the message.
|
||||||
|
|
||||||
|
## References and Resources
|
||||||
|
|
||||||
|
For further information on the `Message` class and its usage, refer to the official swarms.agents documentation and relevant tutorials related to message handling and communication within the agent system.
|
@ -0,0 +1,79 @@
|
|||||||
|
# Module/Class Name: OmniModalAgent
|
||||||
|
|
||||||
|
The `OmniModalAgent` class is a module that operates based on the Language Model (LLM) aka Language Understanding Model, Plans, Tasks, and Tools. It is designed to be a multi-modal chatbot which uses various AI-based capabilities for fulfilling user requests.
|
||||||
|
|
||||||
|
It has the following architecture:
|
||||||
|
1. Language Model (LLM).
|
||||||
|
2. Chat Planner - Plans
|
||||||
|
3. Task Executor - Tasks
|
||||||
|
4. Tools - Tools
|
||||||
|
|
||||||
|
![OmniModalAgent](https://source.unsplash.com/random)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Usage
|
||||||
|
from swarms import OmniModalAgent, OpenAIChat
|
||||||
|
|
||||||
|
llm = OpenAIChat()
|
||||||
|
agent = OmniModalAgent(llm)
|
||||||
|
response = agent.run("Hello, how are you? Create an image of how your are doing!")
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Initialization
|
||||||
|
|
||||||
|
The constructor of `OmniModalAgent` class takes two main parameters:
|
||||||
|
- `llm`: A `BaseLanguageModel` that represents the language model
|
||||||
|
- `tools`: A List of `BaseTool` instances that are used by the agent for fulfilling different requests.
|
||||||
|
|
||||||
|
```python
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
llm: BaseLanguageModel,
|
||||||
|
# tools: List[BaseTool]
|
||||||
|
):
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Methods
|
||||||
|
|
||||||
|
The class has two main methods:
|
||||||
|
1. `run`: This method takes an input string and executes various plans and tasks using the provided tools. Ultimately, it generates a response based on the user's input and returns it.
|
||||||
|
- Parameters:
|
||||||
|
- `input`: A string representing the user's input text.
|
||||||
|
- Returns:
|
||||||
|
- A string representing the response.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
```python
|
||||||
|
response = agent.run("Hello, how are you? Create an image of how your are doing!")
|
||||||
|
```
|
||||||
|
|
||||||
|
2. `chat`: This method is used to simulate a chat dialog with the agent. It can take user's messages and return the response (or stream the response word-by-word if required).
|
||||||
|
- Parameters:
|
||||||
|
- `msg` (optional): A string representing the message to send to the agent.
|
||||||
|
- `streaming` (optional): A boolean specifying whether to stream the response.
|
||||||
|
- Returns:
|
||||||
|
- A string representing the response from the agent.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
```python
|
||||||
|
response = agent.chat("Hello")
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Streaming Response
|
||||||
|
|
||||||
|
The class provides a method `_stream_response` that can be used to get the response token by token (i.e. word by word). It yields individual tokens from the response.
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
```python
|
||||||
|
for token in _stream_response(response):
|
||||||
|
print(token)
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,113 @@
|
|||||||
|
# ToolAgent Documentation
|
||||||
|
|
||||||
|
|
||||||
|
### Overview and Introduction
|
||||||
|
|
||||||
|
The `ToolAgent` class represents an intelligent agent capable of performing a specific task using a pre-trained model and tokenizer. It leverages the Transformer models of the Hugging Face `transformers` library to generate outputs that adhere to a specific JSON schema. This provides developers with a flexible tool for creating bots, text generators, and conversational AI agents. The `ToolAgent` operates based on a JSON schema provided by you, the user. Using the schema, the agent applies the provided model and tokenizer to generate structured text data that matches the specified format.
|
||||||
|
|
||||||
|
The primary objective of the `ToolAgent` class is to amplify the efficiency of developers and AI practitioners by simplifying the process of generating meaningful outputs that navigate the complexities of the model and tokenizer.
|
||||||
|
|
||||||
|
### Class Definition
|
||||||
|
|
||||||
|
The `ToolAgent` class has the following definition:
|
||||||
|
|
||||||
|
```python
|
||||||
|
class ToolAgent(AbstractLLM):
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
name: str,
|
||||||
|
description: str,
|
||||||
|
model: Any,
|
||||||
|
tokenizer: Any,
|
||||||
|
json_schema: Any,
|
||||||
|
*args,
|
||||||
|
**kwargs,
|
||||||
|
)
|
||||||
|
def run(self, task: str, *args, **kwargs)
|
||||||
|
def __call__(self, task: str, *args, **kwargs)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Arguments
|
||||||
|
|
||||||
|
The `ToolAgent` class takes the following arguments:
|
||||||
|
|
||||||
|
| Argument | Type | Description |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| name | str | The name of the tool agent.
|
||||||
|
| description | str | A description of the tool agent.
|
||||||
|
| model | Any | The model used by the tool agent (e.g., `transformers.AutoModelForCausalLM`).
|
||||||
|
| tokenizer | Any | The tokenizer used by the tool agent (e.g., `transformers.AutoTokenizer`).
|
||||||
|
| json_schema | Any | The JSON schema used by the tool agent.
|
||||||
|
| *args | - | Variable-length arguments.
|
||||||
|
| **kwargs | - | Keyword arguments.
|
||||||
|
|
||||||
|
### Methods
|
||||||
|
|
||||||
|
`ToolAgent` exposes the following methods:
|
||||||
|
|
||||||
|
#### `run(self, task: str, *args, **kwargs) -> Any`
|
||||||
|
|
||||||
|
- Description: Runs the tool agent for a specific task.
|
||||||
|
- Parameters:
|
||||||
|
- `task` (str): The task to be performed by the tool agent.
|
||||||
|
- `*args`: Variable-length argument list.
|
||||||
|
- `**kwargs`: Arbitrary keyword arguments.
|
||||||
|
- Returns: The output of the tool agent.
|
||||||
|
- Raises: Exception if an error occurs during the execution of the tool agent.
|
||||||
|
|
||||||
|
|
||||||
|
#### `__call__(self, task: str, *args, **kwargs) -> Any`
|
||||||
|
|
||||||
|
- Description: Calls the tool agent to perform a specific task.
|
||||||
|
- Parameters:
|
||||||
|
- `task` (str): The task to be performed by the tool agent.
|
||||||
|
- `*args`: Variable-length argument list.
|
||||||
|
- `**kwargs`: Arbitrary keyword arguments.
|
||||||
|
- Returns: The output of the tool agent.
|
||||||
|
|
||||||
|
### Usage Example
|
||||||
|
|
||||||
|
```python
|
||||||
|
from transformers import AutoModelForCausalLM, AutoTokenizer
|
||||||
|
from swarms import ToolAgent
|
||||||
|
|
||||||
|
# Creating a model and tokenizer
|
||||||
|
model = AutoModelForCausalLM.from_pretrained("databricks/dolly-v2-12b")
|
||||||
|
tokenizer = AutoTokenizer.from_pretrained("databricks/dolly-v2-12b")
|
||||||
|
|
||||||
|
# Defining a JSON schema
|
||||||
|
json_schema = {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"name": {"type": "string"},
|
||||||
|
"age": {"type": "number"},
|
||||||
|
"is_student": {"type": "boolean"},
|
||||||
|
"courses": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {"type": "string"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Defining a task
|
||||||
|
task = "Generate a person's information based on the following schema:"
|
||||||
|
|
||||||
|
# Creating the ToolAgent instance
|
||||||
|
agent = ToolAgent(model=model, tokenizer=tokenizer, json_schema=json_schema)
|
||||||
|
|
||||||
|
# Running the tool agent
|
||||||
|
generated_data = agent.run(task)
|
||||||
|
|
||||||
|
# Accessing and printing the generated data
|
||||||
|
print(generated_data)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Additional Information and Tips
|
||||||
|
|
||||||
|
When using the `ToolAgent`, it is important to ensure compatibility between the provided model, tokenizer, and the JSON schema. Additionally, any errors encountered during the execution of the tool agent are propagated as exceptions. Handling such exceptions appropriately can improve the robustness of the tool agent usage.
|
||||||
|
|
||||||
|
### References and Resources
|
||||||
|
|
||||||
|
For further exploration and understanding of the underlying Transformer-based models and tokenizers, refer to the Hugging Face `transformers` library documentation and examples. Additionally, for JSON schema modeling, you can refer to the official JSON Schema specification and examples.
|
||||||
|
|
||||||
|
This documentation provides a comprehensive guide on using the `ToolAgent` class from `swarms` library, and it is recommended to refer back to this document when utilizing the `ToolAgent` for developing your custom conversational agents or text generation tools.
|
@ -0,0 +1,78 @@
|
|||||||
|
# WorkerClass Documentation
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The Worker class represents an autonomous agent that can perform tasks through function calls or by running a chat. It can be used to create applications that demand effective user interactions like search engines, human-like conversational bots, or digital assistants.
|
||||||
|
|
||||||
|
The `Worker` class is part of the `swarms.agents` codebase. This module is largely used in Natural Language Processing (NLP) projects where the agent undertakes conversations and other language-specific operations.
|
||||||
|
|
||||||
|
## Class Definition
|
||||||
|
|
||||||
|
The class `Worker` has the following arguments:
|
||||||
|
|
||||||
|
| Argument | Type | Default Value | Description |
|
||||||
|
|-----------------------|---------------|----------------------------------|----------------------------------------------------|
|
||||||
|
| name | str | "Worker" | Name of the agent. |
|
||||||
|
| role | str | "Worker in a swarm" | Role of the agent. |
|
||||||
|
| external_tools | list | None | List of external tools available to the agent. |
|
||||||
|
| human_in_the_loop | bool | False | Determines whether human interaction is required. |
|
||||||
|
| temperature | float | 0.5 | Temperature for the autonomous agent. |
|
||||||
|
| llm | None | None | Language model. |
|
||||||
|
| openai_api_key | str | None | OpenAI API key. |
|
||||||
|
| tools | List[Any] | None | List of tools available to the agent. |
|
||||||
|
| embedding_size | int | 1536 | Size of the word embeddings. |
|
||||||
|
| search_kwargs | dict | {"k": 8} | Search parameters. |
|
||||||
|
| args | Multiple | | Additional arguments that can be passed. |
|
||||||
|
| kwargs | Multiple | | Additional keyword arguments that can be passed. |
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
#### Example 1: Creating and Running an Agent
|
||||||
|
|
||||||
|
```python
|
||||||
|
from swarms import Worker
|
||||||
|
|
||||||
|
worker = Worker(
|
||||||
|
name="My Worker",
|
||||||
|
role="Worker",
|
||||||
|
external_tools=[MyTool1(), MyTool2()],
|
||||||
|
human_in_the_loop=False,
|
||||||
|
temperature=0.5,
|
||||||
|
llm=some_language_model,
|
||||||
|
openai_api_key="my_key"
|
||||||
|
)
|
||||||
|
worker.run("What's the weather in Miami?")
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Example 2: Receiving and Sending Messages
|
||||||
|
|
||||||
|
```python
|
||||||
|
worker.receieve("User", "Hello there!")
|
||||||
|
worker.receieve("User", "Can you tell me something about history?")
|
||||||
|
worker.send()
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Example 3: Setting up Tools
|
||||||
|
|
||||||
|
```python
|
||||||
|
external_tools = [MyTool1(), MyTool2()]
|
||||||
|
worker = Worker(
|
||||||
|
name="My Worker",
|
||||||
|
role="Worker",
|
||||||
|
external_tools=external_tools,
|
||||||
|
human_in_the_loop=False,
|
||||||
|
temperature=0.5,
|
||||||
|
)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Additional Information and Tips
|
||||||
|
|
||||||
|
- The class allows the setting up of tools for the worker to operate effectively. It provides setup facilities for essential computing infrastructure, such as the agent's memory and language model.
|
||||||
|
- By setting the `human_in_the_loop` parameter to True, interactions with the worker can be made more user-centric.
|
||||||
|
- The `openai_api_key` argument can be provided for leveraging the OpenAI infrastructure and services.
|
||||||
|
- A qualified language model can be passed as an instance of the `llm` object, which can be useful when integrating with state-of-the-art text generation engines.
|
||||||
|
|
||||||
|
## References and Resources
|
||||||
|
|
||||||
|
- [OpenAI APIs](https://openai.com)
|
||||||
|
- [Models and Languages at HuggingFace](https://huggingface.co/models)
|
||||||
|
- [Deep Learning and Language Modeling at the Allen Institute for AI](https://allenai.org)
|
@ -1,13 +1,35 @@
|
|||||||
from swarms.agents.message import Message
|
|
||||||
from swarms.agents.base import AbstractAgent
|
from swarms.agents.base import AbstractAgent
|
||||||
from swarms.agents.tool_agent import ToolAgent
|
|
||||||
from swarms.agents.simple_agent import SimpleAgent
|
|
||||||
from swarms.agents.omni_modal_agent import OmniModalAgent
|
from swarms.agents.omni_modal_agent import OmniModalAgent
|
||||||
|
from swarms.agents.simple_agent import SimpleAgent
|
||||||
|
from swarms.agents.stopping_conditions import (
|
||||||
|
check_cancelled,
|
||||||
|
check_complete,
|
||||||
|
check_done,
|
||||||
|
check_end,
|
||||||
|
check_error,
|
||||||
|
check_exit,
|
||||||
|
check_failure,
|
||||||
|
check_finished,
|
||||||
|
check_stopped,
|
||||||
|
check_success,
|
||||||
|
)
|
||||||
|
from swarms.agents.tool_agent import ToolAgent
|
||||||
|
from swarms.agents.worker_agent import WorkerAgent
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"Message",
|
|
||||||
"AbstractAgent",
|
"AbstractAgent",
|
||||||
"ToolAgent",
|
"ToolAgent",
|
||||||
"SimpleAgent",
|
"SimpleAgent",
|
||||||
"OmniModalAgent",
|
"OmniModalAgent",
|
||||||
|
"check_done",
|
||||||
|
"check_finished",
|
||||||
|
"check_complete",
|
||||||
|
"check_success",
|
||||||
|
"check_failure",
|
||||||
|
"check_error",
|
||||||
|
"check_stopped",
|
||||||
|
"check_cancelled",
|
||||||
|
"check_exit",
|
||||||
|
"check_end",
|
||||||
|
"WorkerAgent",
|
||||||
]
|
]
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
def check_done(s):
|
||||||
|
return "<DONE>" in s
|
||||||
|
|
||||||
|
|
||||||
|
def check_finished(s):
|
||||||
|
return "finished" in s
|
||||||
|
|
||||||
|
|
||||||
|
def check_complete(s):
|
||||||
|
return "complete" in s
|
||||||
|
|
||||||
|
|
||||||
|
def check_success(s):
|
||||||
|
return "success" in s
|
||||||
|
|
||||||
|
|
||||||
|
def check_failure(s):
|
||||||
|
return "failure" in s
|
||||||
|
|
||||||
|
|
||||||
|
def check_error(s):
|
||||||
|
return "error" in s
|
||||||
|
|
||||||
|
|
||||||
|
def check_stopped(s):
|
||||||
|
return "stopped" in s
|
||||||
|
|
||||||
|
|
||||||
|
def check_cancelled(s):
|
||||||
|
return "cancelled" in s
|
||||||
|
|
||||||
|
|
||||||
|
def check_exit(s):
|
||||||
|
return "exit" in s
|
||||||
|
|
||||||
|
|
||||||
|
def check_end(s):
|
||||||
|
return "end" in s
|
@ -0,0 +1,103 @@
|
|||||||
|
import asyncio
|
||||||
|
from dataclasses import dataclass, field
|
||||||
|
from typing import Any, Callable, List, Optional
|
||||||
|
from swarms.structs.task import Task
|
||||||
|
from swarms.utils.logger import logger
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class AsyncWorkflow:
|
||||||
|
"""
|
||||||
|
Represents an asynchronous workflow to run tasks.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
name (str): The name of the workflow.
|
||||||
|
description (str): The description of the workflow.
|
||||||
|
max_loops (int): The maximum number of loops to run the workflow.
|
||||||
|
autosave (bool): Flag indicating whether to autosave the results.
|
||||||
|
dashboard (bool): Flag indicating whether to display a dashboard.
|
||||||
|
task_pool (List[Any]): The list of tasks in the workflow.
|
||||||
|
results (List[Any]): The list of results from running the tasks.
|
||||||
|
loop (Optional[asyncio.AbstractEventLoop]): The event loop to use.
|
||||||
|
stopping_condition (Optional[Callable]): The stopping condition for the workflow.
|
||||||
|
|
||||||
|
Methods:
|
||||||
|
add(tasks: List[Any]) -> None:
|
||||||
|
Add tasks to the workflow.
|
||||||
|
|
||||||
|
delete(task: Task = None, tasks: List[Task] = None) -> None:
|
||||||
|
Delete a task from the workflow.
|
||||||
|
|
||||||
|
run() -> List[Any]:
|
||||||
|
Run the workflow and return the results.
|
||||||
|
"""
|
||||||
|
|
||||||
|
name: str = "Async Workflow"
|
||||||
|
description: str = "A workflow to run asynchronous tasks"
|
||||||
|
max_loops: int = 1
|
||||||
|
autosave: bool = True
|
||||||
|
dashboard: bool = False
|
||||||
|
task_pool: List[Any] = field(default_factory=list)
|
||||||
|
results: List[Any] = field(default_factory=list)
|
||||||
|
loop: Optional[asyncio.AbstractEventLoop] = None
|
||||||
|
stopping_condition: Optional[Callable] = None
|
||||||
|
|
||||||
|
async def add(self, task: Any, tasks: List[Any]):
|
||||||
|
"""Add tasks to the workflow"""
|
||||||
|
try:
|
||||||
|
if tasks:
|
||||||
|
for task in tasks:
|
||||||
|
self.task_pool.extend(tasks)
|
||||||
|
elif task:
|
||||||
|
self.task_pool.append(task)
|
||||||
|
|
||||||
|
else:
|
||||||
|
if task and tasks:
|
||||||
|
# Add the task and tasks to the task pool
|
||||||
|
self.task_pool.append(task)
|
||||||
|
self.task_pool.extend(tasks)
|
||||||
|
else:
|
||||||
|
raise ValueError(
|
||||||
|
"Either task or tasks must be provided"
|
||||||
|
)
|
||||||
|
|
||||||
|
except Exception as error:
|
||||||
|
logger.error(f"[ERROR][AsyncWorkflow] {error}")
|
||||||
|
|
||||||
|
async def delete(
|
||||||
|
self, task: Any = None, tasks: List[Task] = None
|
||||||
|
):
|
||||||
|
"""Delete a task from the workflow"""
|
||||||
|
try:
|
||||||
|
if task:
|
||||||
|
self.task_pool.remove(task)
|
||||||
|
elif tasks:
|
||||||
|
for task in tasks:
|
||||||
|
self.task_pool.remove(task)
|
||||||
|
except Exception as error:
|
||||||
|
logger.error(f"[ERROR][AsyncWorkflow] {error}")
|
||||||
|
|
||||||
|
async def run(self):
|
||||||
|
"""Run the workflow"""
|
||||||
|
if self.loop is None:
|
||||||
|
self.loop = asyncio.get_event_loop()
|
||||||
|
for i in range(self.max_loops):
|
||||||
|
logger.info(
|
||||||
|
f"[INFO][AsyncWorkflow] Loop {i + 1}/{self.max_loops}"
|
||||||
|
)
|
||||||
|
futures = [
|
||||||
|
asyncio.ensure_future(task.execute())
|
||||||
|
for task in self.task_pool
|
||||||
|
]
|
||||||
|
self.results = await asyncio.gather(*futures)
|
||||||
|
# if self.autosave:
|
||||||
|
# self.save()
|
||||||
|
# if self.dashboard:
|
||||||
|
# self.display()
|
||||||
|
|
||||||
|
# Add a stopping condition to stop the workflow, if provided but stopping_condition takes in a parameter s for string
|
||||||
|
if self.stopping_condition:
|
||||||
|
if self.stopping_condition(self.results):
|
||||||
|
break
|
||||||
|
|
||||||
|
return self.results
|
@ -0,0 +1,33 @@
|
|||||||
|
import inspect
|
||||||
|
|
||||||
|
|
||||||
|
def get_cls_init_params(cls) -> str:
|
||||||
|
"""
|
||||||
|
Get the initialization parameters of a class.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
cls: The class to retrieve the initialization parameters from.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: A string representation of the initialization parameters.
|
||||||
|
|
||||||
|
"""
|
||||||
|
init_signature = inspect.signature(cls.__init__)
|
||||||
|
params = init_signature.parameters
|
||||||
|
params_str_list = []
|
||||||
|
|
||||||
|
for name, param in params.items():
|
||||||
|
if name == "self":
|
||||||
|
continue
|
||||||
|
if name == "kwargs":
|
||||||
|
value = "Any keyword arguments"
|
||||||
|
elif hasattr(cls, name):
|
||||||
|
value = getattr(cls, name)
|
||||||
|
else:
|
||||||
|
value = cls.__dict__.get(name, "Unknown")
|
||||||
|
|
||||||
|
params_str_list.append(
|
||||||
|
f" {name.capitalize().replace('_', ' ')}: {value}"
|
||||||
|
)
|
||||||
|
|
||||||
|
return "\n".join(params_str_list)
|
@ -0,0 +1,21 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
def get_file_extension(s):
|
||||||
|
"""
|
||||||
|
Get the file extension from a given string.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
s (str): The input string.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str or None: The file extension if found, or None if not found.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValueError: If the input is not a string.
|
||||||
|
"""
|
||||||
|
if not isinstance(s, str):
|
||||||
|
raise ValueError("Input must be a string")
|
||||||
|
|
||||||
|
match = re.search(r"\.(pdf|csv|txt|docx|xlsx)$", s, re.IGNORECASE)
|
||||||
|
return match.group()[1:] if match else None
|
Loading…
Reference in new issue