Merge branch 'master' into master

pull/93/head
Zack Bradshaw 2 years ago committed by GitHub
commit ac81c795df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,12 @@
# this is a config file for the github action labeler
# Add 'label1' to any changes within 'example' folder or any subfolders
example_change:
- example/**
# Add 'label2' to any file changes within 'example2' folder
example2_change: example2/*
# Add label3 to any change to .txt files within the entire repository. Quotation marks are required for the leading asterisk
text_files:
- '**/*.txt'

@ -9,6 +9,7 @@ on:
jobs: jobs:
build: build:
name: 👋 Welcome name: 👋 Welcome
permissions: write-all
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/first-interaction@v1.2.0 - uses: actions/first-interaction@v1.2.0

@ -40,6 +40,7 @@ We have a small gallery of examples to run here, [for more check out the docs to
### `Flow` Example ### `Flow` Example
- The `Flow` is a superior iteratioin of the `LLMChain` from Langchain, our intent with `Flow` is to create the most reliable loop structure that gives the agents their "autonomy" through 3 main methods of interaction, one through user specified loops, then dynamic where the agent parses a <DONE> token, and or an interactive human input verison, or a mix of all 3. - The `Flow` is a superior iteratioin of the `LLMChain` from Langchain, our intent with `Flow` is to create the most reliable loop structure that gives the agents their "autonomy" through 3 main methods of interaction, one through user specified loops, then dynamic where the agent parses a <DONE> token, and or an interactive human input verison, or a mix of all 3.
```python ```python
from swarms.models import OpenAIChat from swarms.models import OpenAIChat
@ -47,74 +48,89 @@ from swarms.structs import Flow
api_key = "" api_key = ""
# Initialize the language model, this model can be swapped out with Anthropic, ETC, Huggingface Models like Mistral, ETC
# Initialize the language model,
# This model can be swapped out with Anthropic, ETC, Huggingface Models like Mistral, ETC
llm = OpenAIChat( llm = OpenAIChat(
# model_name="gpt-4"
openai_api_key=api_key, openai_api_key=api_key,
temperature=0.5, temperature=0.5,
# max_tokens=100,
) )
# Initialize the flow ## Initialize the workflow
flow = Flow( flow = Flow(
llm=llm, llm=llm,
max_loops=5, max_loops=2,
dashboard=True,
# stopping_condition=None, # You can define a stopping condition as needed.
# loop_interval=1,
# retry_attempts=3,
# retry_interval=1,
# interactive=False, # Set to 'True' for interactive mode.
# dynamic_temperature=False, # Set to 'True' for dynamic temperature handling.
) )
out = flow.run("Generate a 10,000 word blog, say Stop when done") # out = flow.load_state("flow_state.json")
print(out) # temp = flow.dynamic_temperature()
# filter = flow.add_response_filter("Trump")
out = flow.run("Generate a 10,000 word blog on health and wellness.")
# out = flow.validate_response(out)
# out = flow.analyze_feedback(out)
# out = flow.print_history_and_memory()
# # out = flow.save_state("flow_state.json")
# print(out)
```
```
## `GodMode` ------
- A powerful tool for concurrent execution of tasks using multiple Language Model (LLM) instances.
### `SequentialWorkflow`
- Execute tasks step by step by passing in an LLM and the task description!
- Pass in flows with various LLMs
- Save and restore Workflow states!
```python ```python
from swarms.swarms import GodMode
from swarms.models import OpenAIChat from swarms.models import OpenAIChat
from swarms.structs import Flow
from swarms.structs.sequential_workflow import SequentialWorkflow
api_key = "" # Example usage
api_key = (
"" # Your actual API key here
)
# Initialize the language flow
llm = OpenAIChat( llm = OpenAIChat(
openai_api_key=api_key openai_api_key=api_key,
temperature=0.5,
max_tokens=3000,
) )
# Initialize the Flow with the language flow
flow1 = Flow(llm=llm, max_loops=1, dashboard=False)
llms = [ # Create another Flow for a different task
llm, flow2 = Flow(llm=llm, max_loops=1, dashboard=False)
llm,
llm
]
god_mode = GodMode(llms) # Create the workflow
workflow = SequentialWorkflow(max_loops=1)
task = 'Generate a 10,000 word blog on health and wellness.' # Add tasks to the workflow
workflow.add("Generate a 10,000 word blog on health and wellness.", flow1)
out = god_mode.run(task) # Suppose the next task takes the output of the first task as input
god_mode.print_responses(task) workflow.add("Summarize the generated blog", flow2)
```
------ # Run the workflow
workflow.run()
### `OmniModalAgent`
- OmniModal Agent is an LLM that access to 10+ multi-modal encoders and diffusers! It can generate images, videos, speech, music and so much more, get started with:
```python
from swarms.models import OpenAIChat
from swarms.agents import OmniModalAgent
api_key = "SK-" # Output the results
for task in workflow.tasks:
llm = OpenAIChat(model_name="gpt-4", openai_api_key=api_key) print(f"Task: {task.description}, Result: {task.result}")
agent = OmniModalAgent(llm)
agent.run("Create a video of a swarm of fish")
``` ```
--- ---
## Documentation ## Documentation
@ -122,8 +138,7 @@ agent.run("Create a video of a swarm of fish")
## Contribute ## Contribute
- We're always looking for contributors to help us improve and expand this project. If you're interested, please check out our [Contributing Guidelines](CONTRIBUTING.md) and our [contributing board](https://github.com/users/kyegomez/projects/1)
We're always looking for contributors to help us improve and expand this project. If you're interested, please check out our [Contributing Guidelines](CONTRIBUTING.md) and our [contributing board](https://github.com/users/kyegomez/projects/1)
# License # License

@ -23,7 +23,7 @@ Distribution Agent:
""" """
from swarms import OpenAIChat from swarms.models import OpenAIChat
from termcolor import colored from termcolor import colored
TOPIC_GENERATOR = f""" TOPIC_GENERATOR = f"""

@ -0,0 +1,63 @@
# 2O+ Autonomous Agent Blogs
1. **The Ultimate Guide to Deploying Production-Ready Autonomous Agents with Swarms**
- A comprehensive start-to-finish guide on implementing Swarms in a production environment.
2. **5 Steps to Elevate Your AI with Swarms Multi-Modal Autonomous Agents**
- A walkthrough highlighting the simplicity of Swarms setup and deployment for various AI applications.
3. **Integrating Swarms Into Your Enterprise Workflow: A Step-By-Step Tutorial**
- A practical guide focusing on integrating Swarms into existing enterprise systems.
4. **Swarms Flow: Streamlining AI Deployment in Your Business**
- Exploring the benefits and technicalities of using the Flow feature to simplify complex AI workflows.
5. **From Zero to Hero: Building Your First Enterprise-Grade AI Agent with Swarms**
- A beginner-friendly walkthrough for building and deploying an AI agent using Swarms.
6. **Scaling AI with Swarms: Managing Multi-Agent Systems Efficiently**
- Strategies and best practices for scaling multi-agent systems in enterprise settings.
7. **Creating Resilient AI Systems with Swarms' Autonomous Agents**
- Discussing the robustness of Swarms agents and how they maintain performance under stress.
8. **Unlocking New Capabilities: Advanced Features of Swarms for AI Engineers**
- Diving into the more sophisticated features of Swarms and how they can be leveraged in complex projects.
9. **Swarms Quick Wins: Implementing AI Agents in Less Than 5 Lines of Code**
- A focused guide on rapidly deploying functional AI agents with minimal coding.
10. **Benchmarking Your AI: Performance Metrics with Swarms**
- How to use Swarms to measure and optimize the performance of AI agents.
11. **Swarms Case Studies: Real-World Success Stories from AI Engineers**
- Sharing stories and testimonials of how various organizations successfully implemented Swarms.
12. **Effortless Multi-Modal Model Deployment: A Swarms Walkthrough**
- Explaining how to use Swarms to deploy multi-modal models with ease.
13. **Future-Proof Your AI: Adapting to New Tech with Swarms**
- How Swarms' flexible architecture allows for easy updates and adaptation to new AI technologies.
14. **Enterprise AI Security: Ensuring Your Swarms Agents are Hack-Proof**
- Best practices for securing autonomous agents in enterprise applications.
15. **Migrating to Swarms: Transitioning From Legacy Systems**
- A guide for AI engineers on migrating existing AI systems to Swarms without downtime.
16. **Multi-Agent Collaboration: How Swarms Facilitates Teamwork Among AI**
- An insight into how Swarms allows for multiple AI agents to work together seamlessly.
17. **The Engineer's Toolkit: Swarms' Features Every AI Developer Must Know**
- Highlighting the most useful tools and features of Swarms from an AI developers perspective.
18. **Swarms for Different Industries: Customizing AI Agents for Niche Markets**
- Exploring how Swarms can be tailored to fit the needs of various industries such as healthcare, finance, and retail.
19. **Building Intelligent Workflows with Swarms Flow**
- A tutorial on using the Flow feature to create intelligent, responsive AI-driven workflows.
20. **Troubleshooting Common Issues When Deploying Swarms Autonomous Agents**
- A problem-solving guide for AI engineers on overcoming common challenges when implementing Swarms agents.
Each blog or walkthrough can be structured to not only showcase the functionality and benefits of the Swarms framework but also to establish the brand as a thought leader in the space of enterprise AI solutions.

@ -0,0 +1,239 @@
# Enterprise-Grade Workflow Automation With Autonomous Agents
========================================================================
Welcome to this comprehensive walkthrough guide tutorial on the SequentialWorkflow feature of the Swarms Framework! In this tutorial, we will explore the purpose, usage, and key concepts of the SequentialWorkflow class, which is a part of the swarms package. Whether you are a beginner, intermediate, or expert developer, this tutorial will provide you with a clear understanding of how to effectively use the SequentialWorkflow class in your projects.
AI engineering is a dynamic and evolving field that involves the development and deployment of intelligent systems and applications. In this ever-changing landscape, AI engineers often face the challenge of orchestrating complex sequences of tasks, managing data flows, and ensuring the smooth execution of AI workflows. This is where the Workflow Class, such as the SequentialWorkflow class we discussed earlier, plays a pivotal role in enabling AI engineers to achieve their goals efficiently and effectively.
## The Versatile World of AI Workflows
AI workflows encompass a wide range of tasks and processes, from data preprocessing and model training to natural language understanding and decision-making. These workflows are the backbone of AI systems, guiding them through intricate sequences of actions to deliver meaningful results. Here are some of the diverse use cases where the Workflow Class can empower AI engineers:
### 1. Natural Language Processing (NLP) Pipelines
AI engineers often build NLP pipelines that involve multiple stages such as text preprocessing, tokenization, feature extraction, model inference, and post-processing. The Workflow Class enables the orderly execution of these stages, ensuring that textual data flows seamlessly through each step, resulting in accurate and coherent NLP outcomes.
### 2. Data Ingestion and Transformation
AI projects frequently require the ingestion of diverse data sources, including structured databases, unstructured text, and multimedia content. The Workflow Class can be used to design data ingestion workflows that extract, transform, and load (ETL) data efficiently, making it ready for downstream AI tasks like training and analysis.
### 3. Autonomous Agents and Robotics
In autonomous robotics and intelligent agent systems, workflows are essential for decision-making, sensor fusion, motion planning, and control. AI engineers can use the Workflow Class to create structured sequences of actions that guide robots and agents through dynamic environments, enabling them to make informed decisions and accomplish tasks autonomously.
### 4. Machine Learning Model Training
Training machine learning models involves a series of steps, including data preprocessing, feature engineering, model selection, hyperparameter tuning, and evaluation. The Workflow Class simplifies the orchestration of these steps, allowing AI engineers to experiment with different configurations and track the progress of model training.
### 5. Content Generation and Summarization
AI-driven content generation tasks, such as generating articles, reports, or summaries, often require multiple steps, including content creation and post-processing. The Workflow Class can be used to create content generation workflows, ensuring that the generated content meets quality and coherence criteria.
### 6. Adaptive Decision-Making
In AI systems that make real-time decisions based on changing data and environments, workflows facilitate adaptive decision-making. Engineers can use the Workflow Class to design decision-making pipelines that take into account the latest information and make informed choices.
## Enabling Efficiency and Maintainability
The Workflow Class provides AI engineers with a structured and maintainable approach to building, executing, and managing complex AI workflows. It offers the following advantages:
- Modularity: Workflows can be modularly designed, allowing engineers to focus on individual task implementations and ensuring code reusability.
- Debugging and Testing: The Workflow Class simplifies debugging and testing by providing a clear sequence of tasks and well-defined inputs and outputs for each task.
- Scalability: As AI projects grow in complexity, the Workflow Class can help manage and scale workflows by adding or modifying tasks as needed.
- Error Handling: The class supports error handling strategies, enabling engineers to define how to handle unexpected failures gracefully.
- Maintainability: With structured workflows, AI engineers can easily maintain and update AI systems as requirements evolve or new data sources become available.
The Workflow Class, such as the SequentialWorkflow class, is an indispensable tool in the toolkit of AI engineers. It empowers engineers to design, execute, and manage AI workflows across a diverse range of use cases. By providing structure, modularity, and maintainability to AI projects, the Workflow Class contributes significantly to the efficiency and success of AI engineering endeavors. As the field of AI continues to advance, harnessing the power of workflow orchestration will remain a key ingredient in building intelligent and adaptable systems, now lets get started with SequentialWorkflow.
## Official Swarms Links
Here is the Swarms website:
Here is the Swarms Github:
Here are the Swarms docs:
And, join the Swarm community!
Book a call with The Swarm Corporation here if youre interested in high performance custom swarms!
Now lets begin…
## Installation
Before we dive into the tutorial, make sure you have the following prerequisites in place:
Python installed on your system.
The swarms library installed. You can install it via pip using the following command:
`pip3 install --upgrade swarms`
Additionally, you will need an API key for the OpenAIChat model to run the provided code examples. Replace "YOUR_API_KEY" with your actual API key in the code examples where applicable.
## Getting Started
Lets start by importing the necessary modules and initializing the OpenAIChat model, which we will use in our workflow tasks.
```python
from swarms.models import OpenAIChat
from swarms.structs import Flow
from swarms.structs.sequential_workflow import SequentialWorkflow
# Replace "YOUR_API_KEY" with your actual OpenAI API key
api_key = "YOUR_API_KEY"
# Initialize the language model flow (e.g., GPT-3)
llm = OpenAIChat(
openai_api_key=api_key,
temperature=0.5,
max_tokens=3000,
)
We have initialized the OpenAIChat model, which will be used as a callable object in our tasks. Now, lets proceed to create the SequentialWorkflow.
Creating a SequentialWorkflow
To create a SequentialWorkflow, follow these steps:
# Initialize Flows for individual tasks
flow1 = Flow(llm=llm, max_loops=1, dashboard=False)
flow2 = Flow(llm=llm, max_loops=1, dashboard=False)
# Create the Sequential Workflow
workflow = SequentialWorkflow(max_loops=1)
``````
In this code snippet, we have initialized two Flow instances (flow1 and flow2) representing individual tasks within our workflow. These flows will use the OpenAIChat model we initialized earlier. We then create a SequentialWorkflow instance named workflow with a maximum loop count of 1. The max_loops parameter determines how many times the entire workflow can be run, and we set it to 1 for this example.
Adding Tasks to the SequentialWorkflow
Now that we have created the SequentialWorkflow, lets add tasks to it. In our example, well create two tasks: one for generating a 10,000-word blog on “health and wellness” and another for summarizing the generated blog.
```
### Add tasks to the workflow
workflow.add("Generate a 10,000 word blog on health and wellness.", flow1)
`workflow.add("Summarize the generated blog", flow2)`
The workflow.add() method is used to add tasks to the workflow. Each task is described using a human-readable description, such as "Generate a 10,000 word blog on health and wellness," and is associated with a flow (callable object) that will be executed as the task. In our example, flow1 and flow2 represent the tasks.
Running the SequentialWorkflow
With tasks added to the SequentialWorkflow, we can now run the workflow sequentially using the workflow.run() method.
### Run the workflow
`workflow.run()`
Executing workflow.run() will start the execution of tasks in the order they were added to the workflow. In our example, it will first generate the blog and then summarize it.
Accessing Task Results
After running the workflow, you can access the results of each task using the get_task_results() method.
# Get and display the results of each task in the workflow
```python
results = workflow.get_task_results()
for task_description, result in results.items():
print(f"Task: {task_description}, Result: {result}")
```
The workflow.get_task_results() method returns a dictionary where the keys are task descriptions, and the values are the corresponding results. You can then iterate through the results and print them, as shown in the code snippet.
Resetting a SequentialWorkflow
Sometimes, you might need to reset a SequentialWorkflow to start fresh. You can use the workflow.reset_workflow() method for this purpose.
### Reset the workflow
`workflow.reset_workflow()`
Resetting the workflow clears the results of each task, allowing you to rerun the workflow from the beginning without reinitializing it.
Updating Task Arguments
You can also update the arguments of a specific task in the workflow using the workflow.update_task() method.
### Update the arguments of a specific task in the workflow
`workflow.update_task("Generate a 10,000 word blog on health and wellness.", max_loops=2)`
In this example, we update the max_loops argument of the task with the description "Generate a 10,000 word blog on health and wellness" to 2. This can be useful if you want to change the behavior of a specific task without recreating the entire workflow.
# Conclusion: Mastering Workflow Orchestration in AI Engineering
In the ever-evolving landscape of artificial intelligence (AI), where the pace of innovation and complexity of tasks are ever-increasing, harnessing the power of workflow orchestration is paramount. In this comprehensive walkthrough guide, weve embarked on a journey through the world of workflow orchestration, focusing on the Workflow Class, with a specific emphasis on the SequentialWorkflow class. As we conclude this exploration, weve delved deep into the intricacies of orchestrating AI workflows, and its time to reflect on the valuable insights gained and the immense potential that this knowledge unlocks for AI engineers.
## The Art of Workflow Orchestration
At its core, workflow orchestration is the art of designing, managing, and executing sequences of tasks or processes in a structured and efficient manner. In the realm of AI engineering, where tasks can range from data preprocessing and model training to decision-making and autonomous actions, mastering workflow orchestration is a game-changer. It empowers AI engineers to streamline their work, ensure reliable execution, and deliver impactful results.
The Workflow Class, and particularly the SequentialWorkflow class weve explored, acts as a guiding light in this intricate journey. It provides AI engineers with a toolbox of tools and techniques to conquer the challenges of orchestrating AI workflows effectively. Through a disciplined approach and adherence to best practices, AI engineers can achieve the following:
### 1. Structured Workflow Design
A well-structured workflow is the cornerstone of any successful AI project. The Workflow Class encourages AI engineers to break down complex tasks into manageable units. Each task becomes a building block that contributes to the overarching goal. Whether its preprocessing data, training a machine learning model, or generating content, structured workflow design ensures clarity, modularity, and maintainability.
### 2. Efficient Task Sequencing
In AI, the order of tasks often matters. One tasks output can be another tasks input, and ensuring the correct sequence of execution is crucial. The SequentialWorkflow class enforces this sequential execution, eliminating the risk of running tasks out of order. It ensures that the workflow progresses systematically, following the predefined sequence of tasks.
### 3. Error Resilience and Recovery
AI systems must be resilient in the face of unexpected errors and failures. The Workflow Class equips AI engineers with error handling strategies, such as retries and fallbacks. These strategies provide the ability to gracefully handle issues, recover from failures, and continue the workflows execution without disruption.
### 4. Code Modularity and Reusability
Building AI workflows often involves implementing various tasks, each with its own logic. The Workflow Class encourages code modularity, allowing AI engineers to encapsulate tasks as separate units. This modularity promotes code reusability, making it easier to adapt and expand workflows as AI projects evolve.
### 5. Efficient Debugging and Testing
Debugging and testing AI workflows can be challenging without clear structure and boundaries. The Workflow Class provides a clear sequence of tasks with well-defined inputs and outputs. This structure simplifies the debugging process, as AI engineers can isolate and test individual tasks, ensuring that each component functions as intended.
### 6. Scalability and Adaptability
As AI projects grow in complexity, the Workflow Class scales effortlessly. AI engineers can add or modify tasks as needed, accommodating new data sources, algorithms, or requirements. This scalability ensures that workflows remain adaptable to changing demands and evolving AI landscapes.
### 7. Maintainability and Future-Proofing
Maintaining AI systems over time is a crucial aspect of engineering. The Workflow Class fosters maintainability by providing a clear roadmap of tasks and their interactions. AI engineers can revisit, update, and extend workflows with confidence, ensuring that AI systems remain effective and relevant in the long run.
## Empowering AI Engineers
The knowledge and skills gained from this walkthrough guide go beyond technical proficiency. They empower AI engineers to be architects of intelligent systems, capable of orchestrating AI workflows that solve real-world problems. The Workflow Class is a versatile instrument in their hands, enabling them to tackle diverse use cases and engineering challenges.
## Diverse Use Cases for Workflow Class
Throughout this guide, we explored a myriad of use cases where the Workflow Class shines:
Natural Language Processing (NLP) Pipelines: In NLP, workflows involve multiple stages, and the Workflow Class ensures orderly execution, resulting in coherent NLP outcomes.
Data Ingestion and Transformation: Data is the lifeblood of AI, and structured data workflows ensure efficient data preparation for downstream tasks.
Autonomous Agents and Robotics: For robots and intelligent agents, workflows enable autonomous decision-making and task execution.
Machine Learning Model Training: Model training workflows encompass numerous steps, and structured orchestration simplifies the process.
Content Generation and Summarization: Workflows for content generation ensure that generated content meets quality and coherence criteria.
Adaptive Decision-Making: In dynamic environments, workflows facilitate adaptive decision-making based on real-time data.
## Efficiency and Maintainability
AI engineers not only have the tools to tackle these use cases but also the means to do so efficiently. The Workflow Class fosters efficiency and maintainability, making AI engineering endeavors more manageable:
- Modularity: Encapsulate tasks as separate units, promoting code reusability and maintainability.
- Debugging and Testing: Streamline debugging and testing through clear task boundaries and well-defined inputs and outputs.
- Scalability: As AI projects grow, workflows scale with ease, accommodating new components and requirements.
Error Handling: Gracefully handle errors and failures, ensuring that AI systems continue to operate smoothly.
- Maintainability: AI systems remain adaptable and maintainable, even as the AI landscape evolves and requirements change.
## The Future of AI Engineering
As AI engineering continues to advance, workflow orchestration will play an increasingly pivotal role. The Workflow Class is not a static tool; it is a dynamic enabler of innovation. In the future, we can expect further enhancements and features to meet the evolving demands of AI engineering:
### 1. Asynchronous Support
Support for asynchronous task execution will improve the efficiency of workflows, especially when tasks involve waiting for external events or resources.
### 2. Context Managers
Introducing context manager support for tasks can simplify resource management, such as opening and closing files or database connections.
### 3. Workflow History
Maintaining a detailed history of workflow execution, including timestamps, task durations, and input/output data, will facilitate debugging and performance analysis.
### 4. Parallel Processing
Enhancing the module to support parallel processing with a pool of workers can significantly speed up the execution of tasks, especially for computationally intensive workflows.
### 5. Error Handling Strategies
Providing built-in error handling strategies, such as retries, fallbacks, and circuit breakers, will further enhance the resilience of workflows.
## Closing Thoughts
In conclusion, the journey through workflow orchestration in AI engineering has been both enlightening and empowering. The Workflow Class, and particularly the SequentialWorkflow class, has proven to be an invaluable ally in the AI engineers toolkit. It offers structure, modularity, and efficiency, ensuring that AI projects progress smoothly from inception to deployment.
As AI continues to permeate every aspect of our lives, the skills acquired in this guide will remain highly relevant and sought after. AI engineers armed with workflow orchestration expertise will continue to push the boundaries of what is possible, solving complex problems, and driving innovation.
But beyond the technical aspects, this guide also emphasizes the importance of creativity, adaptability, and problem-solving. AI engineering is not just about mastering tools; its about using them to make a meaningful impact on the world.
So, whether youre just starting your journey into AI engineering or youre a seasoned professional seeking to expand your horizons, remember that the power of workflow orchestration lies not only in the code but in the limitless potential it unlocks for you as an AI engineer. As you embark on your own AI adventures, may this guide serve as a reliable companion, illuminating your path and inspiring your journey towards AI excellence.
The world of AI is waiting for your innovation and creativity. With workflow orchestration as your guide, you have the tools to shape the future. The possibilities are boundless, and the future is yours to create.
Official Swarms Links
Here is the Swarms website:
Here is the Swarms Github:
Here are the Swarms docs:
And, join the Swarm community!
Book a call with The Swarm Corporation here if youre interested in high performance custom swarms!

@ -1,93 +0,0 @@
Create multi-page long and explicit professional pytorch-like documentation for the swarms code below follow the outline for the swarms library, provide many examples and teach the user about the code, provide examples for every function, make the documentation 10,000 words, provide many usage examples and note this is markdown docs, create the documentation for the code to document.
Now make the professional documentation for this code, provide the architecture and how the class works and why it works that way, it's purpose, provide args, their types, 3 ways of usage examples, in examples use from shapeless import x
BE VERY EXPLICIT AND THOROUGH, MAKE IT DEEP AND USEFUL
########
Step 1: Understand the purpose and functionality of the module or framework
Read and analyze the description provided in the documentation to understand the purpose and functionality of the module or framework.
Identify the key features, parameters, and operations performed by the module or framework.
Step 2: Provide an overview and introduction
Start the documentation by providing a brief overview and introduction to the module or framework.
Explain the importance and relevance of the module or framework in the context of the problem it solves.
Highlight any key concepts or terminology that will be used throughout the documentation.
Step 3: Provide a class or function definition
Provide the class or function definition for the module or framework.
Include the parameters that need to be passed to the class or function and provide a brief description of each parameter.
Specify the data types and default values for each parameter.
Step 4: Explain the functionality and usage
Provide a detailed explanation of how the module or framework works and what it does.
Describe the steps involved in using the module or framework, including any specific requirements or considerations.
Provide code examples to demonstrate the usage of the module or framework.
Explain the expected inputs and outputs for each operation or function.
Step 5: Provide additional information and tips
Provide any additional information or tips that may be useful for using the module or framework effectively.
Address any common issues or challenges that developers may encounter and provide recommendations or workarounds.
Step 6: Include references and resources
Include references to any external resources or research papers that provide further information or background on the module or framework.
Provide links to relevant documentation or websites for further exploration.
Example Template for the given documentation:
# Module/Function Name: MultiheadAttention
class torch.nn.MultiheadAttention(embed_dim, num_heads, dropout=0.0, bias=True, add_bias_kv=False, add_zero_attn=False, kdim=None, vdim=None, batch_first=False, device=None, dtype=None):
"""
Creates a multi-head attention module for joint information representation from the different subspaces.
Parameters:
- embed_dim (int): Total dimension of the model.
- num_heads (int): Number of parallel attention heads. The embed_dim will be split across num_heads.
- dropout (float): Dropout probability on attn_output_weights. Default: 0.0 (no dropout).
- bias (bool): If specified, adds bias to input/output projection layers. Default: True.
- add_bias_kv (bool): If specified, adds bias to the key and value sequences at dim=0. Default: False.
- add_zero_attn (bool): If specified, adds a new batch of zeros to the key and value sequences at dim=1. Default: False.
- kdim (int): Total number of features for keys. Default: None (uses kdim=embed_dim).
- vdim (int): Total number of features for values. Default: None (uses vdim=embed_dim).
- batch_first (bool): If True, the input and output tensors are provided as (batch, seq, feature). Default: False.
- device (torch.device): If specified, the tensors will be moved to the specified device.
- dtype (torch.dtype): If specified, the tensors will have the specified dtype.
"""
def forward(query, key, value, key_padding_mask=None, need_weights=True, attn_mask=None, average_attn_weights=True, is_causal=False):
"""
Forward pass of the multi-head attention module.
Parameters:
- query (Tensor): Query embeddings of shape (L, E_q) for unbatched input, (L, N, E_q) when batch_first=False, or (N, L, E_q) when batch_first=True.
- key (Tensor): Key embeddings of shape (S, E_k) for unbatched input, (S, N, E_k) when batch_first=False, or (N, S, E_k) when batch_first=True.
- value (Tensor): Value embeddings of shape (S, E_v) for unbatched input, (S, N, E_v) when batch_first=False, or (N, S, E_v) when batch_first=True.
- key_padding_mask (Optional[Tensor]): If specified, a mask indicating elements to be ignored in key for attention computation.
- need_weights (bool): If specified, returns attention weights in addition to attention outputs. Default: True.
- attn_mask (Optional[Tensor]): If specified, a mask preventing attention to certain positions.
- average_attn_weights (bool): If true, returns averaged attention weights per head. Otherwise, returns attention weights separately per head. Note that this flag only has an effect when need_weights=True. Default: True.
- is_causal (bool): If specified, applies a causal mask as the attention mask. Default: False.
Returns:
Tuple[Tensor, Optional[Tensor]]:
- attn_output (Tensor): Attention outputs of shape (L, E) for unbatched input, (L, N, E) when batch_first=False, or (N, L, E) when batch_first=True.
- attn_output_weights (Optional[Tensor]): Attention weights of shape (L, S) when unbatched or (N, L, S) when batched. Optional, only returned when need_weights=True.
"""
# Implementation of the forward pass of the attention module goes here
return attn_output, attn_output_weights
# Usage example:
multihead_attn = nn.MultiheadAttention(embed_dim, num_heads)
attn_output, attn_output_weights = multihead_attn(query, key, value)
Note:
The above template includes the class or function definition, parameters, description, and usage example.
To replicate the documentation for any other module or framework, follow the same structure and provide the specific details for that module or framework.
############# CODE TO DOCUMENT, DOCUMENT THE

@ -53,7 +53,7 @@ The `BaseChunker` class is the core component of the `BaseChunker` module. It is
#### Parameters: #### Parameters:
- `separators` (list[ChunkSeparator]): Specifies a list of `ChunkSeparator` objects used to split the text into chunks. - `separators` (list[ChunkSeparator]): Specifies a list of `ChunkSeparator` objects used to split the text into chunks.
- `tokenizer` (OpenAiTokenizer): Defines the tokenizer to be used for counting tokens in the text. - `tokenizer` (OpenAITokenizer): Defines the tokenizer to be used for counting tokens in the text.
- `max_tokens` (int): Sets the maximum token limit for each chunk. - `max_tokens` (int): Sets the maximum token limit for each chunk.
### 4.2. Examples <a name="examples"></a> ### 4.2. Examples <a name="examples"></a>

@ -52,7 +52,7 @@ The `PdfChunker` class is the core component of the `PdfChunker` module. It is u
#### Parameters: #### Parameters:
- `separators` (list[ChunkSeparator]): Specifies a list of `ChunkSeparator` objects used to split the PDF text content into chunks. - `separators` (list[ChunkSeparator]): Specifies a list of `ChunkSeparator` objects used to split the PDF text content into chunks.
- `tokenizer` (OpenAiTokenizer): Defines the tokenizer used for counting tokens in the text. - `tokenizer` (OpenAITokenizer): Defines the tokenizer used for counting tokens in the text.
- `max_tokens` (int): Sets the maximum token limit for each chunk. - `max_tokens` (int): Sets the maximum token limit for each chunk.
### 4.2. Examples <a name="examples"></a> ### 4.2. Examples <a name="examples"></a>

@ -70,17 +70,18 @@ class Anthropic:
```python ```python
# Import necessary modules and classes # Import necessary modules and classes
from swarms.models import Anthropic from swarms.models import Anthropic
import torch
# Initialize an instance of the Anthropic class # Initialize an instance of the Anthropic class
anthropic_instance = Anthropic() model = Anthropic(
anthropic_api_key=""
)
# Using the generate method # Using the run method
completion_1 = anthropic_instance.generate("What is the capital of France?") completion_1 = model.run("What is the capital of France?")
print(completion_1) print(completion_1)
# Using the __call__ method # Using the __call__ method
completion_2 = anthropic_instance("How far is the moon from the earth?", stop=["miles", "km"]) completion_2 = model("How far is the moon from the earth?", stop=["miles", "km"])
print(completion_2) print(completion_2)
``` ```

@ -0,0 +1,261 @@
# `Dalle3` Documentation
## Table of Contents
1. [Introduction](#introduction)
2. [Installation](#installation)
3. [Quick Start](#quick-start)
4. [Dalle3 Class](#dalle3-class)
- [Attributes](#attributes)
- [Methods](#methods)
5. [Usage Examples](#usage-examples)
6. [Error Handling](#error-handling)
7. [Advanced Usage](#advanced-usage)
8. [References](#references)
---
## Introduction<a name="introduction"></a>
The Dalle3 library is a Python module that provides an easy-to-use interface for generating images from text descriptions using the DALL·E 3 model by OpenAI. DALL·E 3 is a powerful language model capable of converting textual prompts into images. This documentation will guide you through the installation, setup, and usage of the Dalle3 library.
---
## Installation<a name="installation"></a>
To use the Dalle3 model, you must first install swarms:
```bash
pip install swarms
```
---
## Quick Start<a name="quick-start"></a>
Let's get started with a quick example of using the Dalle3 library to generate an image from a text prompt:
```python
from swarms.models.dalle3 import Dalle3
# Create an instance of the Dalle3 class
dalle = Dalle3()
# Define a text prompt
task = "A painting of a dog"
# Generate an image from the text prompt
image_url = dalle3(task)
# Print the generated image URL
print(image_url)
```
This example demonstrates the basic usage of the Dalle3 library to convert a text prompt into an image. The generated image URL will be printed to the console.
---
## Dalle3 Class<a name="dalle3-class"></a>
The Dalle3 library provides a `Dalle3` class that allows you to interact with the DALL·E 3 model. This class has several attributes and methods for generating images from text prompts.
### Attributes<a name="attributes"></a>
- `model` (str): The name of the DALL·E 3 model. Default: "dall-e-3".
- `img` (str): The image URL generated by the Dalle3 API.
- `size` (str): The size of the generated image. Default: "1024x1024".
- `max_retries` (int): The maximum number of API request retries. Default: 3.
- `quality` (str): The quality of the generated image. Default: "standard".
- `n` (int): The number of variations to create. Default: 4.
### Methods<a name="methods"></a>
#### `__call__(self, task: str) -> Dalle3`
This method makes a call to the Dalle3 API and returns the image URL generated from the provided text prompt.
Parameters:
- `task` (str): The text prompt to be converted to an image.
Returns:
- `Dalle3`: An instance of the Dalle3 class with the image URL generated by the Dalle3 API.
#### `create_variations(self, img: str)`
This method creates variations of an image using the Dalle3 API.
Parameters:
- `img` (str): The image to be used for the API request.
Returns:
- `img` (str): The image URL of the generated variations.
---
## Usage Examples<a name="usage-examples"></a>
### Example 1: Basic Image Generation
```python
from swarms.models.dalle3 import Dalle3
# Create an instance of the Dalle3 class
dalle3 = Dalle3()
# Define a text prompt
task = "A painting of a dog"
# Generate an image from the text prompt
image_url = dalle3(task)
# Print the generated image URL
print(image_url)
```
### Example 2: Creating Image Variations
```python
from swarms.models.dalle3 import Dalle3
# Create an instance of the Dalle3 class
dalle3 = Dalle3()
# Define the URL of an existing image
img_url = "https://images.unsplash.com/photo-1694734479898-6ac4633158ac?q=80&w=1287&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D
# Create variations of the image
variations_url = dalle3.create_variations(img_url)
# Print the URLs of the generated variations
print(variations_url)
```
Certainly! Here are additional examples that cover various edge cases and methods of the `Dalle3` class in the Dalle3 library:
### Example 3: Customizing Image Size
You can customize the size of the generated image by specifying the `size` parameter when creating an instance of the `Dalle3` class. Here's how to generate a smaller image:
```python
from swarms.models.dalle3 import Dalle3
# Create an instance of the Dalle3 class with a custom image size
dalle3 = Dalle3(size="512x512")
# Define a text prompt
task = "A small painting of a cat"
# Generate a smaller image from the text prompt
image_url = dalle3(task)
# Print the generated image URL
print(image_url)
```
### Example 4: Adjusting Retry Limit
You can adjust the maximum number of API request retries using the `max_retries` parameter. Here's how to increase the retry limit:
```python
from swarms.models.dalle3 import Dalle3
# Create an instance of the Dalle3 class with a higher retry limit
dalle3 = Dalle3(max_retries=5)
# Define a text prompt
task = "An image of a landscape"
# Generate an image with a higher retry limit
image_url = dalle3(task)
# Print the generated image URL
print(image_url)
```
### Example 5: Generating Image Variations
To create variations of an existing image, you can use the `create_variations` method. Here's an example:
```python
from swarms.models.dalle3 import Dalle3
# Create an instance of the Dalle3 class
dalle3 = Dalle3()
# Define the URL of an existing image
img_url = "https://images.unsplash.com/photo-1677290043066-12eccd944004?q=80&w=1287&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
# Create variations of the image
variations_url = dalle3.create_variations(img_url)
# Print the URLs of the generated variations
print(variations_url)
```
### Example 6: Handling API Errors
The Dalle3 library provides error handling for API-related issues. Here's how to handle and display API errors:
```python
from swarms.models.dalle3 import Dalle3
# Create an instance of the Dalle3 class
dalle3 = Dalle3()
# Define a text prompt
task = "Invalid prompt that may cause an API error"
try:
# Attempt to generate an image with an invalid prompt
image_url = dalle3(task)
print(image_url)
except Exception as e:
print(f"Error occurred: {str(e)}")
```
### Example 7: Customizing Image Quality
You can customize the quality of the generated image by specifying the `quality` parameter. Here's how to generate a high-quality image:
```python
from swarms.models.dalle3 import Dalle3
# Create an instance of the Dalle3 class with high quality
dalle3 = Dalle3(quality="high")
# Define a text prompt
task = "A high-quality image of a sunset"
# Generate a high-quality image from the text prompt
image_url = dalle3(task)
# Print the generated image URL
print(image_url)
```
---
## Error Handling<a name="error-handling"></a>
The Dalle3 library provides error handling for API-related issues. If an error occurs during API communication, the library will handle it and provide detailed error messages. Make sure to handle exceptions appropriately in your code.
---
## Advanced Usage<a name="advanced-usage"></a>
For advanced usage and customization of the Dalle3 library, you can explore the attributes and methods of the `Dalle3` class. Adjusting parameters such as `size`, `max_retries`, and `quality` allows you to fine-tune the image generation process to your specific needs.
---
## References<a name="references"></a>
For more information about the DALL·E 3 model and the Dalle3 library, you can refer to the official OpenAI documentation and resources.
- [OpenAI API Documentation](https://beta.openai.com/docs/)
- [DALL·E 3 Model Information](https://openai.com/research/dall-e-3)
- [Dalle3 GitHub Repository](https://github.com/openai/dall-e-3)
---
This concludes the documentation for the Dalle3 library. You can now use the library to generate images from text prompts and explore its advanced features for various applications.

@ -0,0 +1,123 @@
# DistilWhisperModel Documentation
## Overview
The `DistilWhisperModel` is a Python class designed to handle English speech recognition tasks. It leverages the capabilities of the Whisper model, which is fine-tuned for speech-to-text processes. It is designed for both synchronous and asynchronous transcription of audio inputs, offering flexibility for real-time applications or batch processing.
## Installation
Before you can use `DistilWhisperModel`, ensure you have the required libraries installed:
```sh
pip3 install --upgrade swarms
```
## Initialization
The `DistilWhisperModel` class is initialized with the following parameters:
| Parameter | Type | Description | Default |
|-----------|------|-------------|---------|
| `model_id` | `str` | The identifier for the pre-trained Whisper model | `"distil-whisper/distil-large-v2"` |
Example of initialization:
```python
from swarms.models import DistilWhisperModel
# Initialize with default model
model_wrapper = DistilWhisperModel()
# Initialize with a specific model ID
model_wrapper = DistilWhisperModel(model_id='distil-whisper/distil-large-v2')
```
## Attributes
After initialization, the `DistilWhisperModel` has several attributes:
| Attribute | Type | Description |
|-----------|------|-------------|
| `device` | `str` | The device used for computation (`"cuda:0"` for GPU or `"cpu"`). |
| `torch_dtype` | `torch.dtype` | The data type used for the Torch tensors. |
| `model_id` | `str` | The model identifier string. |
| `model` | `torch.nn.Module` | The actual Whisper model loaded from the identifier. |
| `processor` | `transformers.AutoProcessor` | The processor for handling input data. |
## Methods
### `transcribe`
Transcribes audio input synchronously.
**Arguments**:
| Argument | Type | Description |
|----------|------|-------------|
| `inputs` | `Union[str, dict]` | File path or audio data dictionary. |
**Returns**: `str` - The transcribed text.
**Usage Example**:
```python
# Synchronous transcription
transcription = model_wrapper.transcribe('path/to/audio.mp3')
print(transcription)
```
### `async_transcribe`
Transcribes audio input asynchronously.
**Arguments**:
| Argument | Type | Description |
|----------|------|-------------|
| `inputs` | `Union[str, dict]` | File path or audio data dictionary. |
**Returns**: `Coroutine` - A coroutine that when awaited, returns the transcribed text.
**Usage Example**:
```python
import asyncio
# Asynchronous transcription
transcription = asyncio.run(model_wrapper.async_transcribe('path/to/audio.mp3'))
print(transcription)
```
### `real_time_transcribe`
Simulates real-time transcription of an audio file.
**Arguments**:
| Argument | Type | Description |
|----------|------|-------------|
| `audio_file_path` | `str` | Path to the audio file. |
| `chunk_duration` | `int` | Duration of audio chunks in seconds. |
**Usage Example**:
```python
# Real-time transcription simulation
model_wrapper.real_time_transcribe('path/to/audio.mp3', chunk_duration=5)
```
## Error Handling
The `DistilWhisperModel` class incorporates error handling for file not found errors and generic exceptions during the transcription process. If a non-recoverable exception is raised, it is printed to the console in red to indicate failure.
## Conclusion
The `DistilWhisperModel` offers a convenient interface to the powerful Whisper model for speech recognition. Its design supports both batch and real-time transcription, catering to different application needs. The class's error handling and retry logic make it robust for real-world applications.
## Additional Notes
- Ensure you have appropriate permissions to read audio files when using file paths.
- Transcription quality depends on the audio quality and the Whisper model's performance on your dataset.
- Adjust `chunk_duration` according to the processing power of your system for real-time transcription.
For a full list of models supported by `transformers.AutoModelForSpeechSeq2Seq`, visit the [Hugging Face Model Hub](https://huggingface.co/models).

@ -42,13 +42,6 @@ from swarms.models import Fuyu
fuyu = Fuyu() fuyu = Fuyu()
``` ```
### Example 1 - Initialization
```python
from swarms.models import Fuyu
fuyu = Fuyu()
```
2. Generate Text with Fuyu: 2. Generate Text with Fuyu:

@ -0,0 +1,251 @@
# `GPT4Vision` Documentation
## Table of Contents
- [Overview](#overview)
- [Installation](#installation)
- [Initialization](#initialization)
- [Methods](#methods)
- [process_img](#process_img)
- [__call__](#__call__)
- [run](#run)
- [arun](#arun)
- [Configuration Options](#configuration-options)
- [Usage Examples](#usage-examples)
- [Additional Tips](#additional-tips)
- [References and Resources](#references-and-resources)
---
## Overview
The GPT4Vision Model API is designed to provide an easy-to-use interface for interacting with the OpenAI GPT-4 Vision model. This model can generate textual descriptions for images and answer questions related to visual content. Whether you want to describe images or perform other vision-related tasks, GPT4Vision makes it simple and efficient.
The library offers a straightforward way to send images and tasks to the GPT-4 Vision model and retrieve the generated responses. It handles API communication, authentication, and retries, making it a powerful tool for developers working with computer vision and natural language processing tasks.
## Installation
To use the GPT4Vision Model API, you need to install the required dependencies and configure your environment. Follow these steps to get started:
1. Install the required Python package:
```bash
pip3 install --upgrade swarms
```
2. Make sure you have an OpenAI API key. You can obtain one by signing up on the [OpenAI platform](https://beta.openai.com/signup/).
3. Set your OpenAI API key as an environment variable. You can do this in your code or your environment configuration. Alternatively, you can provide the API key directly when initializing the `GPT4Vision` class.
## Initialization
To start using the GPT4Vision Model API, you need to create an instance of the `GPT4Vision` class. You can customize its behavior by providing various configuration options, but it also comes with sensible defaults.
Here's how you can initialize the `GPT4Vision` class:
```python
from swarms.models.gpt4v import GPT4Vision
gpt4vision = GPT4Vision(
api_key="Your Key"
)
```
The above code initializes the `GPT4Vision` class with default settings. You can adjust these settings as needed.
## Methods
### `process_img`
The `process_img` method is used to preprocess an image before sending it to the GPT-4 Vision model. It takes the image path as input and returns the processed image in a format suitable for API requests.
```python
processed_img = gpt4vision.process_img(img_path)
```
- `img_path` (str): The file path or URL of the image to be processed.
### `__call__`
The `__call__` method is the main method for interacting with the GPT-4 Vision model. It sends the image and tasks to the model and returns the generated response.
```python
response = gpt4vision(img, tasks)
```
- `img` (Union[str, List[str]]): Either a single image URL or a list of image URLs to be used for the API request.
- `tasks` (List[str]): A list of tasks or questions related to the image(s).
This method returns a `GPT4VisionResponse` object, which contains the generated answer.
### `run`
The `run` method is an alternative way to interact with the GPT-4 Vision model. It takes a single task and image URL as input and returns the generated response.
```python
response = gpt4vision.run(task, img)
```
- `task` (str): The task or question related to the image.
- `img` (str): The image URL to be used for the API request.
This method simplifies interactions when dealing with a single task and image.
### `arun`
The `arun` method is an asynchronous version of the `run` method. It allows for asynchronous processing of API requests, which can be useful in certain scenarios.
```python
import asyncio
async def main():
response = await gpt4vision.arun(task, img)
print(response)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
```
- `task` (str): The task or question related to the image.
- `img` (str): The image URL to be used for the API request.
## Configuration Options
The `GPT4Vision` class provides several configuration options that allow you to customize its behavior:
- `max_retries` (int): The maximum number of retries to make to the API. Default: 3
- `backoff_factor` (float): The backoff factor to use for exponential backoff. Default: 2.0
- `timeout_seconds` (int): The timeout in seconds for the API request. Default: 10
- `api_key` (str): The API key to use for the API request. Default: None (set via environment variable)
- `quality` (str): The quality of the image to generate. Options: 'low' or 'high'. Default: 'low'
- `max_tokens` (int): The maximum number of tokens to use for the API request. Default: 200
## Usage Examples
### Example 1: Generating Image Descriptions
```python
gpt4vision = GPT4Vision()
img = "https://example.com/image.jpg"
tasks = ["Describe this image."]
response = gpt4vision(img, tasks)
print(response.answer)
```
In this example, we create an instance of `GPT4Vision`, provide an image URL, and ask the model to describe the image. The response contains the generated description.
### Example 2: Custom Configuration
```python
custom_config = {
"max_retries": 5,
"timeout_seconds": 20,
"quality": "high",
"max_tokens": 300,
}
gpt4vision = GPT4Vision(**custom_config)
img = "https://example.com/another_image.jpg"
tasks = ["What objects can you identify in this image?"]
response = gpt4vision(img, tasks)
print(response.answer)
```
In this example, we create an instance of `GPT4Vision` with custom configuration options. We set a higher timeout, request high-quality images, and allow more tokens in the response.
### Example 3: Using the `run` Method
```python
gpt4vision = GPT4Vision()
img = "https://example.com/image.jpg"
task = "Describe this image in detail."
response = gpt4vision.run(task, img)
print(response)
```
In this example, we use the `run` method to simplify the interaction by providing a single task and image URL.
# Model Usage and Image Understanding
The GPT-4 Vision model processes images in a unique way, allowing it to answer questions about both or each of the images independently. Here's an overview:
| Purpose | Description |
| --------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| Image Understanding | The model is shown two copies of the same image and can answer questions about both or each of the images independently. |
# Image Detail Control
You have control over how the model processes the image and generates textual understanding by using the `detail` parameter, which has two options: `low` and `high`.
| Detail | Description |
| -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| low | Disables the "high-res" model. The model receives a low-res 512 x 512 version of the image and represents the image with a budget of 65 tokens. Ideal for use cases not requiring high detail. |
| high | Enables "high-res" mode. The model first sees the low-res image and then creates detailed crops of input images as 512px squares based on the input image size. Uses a total of 129 tokens. |
# Managing Images
To use the Chat Completions API effectively, you must manage the images you pass to the model. Here are some key considerations:
| Management Aspect | Description |
| ------------------------- | ------------------------------------------------------------------------------------------------- |
| Image Reuse | To pass the same image multiple times, include the image with each API request. |
| Image Size Optimization | Improve latency by downsizing images to meet the expected size requirements. |
| Image Deletion | After processing, images are deleted from OpenAI servers and not retained. No data is used for training. |
# Limitations
While GPT-4 with Vision is powerful, it has some limitations:
| Limitation | Description |
| -------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| Medical Images | Not suitable for interpreting specialized medical images like CT scans. |
| Non-English Text | May not perform optimally when handling non-Latin alphabets, such as Japanese or Korean. |
| Large Text in Images | Enlarge text within images for readability, but avoid cropping important details. |
| Rotated or Upside-Down Text/Images | May misinterpret rotated or upside-down text or images. |
| Complex Visual Elements | May struggle to understand complex graphs or text with varying colors or styles. |
| Spatial Reasoning | Struggles with tasks requiring precise spatial localization, such as identifying chess positions. |
| Accuracy | May generate incorrect descriptions or captions in certain scenarios. |
| Panoramic and Fisheye Images | Struggles with panoramic and fisheye images. |
# Calculating Costs
Image inputs are metered and charged in tokens. The token cost depends on the image size and detail option.
| Example | Token Cost |
| --------------------------------------------- | ----------- |
| 1024 x 1024 square image in detail: high mode | 765 tokens |
| 2048 x 4096 image in detail: high mode | 1105 tokens |
| 4096 x 8192 image in detail: low mode | 85 tokens |
# FAQ
Here are some frequently asked questions about GPT-4 with Vision:
| Question | Answer |
| -------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| Fine-Tuning Image Capabilities | No, fine-tuning the image capabilities of GPT-4 is not supported at this time. |
| Generating Images | GPT-4 is used for understanding images, not generating them. |
| Supported Image File Types | Supported image file types include PNG (.png), JPEG (.jpeg and .jpg), WEBP (.webp), and non-animated GIF (.gif). |
| Image Size Limitations | Image uploads are restricted to 20MB per image. |
| Image Deletion | Uploaded images are automatically deleted after processing by the model. |
| Learning More | For more details about GPT-4 with Vision, refer to the GPT-4 with Vision system card. |
| CAPTCHA Submission | CAPTCHAs are blocked for safety reasons. |
| Rate Limits | Image processing counts toward your tokens per minute (TPM) limit. Refer to the calculating costs section for details. |
| Image Metadata | The model does not receive image metadata. |
| Handling Unclear Images | If an image is unclear, the model will do its best to interpret it, but results may be less accurate. |
## Additional Tips
- Make sure to handle potential exceptions and errors when making API requests. The library includes retries and error handling, but it's essential to handle exceptions gracefully in your code.
- Experiment with different configuration options to optimize the trade-off between response quality and response time based on your specific requirements.
## References and Resources
- [OpenAI Platform](https://beta.openai.com/signup/): Sign up for an OpenAI API key.
- [OpenAI API Documentation](https://platform.openai.com/docs/api-reference/chat/create): Official API documentation for the GPT-4 Vision model.
Now you have a comprehensive understanding of the GPT4Vision Model API, its configuration options, and how to use it for various computer vision and natural language processing tasks. Start experimenting and integrating it into your projects to leverage the power of GPT-4 Vision for image-related tasks.
# Conclusion
With GPT-4 Vision, you have a powerful tool for understanding and generating textual descriptions for images. By considering its capabilities, limitations, and cost calculations, you can effectively leverage this model for various image-related tasks.

@ -108,8 +108,13 @@ Here are three usage examples:
```python ```python
from swarms.structs import Flow from swarms.structs import Flow
# Select any Language model from the models folder
from swarms.models import Mistral, OpenAIChat
flow = Flow(llm=my_language_model, max_loops=5) llm = Mistral()
# llm = OpenAIChat()
flow = Flow(llm=llm, max_loops=5)
# Define a starting task or message # Define a starting task or message
initial_task = "Generate an long form analysis on the transformer model architecture." initial_task = "Generate an long form analysis on the transformer model architecture."
@ -126,7 +131,7 @@ from swarms.structs import Flow
def stop_when_repeats(response: str) -> bool: def stop_when_repeats(response: str) -> bool:
return "Stop" in response.lower() return "Stop" in response.lower()
flow = Flow(llm=my_language_model, max_loops=5, stopping_condition=stop_when_repeats) flow = Flow(llm=llm, max_loops=5, stopping_condition=stop_when_repeats)
``` ```
### Example 3: Interactive Conversation ### Example 3: Interactive Conversation
@ -134,7 +139,7 @@ flow = Flow(llm=my_language_model, max_loops=5, stopping_condition=stop_when_rep
```python ```python
from swarms.structs import Flow from swarms.structs import Flow
flow = Flow(llm=my_language_model, max_loops=5, interactive=True) flow = Flow(llm=llm, max_loops=5, interactive=True)
# Provide initial task # Provide initial task
initial_task = "Rank and prioritize the following financial documents and cut out 30% of our expenses" initial_task = "Rank and prioritize the following financial documents and cut out 30% of our expenses"

@ -0,0 +1,614 @@
# `SequentialWorkflow` Documentation
The **SequentialWorkflow** class is a Python module designed to facilitate the execution of a sequence of tasks in a sequential manner. It is a part of the `swarms.structs` package and is particularly useful for orchestrating the execution of various callable objects, such as functions or models, in a predefined order. This documentation will provide an in-depth understanding of the **SequentialWorkflow** class, including its purpose, architecture, usage, and examples.
## Purpose and Relevance
The **SequentialWorkflow** class is essential for managing and executing a series of tasks or processes, where each task may depend on the outcome of the previous one. It is commonly used in various application scenarios, including but not limited to:
1. **Natural Language Processing (NLP) Workflows:** In NLP workflows, multiple language models are employed sequentially to process and generate text. Each model may depend on the results of the previous one, making sequential execution crucial.
2. **Data Analysis Pipelines:** Data analysis often involves a series of tasks such as data preprocessing, transformation, and modeling steps. These tasks must be performed sequentially to ensure data consistency and accuracy.
3. **Task Automation:** In task automation scenarios, there is a need to execute a series of automated tasks in a specific order. Sequential execution ensures that each task is performed in a predefined sequence, maintaining the workflow's integrity.
By providing a structured approach to managing these tasks, the **SequentialWorkflow** class helps developers streamline their workflow execution and improve code maintainability.
## Key Concepts and Terminology
Before delving into the details of the **SequentialWorkflow** class, let's define some key concepts and terminology that will be used throughout the documentation:
### Task
A **task** refers to a specific unit of work that needs to be executed as part of the workflow. Each task is associated with a description and can be implemented as a callable object, such as a function or a model.
### Flow
A **flow** represents a callable object that can be a task within the **SequentialWorkflow**. Flows encapsulate the logic and functionality of a particular task. Flows can be functions, models, or any callable object that can be executed.
### Sequential Execution
Sequential execution refers to the process of running tasks one after the other in a predefined order. In a **SequentialWorkflow**, tasks are executed sequentially, meaning that each task starts only after the previous one has completed.
### Workflow
A **workflow** is a predefined sequence of tasks that need to be executed in a specific order. It represents the overall process or pipeline that the **SequentialWorkflow** manages.
### Dashboard (Optional)
A **dashboard** is an optional feature of the **SequentialWorkflow** that provides real-time monitoring and visualization of the workflow's progress. It displays information such as the current task being executed, task results, and other relevant metadata.
### Max Loops
The **maximum number of times** the entire workflow can be run. This parameter allows developers to control how many times the workflow is executed.
### Autosaving
**Autosaving** is a feature that allows the **SequentialWorkflow** to automatically save its state to a file at specified intervals. This feature helps in resuming a workflow from where it left off, even after interruptions.
Now that we have a clear understanding of the key concepts and terminology, let's explore the architecture and usage of the **SequentialWorkflow** class in more detail.
## Architecture of SequentialWorkflow
The architecture of the **SequentialWorkflow** class is designed to provide a structured and flexible way to define, manage, and execute a sequence of tasks. It comprises the following core components:
1. **Task**: The **Task** class represents an individual unit of work within the workflow. Each task has a description, which serves as a human-readable identifier for the task. Tasks can be implemented as callable objects, allowing for great flexibility in defining their functionality.
2. **Workflow**: The **SequentialWorkflow** class itself represents the workflow. It manages a list of tasks in the order they should be executed. Workflows can be run sequentially or asynchronously, depending on the use case.
3. **Task Execution**: Task execution is the process of running each task in the workflow. Tasks are executed one after another in the order they were added to the workflow. Task results can be passed as inputs to subsequent tasks.
4. **Dashboard (Optional)**: The **SequentialWorkflow** optionally includes a dashboard feature. The dashboard provides a visual interface for monitoring the progress of the workflow. It displays information about the current task, task results, and other relevant metadata.
5. **State Management**: The **SequentialWorkflow** supports state management, allowing developers to save and load the state of the workflow to and from JSON files. This feature is valuable for resuming workflows after interruptions or for sharing workflow configurations.
## Usage of SequentialWorkflow
The **SequentialWorkflow** class is versatile and can be employed in a wide range of applications. Its usage typically involves the following steps:
1. **Initialization**: Begin by initializing any callable objects or flows that will serve as tasks in the workflow. These callable objects can include functions, models, or any other Python objects that can be executed.
2. **Workflow Creation**: Create an instance of the **SequentialWorkflow** class. Specify the maximum number of loops the workflow should run and whether a dashboard should be displayed.
3. **Task Addition**: Add tasks to the workflow using the `add` method. Each task should be described using a human-readable description, and the associated flow (callable object) should be provided. Additional arguments and keyword arguments can be passed to the task.
4. **Task Execution**: Execute the workflow using the `run` method. The tasks within the workflow will be executed sequentially, with task results passed as inputs to subsequent tasks.
5. **Accessing Results**: After running the workflow, you can access the results of each task using the `get_task_results` method or by directly accessing the `result` attribute of each task.
6. **Optional Features**: Optionally, you can enable features such as autosaving of the workflow state and utilize the dashboard for real-time monitoring.
## Installation
Before using the Sequential Workflow library, you need to install it. You can install it via pip:
```bash
pip3 install --upgrade swarms
```
## Quick Start
Let's begin with a quick example to demonstrate how to create and run a Sequential Workflow. In this example, we'll create a workflow that generates a 10,000-word blog on "health and wellness" using an AI model and then summarizes the generated content.
```python
from swarms.models import OpenAIChat
from swarms.structs import Flow
from swarms.structs.sequential_workflow import SequentialWorkflow
# Initialize the language model flow (e.g., GPT-3)
llm = OpenAIChat(
openai_api_key="YOUR_API_KEY",
temperature=0.5,
max_tokens=3000,
)
# Initialize flows for individual tasks
flow1 = Flow(llm=llm, max_loops=1, dashboard=False)
flow2 = Flow(llm=llm, max_loops=1, dashboard=False)
# Create the Sequential Workflow
workflow = SequentialWorkflow(max_loops=1)
# Add tasks to the workflow
workflow.add("Generate a 10,000 word blog on health and wellness.", flow1)
workflow.add("Summarize the generated blog", flow2)
# Run the workflow
workflow.run()
# Output the results
for task in workflow.tasks:
print(f"Task: {task.description}, Result: {task.result}")
```
This quick example demonstrates the basic usage of the Sequential Workflow. It creates two tasks and executes them sequentially.
## Class: `Task`
### Description
The `Task` class represents an individual task in the workflow. A task is essentially a callable object, such as a function or a class, that can be executed sequentially. Tasks can have arguments and keyword arguments.
### Class Definition
```python
class Task:
def __init__(self, description: str, flow: Union[Callable, Flow], args: List[Any] = [], kwargs: Dict[str, Any] = {}, result: Any = None, history: List[Any] = [])
```
### Parameters
- `description` (str): A description of the task.
- `flow` (Union[Callable, Flow]): The callable object representing the task. It can be a function, class, or a `Flow` instance.
- `args` (List[Any]): A list of positional arguments to pass to the task when executed. Default is an empty list.
- `kwargs` (Dict[str, Any]): A dictionary of keyword arguments to pass to the task when executed. Default is an empty dictionary.
- `result` (Any): The result of the task's execution. Default is `None`.
- `history` (List[Any]): A list to store the historical results of the task. Default is an empty list.
### Methods
#### `execute()`
Execute the task.
```python
def execute(self):
```
This method executes the task and updates the `result` and `history` attributes of the task. It checks if the task is a `Flow` instance and if the 'task' argument is needed.
## Class: `SequentialWorkflow`
### Description
The `SequentialWorkflow` class is responsible for managing a sequence of tasks and executing them in a sequential order. It provides methods for adding tasks, running the workflow, and managing the state of the tasks.
### Class Definition
```python
class SequentialWorkflow:
def __init__(self, max_loops: int = 1, autosave: bool = False, saved_state_filepath: Optional[str] = "sequential_workflow_state.json", restore_state_filepath: Optional[str] = None, dashboard: bool = False, tasks: List[Task] = [])
```
### Parameters
- `max_loops` (int): The maximum number of times to run the workflow sequentially. Default is `1`.
- `autosave` (bool): Whether to enable autosaving of the workflow state. Default is `False`.
- `saved_state_filepath` (Optional[str]): The file path to save the workflow state when autosave is enabled. Default is `"sequential_workflow_state.json"`.
- `restore_state_filepath` (Optional[str]): The file path to restore the workflow state when initializing. Default is `None`.
- `dashboard` (bool): Whether to display a dashboard with workflow information. Default is `False`.
- `tasks` (List[Task]): A list of `Task` instances representing the tasks in the workflow. Default is an empty list.
### Methods
#### `add(task: str, flow: Union[Callable, Flow], *args, **kwargs)`
Add a task to the workflow.
```python
def add(self, task: str, flow: Union[Callable, Flow], *args, **kwargs) -> None:
```
This method adds a new task to the workflow. You can provide a description of the task, the callable object (function, class, or `Flow` instance), and any additional positional or keyword arguments required for the task.
#### `reset_workflow()`
Reset the workflow by clearing the results of each task.
```python
def reset_workflow(self) -> None:
```
This method clears the results of each task in the workflow, allowing you to start fresh without reinitializing the workflow.
#### `get_task_results()`
Get the results of each task in the workflow.
```python
def get_task_results(self) -> Dict[str, Any]:
```
This method returns a dictionary containing the results of each task in the workflow, where the keys are task descriptions, and the values are the corresponding results.
#### `remove_task(task_description: str)`
Remove a task from the workflow.
```python
def remove_task(self, task_description: str) -> None:
```
This method removes a specific task from the workflow based on its description.
#### `update_task(task_description: str, **updates)`
Update the arguments of a task in the workflow.
```python
def update_task(self, task_description: str, **updates) -> None:
```
This method allows you to update the arguments and keyword arguments of a task in the workflow. You specify the task's description and provide the updates as keyword arguments.
#### `save_workflow_state(filepath: Optional[str] = "sequential_workflow_state.json", **kwargs)`
Save the workflow state to a JSON file.
```python
def save_workflow_state(self, filepath: Optional[str] = "sequential_workflow_state.json", **kwargs) -> None:
```
This method saves the current state of the workflow, including the results and history of each task, to a JSON file. You can specify the file path for saving the state.
#### `load_workflow_state(filepath: str = None, **kwargs)`
Load the workflow state from a JSON file and restore the workflow state.
```python
def load_workflow_state(self, filepath: str = None, **kwargs) -> None:
```
This method loads a previously saved workflow state from a JSON file
and restores the state, allowing you to continue the workflow from where it was saved. You can specify the file path for loading the state.
#### `run()`
Run the workflow sequentially.
```python
def run(self) -> None:
```
This method executes the tasks in the workflow sequentially. It checks if a task is a `Flow` instance and handles the flow of data between tasks accordingly.
#### `arun()`
Asynchronously run the workflow.
```python
async def arun(self) -> None:
```
This method asynchronously executes the tasks in the workflow sequentially. It's suitable for use cases where asynchronous execution is required. It also handles data flow between tasks.
#### `workflow_bootup(**kwargs)`
Display a bootup message for the workflow.
```python
def workflow_bootup(self, **kwargs) -> None:
```
This method displays a bootup message when the workflow is initialized. You can customize the message by providing additional keyword arguments.
#### `workflow_dashboard(**kwargs)`
Display a dashboard for the workflow.
```python
def workflow_dashboard(self, **kwargs) -> None:
```
This method displays a dashboard with information about the workflow, such as the number of tasks, maximum loops, and autosave settings. You can customize the dashboard by providing additional keyword arguments.
## Examples
Let's explore some examples to illustrate how to use the Sequential Workflow library effectively.
Sure, I'll recreate the usage examples section for each method and use case using the provided foundation. Here are the examples:
### Example 1: Adding Tasks to a Sequential Workflow
In this example, we'll create a Sequential Workflow and add tasks to it.
```python
from swarms.models import OpenAIChat
from swarms.structs import Flow
from swarms.structs.sequential_workflow import SequentialWorkflow
# Example usage
api_key = (
"" # Your actual API key here
)
# Initialize the language flow
llm = OpenAIChat(
openai_api_key=api_key,
temperature=0.5,
max_tokens=3000,
)
# Initialize Flows for individual tasks
flow1 = Flow(llm=llm, max_loops=1, dashboard=False)
flow2 = Flow(llm=llm, max_loops=1, dashboard=False)
# Create the Sequential Workflow
workflow = SequentialWorkflow(max_loops=1)
# Add tasks to the workflow
workflow.add("Generate a 10,000 word blog on health and wellness.", flow1)
workflow.add("Summarize the generated blog", flow2)
# Output the list of tasks in the workflow
print("Tasks in the workflow:")
for task in workflow.tasks:
print(f"Task: {task.description}")
```
In this example, we create a Sequential Workflow and add two tasks to it.
### Example 2: Resetting a Sequential Workflow
In this example, we'll create a Sequential Workflow, add tasks to it, and then reset it.
```python
from swarms.models import OpenAIChat
from swarms.structs import Flow
from swarms.structs.sequential_workflow import SequentialWorkflow
# Example usage
api_key = (
"" # Your actual API key here
)
# Initialize the language flow
llm = OpenAIChat(
openai_api_key=api_key,
temperature=0.5,
max_tokens=3000,
)
# Initialize Flows for individual tasks
flow1 = Flow(llm=llm, max_loops=1, dashboard=False)
flow2 = Flow(llm=llm, max_loops=1, dashboard=False)
# Create the Sequential Workflow
workflow = SequentialWorkflow(max_loops=1)
# Add tasks to the workflow
workflow.add("Generate a 10,000 word blog on health and wellness.", flow1)
workflow.add("Summarize the generated blog", flow2)
# Reset the workflow
workflow.reset_workflow()
# Output the list of tasks in the workflow after resetting
print("Tasks in the workflow after resetting:")
for task in workflow.tasks:
print(f"Task: {task.description}")
```
In this example, we create a Sequential Workflow, add two tasks to it, and then reset the workflow, clearing all task results.
### Example 3: Getting Task Results from a Sequential Workflow
In this example, we'll create a Sequential Workflow, add tasks to it, run the workflow, and then retrieve the results of each task.
```python
from swarms.models import OpenAIChat
from swarms.structs import Flow
from swarms.structs.sequential_workflow import SequentialWorkflow
# Example usage
api_key = (
"" # Your actual API key here
)
# Initialize the language flow
llm = OpenAIChat(
openai_api_key=api_key,
temperature=0.5,
max_tokens=3000,
)
# Initialize Flows for individual tasks
flow1 = Flow(llm=llm, max_loops=1, dashboard=False)
flow2 = Flow(llm=llm, max_loops=1, dashboard=False)
# Create the Sequential Workflow
workflow = SequentialWorkflow(max_loops=1)
# Add tasks to the workflow
workflow.add("Generate a 10,000 word blog on health and wellness.", flow1)
workflow.add("Summarize the generated blog", flow2)
# Run the workflow
workflow.run()
# Get and display the results of each task in the workflow
results = workflow.get_task_results()
for task_description, result in results.items():
print(f"Task: {task_description}, Result: {result}")
```
In this example, we create a Sequential Workflow, add two tasks to it, run the workflow, and then retrieve and display the results of each task.
### Example 4: Removing a Task from a Sequential Workflow
In this example, we'll create a Sequential Workflow, add tasks to it, and then remove a specific task from the workflow.
```python
from swarms.models import OpenAIChat
from swarms.structs import Flow
from swarms.structs.sequential_workflow import SequentialWorkflow
# Example usage
api_key = (
"" # Your actual API key here
)
# Initialize the language flow
llm = OpenAIChat(
openai_api_key=api_key,
temperature=0.5,
max_tokens=3000,
)
# Initialize Flows for individual tasks
flow1 = Flow(llm=llm, max_loops=1, dashboard=False)
flow2 = Flow(llm=llm, max_loops=1, dashboard=False)
# Create the Sequential Workflow
workflow = SequentialWorkflow(max_loops=1)
# Add tasks to the workflow
workflow.add("Generate a 10,000 word blog on health and wellness.", flow1)
workflow.add("Summarize the generated blog", flow2)
# Remove a specific task from the workflow
workflow.remove_task("Generate a 10,000 word blog on health and wellness.")
# Output the list of tasks in the workflow after removal
print("Tasks in the workflow after removing a task:")
for task in workflow.tasks:
print(f"Task: {task.description}")
```
In this example, we create a Sequential Workflow, add two tasks to it, and then remove a specific task from the workflow.
### Example 5: Updating Task Arguments in a Sequential Workflow
In this example, we'll create a Sequential Workflow, add tasks to it, and then update the arguments of a specific task in the workflow.
```python
from swarms.models import OpenAIChat
from swarms.structs import Flow
from swarms.structs.sequential_workflow import SequentialWorkflow
# Example usage
api_key = (
"" # Your actual API key here
)
# Initialize the language flow
llm = OpenAIChat(
openai_api_key=api_key,
temperature=0.5,
max_tokens=3000,
)
# Initialize Flows for individual tasks
flow1 = Flow(llm=llm, max_loops=1, dashboard=False)
flow2 = Flow(llm=llm, max_loops=1, dashboard=False)
# Create the Sequential Workflow
workflow = SequentialWorkflow(max_loops=1)
# Add tasks to the workflow
workflow.add("Generate a 10,000 word blog on health and wellness.", flow1)
workflow.add("Summarize the generated blog", flow2)
# Update the arguments of a specific task in the workflow
workflow.update_task("Generate a 10,000 word blog on health and wellness.", max_loops=2)
# Output the list of tasks in the workflow after updating task arguments
print("Tasks in the workflow after updating task arguments:")
for task in workflow.tasks:
print(f"Task: {task.description}, Arguments: {
task.arguments}")
```
In this example, we create a Sequential Workflow, add two tasks to it, and then update the arguments of a specific task in the workflow.
These examples demonstrate various operations and use cases for working with a Sequential Workflow.
# Why `SequentialWorkflow`?
## Enhancing Autonomous Agent Development
The development of autonomous agents, whether they are conversational AI, robotic systems, or any other AI-driven application, often involves complex workflows that require a sequence of tasks to be executed in a specific order. Managing and orchestrating these tasks efficiently is crucial for building reliable and effective agents. The Sequential Workflow module serves as a valuable tool for AI engineers in achieving this goal.
## Reliability and Coordination
One of the primary challenges in autonomous agent development is ensuring that tasks are executed in the correct sequence and that the results of one task can be used as inputs for subsequent tasks. The Sequential Workflow module simplifies this process by allowing AI engineers to define and manage workflows in a structured and organized manner.
By using the Sequential Workflow module, AI engineers can achieve the following benefits:
### 1. Improved Reliability
Reliability is a critical aspect of autonomous agents. The ability to handle errors gracefully and recover from failures is essential for building robust systems. The Sequential Workflow module offers a systematic approach to task execution, making it easier to handle errors, retry failed tasks, and ensure that the agent continues to operate smoothly.
### 2. Task Coordination
Coordinating tasks in the correct order is essential for achieving the desired outcome. The Sequential Workflow module enforces task sequencing, ensuring that each task is executed only when its dependencies are satisfied. This eliminates the risk of executing tasks out of order, which can lead to incorrect results.
### 3. Code Organization
Managing complex workflows can become challenging without proper organization. The Sequential Workflow module encourages AI engineers to structure their code in a modular and maintainable way. Each task can be encapsulated as a separate unit, making it easier to understand, modify, and extend the agent's behavior.
### 4. Workflow Visualization
Visualization is a powerful tool for understanding and debugging workflows. The Sequential Workflow module can be extended to include a visualization dashboard, allowing AI engineers to monitor the progress of tasks, track results, and identify bottlenecks or performance issues.
## TODO: Future Features
While the Sequential Workflow module offers significant advantages, there are opportunities for further enhancement. Here is a list of potential features and improvements that can be added to make it even more versatile and adaptable for various AI engineering tasks:
### 1. Asynchronous Support
Adding support for asynchronous task execution can improve the efficiency of workflows, especially when dealing with tasks that involve waiting for external events or resources.
### 2. Context Managers
Introducing context manager support for tasks can simplify resource management, such as opening and closing files, database connections, or network connections within a task's context.
### 3. Workflow History
Maintaining a detailed history of workflow execution, including timestamps, task durations, and input/output data, can facilitate debugging and performance analysis.
### 4. Parallel Processing
Enhancing the module to support parallel processing with a pool of workers can significantly speed up the execution of tasks, especially for computationally intensive workflows.
### 5. Error Handling Strategies
Providing built-in error handling strategies, such as retries, fallbacks, and custom error handling functions, can make the module more robust in handling unexpected failures.
## Conclusion
The Sequential Workflow module is a valuable tool for AI engineers working on autonomous agents and complex AI-driven applications. It offers a structured and reliable approach to defining and executing workflows, ensuring that tasks are performed in the correct sequence. By using this module, AI engineers can enhance the reliability, coordination, and maintainability of their agents.
As the field of AI continues to evolve, the demand for efficient workflow management tools will only increase. The Sequential Workflow module is a step towards meeting these demands and empowering AI engineers to create more reliable and capable autonomous agents. With future enhancements and features, it has the potential to become an indispensable asset in the AI engineer's toolkit.
In summary, the Sequential Workflow module provides a foundation for orchestrating complex tasks and workflows, enabling AI engineers to focus on designing intelligent agents that can perform tasks with precision and reliability.
## Frequently Asked Questions (FAQs)
### Q1: What is the difference between a task and a flow in Sequential Workflows?
**A1:** In Sequential Workflows, a **task** refers to a specific unit of work that needs to be executed. It can be implemented as a callable object, such as a Python function, and is the fundamental building block of a workflow.
A **flow**, on the other hand, is an encapsulation of a task within the workflow. Flows define the order in which tasks are executed and can be thought of as task containers. They allow you to specify dependencies, error handling, and other workflow-related configurations.
### Q2: Can I run tasks in parallel within a Sequential Workflow?
**A2:** Yes, you can run tasks in parallel within a Sequential Workflow by using parallel execution techniques. This advanced feature allows you to execute multiple tasks concurrently, improving performance and efficiency. You can explore this feature further in the guide's section on "Parallel Execution."
### Q3: How do I handle errors within Sequential Workflows?
**A3:** Error handling within Sequential Workflows can be implemented by adding error-handling logic within your task functions. You can catch exceptions and handle errors gracefully, ensuring that your workflow can recover from unexpected scenarios. The guide also covers more advanced error handling strategies, such as retrying failed tasks and handling specific error types.
### Q4: What are some real-world use cases for Sequential Workflows?
**A4:** Sequential Workflows can be applied to a wide range of real-world use cases, including:
- **Data ETL (Extract, Transform, Load) Processes:** Automating data pipelines that involve data extraction, transformation, and loading into databases or data warehouses.
- **Batch Processing:** Running batch jobs that process large volumes of data or perform data analysis.
- **Automation of DevOps Tasks:** Streamlining DevOps processes such as deployment, provisioning, and monitoring.
- **Cross-system Integrations:** Automating interactions between different systems, services, or APIs.
- **Report Generation:** Generating reports and documents automatically based on data inputs.
- **Workflow Orchestration:** Orchestrating complex workflows involving multiple steps and dependencies.
- **Resource Provisioning:** Automatically provisioning and managing cloud resources.
These are just a few examples, and Sequential Workflows can be tailored to various automation needs across industries.

@ -1,24 +1,39 @@
from swarms.models import OpenAIChat from swarms.models import OpenAIChat
from swarms import Worker from swarms.structs import Flow
from swarms.prompts import PRODUCT_AGENT_PROMPT
api_key = "" api_key = ""
# Initialize the language model, this model can be swapped out with Anthropic, ETC, Huggingface Models like Mistral, ETC
llm = OpenAIChat( llm = OpenAIChat(
# model_name="gpt-4"
openai_api_key=api_key, openai_api_key=api_key,
temperature=0.5, temperature=0.5,
# max_tokens=100,
) )
node = Worker(
## Initialize the workflow
flow = Flow(
llm=llm, llm=llm,
ai_name="Optimus Prime", max_loops=5,
openai_api_key=api_key, dashboard=True,
ai_role=PRODUCT_AGENT_PROMPT, # tools = [search_api, slack, ]
external_tools=None, # stopping_condition=None, # You can define a stopping condition as needed.
human_in_the_loop=False, # loop_interval=1,
temperature=0.5, # retry_attempts=3,
# retry_interval=1,
# interactive=False, # Set to 'True' for interactive mode.
# dynamic_temperature=False, # Set to 'True' for dynamic temperature handling.
) )
task = "Locate 5 trending topics on healthy living, locate a website like NYTimes, and then generate an image of people doing those topics." # out = flow.load_state("flow_state.json")
response = node.run(task) # temp = flow.dynamic_temperature()
print(response) # filter = flow.add_response_filter("Trump")
out = flow.run(
"Generate a 10,000 word blog on mental clarity and the benefits of meditation."
)
# out = flow.validate_response(out)
# out = flow.analyze_feedback(out)
# out = flow.print_history_and_memory()
# # out = flow.save_state("flow_state.json")
# print(out)

@ -1,35 +0,0 @@
from swarms.models import OpenAIChat
from swarms.structs import Flow
api_key = ""
# Initialize the language model, this model can be swapped out with Anthropic, ETC, Huggingface Models like Mistral, ETC
llm = OpenAIChat(
openai_api_key=api_key,
temperature=0.5,
max_tokens=3000,
)
# Initialize the flow
flow = Flow(
llm=llm,
max_loops=5,
dashboard=True,
)
flow = Flow(
llm=llm,
max_loops=5,
dashboard=True,
# stopping_condition=None, # You can define a stopping condition as needed.
# loop_interval=1,
# retry_attempts=3,
# retry_interval=1,
# interactive=False, # Set to 'True' for interactive mode.
# dynamic_temperature=False, # Set to 'True' for dynamic temperature handling.
)
out = flow.run("Generate a 10,000 word blog on health and wellness.")
print(out)

@ -1,16 +0,0 @@
from swarms.swarms import GodMode
from swarms.models import OpenAIChat
api_key = ""
llm = OpenAIChat(openai_api_key=api_key)
llms = [llm, llm, llm]
god_mode = GodMode(llms)
task = "Generate a 10,000 word blog on health and wellness."
out = god_mode.run(task)
god_mode.print_responses(task)

@ -1,109 +1,49 @@
# from swarms.structs import Flow from swarms import OpenAI, Flow
# from swarms.models import OpenAIChat from swarms.swarms.groupchat import GroupChatManager, GroupChat
# from swarms.swarms.groupchat import GroupChat
# from swarms.agents import SimpleAgent
# api_key = ""
# llm = OpenAIChat( api_key = ""
# openai_api_key=api_key,
# )
# agent1 = SimpleAgent("Captain Price", Flow(llm=llm, max_loops=4)) llm = OpenAI(
# agent2 = SimpleAgent("John Mactavis", Flow(llm=llm, max_loops=4))
# # Create a groupchat with the 2 agents
# chat = GroupChat([agent1, agent2])
# # Assign duties to the agents
# chat.assign_duty(agent1.name, "Buy the groceries")
# chat.assign_duty(agent2.name, "Clean the house")
# # Initate a chat
# response = chat.run("Captain Price", "Hello, how are you John?")
# print(response)
from swarms.models import OpenAIChat
from swarms.structs import Flow
import random
api_key = "" # Your API Key here
class GroupChat:
"""
GroupChat class that facilitates agent-to-agent communication using multiple instances of the Flow class.
"""
def __init__(self, agents: list):
self.agents = {f"agent_{i}": agent for i, agent in enumerate(agents)}
self.message_log = []
def add_agent(self, agent: Flow):
agent_id = f"agent_{len(self.agents)}"
self.agents[agent_id] = agent
def remove_agent(self, agent_id: str):
if agent_id in self.agents:
del self.agents[agent_id]
def send_message(self, sender_id: str, recipient_id: str, message: str):
if sender_id not in self.agents or recipient_id not in self.agents:
raise ValueError("Invalid sender or recipient ID.")
formatted_message = f"{sender_id} to {recipient_id}: {message}"
self.message_log.append(formatted_message)
recipient_agent = self.agents[recipient_id]
recipient_agent.run(message)
def broadcast_message(self, sender_id: str, message: str):
for agent_id, agent in self.agents.items():
if agent_id != sender_id:
self.send_message(sender_id, agent_id, message)
def get_message_log(self):
return self.message_log
class EnhancedGroupChatV2(GroupChat):
def __init__(self, agents: list):
super().__init__(agents)
def multi_round_conversation(self, rounds: int = 5):
"""
Initiate a multi-round conversation between agents.
Args:
rounds (int): The number of rounds of conversation.
"""
for _ in range(rounds):
# Randomly select a sender and recipient agent for the conversation
sender_id = random.choice(list(self.agents.keys()))
recipient_id = random.choice(list(self.agents.keys()))
while recipient_id == sender_id: # Ensure the recipient is not the sender
recipient_id = random.choice(list(self.agents.keys()))
# Generate a message (for simplicity, a generic message is used)
message = f"Hello {recipient_id}, how are you today?"
self.send_message(sender_id, recipient_id, message)
# Sample usage with EnhancedGroupChatV2
# Initialize the language model
llm = OpenAIChat(
openai_api_key=api_key, openai_api_key=api_key,
temperature=0.5, temperature=0.5,
max_tokens=3000, max_tokens=3000,
) )
# Initialize two Flow agents # Initialize the flow
agent1 = Flow(llm=llm, max_loops=5, dashboard=True) flow1 = Flow(
agent2 = Flow(llm=llm, max_loops=5, dashboard=True) llm=llm,
max_loops=1,
system_message="YOU ARE SILLY, YOU OFFER NOTHING OF VALUE",
name="silly",
dashboard=True,
)
flow2 = Flow(
llm=llm,
max_loops=1,
system_message="YOU ARE VERY SMART AND ANSWER RIDDLES",
name="detective",
dashboard=True,
)
flow3 = Flow(
llm=llm,
max_loops=1,
system_message="YOU MAKE RIDDLES",
name="riddler",
dashboard=True,
)
manager = Flow(
llm=llm,
max_loops=1,
system_message="YOU ARE A GROUP CHAT MANAGER",
name="manager",
dashboard=True,
)
# Create an enhanced group chat with the two agents
enhanced_group_chat_v2 = EnhancedGroupChatV2(agents=[agent1, agent2])
# Simulate multi-round agent to agent communication # Example usage:
enhanced_group_chat_v2.multi_round_conversation(rounds=5) agents = [flow1, flow2, flow3]
enhanced_group_chat_v2.get_message_log() # Get the conversation log group_chat = GroupChat(agents=agents, messages=[], max_round=10)
chat_manager = GroupChatManager(groupchat=group_chat, selector=manager)
chat_history = chat_manager("Write me a riddle")

@ -61,26 +61,13 @@ nav:
- Home: - Home:
- Overview: "index.md" - Overview: "index.md"
- Contributing: "contributing.md" - Contributing: "contributing.md"
- FAQ: "faq.md"
- Purpose: "purpose.md"
- Roadmap: "roadmap.md"
- Weaknesses: "failures.md"
- Design: "design.md"
- Flywheel: "flywheel.md"
- Bounties: "bounties.md"
- Metric: "metric.md"
- Distribution: "distribution"
- Research: "research.md"
- Demos: "demos.md"
- Architecture: "architecture.md"
- Checklist: "checklist.md"
- Hiring: "hiring.md"
- Swarms: - Swarms:
- Overview: "swarms/index.md" - Overview: "swarms/index.md"
- swarms.swarms: - swarms.swarms:
- AbstractSwarm: "swarms/swarms/abstractswarm.md" - AbstractSwarm: "swarms/swarms/abstractswarm.md"
- AutoScaler: "swarms/swarms/autoscaler.md" - AutoScaler: "swarms/swarms/autoscaler.md"
- GodMode: "swarms/swarms/godmode.md" - GodMode: "swarms/swarms/godmode.md"
- Groupchat: "swarms/swarms/groupchat.md"
- swarms.workers: - swarms.workers:
- AbstractWorker: "swarms/workers/base.md" - AbstractWorker: "swarms/workers/base.md"
- Overview: "swarms/workers/index.md" - Overview: "swarms/workers/index.md"
@ -105,28 +92,45 @@ nav:
- BingChat: "swarms/models/bingchat.md" - BingChat: "swarms/models/bingchat.md"
- Kosmos: "swarms/models/kosmos.md" - Kosmos: "swarms/models/kosmos.md"
- Nougat: "swarms/models/nougat.md" - Nougat: "swarms/models/nougat.md"
- Dalle3: "swarms/models/dalle3.md"
- GPT4V: "swarms/models/gpt4v.md"
- LayoutLMDocumentQA: "swarms/models/layoutlm_document_qa.md" - LayoutLMDocumentQA: "swarms/models/layoutlm_document_qa.md"
- DistilWhisperModel: "swarms/models/distilled_whisperx.md"
- swarms.structs: - swarms.structs:
- Overview: "swarms/structs/overview.md" - Overview: "swarms/structs/overview.md"
- Workflow: "swarms/structs/workflow.md" - Workflow: "swarms/structs/workflow.md"
- Flow: "swarms/structs/flow.md" - Flow: "swarms/structs/flow.md"
- SequentialWorkflow: 'swarms/structs/sequential_workflow.md'
- swarms.memory: - swarms.memory:
- PineconeVectorStoreStore: "swarms/memory/pinecone.md" - PineconeVectorStoreStore: "swarms/memory/pinecone.md"
- PGVectorStore: "swarms/memory/pg.md" - PGVectorStore: "swarms/memory/pg.md"
- swarms.chunkers: - swarms.chunkers:
- BaseChunker: "swarms/chunkers/basechunker.md" - BaseChunker: "swarms/chunkers/basechunker.md"
- PdfChunker: "swarms/chunkers/pdf_chunker.md" - PdfChunker: "swarms/chunkers/pdf_chunker.md"
- Walkthroughs: - Guides:
- Overview: "examples/index.md" - Overview: "examples/index.md"
- Structs:
- Flow: "examples/flow.md"
- Agents: - Agents:
- Flow: "examples/flow.md"
- SequentialWorkflow: "examples/reliable_autonomous_agents.md"
- OmniAgent: "examples/omni_agent.md" - OmniAgent: "examples/omni_agent.md"
- Worker: - 2O+ Autonomous Agent Blogs: "examples/ideas.md"
- Basic: "examples/worker.md"
- StackedWorker: "examples/stacked_worker.md"
- Applications: - Applications:
- CustomerSupport: - CustomerSupport:
- Overview: "applications/customer_support.md" - Overview: "applications/customer_support.md"
- Marketing: - Marketing:
- Overview: "applications/marketing_agencies.md" - Overview: "applications/marketing_agencies.md"
- Corporate:
- FAQ: "corporate/faq.md"
- Purpose: "corporate/purpose.md"
- Roadmap: "corporate/roadmap.md"
- Weaknesses: "corporate/failures.md"
- Design: "corporate/design.md"
- Flywheel: "corporate/flywheel.md"
- Bounties: "corporate/bounties.md"
- Metric: "corporate/metric.md"
- Distribution: "corporate/distribution"
- Research: "corporate/research.md"
- Demos: "corporate/demos.md"
- Architecture: "corporate/architecture.md"
- Checklist: "corporate/checklist.md"
- Hiring: "corporate/hiring.md"

@ -0,0 +1,30 @@
from swarms.structs import Flow
from swarms.models import Idefics
# Multi Modality Auto Agent
llm = Idefics(max_length=2000)
task = "User: What is in this image? https://upload.wikimedia.org/wikipedia/commons/8/86/Id%C3%A9fix.JPG"
## Initialize the workflow
flow = Flow(
llm=llm,
max_loops=2,
dashboard=True,
# stopping_condition=None, # You can define a stopping condition as needed.
# loop_interval=1,
# retry_attempts=3,
# retry_interval=1,
# interactive=False, # Set to 'True' for interactive mode.
# dynamic_temperature=False, # Set to 'True' for dynamic temperature handling.
)
# out = flow.load_state("flow_state.json")
# temp = flow.dynamic_temperature()
# filter = flow.add_response_filter("Trump")
out = flow.run(task)
# out = flow.validate_response(out)
# out = flow.analyze_feedback(out)
# out = flow.print_history_and_memory()
# # out = flow.save_state("flow_state.json")
# print(out)

@ -0,0 +1,6 @@
from swarms.models.dalle3 import Dalle3
model = Dalle3()
task = "A painting of a dog"
img = model(task)

@ -0,0 +1,7 @@
from swarms.models.gpt4v import GPT4Vision
gpt4vision = GPT4Vision(api_key="")
task = "What is the following image about?"
img = "https://cdn.openai.com/dall-e/encoded/feats/feats_01J9J5ZKJZJY9.png"
answer = gpt4vision.run(task, img)

@ -1,56 +0,0 @@
from swarms.models import OpenAIChat # Replace with your actual OpenAIChat import
if __name__ == "__main__":
api_key = "" # Your OpenAI API key here
agent = MultiTempAgent(api_key)
prompt = "Write a blog post about health and wellness"
final_output = agent.run(prompt)
print("Final chosen output:")
print(final_output)
class MultiTempAgent:
def __init__(self, api_key, default_temp=0.5, alt_temps=[0.2, 0.7, 0.9]):
self.api_key = api_key
self.default_temp = default_temp
self.alt_temps = alt_temps
def ask_user_feedback(self, text):
print(f"Generated text: {text}")
feedback = input("Are you satisfied with this output? (yes/no): ")
return feedback.lower() == "yes"
def present_options_to_user(self, outputs):
print("Alternative outputs:")
for temp, output in outputs.items():
print(f"Temperature {temp}: {output}")
chosen_temp = float(input("Choose the temperature of the output you like: "))
return outputs.get(chosen_temp, "Invalid temperature chosen.")
def run(self, prompt):
try:
llm = OpenAIChat(openai_api_key=self.api_key, temperature=self.default_temp)
initial_output = llm(prompt) # Using llm as a callable
except Exception as e:
print(f"Error generating initial output: {e}")
initial_output = None
user_satisfied = self.ask_user_feedback(initial_output)
if user_satisfied:
return initial_output
else:
outputs = {}
for temp in self.alt_temps:
try:
llm = OpenAIChat(
openai_api_key=self.api_key, temperature=temp
) # Re-initializing
outputs[temp] = llm(prompt) # Using llm as a callable
except Exception as e:
print(f"Error generating text at temperature {temp}: {e}")
outputs[temp] = None
chosen_output = self.present_options_to_user(outputs)
return chosen_output

@ -2,5 +2,5 @@ from swarms.models.openai_models import OpenAIChat
openai = OpenAIChat(openai_api_key="", verbose=False) openai = OpenAIChat(openai_api_key="", verbose=False)
chat = openai("Are quantum fields everywhere?") chat = openai("What are quantum fields?")
print(chat) print(chat)

@ -0,0 +1,35 @@
from swarms.models import OpenAIChat
from swarms.structs import Flow
api_key = ""
# Initialize the language model, this model can be swapped out with Anthropic, ETC, Huggingface Models like Mistral, ETC
llm = OpenAIChat(
# model_name="gpt-4"
openai_api_key=api_key,
temperature=0.5,
# max_tokens=100,
)
## Initialize the workflow
flow = Flow(
llm=llm,
max_loops=2,
dashboard=True,
# stopping_condition=None, # You can define a stopping condition as needed.
# loop_interval=1,
# retry_attempts=3,
# retry_interval=1,
# interactive=False, # Set to 'True' for interactive mode.
# dynamic_temperature=False, # Set to 'True' for dynamic temperature handling.
)
# out = flow.load_state("flow_state.json")
# temp = flow.dynamic_temperature()
# filter = flow.add_response_filter("Trump")
out = flow.run("Generate a 10,000 word blog on health and wellness.")
# out = flow.validate_response(out)
# out = flow.analyze_feedback(out)
# out = flow.print_history_and_memory()
# # out = flow.save_state("flow_state.json")
# print(out)

@ -0,0 +1,31 @@
from swarms.models import OpenAIChat
from swarms.structs import Flow
from swarms.structs.sequential_workflow import SequentialWorkflow
# Example usage
llm = OpenAIChat(
temperature=0.5,
max_tokens=3000,
)
# Initialize the Flow with the language flow
flow1 = Flow(llm=llm, max_loops=1, dashboard=False)
# Create another Flow for a different task
flow2 = Flow(llm=llm, max_loops=1, dashboard=False)
# Create the workflow
workflow = SequentialWorkflow(max_loops=1)
# Add tasks to the workflow
workflow.add("Generate a 10,000 word blog on health and wellness.", flow1)
# Suppose the next task takes the output of the first task as input
workflow.add("Summarize the generated blog", flow2)
# Run the workflow
workflow.run()
# Output the results
for task in workflow.tasks:
print(f"Task: {task.description}, Result: {task.result}")

@ -1,39 +1,16 @@
from swarms.swarms import GodMode
from swarms.models import OpenAIChat from swarms.models import OpenAIChat
from swarms.swarms import GodMode api_key = ""
from swarms.workers.worker import Worker
llm = OpenAIChat(openai_api_key=api_key)
llm = OpenAIChat(model_name="gpt-4", openai_api_key="api-key", temperature=0.5)
worker1 = Worker( llms = [llm, llm, llm]
llm=llm,
ai_name="Bumble Bee",
ai_role="Worker in a swarm",
external_tools=None,
human_in_the_loop=False,
temperature=0.5,
)
worker2 = Worker(
llm=llm,
ai_name="Optimus Prime",
ai_role="Worker in a swarm",
external_tools=None,
human_in_the_loop=False,
temperature=0.5,
)
worker3 = Worker(
llm=llm,
ai_name="Megatron",
ai_role="Worker in a swarm",
external_tools=None,
human_in_the_loop=False,
temperature=0.5,
)
# Usage
agents = [worker1, worker2, worker3]
god_mode = GodMode(agents) god_mode = GodMode(llms)
task = "What are the biggest risks facing humanity?" task = "Generate a 10,000 word blog on health and wellness."
out = god_mode.run(task)
god_mode.print_responses(task) god_mode.print_responses(task)

@ -1,61 +1,49 @@
from swarms.models import OpenAIChat from swarms import OpenAI, Flow
from swarms.swarms import GroupChat, GroupChatManager from swarms.swarms.groupchat import GroupChatManager, GroupChat
from swarms.workers import Worker
llm = OpenAIChat(model_name="gpt-4", openai_api_key="api-key", temperature=0.5)
node = Worker( api_key = ""
llm=llm,
ai_name="Optimus Prime", llm = OpenAI(
ai_role="Worker in a swarm", openai_api_key=api_key,
external_tools=None,
human_in_the_loop=False,
temperature=0.5, temperature=0.5,
max_tokens=3000,
) )
node2 = Worker( # Initialize the flow
flow1 = Flow(
llm=llm, llm=llm,
ai_name="Optimus Prime", max_loops=1,
ai_role="Worker in a swarm", system_message="YOU ARE SILLY, YOU OFFER NOTHING OF VALUE",
external_tools=None, name="silly",
human_in_the_loop=False, dashboard=True,
temperature=0.5,
) )
flow2 = Flow(
node3 = Worker(
llm=llm, llm=llm,
ai_name="Optimus Prime", max_loops=1,
ai_role="Worker in a swarm", system_message="YOU ARE VERY SMART AND ANSWER RIDDLES",
external_tools=None, name="detective",
human_in_the_loop=False, dashboard=True,
temperature=0.5,
) )
flow3 = Flow(
nodes = [node, node2, node3] llm=llm,
max_loops=1,
messages = [ system_message="YOU MAKE RIDDLES",
{ name="riddler",
"role": "system", dashboard=True,
"context": "Create an a small feedforward in pytorch",
}
]
group = GroupChat(
workers=nodes,
messages=messages,
max_rounds=3,
) )
manager = Flow(
llm=llm,
manager = GroupChatManager( max_loops=1,
groupchat=group, system_message="YOU ARE A GROUP CHAT MANAGER",
max_consecutive_auto_reply=3, name="manager",
dashboard=True,
) )
output = group.run(
messages,
sender=node,
config=group,
)
print(output) # Example usage:
agents = [flow1, flow2, flow3]
group_chat = GroupChat(agents=agents, messages=[], max_round=10)
chat_manager = GroupChatManager(groupchat=group_chat, selector=manager)
chat_history = chat_manager("Write me a riddle")

@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
[tool.poetry] [tool.poetry]
name = "swarms" name = "swarms"
version = "1.9.3" version = "2.0.2"
description = "Swarms - Pytorch" description = "Swarms - Pytorch"
license = "MIT" license = "MIT"
authors = ["Kye Gomez <kye@apac.ai>"] authors = ["Kye Gomez <kye@apac.ai>"]
@ -28,7 +28,6 @@ openai = "*"
langchain = "*" langchain = "*"
asyncio = "*" asyncio = "*"
nest_asyncio = "*" nest_asyncio = "*"
pegasusx = "*"
einops = "*" einops = "*"
google-generativeai = "*" google-generativeai = "*"
torch = "*" torch = "*"
@ -42,17 +41,15 @@ sentencepiece = "*"
wget = "*" wget = "*"
griptape = "*" griptape = "*"
httpx = "*" httpx = "*"
tiktoken = "*"
attrs = "*" attrs = "*"
ggl = "*" ggl = "*"
beautifulsoup4 = "*" beautifulsoup4 = "*"
huggingface-hub = "*" huggingface-hub = "*"
pydantic = "*" pydantic = "*"
tenacity = "*" tenacity = "*"
redis = "*"
Pillow = "*" Pillow = "*"
chromadb = "*" chromadb = "*"
agent-protocol = "*"
open-interpreter = "*"
tabulate = "*" tabulate = "*"
termcolor = "*" termcolor = "*"
black = "*" black = "*"

@ -29,6 +29,7 @@ sentencepiece
duckduckgo-search duckduckgo-search
agent-protocol agent-protocol
chromadb chromadb
tiktoken
open-interpreter open-interpreter
tabulate tabulate
colored colored

@ -0,0 +1,35 @@
from swarms.models import OpenAIChat
from swarms.structs import Flow
from swarms.structs.sequential_workflow import SequentialWorkflow
# Example usage
api_key = "" # Your actual API key here
# Initialize the language flow
llm = OpenAIChat(
openai_api_key=api_key,
temperature=0.5,
max_tokens=3000,
)
# Initialize the Flow with the language flow
flow1 = Flow(llm=llm, max_loops=1, dashboard=False)
# Create another Flow for a different task
flow2 = Flow(llm=llm, max_loops=1, dashboard=False)
# Create the workflow
workflow = SequentialWorkflow(max_loops=1)
# Add tasks to the workflow
workflow.add("Generate a 10,000 word blog on health and wellness.", flow1)
# Suppose the next task takes the output of the first task as input
workflow.add("Summarize the generated blog", flow2)
# Run the workflow
workflow.run()
# Output the results
for task in workflow.tasks:
print(f"Task: {task.description}, Result: {task.result}")

@ -1,10 +1,12 @@
from swarms.agents.omni_modal_agent import OmniModalAgent from swarms.agents.omni_modal_agent import OmniModalAgent
from swarms.agents.hf_agents import HFAgent from swarms.agents.hf_agents import HFAgent
from swarms.agents.message import Message from swarms.agents.message import Message
# from swarms.agents.stream_response import stream # from swarms.agents.stream_response import stream
from swarms.agents.base import AbstractAgent from swarms.agents.base import AbstractAgent
from swarms.agents.registry import Registry from swarms.agents.registry import Registry
from swarms.agents.idea_to_image_agent import Idea2Image
# from swarms.agents.idea_to_image_agent import Idea2Image
from swarms.agents.simple_agent import SimpleAgent from swarms.agents.simple_agent import SimpleAgent
@ -16,6 +18,6 @@ __all__ = [
"Message", "Message",
"AbstractAgent", "AbstractAgent",
"Registry", "Registry",
"Idea2Image", # "Idea2Image",
"SimpleAgent", "SimpleAgent",
] ]

@ -0,0 +1,4 @@
"""
Companion agents converse with the user about the agent the user wants to create then creates the agent with the desired attributes and traits and tools and configurations
"""

@ -1,7 +1,7 @@
import os import os
import logging import logging
from dataclasses import dataclass from dataclasses import dataclass
from dalle3 import Dalle from swarms.models.dalle3 import Dalle
from swarms.models import OpenAIChat from swarms.models import OpenAIChat

@ -16,7 +16,6 @@ from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import Chroma from langchain.vectorstores import Chroma
from pydantic import BaseModel, Field from pydantic import BaseModel, Field
from swarms.prompts.sales import SALES_AGENT_TOOLS_PROMPT, conversation_stages from swarms.prompts.sales import SALES_AGENT_TOOLS_PROMPT, conversation_stages
from swarms.tools.interpreter_tool import compile
# classes # classes
@ -166,12 +165,7 @@ def get_tools(product_catalog):
func=knowledge_base.run, func=knowledge_base.run,
description="useful for when you need to answer questions about product information", description="useful for when you need to answer questions about product information",
), ),
# Interpreter
Tool(
name="Code Interepeter",
func=compile,
description="Useful when you need to run code locally, such as Python, Javascript, Shell, and more.",
)
# omnimodal agent # omnimodal agent
] ]

@ -1,10 +1,13 @@
from __future__ import annotations from __future__ import annotations
from abc import ABC from abc import ABC
from typing import Optional from typing import Optional
from attr import define, field, Factory
from attr import Factory, define, field
from griptape.artifacts import TextArtifact from griptape.artifacts import TextArtifact
from swarms.chunkers.chunk_seperators import ChunkSeparator
from griptape.tokenizers import OpenAiTokenizer from swarms.chunkers.chunk_seperator import ChunkSeparator
from swarms.models.openai_tokenizer import OpenAITokenizer
@define @define
@ -16,6 +19,24 @@ class BaseChunker(ABC):
Usage: Usage:
-------------- --------------
from swarms.chunkers.base import BaseChunker
from swarms.chunkers.chunk_seperator import ChunkSeparator
class PdfChunker(BaseChunker):
DEFAULT_SEPARATORS = [
ChunkSeparator("\n\n"),
ChunkSeparator(". "),
ChunkSeparator("! "),
ChunkSeparator("? "),
ChunkSeparator(" "),
]
# Example
pdf = "swarmdeck.pdf"
chunker = PdfChunker()
chunks = chunker.chunk(pdf)
print(chunks)
""" """
@ -26,10 +47,10 @@ class BaseChunker(ABC):
default=Factory(lambda self: self.DEFAULT_SEPARATORS, takes_self=True), default=Factory(lambda self: self.DEFAULT_SEPARATORS, takes_self=True),
kw_only=True, kw_only=True,
) )
tokenizer: OpenAiTokenizer = field( tokenizer: OpenAITokenizer = field(
default=Factory( default=Factory(
lambda: OpenAiTokenizer( lambda: OpenAITokenizer(
model=OpenAiTokenizer.DEFAULT_OPENAI_GPT_3_CHAT_MODEL model=OpenAITokenizer.DEFAULT_OPENAI_GPT_3_CHAT_MODEL
) )
), ),
kw_only=True, kw_only=True,
@ -47,7 +68,7 @@ class BaseChunker(ABC):
def _chunk_recursively( def _chunk_recursively(
self, chunk: str, current_separator: Optional[ChunkSeparator] = None self, chunk: str, current_separator: Optional[ChunkSeparator] = None
) -> list[str]: ) -> list[str]:
token_count = self.tokenizer.token_count(chunk) token_count = self.tokenizer.count_tokens(chunk)
if token_count <= self.max_tokens: if token_count <= self.max_tokens:
return [chunk] return [chunk]

@ -15,3 +15,10 @@ class MarkdownChunker(BaseChunker):
ChunkSeparator("? "), ChunkSeparator("? "),
ChunkSeparator(" "), ChunkSeparator(" "),
] ]
# # Example using chunker to chunk a markdown file
# file = open("README.md", "r")
# text = file.read()
# chunker = MarkdownChunker()
# chunks = chunker.chunk(text)

@ -0,0 +1,124 @@
"""
Omni Chunker is a chunker that chunks all files into select chunks of size x strings
Usage:
--------------
from swarms.chunkers.omni_chunker import OmniChunker
# Example
pdf = "swarmdeck.pdf"
chunker = OmniChunker(chunk_size=1000, beautify=True)
chunks = chunker(pdf)
print(chunks)
"""
from dataclasses import dataclass
from typing import List, Optional, Callable
from termcolor import colored
import os
import sys
@dataclass
class OmniChunker:
"""
"""
chunk_size: int = 1000
beautify: bool = False
use_tokenizer: bool = False
tokenizer: Optional[Callable[[str], List[str]]] = None
def __call__(self, file_path: str) -> List[str]:
"""
Chunk the given file into parts of size `chunk_size`.
Args:
file_path (str): The path to the file to chunk.
Returns:
List[str]: A list of string chunks from the file.
"""
if not os.path.isfile(file_path):
print(colored("The file does not exist.", "red"))
return []
file_extension = os.path.splitext(file_path)[1]
try:
with open(file_path, "rb") as file:
content = file.read()
# Decode content based on MIME type or file extension
decoded_content = self.decode_content(content, file_extension)
chunks = self.chunk_content(decoded_content)
return chunks
except Exception as e:
print(colored(f"Error reading file: {e}", "red"))
return []
def decode_content(self, content: bytes, file_extension: str) -> str:
"""
Decode the content of the file based on its MIME type or file extension.
Args:
content (bytes): The content of the file.
file_extension (str): The file extension of the file.
Returns:
str: The decoded content of the file.
"""
# Add logic to handle different file types based on the extension
# For simplicity, this example assumes text files encoded in utf-8
try:
return content.decode("utf-8")
except UnicodeDecodeError as e:
print(
colored(
f"Could not decode file with extension {file_extension}: {e}",
"yellow",
)
)
return ""
def chunk_content(self, content: str) -> List[str]:
"""
Split the content into chunks of size `chunk_size`.
Args:
content (str): The content to chunk.
Returns:
List[str]: The list of chunks.
"""
return [
content[i : i + self.chunk_size]
for i in range(0, len(content), self.chunk_size)
]
def __str__(self):
return f"OmniChunker(chunk_size={self.chunk_size}, beautify={self.beautify})"
def metrics(self):
return {
"chunk_size": self.chunk_size,
"beautify": self.beautify,
}
def print_dashboard(self):
print(
colored(
f"""
Omni Chunker
------------
{self.metrics()}
""",
"cyan",
)
)

@ -10,3 +10,10 @@ class PdfChunker(BaseChunker):
ChunkSeparator("? "), ChunkSeparator("? "),
ChunkSeparator(" "), ChunkSeparator(" "),
] ]
# # Example
# pdf = "swarmdeck.pdf"
# chunker = PdfChunker()
# chunks = chunker.chunk(pdf)
# print(chunks)

@ -17,6 +17,11 @@ from swarms.models.vilt import Vilt
from swarms.models.nougat import Nougat from swarms.models.nougat import Nougat
from swarms.models.layoutlm_document_qa import LayoutLMDocumentQA from swarms.models.layoutlm_document_qa import LayoutLMDocumentQA
# from swarms.models.gpt4v import GPT4Vision
# from swarms.models.dalle3 import Dalle3
# from swarms.models.distilled_whisperx import DistilWhisperModel
# from swarms.models.fuyu import Fuyu # Not working, wait until they update # from swarms.models.fuyu import Fuyu # Not working, wait until they update
import sys import sys
@ -41,4 +46,6 @@ __all__ = [
"HuggingfaceLLM", "HuggingfaceLLM",
"MPT7B", "MPT7B",
"WizardLLMStoryTeller", "WizardLLMStoryTeller",
# "GPT4Vision",
# "Dalle3",
] ]

@ -7,9 +7,31 @@ class Anthropic:
Anthropic large language models. Anthropic large language models.
Args: Args:
model: The model to use. Defaults to "claude-2".
max_tokens_to_sample: The maximum number of tokens to sample.
temperature: The temperature to use for sampling.
top_k: The top_k to use for sampling.
top_p: The top_p to use for sampling.
streaming: Whether to stream the response or not.
default_request_timeout: The default request timeout to use.
Attributes:
model: The model to use.
max_tokens_to_sample: The maximum number of tokens to sample.
temperature: The temperature to use for sampling.
top_k: The top_k to use for sampling.
top_p: The top_p to use for sampling.
streaming: Whether to stream the response or not.
default_request_timeout: The default request timeout to use.
anthropic_api_url: The API URL to use.
anthropic_api_key: The API key to use.
Usage:
model_wrapper = Anthropic()
completion = model_wrapper("Hello, my name is")
print(completion)
""" """
@ -22,6 +44,7 @@ class Anthropic:
top_p=None, top_p=None,
streaming=False, streaming=False,
default_request_timeout=None, default_request_timeout=None,
api_key: str = None,
): ):
self.model = model self.model = model
self.max_tokens_to_sample = max_tokens_to_sample self.max_tokens_to_sample = max_tokens_to_sample
@ -34,6 +57,7 @@ class Anthropic:
"ANTHROPIC_API_URL", "https://api.anthropic.com" "ANTHROPIC_API_URL", "https://api.anthropic.com"
) )
self.anthropic_api_key = os.getenv("ANTHROPIC_API_KEY") self.anthropic_api_key = os.getenv("ANTHROPIC_API_KEY")
self.api_key = api_key
def _default_params(self): def _default_params(self):
"""Get the default parameters for calling Anthropic API.""" """Get the default parameters for calling Anthropic API."""
@ -51,9 +75,10 @@ class Anthropic:
def run(self, task: str, stop=None): def run(self, task: str, stop=None):
"""Call out to Anthropic's completion endpoint.""" """Call out to Anthropic's completion endpoint."""
api_key = self.api_key or self.anthropic_api_key
stop = stop or [] stop = stop or []
params = self._default_params() params = self._default_params()
headers = {"Authorization": f"Bearer {self.anthropic_api_key}"} headers = {"Authorization": f"Bearer {api_key}"}
data = {"prompt": task, "stop_sequences": stop, **params} data = {"prompt": task, "stop_sequences": stop, **params}
response = requests.post( response = requests.post(
f"{self.anthropic_api_url}/completions", f"{self.anthropic_api_url}/completions",

@ -0,0 +1,172 @@
import logging
import os
from dataclasses import dataclass
from io import BytesIO
import openai
from dotenv import load_dotenv
from openai import OpenAI
from PIL import Image
from pydantic import validator
from termcolor import colored
load_dotenv()
# api_key = os.getenv("OPENAI_API_KEY")
# Configure Logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
@dataclass
class Dalle3:
"""
Dalle3 model class
Attributes:
-----------
image_url: str
The image url generated by the Dalle3 API
Methods:
--------
__call__(self, task: str) -> Dalle3:
Makes a call to the Dalle3 API and returns the image url
Example:
--------
>>> dalle3 = Dalle3()
>>> task = "A painting of a dog"
>>> image_url = dalle3(task)
>>> print(image_url)
https://cdn.openai.com/dall-e/encoded/feats/feats_01J9J5ZKJZJY9.png
"""
model: str = "dall-e-3"
img: str = None
size: str = "1024x1024"
max_retries: int = 3
quality: str = "standard"
api_key: str = None
n: int = 4
client = OpenAI(
api_key=api_key,
max_retries=max_retries,
)
class Config:
"""Config class for the Dalle3 model"""
arbitrary_types_allowed = True
@validator("max_retries", "time_seconds")
def must_be_positive(cls, value):
if value <= 0:
raise ValueError("Must be positive")
return value
def read_img(self, img: str):
"""Read the image using pil"""
img = Image.open(img)
return img
def set_width_height(self, img: str, width: int, height: int):
"""Set the width and height of the image"""
img = self.read_img(img)
img = img.resize((width, height))
return img
def convert_to_bytesio(self, img: str, format: str = "PNG"):
"""Convert the image to an bytes io object"""
byte_stream = BytesIO()
img.save(byte_stream, format=format)
byte_array = byte_stream.getvalue()
return byte_array
# @lru_cache(maxsize=32)
def __call__(self, task: str):
"""
Text to image conversion using the Dalle3 API
Parameters:
-----------
task: str
The task to be converted to an image
Returns:
--------
Dalle3:
An instance of the Dalle3 class with the image url generated by the Dalle3 API
Example:
--------
>>> dalle3 = Dalle3()
>>> task = "A painting of a dog"
>>> image_url = dalle3(task)
>>> print(image_url)
https://cdn.openai.com/dall-e/encoded/feats/feats_01J9J5ZKJZJY9.png
"""
try:
# Making a call to the the Dalle3 API
response = self.client.images.generate(
model=self.model,
prompt=task,
size=self.size,
quality=self.quality,
n=self.n,
)
# Extracting the image url from the response
img = response.data[0].url
return img
except openai.OpenAIError as error:
# Handling exceptions and printing the errors details
print(
colored(
f"Error running Dalle3: {error} try optimizing your api key and or try again",
"red",
)
)
raise error
def create_variations(self, img: str):
"""
Create variations of an image using the Dalle3 API
Parameters:
-----------
img: str
The image to be used for the API request
Returns:
--------
img: str
The image url generated by the Dalle3 API
Example:
--------
>>> dalle3 = Dalle3()
>>> img = "https://cdn.openai.com/dall-e/encoded/feats/feats_01J9J5ZKJZJY9.png"
>>> img = dalle3.create_variations(img)
>>> print(img)
"""
try:
response = self.client.images.create_variation(
img=open(img, "rb"), n=self.n, size=self.size
)
img = response.data[0].url
return img
except (Exception, openai.OpenAIError) as error:
print(
colored(
f"Error running Dalle3: {error} try optimizing your api key and or try again",
"red",
)
)
print(colored(f"Error running Dalle3: {error.http_status}", "red"))
print(colored(f"Error running Dalle3: {error.error}", "red"))
raise error

@ -1,3 +1,160 @@
""" import asyncio
import os
import time
from functools import wraps
from typing import Union
""" import torch
from termcolor import colored
from transformers import AutoModelForSpeechSeq2Seq, AutoProcessor, pipeline
def async_retry(max_retries=3, exceptions=(Exception,), delay=1):
"""
A decorator for adding retry logic to async functions.
:param max_retries: Maximum number of retries before giving up.
:param exceptions: A tuple of exceptions to catch and retry on.
:param delay: Delay between retries.
"""
def decorator(func):
@wraps(func)
async def wrapper(*args, **kwargs):
retries = max_retries
while retries:
try:
return await func(*args, **kwargs)
except exceptions as e:
retries -= 1
if retries <= 0:
raise
print(f"Retry after exception: {e}, Attempts remaining: {retries}")
await asyncio.sleep(delay)
return wrapper
return decorator
class DistilWhisperModel:
"""
This class encapsulates the Distil-Whisper model for English speech recognition.
It allows for both synchronous and asynchronous transcription of short and long-form audio.
Args:
model_id: The model ID to use. Defaults to "distil-whisper/distil-large-v2".
Attributes:
device: The device to use for inference.
torch_dtype: The torch data type to use for inference.
model_id: The model ID to use.
model: The model instance.
processor: The processor instance.
Usage:
model_wrapper = DistilWhisperModel()
transcription = model_wrapper('path/to/audio.mp3')
# For async usage
transcription = asyncio.run(model_wrapper.async_transcribe('path/to/audio.mp3'))
"""
def __init__(self, model_id="distil-whisper/distil-large-v2"):
self.device = "cuda:0" if torch.cuda.is_available() else "cpu"
self.torch_dtype = torch.float16 if torch.cuda.is_available() else torch.float32
self.model_id = model_id
self.model = AutoModelForSpeechSeq2Seq.from_pretrained(
model_id,
torch_dtype=self.torch_dtype,
low_cpu_mem_usage=True,
use_safetensors=True,
).to(self.device)
self.processor = AutoProcessor.from_pretrained(model_id)
def __call__(self, inputs: Union[str, dict]):
return self.transcribe(inputs)
def transcribe(self, inputs: Union[str, dict]):
"""
Synchronously transcribe the given audio input using the Distil-Whisper model.
:param inputs: A string representing the file path or a dict with audio data.
:return: The transcribed text.
"""
pipe = pipeline(
"automatic-speech-recognition",
model=self.model,
tokenizer=self.processor.tokenizer,
feature_extractor=self.processor.feature_extractor,
max_new_tokens=128,
torch_dtype=self.torch_dtype,
device=self.device,
)
return pipe(inputs)["text"]
@async_retry()
async def async_transcribe(self, inputs: Union[str, dict]):
"""
Asynchronously transcribe the given audio input using the Distil-Whisper model.
:param inputs: A string representing the file path or a dict with audio data.
:return: The transcribed text.
"""
loop = asyncio.get_event_loop()
return await loop.run_in_executor(None, self.transcribe, inputs)
def real_time_transcribe(self, audio_file_path, chunk_duration=5):
"""
Simulates real-time transcription of an audio file, processing and printing results
in chunks with colored output for readability.
:param audio_file_path: Path to the audio file to be transcribed.
:param chunk_duration: Duration in seconds of each audio chunk to be processed.
"""
if not os.path.isfile(audio_file_path):
print(colored("The audio file was not found.", "red"))
return
# Assuming `chunk_duration` is in seconds and `processor` can handle chunk-wise processing
try:
with torch.no_grad():
# Load the whole audio file, but process and transcribe it in chunks
audio_input = self.processor.audio_file_to_array(audio_file_path)
sample_rate = audio_input.sampling_rate
total_duration = len(audio_input.array) / sample_rate
chunks = [
audio_input.array[i : i + sample_rate * chunk_duration]
for i in range(
0, len(audio_input.array), sample_rate * chunk_duration
)
]
print(colored("Starting real-time transcription...", "green"))
for i, chunk in enumerate(chunks):
# Process the current chunk
processed_inputs = self.processor(
chunk,
sampling_rate=sample_rate,
return_tensors="pt",
padding=True,
)
processed_inputs = processed_inputs.input_values.to(self.device)
# Generate transcription for the chunk
logits = self.model.generate(processed_inputs)
transcription = self.processor.batch_decode(
logits, skip_special_tokens=True
)[0]
# Print the chunk's transcription
print(
colored(f"Chunk {i+1}/{len(chunks)}: ", "yellow")
+ transcription
)
# Wait for the chunk's duration to simulate real-time processing
time.sleep(chunk_duration)
except Exception as e:
print(colored(f"An error occurred during transcription: {e}", "red"))

@ -60,7 +60,5 @@ class Fuyu:
for k, v in model_inputs.items(): for k, v in model_inputs.items():
model_inputs[k] = v.to(self.device_map) model_inputs[k] = v.to(self.device_map)
output = self.model.generate( output = self.model.generate(**model_inputs, max_new_tokens=self.max_new_tokens)
**model_inputs, max_new_tokens=self.fmax_new_tokens
)
text = self.processor.batch_decode(output[:, -7:], skip_special_tokens=True) text = self.processor.batch_decode(output[:, -7:], skip_special_tokens=True)

@ -0,0 +1,288 @@
import base64
import logging
import os
import time
from dataclasses import dataclass
from typing import List, Optional, Union
import requests
from dotenv import load_dotenv
from openai import OpenAI
from termcolor import colored
# ENV
load_dotenv()
def logging_config():
"""Configures logging"""
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
)
logger = logging.getLogger(__name__)
return logger
@dataclass
class GPT4VisionResponse:
"""A response structure for GPT-4"""
answer: str
@dataclass
class GPT4Vision:
"""
GPT4Vision model class
Attributes:
-----------
max_retries: int
The maximum number of retries to make to the API
backoff_factor: float
The backoff factor to use for exponential backoff
timeout_seconds: int
The timeout in seconds for the API request
api_key: str
The API key to use for the API request
quality: str
The quality of the image to generate
max_tokens: int
The maximum number of tokens to use for the API request
Methods:
--------
process_img(self, img_path: str) -> str:
Processes the image to be used for the API request
__call__(self, img: Union[str, List[str]], tasks: List[str]) -> GPT4VisionResponse:
Makes a call to the GPT-4 Vision API and returns the image url
Example:
>>> gpt4vision = GPT4Vision()
>>> img = "https://cdn.openai.com/dall-e/encoded/feats/feats_01J9J5ZKJZJY9.png"
>>> tasks = ["A painting of a dog"]
>>> answer = gpt4vision(img, tasks)
>>> print(answer)
"""
max_retries: int = 3
model: str = "gpt-4-vision-preview"
backoff_factor: float = 2.0
timeout_seconds: int = 10
api_key: Optional[str] = None
# 'Low' or 'High' for respesctively fast or high quality, but high more token usage
quality: str = "low"
# Max tokens to use for the API request, the maximum might be 3,000 but we don't know
max_tokens: int = 200
client = OpenAI(
api_key=api_key,
max_retries=max_retries,
)
logger = logging_config()
class Config:
"""Config class for the GPT4Vision model"""
arbitary_types_allowed = True
def process_img(self, img: str) -> str:
"""Processes the image to be used for the API request"""
with open(img, "rb") as image_file:
return base64.b64encode(image_file.read()).decode("utf-8")
def __call__(
self,
img: Union[str, List[str]],
tasks: List[str],
) -> GPT4VisionResponse:
"""
Calls the GPT-4 Vision API and returns the image url
Parameters:
-----------
img: Union[str, List[str]]
The image to be used for the API request
tasks: List[str]
The tasks to be used for the API request
Returns:
--------
answer: GPT4VisionResponse
The response from the API request
Example:
--------
>>> gpt4vision = GPT4Vision()
>>> img = "https://cdn.openai.com/dall-e/encoded/feats/feats_01J9J5ZKJZJY9.png"
>>> tasks = ["A painting of a dog"]
>>> answer = gpt4vision(img, tasks)
>>> print(answer)
"""
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {self.api_key}",
}
# Image content
image_content = [
{"type": "imavge_url", "image_url": img}
if img.startswith("http")
else {"type": "image", "data": img}
for img in img
]
messages = [
{
"role": "user",
"content": image_content + [{"type": "text", "text": q} for q in tasks],
}
]
payload = {
"model": "gpt-4-vision-preview",
"messages": messages,
"max_tokens": self.max_tokens,
"detail": self.quality,
}
for attempt in range(self.max_retries):
try:
response = requests.post(
"https://api.openai.com/v1/chat/completions",
headers=headers,
json=payload,
timeout=self.timeout_seconds,
)
response.raise_for_status()
answer = response.json()["choices"][0]["message"]["content"]["text"]
return GPT4VisionResponse(answer=answer)
except requests.exceptions.HTTPError as error:
self.logger.error(
f"HTTP error: {error.response.status_code}, {error.response.text}"
)
if error.response.status_code in [429, 500, 503]:
# Exponential backoff = 429(too many requesys)
# And 503 = (Service unavailable) errors
time.sleep(self.backoff_factor**attempt)
else:
break
except requests.exceptions.RequestException as error:
self.logger.error(f"Request error: {error}")
time.sleep(self.backoff_factor**attempt)
except Exception as error:
self.logger.error(
f"Unexpected Error: {error} try optimizing your api key and try again"
)
raise error from None
raise TimeoutError("API Request timed out after multiple retries")
def run(self, task: str, img: str) -> str:
"""
Runs the GPT-4 Vision API
Parameters:
-----------
task: str
The task to be used for the API request
img: str
The image to be used for the API request
Returns:
--------
out: str
The response from the API request
Example:
--------
>>> gpt4vision = GPT4Vision()
>>> task = "A painting of a dog"
>>> img = "https://cdn.openai.com/dall-e/encoded/feats/feats_01J9J5ZKJZJY9.png"
>>> answer = gpt4vision.run(task, img)
>>> print(answer)
"""
try:
response = self.client.chat.completions.create(
model=self.model,
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": f"{task}"},
{
"type": "image_url",
"image_url": f"{img}",
},
],
}
],
max_tokens=self.max_tokens,
)
out = response.choices[0].text
return out
except Exception as error:
print(
colored(
f"Error when calling GPT4Vision, Error: {error} Try optimizing your key, and try again",
"red",
)
)
async def arun(self, task: str, img: str) -> str:
"""
Asynchronous run method for GPT-4 Vision
Parameters:
-----------
task: str
The task to be used for the API request
img: str
The image to be used for the API request
Returns:
--------
out: str
The response from the API request
Example:
--------
>>> gpt4vision = GPT4Vision()
>>> task = "A painting of a dog"
>>> img = "https://cdn.openai.com/dall-e/encoded/feats/feats_01J9J5ZKJZJY9.png"
>>> answer = await gpt4vision.arun(task, img)
>>> print(answer)
"""
try:
response = await self.client.chat.completions.create(
model=self.model,
messages=[
{
"role": "user",
"content": [
{"type": "text", "text": f"{task}"},
{
"type": "image_url",
"image_url": f"{img}",
},
],
}
],
max_tokens=self.max_tokens,
)
out = response.choices[0].text
return out
except Exception as error:
print(
colored(
f"Error when calling GPT4Vision, Error: {error} Try optimizing your key, and try again",
"red",
)
)

@ -23,7 +23,7 @@ class HuggingfaceLLM:
``` ```
from swarms.models import HuggingfaceLLM from swarms.models import HuggingfaceLLM
model_id = "gpt2-small" model_id = "NousResearch/Yarn-Mistral-7b-128k"
inference = HuggingfaceLLM(model_id=model_id) inference = HuggingfaceLLM(model_id=model_id)
task = "Once upon a time" task = "Once upon a time"
@ -74,15 +74,22 @@ class HuggingfaceLLM:
bnb_config = BitsAndBytesConfig(**quantization_config) bnb_config = BitsAndBytesConfig(**quantization_config)
try: try:
self.tokenizer = AutoTokenizer.from_pretrained(self.model_id) self.tokenizer = AutoTokenizer.from_pretrained(
self.model_id, *args, **kwargs
)
self.model = AutoModelForCausalLM.from_pretrained( self.model = AutoModelForCausalLM.from_pretrained(
self.model_id, quantization_config=bnb_config self.model_id, quantization_config=bnb_config, *args, **kwargs
) )
self.model # .to(self.device) self.model # .to(self.device)
except Exception as e: except Exception as e:
self.logger.error(f"Failed to load the model or the tokenizer: {e}") # self.logger.error(f"Failed to load the model or the tokenizer: {e}")
raise # raise
print(colored(f"Failed to load the model and or the tokenizer: {e}", "red"))
def print_error(self, error: str):
"""Print error"""
print(colored(f"Error: {error}", "red"))
def load_model(self): def load_model(self):
"""Load the model""" """Load the model"""
@ -157,7 +164,12 @@ class HuggingfaceLLM:
del inputs del inputs
return self.tokenizer.decode(outputs[0], skip_special_tokens=True) return self.tokenizer.decode(outputs[0], skip_special_tokens=True)
except Exception as e: except Exception as e:
self.logger.error(f"Failed to generate the text: {e}") print(
colored(
f"HuggingfaceLLM could not generate text because of error: {e}, try optimizing your arguments",
"red",
)
)
raise raise
async def run_async(self, task: str, *args, **kwargs) -> str: async def run_async(self, task: str, *args, **kwargs) -> str:

@ -0,0 +1,74 @@
from typing import Dict, List, Optional
from dataclass import dataclass
from swarms.models import OpenAI
@dataclass
class OpenAIAssistant:
name: str = "OpenAI Assistant"
instructions: str = None
tools: List[Dict] = None
model: str = None
openai_api_key: str = None
temperature: float = 0.5
max_tokens: int = 100
stop: List[str] = None
echo: bool = False
stream: bool = False
log: bool = False
presence: bool = False
dashboard: bool = False
debug: bool = False
max_loops: int = 5
stopping_condition: Optional[str] = None
loop_interval: int = 1
retry_attempts: int = 3
retry_interval: int = 1
interactive: bool = False
dynamic_temperature: bool = False
state: Dict = None
response_filters: List = None
response_filter: Dict = None
response_filter_name: str = None
response_filter_value: str = None
response_filter_type: str = None
response_filter_action: str = None
response_filter_action_value: str = None
response_filter_action_type: str = None
response_filter_action_name: str = None
client = OpenAI()
role: str = "user"
instructions: str = None
def create_assistant(self, task: str):
assistant = self.client.create_assistant(
name=self.name,
instructions=self.instructions,
tools=self.tools,
model=self.model,
)
return assistant
def create_thread(self):
thread = self.client.beta.threads.create()
return thread
def add_message_to_thread(self, thread_id: str, message: str):
message = self.client.beta.threads.add_message(
thread_id=thread_id, role=self.user, content=message
)
return message
def run(self, task: str):
run = self.client.beta.threads.runs.create(
thread_id=self.create_thread().id,
assistant_id=self.create_assistant().id,
instructions=self.instructions,
)
out = self.client.beta.threads.runs.retrieve(
thread_id=run.thread_id, run_id=run.id
)
return out

@ -0,0 +1,150 @@
from __future__ import annotations
import logging
from abc import ABC, abstractmethod
from typing import Optional
import tiktoken
from attr import Factory, define, field
@define(frozen=True)
class BaseTokenizer(ABC):
DEFAULT_STOP_SEQUENCES = ["Observation:"]
stop_sequences: list[str] = field(
default=Factory(lambda: BaseTokenizer.DEFAULT_STOP_SEQUENCES),
kw_only=True,
)
@property
@abstractmethod
def max_tokens(self) -> int:
...
def count_tokens_left(self, text: str) -> int:
diff = self.max_tokens - self.count_tokens(text)
if diff > 0:
return diff
else:
return 0
@abstractmethod
def count_tokens(self, text: str) -> int:
...
@define(frozen=True)
class OpenAITokenizer(BaseTokenizer):
DEFAULT_OPENAI_GPT_3_COMPLETION_MODEL = "text-davinci-003"
DEFAULT_OPENAI_GPT_3_CHAT_MODEL = "gpt-3.5-turbo"
DEFAULT_OPENAI_GPT_4_MODEL = "gpt-4"
DEFAULT_ENCODING = "cl100k_base"
DEFAULT_MAX_TOKENS = 2049
TOKEN_OFFSET = 8
MODEL_PREFIXES_TO_MAX_TOKENS = {
"gpt-4-32k": 32768,
"gpt-4": 8192,
"gpt-3.5-turbo-16k": 16384,
"gpt-3.5-turbo": 4096,
"gpt-35-turbo-16k": 16384,
"gpt-35-turbo": 4096,
"text-davinci-003": 4097,
"text-davinci-002": 4097,
"code-davinci-002": 8001,
"text-embedding-ada-002": 8191,
"text-embedding-ada-001": 2046,
}
EMBEDDING_MODELS = ["text-embedding-ada-002", "text-embedding-ada-001"]
model: str = field(kw_only=True)
@property
def encoding(self) -> tiktoken.Encoding:
try:
return tiktoken.encoding_for_model(self.model)
except KeyError:
return tiktoken.get_encoding(self.DEFAULT_ENCODING)
@property
def max_tokens(self) -> int:
tokens = next(
v
for k, v in self.MODEL_PREFIXES_TO_MAX_TOKENS.items()
if self.model.startswith(k)
)
offset = 0 if self.model in self.EMBEDDING_MODELS else self.TOKEN_OFFSET
return (tokens if tokens else self.DEFAULT_MAX_TOKENS) - offset
def count_tokens(
self, text: str | list, model: Optional[str] = None
) -> int:
"""
Handles the special case of ChatML. Implementation adopted from the official OpenAI notebook:
https://github.com/openai/openai-cookbook/blob/main/examples/How_to_count_tokens_with_tiktoken.ipynb
"""
if isinstance(text, list):
model = model if model else self.model
try:
encoding = tiktoken.encoding_for_model(model)
except KeyError:
logging.warning("model not found. Using cl100k_base encoding.")
encoding = tiktoken.get_encoding("cl100k_base")
if model in {
"gpt-3.5-turbo-0613",
"gpt-3.5-turbo-16k-0613",
"gpt-4-0314",
"gpt-4-32k-0314",
"gpt-4-0613",
"gpt-4-32k-0613",
}:
tokens_per_message = 3
tokens_per_name = 1
elif model == "gpt-3.5-turbo-0301":
# every message follows <|start|>{role/name}\n{content}<|end|>\n
tokens_per_message = 4
# if there's a name, the role is omitted
tokens_per_name = -1
elif "gpt-3.5-turbo" in model or "gpt-35-turbo" in model:
logging.info(
"gpt-3.5-turbo may update over time. Returning num tokens assuming gpt-3.5-turbo-0613."
)
return self.count_tokens(text, model="gpt-3.5-turbo-0613")
elif "gpt-4" in model:
logging.info(
"gpt-4 may update over time. Returning num tokens assuming gpt-4-0613."
)
return self.count_tokens(text, model="gpt-4-0613")
else:
raise NotImplementedError(
f"""token_count() is not implemented for model {model}.
See https://github.com/openai/openai-python/blob/main/chatml.md for
information on how messages are converted to tokens."""
)
num_tokens = 0
for message in text:
num_tokens += tokens_per_message
for key, value in message.items():
num_tokens += len(encoding.encode(value))
if key == "name":
num_tokens += tokens_per_name
# every reply is primed with <|start|>assistant<|message|>
num_tokens += 3
return num_tokens
else:
return len(
self.encoding.encode(
text, allowed_special=set(self.stop_sequences)
)
)

@ -1,5 +1,6 @@
from swarms.structs.workflow import Workflow from swarms.structs.workflow import Workflow
from swarms.structs.task import Task from swarms.structs.task import Task
from swarms.structs.flow import Flow from swarms.structs.flow import Flow
from swarms.structs.sequential_workflow import SequentialWorkflow
__all__ = ["Workflow", "Task", "Flow"] __all__ = ["Workflow", "Task", "Flow", "SequentialWorkflow"]

@ -0,0 +1,5 @@
"""
Base Structure for all Swarm Structures
"""

@ -1,9 +1,14 @@
""" """
TODO: TODO:
- add a method that scrapes all the methods from the llm object and outputs them as a string
- Add tools - Add tools
- Add open interpreter style conversation - Add open interpreter style conversation
- Add configurable save and restore so the user can restore from previus flows
- Add memory vector database retrieval - Add memory vector database retrieval
- add batch processing
- add async processing for run and batch run
- add plan module
- concurrent
-
""" """
import asyncio import asyncio
import copy import copy
@ -15,11 +20,17 @@ from typing import Any, Callable, Dict, List, Optional, Tuple, Generator, Union
from termcolor import colored from termcolor import colored
import inspect import inspect
import random import random
# from swarms.tools.tool import BaseTool
# Prompts
DYNAMIC_STOP_PROMPT = """
When you have finished the task from the Human, output a special token: <DONE>
This will enable you to leave the autonomous loop.
"""
# Constants # Constants
FLOW_SYSTEM_PROMPT = """ FLOW_SYSTEM_PROMPT = f"""
You are an autonomous agent granted autonomy from a Flow structure. You are an autonomous agent granted autonomy from a Flow structure.
Your role is to engage in multi-step conversations with your self or the user, Your role is to engage in multi-step conversations with your self or the user,
generate long-form content like blogs, screenplays, or SOPs, generate long-form content like blogs, screenplays, or SOPs,
@ -27,19 +38,15 @@ and accomplish tasks. You can have internal dialogues with yourself or can inter
to aid in these complex tasks. Your responses should be coherent, contextually relevant, and tailored to the task at hand. to aid in these complex tasks. Your responses should be coherent, contextually relevant, and tailored to the task at hand.
When you have finished the task, and you feel as if you are done: output a special token: <DONE> {DYNAMIC_STOP_PROMPT}
This will enable you to leave the flow loop.
""" """
DYNAMIC_STOP_PROMPT = """ # Utility functions
When you have finished the task, and you feel as if you are done: output a special token: <DONE>
This will enable you to leave the flow loop.
"""
# Custome stopping condition # Custom stopping condition
def stop_when_repeats(response: str) -> bool: def stop_when_repeats(response: str) -> bool:
# Stop if the word stop appears in the response # Stop if the word stop appears in the response
return "Stop" in response.lower() return "Stop" in response.lower()
@ -105,9 +112,13 @@ class Flow:
retry_interval: int = 1, retry_interval: int = 1,
interactive: bool = False, interactive: bool = False,
dashboard: bool = False, dashboard: bool = False,
name: str = "flow-agent", name: str = "Flow agent",
system_message: str = FLOW_SYSTEM_PROMPT, system_prompt: str = FLOW_SYSTEM_PROMPT,
# tools: List[BaseTool] = None,
dynamic_temperature: bool = False, dynamic_temperature: bool = False,
saved_state_path: Optional[str] = "flow_state.json",
autosave: bool = False,
context_length: int = 8192,
**kwargs: Any, **kwargs: Any,
): ):
self.llm = llm self.llm = llm
@ -124,8 +135,12 @@ class Flow:
self.interactive = interactive self.interactive = interactive
self.dashboard = dashboard self.dashboard = dashboard
self.dynamic_temperature = dynamic_temperature self.dynamic_temperature = dynamic_temperature
self.system_message = system_message # self.tools = tools
self.system_prompt = system_prompt
self.name = name self.name = name
self.saved_state_path = saved_state_path
self.autosave = autosave
self.response_filters = []
def provide_feedback(self, feedback: str) -> None: def provide_feedback(self, feedback: str) -> None:
"""Allow users to provide feedback on the responses.""" """Allow users to provide feedback on the responses."""
@ -138,11 +153,6 @@ class Flow:
return self.stopping_condition(response) return self.stopping_condition(response)
return False return False
def __call__(self, prompt, **kwargs) -> str:
"""Invoke the flow by providing a template and its variables."""
response = self.llm(prompt, **kwargs)
return response
def dynamic_temperature(self): def dynamic_temperature(self):
""" """
1. Check the self.llm object for the temperature 1. Check the self.llm object for the temperature
@ -181,9 +191,30 @@ class Flow:
return "\n".join(params_str_list) return "\n".join(params_str_list)
def truncate_history(self):
"""
Take the history and truncate it to fit into the model context length
"""
truncated_history = self.memory[-1][-self.context_length :]
self.memory[-1] = truncated_history
def add_task_to_memory(self, task: str):
"""Add the task to the memory"""
self.memory.append([f"Human: {task}"])
def add_message_to_memory(self, message: str):
"""Add the message to the memory"""
self.memory[-1].append(message)
def add_message_to_memory_and_truncate(self, message: str):
"""Add the message to the memory and truncate"""
self.memory[-1].append(message)
self.truncate_history()
def print_dashboard(self, task: str): def print_dashboard(self, task: str):
"""Print dashboard""" """Print dashboard"""
model_config = self.get_llm_init_params() model_config = self.get_llm_init_params()
print(colored("Initializing Agent Dashboard...", "yellow"))
dashboard = print( dashboard = print(
colored( colored(
@ -197,6 +228,8 @@ class Flow:
---------------------------------------- ----------------------------------------
Flow Configuration: Flow Configuration:
Name: {self.name}
System Prompt: {self.system_prompt}
Task: {task} Task: {task}
Max Loops: {self.max_loops} Max Loops: {self.max_loops}
Stopping Condition: {self.stopping_condition} Stopping Condition: {self.stopping_condition}
@ -204,6 +237,10 @@ class Flow:
Retry Attempts: {self.retry_attempts} Retry Attempts: {self.retry_attempts}
Retry Interval: {self.retry_interval} Retry Interval: {self.retry_interval}
Interactive: {self.interactive} Interactive: {self.interactive}
Dashboard: {self.dashboard}
Dynamic Temperature: {self.dynamic_temperature}
Autosave: {self.autosave}
Saved State: {self.saved_state_path}
---------------------------------------- ----------------------------------------
""", """,
@ -211,7 +248,24 @@ class Flow:
) )
) )
print(dashboard) # print(dashboard)
def activate_autonomous_agent(self):
"""Print the autonomous agent activation message"""
try:
print(colored("Initializing Autonomous Agent...", "yellow"))
# print(colored("Loading modules...", "yellow"))
# print(colored("Modules loaded successfully.", "green"))
print(colored("Autonomous Agent Activated.", "cyan", attrs=["bold"]))
print(colored("All systems operational. Executing task...", "green"))
except Exception as error:
print(
colored(
"Error activating autonomous agent. Try optimizing your parameters...",
"red",
)
)
print(error)
def run(self, task: str, **kwargs): def run(self, task: str, **kwargs):
""" """
@ -228,6 +282,20 @@ class Flow:
5. Repeat until stopping condition is met or max_loops is reached 5. Repeat until stopping condition is met or max_loops is reached
""" """
# Restore from saved state if provided, ortherwise start with a new history
# if self.saved_state:
# self.load_state(self.saved_state)
# history = self.memory[-1]
# print(f"Loaded state from {self.saved_state}")
# else:
# history = [f"Human: {task}"]
# self.memory.append(history)
# print(colored(">>> Autonomous Agent Activated", "cyan", attrs=["bold"]))
self.activate_autonomous_agent()
# if self.autosave:
response = task response = task
history = [f"Human: {task}"] history = [f"Human: {task}"]
@ -249,14 +317,87 @@ class Flow:
while attempt < self.retry_attempts: while attempt < self.retry_attempts:
try: try:
response = self.llm( response = self.llm(
f""" self.agent_history_prompt(FLOW_SYSTEM_PROMPT, response),
SYSTEM_PROMPT: **kwargs,
{FLOW_SYSTEM_PROMPT} )
# print(f"Next query: {response}")
# break
if self.interactive:
print(f"AI: {response}")
history.append(f"AI: {response}")
response = input("You: ")
history.append(f"Human: {response}")
else:
print(f"AI: {response}")
history.append(f"AI: {response}")
print(response)
break
except Exception as e:
logging.error(f"Error generating response: {e}")
attempt += 1
time.sleep(self.retry_interval)
history.append(response)
time.sleep(self.loop_interval)
self.memory.append(history)
if self.autosave:
save_path = self.saved_state_path or "flow_state.json"
print(colored(f"Autosaving flow state to {save_path}", "green"))
self.save_state(save_path)
return response # , history
History: {response} async def arun(self, task: str, **kwargs):
"""Async run"""
pass
""", """
Run the autonomous agent loop
Args:
task (str): The initial task to run
Flow:
1. Generate a response
2. Check stopping condition
3. If stopping condition is met, stop
4. If stopping condition is not met, generate a response
5. Repeat until stopping condition is met or max_loops is reached
"""
# Restore from saved state if provided, ortherwise start with a new history
# if self.saved_state:
# self.load_state(self.saved_state)
# history = self.memory[-1]
# print(f"Loaded state from {self.saved_state}")
# else:
# history = [f"Human: {task}"]
# self.memory.append(history)
print(colored(">>> Autonomous Agent Activated", "cyan", attrs=["bold"]))
response = task
history = [f"Human: {task}"]
# If dashboard = True then print the dashboard
if self.dashboard:
self.print_dashboard(task)
for i in range(self.max_loops):
print(colored(f"\nLoop {i+1} of {self.max_loops}", "blue"))
print("\n")
if self._check_stopping_condition(response) or parse_done_token(response):
break
# Adjust temperature, comment if no work
if self.dynamic_temperature:
self.dynamic_temperature()
attempt = 0
while attempt < self.retry_attempts:
try:
response = self.llm(
self.agent_history_prompt(FLOW_SYSTEM_PROMPT, response),
**kwargs, **kwargs,
) )
# print(f"Next query: {response}") # print(f"Next query: {response}")
@ -279,6 +420,10 @@ class Flow:
history.append(response) history.append(response)
time.sleep(self.loop_interval) time.sleep(self.loop_interval)
self.memory.append(history) self.memory.append(history)
# if self.autosave:
# self.save_state("flow_state.json")
return response # , history return response # , history
def _run(self, **kwargs: Any) -> str: def _run(self, **kwargs: Any) -> str:
@ -288,32 +433,32 @@ class Flow:
logging.info(f"Message history: {history}") logging.info(f"Message history: {history}")
return response return response
def bulk_run(self, inputs: List[Dict[str, Any]]) -> List[str]: def agent_history_prompt(
"""Generate responses for multiple input sets.""" self,
return [self.run(**input_data) for input_data in inputs] system_prompt: str = FLOW_SYSTEM_PROMPT,
history=None,
def run_dynamically(self, task: str, max_loops: Optional[int] = None): ):
""" """
Run the autonomous agent loop dynamically based on the <DONE> Generate the agent history prompt
# Usage Example
# Initialize the Flow
flow = Flow(llm=lambda x: x, max_loops=5)
# Run dynamically based on <DONE> token and optional max loops Args:
response = flow.run_dynamically("Generate a report <DONE>", max_loops=3) system_prompt (str): The system prompt
print(response) history (List[str]): The history of the conversation
response = flow.run_dynamically("Generate a report <DONE>") Returns:
print(response) str: The agent history prompt
"""
system_prompt = system_prompt or self.system_prompt
agent_history_prompt = f"""
SYSTEM_PROMPT: {system_prompt}
History: {history}
""" """
if "<DONE>" in task: return agent_history_prompt
self.stopping_condition = parse_done_token
self.max_loops = max_loops or float("inf") def bulk_run(self, inputs: List[Dict[str, Any]]) -> List[str]:
response = self.run(task) """Generate responses for multiple input sets."""
return response return [self.run(**input_data) for input_data in inputs]
@staticmethod @staticmethod
def from_llm_and_template(llm: Any, template: str) -> "Flow": def from_llm_and_template(llm: Any, template: str) -> "Flow":
@ -332,7 +477,13 @@ class Flow:
json.dump(self.memory, f) json.dump(self.memory, f)
print(f"Saved flow history to {file_path}") print(f"Saved flow history to {file_path}")
def load(self, file_path) -> None: def load(self, file_path: str):
"""
Load the flow history from a file.
Args:
file_path (str): The path to the file containing the saved flow history.
"""
with open(file_path, "r") as f: with open(file_path, "r") as f:
self.memory = json.load(f) self.memory = json.load(f)
print(f"Loaded flow history from {file_path}") print(f"Loaded flow history from {file_path}")
@ -344,6 +495,60 @@ class Flow:
return False return False
return True return True
def print_history_and_memory(self):
"""
Prints the entire history and memory of the flow.
Each message is colored and formatted for better readability.
"""
print(colored("Flow History and Memory", "cyan", attrs=["bold"]))
print(colored("========================", "cyan", attrs=["bold"]))
for loop_index, history in enumerate(self.memory, start=1):
print(colored(f"\nLoop {loop_index}:", "yellow", attrs=["bold"]))
for message in history:
speaker, _, message_text = message.partition(": ")
if "Human" in speaker:
print(colored(f"{speaker}:", "green") + f" {message_text}")
else:
print(colored(f"{speaker}:", "blue") + f" {message_text}")
print(colored("------------------------", "cyan"))
print(colored("End of Flow History", "cyan", attrs=["bold"]))
def step(self, task: str, **kwargs):
"""
Executes a single step in the flow interaction, generating a response
from the language model based on the given input text.
Args:
input_text (str): The input text to prompt the language model with.
Returns:
str: The language model's generated response.
Raises:
Exception: If an error occurs during response generation.
"""
try:
# Generate the response using lm
response = self.llm(task, **kwargs)
# Update the flow's history with the new interaction
if self.interactive:
self.memory.append(f"AI: {response}")
self.memory.append(f"Human: {task}")
else:
self.memory.append(f"AI: {response}")
return response
except Exception as error:
logging.error(f"Error generating response: {error}")
raise
def graceful_shutdown(self):
"""Gracefully shutdown the system saving the state"""
return self.save_state("flow_state.json")
def run_with_timeout(self, task: str, timeout: int = 60) -> str: def run_with_timeout(self, task: str, timeout: int = 60) -> str:
"""Run the loop but stop if it takes longer than the timeout""" """Run the loop but stop if it takes longer than the timeout"""
start_time = time.time() start_time = time.time()
@ -460,22 +665,45 @@ class Flow:
print() print()
return response return response
def streamed_token_generation(self, prompt: str) -> Generator[str, None, None]: def get_llm_params(self):
"""
Extracts and returns the parameters of the llm object for serialization.
It assumes that the llm object has an __init__ method with parameters that can be used to recreate it.
""" """
Generate tokens in real-time for a given prompt. if not hasattr(self.llm, "__init__"):
return None
This method simulates the real-time generation of each token. init_signature = inspect.signature(self.llm.__init__)
For simplicity, we treat each character of the input as a token params = init_signature.parameters
and yield them with a slight delay. In a real-world scenario, llm_params = {}
this would involve using the LLM's internal methods to generate
the response token by token. for name, param in params.items():
if name == "self":
continue
if hasattr(self.llm, name):
value = getattr(self.llm, name)
if isinstance(
value, (str, int, float, bool, list, dict, tuple, type(None))
):
llm_params[name] = value
else:
llm_params[name] = str(
value
) # For non-serializable objects, save their string representation.
return llm_params
def save_state(self, file_path: str) -> None:
"""
Saves the current state of the flow to a JSON file, including the llm parameters.
Args: Args:
prompt (str): The input prompt for which the tokens should be generated. file_path (str): The path to the JSON file where the state will be saved.
Yields: Example:
str: The next token (character) from the generated response. >>> flow.save_state('saved_flow.json')
""" """
tokens = list(prompt) tokens = list(prompt)
for token in tokens: for token in tokens:
time.sleep(0.1) time.sleep(0.1)
@ -497,3 +725,75 @@ Your response:"""
"""Update the system message. """Update the system message.
""" """
self.system_message = system_message self.system_message = system_message
state = {
"memory": self.memory,
# "llm_params": self.get_llm_params(),
"loop_interval": self.loop_interval,
"retry_attempts": self.retry_attempts,
"retry_interval": self.retry_interval,
"interactive": self.interactive,
"dashboard": self.dashboard,
"dynamic_temperature": self.dynamic_temperature,
}
with open(file_path, "w") as f:
json.dump(state, f, indent=4)
saved = colored("Saved flow state to", "green")
print(f"{saved} {file_path}")
def load_state(self, file_path: str):
"""
Loads the state of the flow from a json file and restores the configuration and memory.
Example:
>>> flow = Flow(llm=llm_instance, max_loops=5)
>>> flow.load_state('saved_flow.json')
>>> flow.run("Continue with the task")
"""
with open(file_path, "r") as f:
state = json.load(f)
# Restore other saved attributes
self.memory = state.get("memory", [])
self.max_loops = state.get("max_loops", 5)
self.loop_interval = state.get("loop_interval", 1)
self.retry_attempts = state.get("retry_attempts", 3)
self.retry_interval = state.get("retry_interval", 1)
self.interactive = state.get("interactive", False)
print(f"Flow state loaded from {file_path}")
def retry_on_failure(self, function, retries: int = 3, retry_delay: int = 1):
"""Retry wrapper for LLM calls."""
attempt = 0
while attempt < retries:
try:
return function()
except Exception as error:
logging.error(f"Error generating response: {error}")
attempt += 1
time.sleep(retry_delay)
raise Exception("All retry attempts failed")
def generate_reply(self, history: str, **kwargs) -> str:
"""
Generate a response based on initial or task
"""
prompt = f"""
SYSTEM_PROMPT: {self.system_prompt}
History: {history}
Your response:
"""
response = self.llm(prompt, **kwargs)
return {"role": self.name, "content": response}
def update_system_prompt(self, system_prompt: str):
"""Upddate the system message"""
self.system_prompt = system_prompt

@ -1,20 +1,398 @@
""" """
Sequential Workflow TODO:
- Add a method to update the arguments of a task
- Add a method to get the results of each task
- Add a method to get the results of a specific task
- Add a method to get the results of the workflow
- Add a method to get the results of the workflow as a dataframe
from swarms.models import OpenAIChat, Mistral
from swarms.structs import SequentialWorkflow
- Add a method to run the workflow in parallel with a pool of workers and a queue and a dashboard
- Add a dashboard to visualize the workflow
- Add async support
- Add context manager support
- Add workflow history
"""
import json
from dataclasses import dataclass, field
from typing import Any, Callable, Dict, List, Optional, Union
llm = OpenAIChat(openai_api_key="") from termcolor import colored
mistral = Mistral()
# Max loops will run over the sequential pipeline twice from swarms.structs.flow import Flow
workflow = SequentialWorkflow(max_loops=2)
workflow.add("What's the weather in miami", llm)
workflow.add("Create a report on these metrics", mistral) # Define a generic Task that can handle different types of callable objects
@dataclass
class Task:
"""
Task class for running a task in a sequential workflow.
workflow.run()
""" Examples:
>>> from swarms.structs import Task, Flow
>>> from swarms.models import OpenAIChat
>>> flow = Flow(llm=OpenAIChat(openai_api_key=""), max_loops=1, dashboard=False)
>>> task = Task(description="What's the weather in miami", flow=flow)
>>> task.execute()
>>> task.result
"""
description: str
flow: Union[Callable, Flow]
args: List[Any] = field(default_factory=list)
kwargs: Dict[str, Any] = field(default_factory=dict)
result: Any = None
history: List[Any] = field(default_factory=list)
def execute(self):
"""
Execute the task.
Raises:
ValueError: If a Flow instance is used as a task and the 'task' argument is not provided.
"""
if isinstance(self.flow, Flow):
# Add a prompt to notify the Flow of the sequential workflow
if "prompt" in self.kwargs:
self.kwargs["prompt"] += (
f"\n\nPrevious output: {self.result}" if self.result else ""
)
else:
self.kwargs["prompt"] = f"Main task: {self.description}" + (
f"\n\nPrevious output: {self.result}" if self.result else ""
)
self.result = self.flow.run(*self.args, **self.kwargs)
else:
self.result = self.flow(*self.args, **self.kwargs)
self.history.append(self.result)
# SequentialWorkflow class definition using dataclasses
@dataclass
class SequentialWorkflow:
"""
SequentialWorkflow class for running a sequence of tasks using N number of autonomous agents.
Args:
max_loops (int): The maximum number of times to run the workflow.
dashboard (bool): Whether to display the dashboard for the workflow.
Attributes:
tasks (List[Task]): The list of tasks to execute.
max_loops (int): The maximum number of times to run the workflow.
dashboard (bool): Whether to display the dashboard for the workflow.
Examples:
>>> from swarms.models import OpenAIChat
>>> from swarms.structs import SequentialWorkflow
>>> llm = OpenAIChat(openai_api_key="")
>>> workflow = SequentialWorkflow(max_loops=1)
>>> workflow.add("What's the weather in miami", llm)
>>> workflow.add("Create a report on these metrics", llm)
>>> workflow.run()
>>> workflow.tasks
"""
tasks: List[Task] = field(default_factory=list)
max_loops: int = 1
autosave: bool = False
saved_state_filepath: Optional[str] = "sequential_workflow_state.json"
restore_state_filepath: Optional[str] = None
dashboard: bool = False
def add(self, task: str, flow: Union[Callable, Flow], *args, **kwargs) -> None:
"""
Add a task to the workflow.
Args:
task (str): The task description or the initial input for the Flow.
flow (Union[Callable, Flow]): The model or flow to execute the task.
*args: Additional arguments to pass to the task execution.
**kwargs: Additional keyword arguments to pass to the task execution.
"""
# If the flow is a Flow instance, we include the task in kwargs for Flow.run()
if isinstance(flow, Flow):
kwargs["task"] = task # Set the task as a keyword argument for Flow
# Append the task to the tasks list
self.tasks.append(
Task(description=task, flow=flow, args=list(args), kwargs=kwargs)
)
def reset_workflow(self) -> None:
"""Resets the workflow by clearing the results of each task."""
for task in self.tasks:
task.result = None
def get_task_results(self) -> Dict[str, Any]:
"""
Returns the results of each task in the workflow.
Returns:
Dict[str, Any]: The results of each task in the workflow
"""
return {task.description: task.result for task in self.tasks}
def remove_task(self, task_description: str) -> None:
self.tasks = [
task for task in self.tasks if task.description != task_description
]
def update_task(self, task_description: str, **updates) -> None:
"""
Updates the arguments of a task in the workflow.
Args:
task_description (str): The description of the task to update.
**updates: The updates to apply to the task.
Raises:
ValueError: If the task is not found in the workflow.
Examples:
>>> from swarms.models import OpenAIChat
>>> from swarms.structs import SequentialWorkflow
>>> llm = OpenAIChat(openai_api_key="")
>>> workflow = SequentialWorkflow(max_loops=1)
>>> workflow.add("What's the weather in miami", llm)
>>> workflow.add("Create a report on these metrics", llm)
>>> workflow.update_task("What's the weather in miami", max_tokens=1000)
>>> workflow.tasks[0].kwargs
{'max_tokens': 1000}
"""
for task in self.tasks:
if task.description == task_description:
task.kwargs.update(updates)
break
else:
raise ValueError(f"Task {task_description} not found in workflow.")
def save_workflow_state(
self, filepath: Optional[str] = "sequential_workflow_state.json", **kwargs
) -> None:
"""
Saves the workflow state to a json file.
Args:
filepath (str): The path to save the workflow state to.
Examples:
>>> from swarms.models import OpenAIChat
>>> from swarms.structs import SequentialWorkflow
>>> llm = OpenAIChat(openai_api_key="")
>>> workflow = SequentialWorkflow(max_loops=1)
>>> workflow.add("What's the weather in miami", llm)
>>> workflow.add("Create a report on these metrics", llm)
>>> workflow.save_workflow_state("sequential_workflow_state.json")
"""
filepath = filepath or self.saved_state_filepath
with open(filepath, "w") as f:
# Saving the state as a json for simplicuty
state = {
"tasks": [
{
"description": task.description,
"args": task.args,
"kwargs": task.kwargs,
"result": task.result,
"history": task.history,
}
for task in self.tasks
],
"max_loops": self.max_loops,
}
json.dump(state, f, indent=4)
def workflow_bootup(self, **kwargs) -> None:
print(
colored(
"""
Sequential Workflow Initializing...""",
"green",
attrs=["bold", "underline"],
)
)
def workflow_dashboard(self, **kwargs) -> None:
"""
Displays a dashboard for the workflow.
Args:
**kwargs: Additional keyword arguments to pass to the dashboard.
Examples:
>>> from swarms.models import OpenAIChat
>>> from swarms.structs import SequentialWorkflow
>>> llm = OpenAIChat(openai_api_key="")
>>> workflow = SequentialWorkflow(max_loops=1)
>>> workflow.add("What's the weather in miami", llm)
>>> workflow.add("Create a report on these metrics", llm)
>>> workflow.workflow_dashboard()
"""
print(
colored(
f"""
Sequential Workflow Dashboard
--------------------------------
Tasks: {len(self.tasks)}
Max Loops: {self.max_loops}
Autosave: {self.autosave}
Autosave Filepath: {self.saved_state_filepath}
Restore Filepath: {self.restore_state_filepath}
--------------------------------
Metadata:
kwargs: {kwargs}
""",
"cyan",
attrs=["bold", "underline"],
)
)
def load_workflow_state(self, filepath: str = None, **kwargs) -> None:
"""
Loads the workflow state from a json file and restores the workflow state.
Args:
filepath (str): The path to load the workflow state from.
Examples:
>>> from swarms.models import OpenAIChat
>>> from swarms.structs import SequentialWorkflow
>>> llm = OpenAIChat(openai_api_key="")
>>> workflow = SequentialWorkflow(max_loops=1)
>>> workflow.add("What's the weather in miami", llm)
>>> workflow.add("Create a report on these metrics", llm)
>>> workflow.save_workflow_state("sequential_workflow_state.json")
>>> workflow.load_workflow_state("sequential_workflow_state.json")
"""
filepath = filepath or self.restore_state_filepath
with open(filepath, "r") as f:
state = json.load(f)
self.max_loops = state["max_loops"]
self.tasks = []
for task_state in state["tasks"]:
task = Task(
description=task_state["description"],
flow=task_state["flow"],
args=task_state["args"],
kwargs=task_state["kwargs"],
result=task_state["result"],
history=task_state["history"],
)
self.tasks.append(task)
def run(self) -> None:
"""
Run the workflow.
Raises:
ValueError: If a Flow instance is used as a task and the 'task' argument is not provided.
"""
try:
self.workflow_bootup()
for _ in range(self.max_loops):
for task in self.tasks:
# Check if the current task can be executed
if task.result is None:
# Check if the flow is a Flow and a 'task' argument is needed
if isinstance(task.flow, Flow):
# Ensure that 'task' is provided in the kwargs
if "task" not in task.kwargs:
raise ValueError(
f"The 'task' argument is required for the Flow flow execution in '{task.description}'"
)
# Separate the 'task' argument from other kwargs
flow_task_arg = task.kwargs.pop("task")
task.result = task.flow.run(
flow_task_arg, *task.args, **task.kwargs
)
else:
# If it's not a Flow instance, call the flow directly
task.result = task.flow(*task.args, **task.kwargs)
# Pass the result as an argument to the next task if it exists
next_task_index = self.tasks.index(task) + 1
if next_task_index < len(self.tasks):
next_task = self.tasks[next_task_index]
if isinstance(next_task.flow, Flow):
# For Flow flows, 'task' should be a keyword argument
next_task.kwargs["task"] = task.result
else:
# For other callable flows, the result is added to args
next_task.args.insert(0, task.result)
# Autosave the workflow state
if self.autosave:
self.save_workflow_state("sequential_workflow_state.json")
except Exception as e:
print(
colored(
f"Error initializing the Sequential workflow: {e} try optimizing your inputs like the flow class and task description",
"red",
attrs=["bold", "underline"],
)
)
async def arun(self) -> None:
"""
Asynchronously run the workflow.
Raises:
ValueError: If a Flow instance is used as a task and the 'task' argument is not provided.
"""
for _ in range(self.max_loops):
for task in self.tasks:
# Check if the current task can be executed
if task.result is None:
# Check if the flow is a Flow and a 'task' argument is needed
if isinstance(task.flow, Flow):
# Ensure that 'task' is provided in the kwargs
if "task" not in task.kwargs:
raise ValueError(
f"The 'task' argument is required for the Flow flow execution in '{task.description}'"
)
# Separate the 'task' argument from other kwargs
flow_task_arg = task.kwargs.pop("task")
task.result = await task.flow.arun(
flow_task_arg, *task.args, **task.kwargs
)
else:
# If it's not a Flow instance, call the flow directly
task.result = await task.flow(*task.args, **task.kwargs)
# Pass the result as an argument to the next task if it exists
next_task_index = self.tasks.index(task) + 1
if next_task_index < len(self.tasks):
next_task = self.tasks[next_task_index]
if isinstance(next_task.flow, Flow):
# For Flow flows, 'task' should be a keyword argument
next_task.kwargs["task"] = task.result
else:
# For other callable flows, the result is added to args
next_task.args.insert(0, task.result)
# Autosave the workflow state
if self.autosave:
self.save_workflow_state("sequential_workflow_state.json")

@ -78,8 +78,6 @@ class AbstractSwarm(ABC):
Scale down the number of workers Scale down the number of workers
""" """
# TODO: Pass in abstract LLM class that can utilize Hf or Anthropic models, Move away from OPENAI # TODO: Pass in abstract LLM class that can utilize Hf or Anthropic models, Move away from OPENAI

@ -1,7 +1,10 @@
from dataclasses import dataclass from dataclasses import dataclass
import sys import sys
from typing import Dict, List, Optional, Union from typing import Dict, List, Optional, Union
import logging import logging
from swarms.structs.flow import Flow
from swarms import Flow, OpenAI from swarms import Flow, OpenAI
@ -39,11 +42,15 @@ class GroupChat:
def select_speaker_msg(self): def select_speaker_msg(self):
"""Return the message for selecting the next speaker.""" """Return the message for selecting the next speaker."""
return f"""You are in a role play game. The following roles are available:
{self._participant_roles()}.
Read the following conversation. return f"""
Then select the next role from {self.agent_names} to play. Only return the role.""" You are in a role play game. The following roles are available:
{self._participant_roles()}.
Read the following conversation.
Then select the next role from {self.agent_names} to play. Only return the role.
"""
def select_speaker(self, last_speaker: Flow, selector: Flow): def select_speaker(self, last_speaker: Flow, selector: Flow):
"""Select the next speaker.""" """Select the next speaker."""
@ -57,41 +64,52 @@ Then select the next role from {self.agent_names} to play. Only return the role.
) )
name = selector.generate_reply( name = selector.generate_reply(
self.format_history(self.messages
self.format_history(
self.messages
+ [ + [
{ {
"role": "system", "role": "system",
"content": f"Read the above conversation. Then select the next most suitable role from {self.agent_names} to play. Only return the role.", "content": f"Read the above conversation. Then select the next most suitable role from {self.agent_names} to play. Only return the role.",
} }
]) ]
)
) )
try: try:
return self.agent_by_name(name['content']) return self.agent_by_name(name["content"])
except ValueError: except ValueError:
return self.next_agent(last_speaker) return self.next_agent(last_speaker)
def _participant_roles(self): def _participant_roles(self):
return "\n".join([f"{agent.name}: {agent.system_message}" for agent in self.agents])
return "\n".join(
[f"{agent.name}: {agent.system_message}" for agent in self.agents]
)
def format_history(self, messages: List[Dict]) -> str: def format_history(self, messages: List[Dict]) -> str:
formatted_messages = [] formatted_messages = []
for message in messages: for message in messages:
formatted_message = f"'{message['role']}:{message['content']}" formatted_message = f"'{message['role']}:{message['content']}"
formatted_messages.append(formatted_message) formatted_messages.append(formatted_message)
return '\n'.join(formatted_messages) return "\n".join(formatted_messages)
class GroupChatManager: class GroupChatManager:
def __init__(self, groupchat: GroupChat, selector: Flow): def __init__(self, groupchat: GroupChat, selector: Flow):
self.groupchat = groupchat self.groupchat = groupchat
self.selector = selector self.selector = selector
def __call__(self, task: str): def __call__(self, task: str):
self.groupchat.messages.append({'role':self.selector.name, 'content': task}) self.groupchat.messages.append({"role": self.selector.name, "content": task})
for i in range(self.groupchat.max_round): for i in range(self.groupchat.max_round):
speaker = self.groupchat.select_speaker(last_speaker=self.selector, selector=self.selector) speaker = self.groupchat.select_speaker(
reply = speaker.generate_reply(self.groupchat.format_history(self.groupchat.messages)) last_speaker=self.selector, selector=self.selector
)
reply = speaker.generate_reply(
self.groupchat.format_history(self.groupchat.messages)
)
self.groupchat.messages.append(reply) self.groupchat.messages.append(reply)
print(reply) print(reply)
if i == self.groupchat.max_round - 1: if i == self.groupchat.max_round - 1:

@ -1,24 +0,0 @@
import os
import interpreter
def compile(task: str):
"""
Open Interpreter lets LLMs run code (Python, Javascript, Shell, and more) locally. You can chat with Open Interpreter through a ChatGPT-like interface in your terminal by running $ interpreter after installing.
This provides a natural-language interface to your computer's general-purpose capabilities:
Create and edit photos, videos, PDFs, etc.
Control a Chrome browser to perform research
Plot, clean, and analyze large datasets
...etc.
Note: You'll be asked to approve code before it's run.
"""
task = interpreter.chat(task, return_messages=True)
interpreter.chat()
interpreter.reset(task)
os.environ["INTERPRETER_CLI_AUTO_RUN"] = True
os.environ["INTERPRETER_CLI_FAST_MODE"] = True
os.environ["INTERPRETER_CLI_DEBUG"] = True

@ -25,6 +25,15 @@ class SubprocessCodeInterpreter(BaseCodeInterpreter):
SubprocessCodeinterpreter is a base class for code interpreters that run code in a subprocess. SubprocessCodeinterpreter is a base class for code interpreters that run code in a subprocess.
Attributes:
start_cmd (str): The command to start the subprocess. Should be a string that can be split by spaces.
process (subprocess.Popen): The subprocess that is running the code.
debug_mode (bool): Whether to print debug statements.
output_queue (queue.Queue): A queue that is filled with output from the subprocess.
done (threading.Event): An event that is set when the subprocess is done running code.
Example:
>>> from swarms.utils.code_interpreter import SubprocessCodeInterpreter
""" """

@ -1,2 +1,2 @@
from swarms.workers.worker import Worker # from swarms.workers.worker import Worker
from swarms.workers.base import AbstractWorker from swarms.workers.base import AbstractWorker

@ -3,7 +3,7 @@ from swarms.chunkers.base import (
BaseChunker, BaseChunker,
TextArtifact, TextArtifact,
ChunkSeparator, ChunkSeparator,
OpenAiTokenizer, OpenAITokenizer,
) # adjust the import paths accordingly ) # adjust the import paths accordingly
@ -21,7 +21,7 @@ def test_default_separators():
def test_default_tokenizer(): def test_default_tokenizer():
chunker = BaseChunker() chunker = BaseChunker()
assert isinstance(chunker.tokenizer, OpenAiTokenizer) assert isinstance(chunker.tokenizer, OpenAITokenizer)
# 2. Test Basic Chunking # 2. Test Basic Chunking

@ -3,12 +3,15 @@
import pytest import pytest
import openai import openai
from unittest.mock import patch from unittest.mock import patch
from swarms.models.simple_ada import get_ada_embeddings # Adjust this import path to your project structure from swarms.models.simple_ada import (
get_ada_embeddings,
) # Adjust this import path to your project structure
from os import getenv from os import getenv
from dotenv import load_dotenv from dotenv import load_dotenv
load_dotenv() load_dotenv()
# Fixture for test texts # Fixture for test texts
@pytest.fixture @pytest.fixture
def test_texts(): def test_texts():
@ -18,20 +21,24 @@ def test_texts():
"A quick brown fox jumps over the lazy dog", "A quick brown fox jumps over the lazy dog",
] ]
# Basic Test # Basic Test
def test_get_ada_embeddings_basic(test_texts): def test_get_ada_embeddings_basic(test_texts):
with patch('openai.Embedding.create') as mock_create: with patch("openai.Embedding.create") as mock_create:
# Mocking the OpenAI API call # Mocking the OpenAI API call
mock_create.return_value = { mock_create.return_value = {"data": [{"embedding": [0.1, 0.2, 0.3]}]}
"data": [
{"embedding": [0.1, 0.2, 0.3]}
]
}
for text in test_texts: for text in test_texts:
embedding = get_ada_embeddings(text) embedding = get_ada_embeddings(text)
assert embedding == [0.1, 0.2, 0.3], "Embedding does not match expected output" assert embedding == [
mock_create.assert_called_with(input=[text.replace("\n", " ")], model="text-embedding-ada-002") 0.1,
0.2,
0.3,
], "Embedding does not match expected output"
mock_create.assert_called_with(
input=[text.replace("\n", " ")], model="text-embedding-ada-002"
)
# Parameterized Test # Parameterized Test
@pytest.mark.parametrize( @pytest.mark.parametrize(
@ -42,27 +49,28 @@ def test_get_ada_embeddings_basic(test_texts):
], ],
) )
def test_get_ada_embeddings_models(text, model, expected_call_model): def test_get_ada_embeddings_models(text, model, expected_call_model):
with patch('openai.Embedding.create') as mock_create: with patch("openai.Embedding.create") as mock_create:
mock_create.return_value = { mock_create.return_value = {"data": [{"embedding": [0.1, 0.2, 0.3]}]}
"data": [
{"embedding": [0.1, 0.2, 0.3]}
]
}
_ = get_ada_embeddings(text, model=model) _ = get_ada_embeddings(text, model=model)
mock_create.assert_called_with(input=[text], model=expected_call_model) mock_create.assert_called_with(input=[text], model=expected_call_model)
# Exception Test # Exception Test
def test_get_ada_embeddings_exception(): def test_get_ada_embeddings_exception():
with patch('openai.Embedding.create') as mock_create: with patch("openai.Embedding.create") as mock_create:
mock_create.side_effect = openai.error.OpenAIError("Test error") mock_create.side_effect = openai.error.OpenAIError("Test error")
with pytest.raises(openai.error.OpenAIError): with pytest.raises(openai.error.OpenAIError):
get_ada_embeddings("Some text") get_ada_embeddings("Some text")
# Tests for environment variable loading # Tests for environment variable loading
def test_env_var_loading(monkeypatch): def test_env_var_loading(monkeypatch):
monkeypatch.setenv("OPENAI_API_KEY", "testkey123") monkeypatch.setenv("OPENAI_API_KEY", "testkey123")
with patch('openai.Embedding.create'): with patch("openai.Embedding.create"):
assert getenv("OPENAI_API_KEY") == "testkey123", "Environment variable for API key is not set correctly" assert (
getenv("OPENAI_API_KEY") == "testkey123"
), "Environment variable for API key is not set correctly"
# ... more tests to cover other aspects such as different input types, large inputs, invalid inputs, etc. # ... more tests to cover other aspects such as different input types, large inputs, invalid inputs, etc.

@ -0,0 +1,127 @@
import os
import pytest
from unittest.mock import Mock, patch
from swarms.models.anthropic import Anthropic
@pytest.fixture
def mock_anthropic_env():
os.environ["ANTHROPIC_API_URL"] = "https://test.anthropic.com"
os.environ["ANTHROPIC_API_KEY"] = "test_api_key"
yield
del os.environ["ANTHROPIC_API_URL"]
del os.environ["ANTHROPIC_API_KEY"]
@pytest.fixture
def mock_requests_post():
with patch("requests.post") as mock_post:
yield mock_post
@pytest.fixture
def anthropic_instance():
return Anthropic(model="test-model")
def test_anthropic_init_default_values(anthropic_instance):
assert anthropic_instance.model == "test-model"
assert anthropic_instance.max_tokens_to_sample == 256
assert anthropic_instance.temperature is None
assert anthropic_instance.top_k is None
assert anthropic_instance.top_p is None
assert anthropic_instance.streaming is False
assert anthropic_instance.default_request_timeout == 600
assert anthropic_instance.anthropic_api_url == "https://test.anthropic.com"
assert anthropic_instance.anthropic_api_key == "test_api_key"
def test_anthropic_init_custom_values():
anthropic_instance = Anthropic(
model="custom-model",
max_tokens_to_sample=128,
temperature=0.8,
top_k=5,
top_p=0.9,
streaming=True,
default_request_timeout=300,
)
assert anthropic_instance.model == "custom-model"
assert anthropic_instance.max_tokens_to_sample == 128
assert anthropic_instance.temperature == 0.8
assert anthropic_instance.top_k == 5
assert anthropic_instance.top_p == 0.9
assert anthropic_instance.streaming is True
assert anthropic_instance.default_request_timeout == 300
def test_anthropic_default_params(anthropic_instance):
default_params = anthropic_instance._default_params()
assert default_params == {
"max_tokens_to_sample": 256,
"model": "test-model",
}
def test_anthropic_run(mock_anthropic_env, mock_requests_post, anthropic_instance):
mock_response = Mock()
mock_response.json.return_value = {"completion": "Generated text"}
mock_requests_post.return_value = mock_response
task = "Generate text"
stop = ["stop1", "stop2"]
completion = anthropic_instance.run(task, stop)
assert completion == "Generated text"
mock_requests_post.assert_called_once_with(
"https://test.anthropic.com/completions",
headers={"Authorization": "Bearer test_api_key"},
json={
"prompt": task,
"stop_sequences": stop,
"max_tokens_to_sample": 256,
"model": "test-model",
},
timeout=600,
)
def test_anthropic_call(mock_anthropic_env, mock_requests_post, anthropic_instance):
mock_response = Mock()
mock_response.json.return_value = {"completion": "Generated text"}
mock_requests_post.return_value = mock_response
task = "Generate text"
stop = ["stop1", "stop2"]
completion = anthropic_instance(task, stop)
assert completion == "Generated text"
mock_requests_post.assert_called_once_with(
"https://test.anthropic.com/completions",
headers={"Authorization": "Bearer test_api_key"},
json={
"prompt": task,
"stop_sequences": stop,
"max_tokens_to_sample": 256,
"model": "test-model",
},
timeout=600,
)
def test_anthropic_exception_handling(
mock_anthropic_env, mock_requests_post, anthropic_instance
):
mock_response = Mock()
mock_response.json.return_value = {"error": "An error occurred"}
mock_requests_post.return_value = mock_response
task = "Generate text"
stop = ["stop1", "stop2"]
with pytest.raises(Exception) as excinfo:
anthropic_instance(task, stop)
assert "An error occurred" in str(excinfo.value)

@ -0,0 +1,410 @@
import os
from unittest.mock import Mock
import pytest
from openai import OpenAIError
from PIL import Image
from termcolor import colored
from playground.models.dalle3 import Dalle3
# Mocking the OpenAI client to avoid making actual API calls during testing
@pytest.fixture
def mock_openai_client():
return Mock()
@pytest.fixture
def dalle3(mock_openai_client):
return Dalle3(client=mock_openai_client)
def test_dalle3_call_success(dalle3, mock_openai_client):
# Arrange
task = "A painting of a dog"
expected_img_url = (
"https://cdn.openai.com/dall-e/encoded/feats/feats_01J9J5ZKJZJY9.png"
)
mock_openai_client.images.generate.return_value = Mock(
data=[Mock(url=expected_img_url)]
)
# Act
img_url = dalle3(task)
# Assert
assert img_url == expected_img_url
mock_openai_client.images.generate.assert_called_once_with(prompt=task, n=4)
def test_dalle3_call_failure(dalle3, mock_openai_client, capsys):
# Arrange
task = "Invalid task"
expected_error_message = "Error running Dalle3: API Error"
# Mocking OpenAIError
mock_openai_client.images.generate.side_effect = OpenAIError(
expected_error_message, http_status=500, error="Internal Server Error"
)
# Act and assert
with pytest.raises(OpenAIError) as excinfo:
dalle3(task)
assert str(excinfo.value) == expected_error_message
mock_openai_client.images.generate.assert_called_once_with(prompt=task, n=4)
# Ensure the error message is printed in red
captured = capsys.readouterr()
assert colored(expected_error_message, "red") in captured.out
def test_dalle3_create_variations_success(dalle3, mock_openai_client):
# Arrange
img_url = "https://cdn.openai.com/dall-e/encoded/feats/feats_01J9J5ZKJZJY9.png"
expected_variation_url = (
"https://cdn.openai.com/dall-e/encoded/feats/feats_02ABCDE.png"
)
mock_openai_client.images.create_variation.return_value = Mock(
data=[Mock(url=expected_variation_url)]
)
# Act
variation_img_url = dalle3.create_variations(img_url)
# Assert
assert variation_img_url == expected_variation_url
mock_openai_client.images.create_variation.assert_called_once()
_, kwargs = mock_openai_client.images.create_variation.call_args
assert kwargs["img"] is not None
assert kwargs["n"] == 4
assert kwargs["size"] == "1024x1024"
def test_dalle3_create_variations_failure(dalle3, mock_openai_client, capsys):
# Arrange
img_url = "https://cdn.openai.com/dall-e/encoded/feats/feats_01J9J5ZKJZJY9.png"
expected_error_message = "Error running Dalle3: API Error"
# Mocking OpenAIError
mock_openai_client.images.create_variation.side_effect = OpenAIError(
expected_error_message, http_status=500, error="Internal Server Error"
)
# Act and assert
with pytest.raises(OpenAIError) as excinfo:
dalle3.create_variations(img_url)
assert str(excinfo.value) == expected_error_message
mock_openai_client.images.create_variation.assert_called_once()
# Ensure the error message is printed in red
captured = capsys.readouterr()
assert colored(expected_error_message, "red") in captured.out
def test_dalle3_read_img():
# Arrange
img_path = "test_image.png"
img = Image.new("RGB", (512, 512))
# Save the image temporarily
img.save(img_path)
# Act
dalle3 = Dalle3()
img_loaded = dalle3.read_img(img_path)
# Assert
assert isinstance(img_loaded, Image.Image)
# Clean up
os.remove(img_path)
def test_dalle3_set_width_height():
# Arrange
img = Image.new("RGB", (512, 512))
width = 256
height = 256
# Act
dalle3 = Dalle3()
img_resized = dalle3.set_width_height(img, width, height)
# Assert
assert img_resized.size == (width, height)
def test_dalle3_convert_to_bytesio():
# Arrange
img = Image.new("RGB", (512, 512))
expected_format = "PNG"
# Act
dalle3 = Dalle3()
img_bytes = dalle3.convert_to_bytesio(img, format=expected_format)
# Assert
assert isinstance(img_bytes, bytes)
assert img_bytes.startswith(b"\x89PNG")
def test_dalle3_call_multiple_times(dalle3, mock_openai_client):
# Arrange
task = "A painting of a dog"
expected_img_url = (
"https://cdn.openai.com/dall-e/encoded/feats/feats_01J9J5ZKJZJY9.png"
)
mock_openai_client.images.generate.return_value = Mock(
data=[Mock(url=expected_img_url)]
)
# Act
img_url1 = dalle3(task)
img_url2 = dalle3(task)
# Assert
assert img_url1 == expected_img_url
assert img_url2 == expected_img_url
assert mock_openai_client.images.generate.call_count == 2
def test_dalle3_call_with_large_input(dalle3, mock_openai_client):
# Arrange
task = "A" * 2048 # Input longer than API's limit
expected_error_message = "Error running Dalle3: API Error"
mock_openai_client.images.generate.side_effect = OpenAIError(
expected_error_message, http_status=500, error="Internal Server Error"
)
# Act and assert
with pytest.raises(OpenAIError) as excinfo:
dalle3(task)
assert str(excinfo.value) == expected_error_message
def test_dalle3_create_variations_with_invalid_image_url(dalle3, mock_openai_client):
# Arrange
img_url = "https://invalid-image-url.com"
expected_error_message = "Error running Dalle3: Invalid image URL"
# Act and assert
with pytest.raises(ValueError) as excinfo:
dalle3.create_variations(img_url)
assert str(excinfo.value) == expected_error_message
def test_dalle3_set_width_height_invalid_dimensions(dalle3):
# Arrange
img = dalle3.read_img("test_image.png")
width = 0
height = -1
# Act and assert
with pytest.raises(ValueError):
dalle3.set_width_height(img, width, height)
def test_dalle3_convert_to_bytesio_invalid_format(dalle3):
# Arrange
img = dalle3.read_img("test_image.png")
invalid_format = "invalid_format"
# Act and assert
with pytest.raises(ValueError):
dalle3.convert_to_bytesio(img, format=invalid_format)
def test_dalle3_call_with_retry(dalle3, mock_openai_client):
# Arrange
task = "A painting of a dog"
expected_img_url = (
"https://cdn.openai.com/dall-e/encoded/feats/feats_01J9J5ZKJZJY9.png"
)
# Simulate a retry scenario
mock_openai_client.images.generate.side_effect = [
OpenAIError("Temporary error", http_status=500, error="Internal Server Error"),
Mock(data=[Mock(url=expected_img_url)]),
]
# Act
img_url = dalle3(task)
# Assert
assert img_url == expected_img_url
assert mock_openai_client.images.generate.call_count == 2
def test_dalle3_create_variations_with_retry(dalle3, mock_openai_client):
# Arrange
img_url = "https://cdn.openai.com/dall-e/encoded/feats/feats_01J9J5ZKJZJY9.png"
expected_variation_url = (
"https://cdn.openai.com/dall-e/encoded/feats/feats_02ABCDE.png"
)
# Simulate a retry scenario
mock_openai_client.images.create_variation.side_effect = [
OpenAIError("Temporary error", http_status=500, error="Internal Server Error"),
Mock(data=[Mock(url=expected_variation_url)]),
]
# Act
variation_img_url = dalle3.create_variations(img_url)
# Assert
assert variation_img_url == expected_variation_url
assert mock_openai_client.images.create_variation.call_count == 2
def test_dalle3_call_exception_logging(dalle3, mock_openai_client, capsys):
# Arrange
task = "A painting of a dog"
expected_error_message = "Error running Dalle3: API Error"
# Mocking OpenAIError
mock_openai_client.images.generate.side_effect = OpenAIError(
expected_error_message, http_status=500, error="Internal Server Error"
)
# Act
with pytest.raises(OpenAIError):
dalle3(task)
# Assert that the error message is logged
captured = capsys.readouterr()
assert expected_error_message in captured.err
def test_dalle3_create_variations_exception_logging(dalle3, mock_openai_client, capsys):
# Arrange
img_url = "https://cdn.openai.com/dall-e/encoded/feats/feats_01J9J5ZKJZJY9.png"
expected_error_message = "Error running Dalle3: API Error"
# Mocking OpenAIError
mock_openai_client.images.create_variation.side_effect = OpenAIError(
expected_error_message, http_status=500, error="Internal Server Error"
)
# Act
with pytest.raises(OpenAIError):
dalle3.create_variations(img_url)
# Assert that the error message is logged
captured = capsys.readouterr()
assert expected_error_message in captured.err
def test_dalle3_read_img_invalid_path(dalle3):
# Arrange
invalid_img_path = "invalid_image_path.png"
# Act and assert
with pytest.raises(FileNotFoundError):
dalle3.read_img(invalid_img_path)
def test_dalle3_call_no_api_key():
# Arrange
task = "A painting of a dog"
dalle3 = Dalle3(api_key=None)
expected_error_message = "Error running Dalle3: API Key is missing"
# Act and assert
with pytest.raises(ValueError) as excinfo:
dalle3(task)
assert str(excinfo.value) == expected_error_message
def test_dalle3_create_variations_no_api_key():
# Arrange
img_url = "https://cdn.openai.com/dall-e/encoded/feats/feats_01J9J5ZKJZJY9.png"
dalle3 = Dalle3(api_key=None)
expected_error_message = "Error running Dalle3: API Key is missing"
# Act and assert
with pytest.raises(ValueError) as excinfo:
dalle3.create_variations(img_url)
assert str(excinfo.value) == expected_error_message
def test_dalle3_call_with_retry_max_retries_exceeded(dalle3, mock_openai_client):
# Arrange
task = "A painting of a dog"
# Simulate max retries exceeded
mock_openai_client.images.generate.side_effect = OpenAIError(
"Temporary error", http_status=500, error="Internal Server Error"
)
# Act and assert
with pytest.raises(OpenAIError) as excinfo:
dalle3(task)
assert "Retry limit exceeded" in str(excinfo.value)
def test_dalle3_create_variations_with_retry_max_retries_exceeded(
dalle3, mock_openai_client
):
# Arrange
img_url = "https://cdn.openai.com/dall-e/encoded/feats/feats_01J9J5ZKJZJY9.png"
# Simulate max retries exceeded
mock_openai_client.images.create_variation.side_effect = OpenAIError(
"Temporary error", http_status=500, error="Internal Server Error"
)
# Act and assert
with pytest.raises(OpenAIError) as excinfo:
dalle3.create_variations(img_url)
assert "Retry limit exceeded" in str(excinfo.value)
def test_dalle3_call_retry_with_success(dalle3, mock_openai_client):
# Arrange
task = "A painting of a dog"
expected_img_url = (
"https://cdn.openai.com/dall-e/encoded/feats/feats_01J9J5ZKJZJY9.png"
)
# Simulate success after a retry
mock_openai_client.images.generate.side_effect = [
OpenAIError("Temporary error", http_status=500, error="Internal Server Error"),
Mock(data=[Mock(url=expected_img_url)]),
]
# Act
img_url = dalle3(task)
# Assert
assert img_url == expected_img_url
assert mock_openai_client.images.generate.call_count == 2
def test_dalle3_create_variations_retry_with_success(dalle3, mock_openai_client):
# Arrange
img_url = "https://cdn.openai.com/dall-e/encoded/feats/feats_01J9J5ZKJZJY9.png"
expected_variation_url = (
"https://cdn.openai.com/dall-e/encoded/feats/feats_02ABCDE.png"
)
# Simulate success after a retry
mock_openai_client.images.create_variation.side_effect = [
OpenAIError("Temporary error", http_status=500, error="Internal Server Error"),
Mock(data=[Mock(url=expected_variation_url)]),
]
# Act
variation_img_url = dalle3.create_variations(img_url)
# Assert
assert variation_img_url == expected_variation_url
assert mock_openai_client.images.create_variation.call_count == 2

@ -0,0 +1,119 @@
# test_distilled_whisperx.py
from unittest.mock import AsyncMock, MagicMock
import pytest
import torch
from transformers import AutoModelForSpeechSeq2Seq, AutoProcessor
from swarms.models.distilled_whisperx import DistilWhisperModel, async_retry
# Fixtures for setting up model, processor, and audio files
@pytest.fixture(scope="module")
def model_id():
return "distil-whisper/distil-large-v2"
@pytest.fixture(scope="module")
def whisper_model(model_id):
return DistilWhisperModel(model_id)
@pytest.fixture(scope="session")
def audio_file_path(tmp_path_factory):
# You would create a small temporary MP3 file here for testing
# or use a public domain MP3 file's path
return "path/to/valid_audio.mp3"
@pytest.fixture(scope="session")
def invalid_audio_file_path():
return "path/to/invalid_audio.mp3"
@pytest.fixture(scope="session")
def audio_dict():
# This should represent a valid audio dictionary as expected by the model
return {"array": torch.randn(1, 16000), "sampling_rate": 16000}
# Test initialization
def test_initialization(whisper_model):
assert whisper_model.model is not None
assert whisper_model.processor is not None
# Test successful transcription with file path
def test_transcribe_with_file_path(whisper_model, audio_file_path):
transcription = whisper_model.transcribe(audio_file_path)
assert isinstance(transcription, str)
# Test successful transcription with audio dict
def test_transcribe_with_audio_dict(whisper_model, audio_dict):
transcription = whisper_model.transcribe(audio_dict)
assert isinstance(transcription, str)
# Test for file not found error
def test_file_not_found(whisper_model, invalid_audio_file_path):
with pytest.raises(Exception):
whisper_model.transcribe(invalid_audio_file_path)
# Asynchronous tests
@pytest.mark.asyncio
async def test_async_transcription_success(whisper_model, audio_file_path):
transcription = await whisper_model.async_transcribe(audio_file_path)
assert isinstance(transcription, str)
@pytest.mark.asyncio
async def test_async_transcription_failure(whisper_model, invalid_audio_file_path):
with pytest.raises(Exception):
await whisper_model.async_transcribe(invalid_audio_file_path)
# Testing real-time transcription simulation
def test_real_time_transcription(whisper_model, audio_file_path, capsys):
whisper_model.real_time_transcribe(audio_file_path, chunk_duration=1)
captured = capsys.readouterr()
assert "Starting real-time transcription..." in captured.out
# Testing retry decorator for asynchronous function
@pytest.mark.asyncio
async def test_async_retry():
@async_retry(max_retries=2, exceptions=(ValueError,), delay=0)
async def failing_func():
raise ValueError("Test")
with pytest.raises(ValueError):
await failing_func()
# Mocking the actual model to avoid GPU/CPU intensive operations during test
@pytest.fixture
def mocked_model(monkeypatch):
model_mock = AsyncMock(AutoModelForSpeechSeq2Seq)
processor_mock = MagicMock(AutoProcessor)
monkeypatch.setattr(
"swarms.models.distilled_whisperx.AutoModelForSpeechSeq2Seq.from_pretrained",
model_mock,
)
monkeypatch.setattr(
"swarms.models.distilled_whisperx.AutoProcessor.from_pretrained", processor_mock
)
return model_mock, processor_mock
@pytest.mark.asyncio
async def test_async_transcribe_with_mocked_model(mocked_model, audio_file_path):
model_mock, processor_mock = mocked_model
# Set up what the mock should return when it's called
model_mock.return_value.generate.return_value = torch.tensor([[0]])
processor_mock.return_value.batch_decode.return_value = ["mocked transcription"]
model_wrapper = DistilWhisperModel()
transcription = await model_wrapper.async_transcribe(audio_file_path)
assert transcription == "mocked transcription"

@ -0,0 +1,386 @@
import logging
import os
from unittest.mock import Mock
import pytest
from dotenv import load_dotenv
from requests.exceptions import ConnectionError, HTTPError, RequestException, Timeout
from swarms.models.gpt4v import GPT4Vision, GPT4VisionResponse
load_dotenv
api_key = os.getenv("OPENAI_API_KEY")
# Mock the OpenAI client
@pytest.fixture
def mock_openai_client():
return Mock()
@pytest.fixture
def gpt4vision(mock_openai_client):
return GPT4Vision(client=mock_openai_client)
def test_gpt4vision_default_values():
# Arrange and Act
gpt4vision = GPT4Vision()
# Assert
assert gpt4vision.max_retries == 3
assert gpt4vision.model == "gpt-4-vision-preview"
assert gpt4vision.backoff_factor == 2.0
assert gpt4vision.timeout_seconds == 10
assert gpt4vision.api_key is None
assert gpt4vision.quality == "low"
assert gpt4vision.max_tokens == 200
def test_gpt4vision_api_key_from_env_variable():
# Arrange
api_key = os.environ["OPENAI_API_KEY"]
# Act
gpt4vision = GPT4Vision()
# Assert
assert gpt4vision.api_key == api_key
def test_gpt4vision_set_api_key():
# Arrange
gpt4vision = GPT4Vision(api_key=api_key)
# Assert
assert gpt4vision.api_key == api_key
def test_gpt4vision_invalid_max_retries():
# Arrange and Act
with pytest.raises(ValueError):
GPT4Vision(max_retries=-1)
def test_gpt4vision_invalid_backoff_factor():
# Arrange and Act
with pytest.raises(ValueError):
GPT4Vision(backoff_factor=-1)
def test_gpt4vision_invalid_timeout_seconds():
# Arrange and Act
with pytest.raises(ValueError):
GPT4Vision(timeout_seconds=-1)
def test_gpt4vision_invalid_max_tokens():
# Arrange and Act
with pytest.raises(ValueError):
GPT4Vision(max_tokens=-1)
def test_gpt4vision_logger_initialized():
# Arrange
gpt4vision = GPT4Vision()
# Assert
assert isinstance(gpt4vision.logger, logging.Logger)
def test_gpt4vision_process_img_nonexistent_file():
# Arrange
gpt4vision = GPT4Vision()
img_path = "nonexistent_image.jpg"
# Act and Assert
with pytest.raises(FileNotFoundError):
gpt4vision.process_img(img_path)
def test_gpt4vision_call_single_task_single_image_no_openai_client(gpt4vision):
# Arrange
img_url = "https://images.unsplash.com/photo-1694734479942-8cc7f4660578?q=80&w=1287&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
task = "Describe this image."
# Act and Assert
with pytest.raises(AttributeError):
gpt4vision(img_url, [task])
def test_gpt4vision_call_single_task_single_image_empty_response(
gpt4vision, mock_openai_client
):
# Arrange
img_url = "https://images.unsplash.com/photo-1694734479942-8cc7f4660578?q=80&w=1287&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
task = "Describe this image."
mock_openai_client.chat.completions.create.return_value.choices = []
# Act
response = gpt4vision(img_url, [task])
# Assert
assert response.answer == ""
mock_openai_client.chat.completions.create.assert_called_once()
def test_gpt4vision_call_multiple_tasks_single_image_empty_responses(
gpt4vision, mock_openai_client
):
# Arrange
img_url = "https://images.unsplash.com/photo-1694734479942-8cc7f4660578?q=80&w=1287&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
tasks = ["Describe this image.", "What's in this picture?"]
mock_openai_client.chat.completions.create.return_value.choices = []
# Act
responses = gpt4vision(img_url, tasks)
# Assert
assert all(response.answer == "" for response in responses)
assert (
mock_openai_client.chat.completions.create.call_count == 1
) # Should be called only once
def test_gpt4vision_call_single_task_single_image_timeout(
gpt4vision, mock_openai_client
):
# Arrange
img_url = "https://images.unsplash.com/photo-1694734479942-8cc7f4660578?q=80&w=1287&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
task = "Describe this image."
mock_openai_client.chat.completions.create.side_effect = Timeout(
"Request timed out"
)
# Act and Assert
with pytest.raises(Timeout):
gpt4vision(img_url, [task])
def test_gpt4vision_call_retry_with_success_after_timeout(
gpt4vision, mock_openai_client
):
# Arrange
img_url = "https://images.unsplash.com/photo-1694734479942-8cc7f4660578?q=80&w=1287&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
task = "Describe this image."
# Simulate success after a timeout and retry
mock_openai_client.chat.completions.create.side_effect = [
Timeout("Request timed out"),
{
"choices": [
{"message": {"content": {"text": "A description of the image."}}}
],
},
]
# Act
response = gpt4vision(img_url, [task])
# Assert
assert response.answer == "A description of the image."
assert (
mock_openai_client.chat.completions.create.call_count == 2
) # Should be called twice
def test_gpt4vision_process_img():
# Arrange
img_path = "test_image.jpg"
gpt4vision = GPT4Vision()
# Act
img_data = gpt4vision.process_img(img_path)
# Assert
assert img_data.startswith("/9j/") # Base64-encoded image data
def test_gpt4vision_call_single_task_single_image(gpt4vision, mock_openai_client):
# Arrange
img_url = "https://images.unsplash.com/photo-1694734479942-8cc7f4660578?q=80&w=1287&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
task = "Describe this image."
expected_response = GPT4VisionResponse(answer="A description of the image.")
mock_openai_client.chat.completions.create.return_value.choices[
0
].text = expected_response.answer
# Act
response = gpt4vision(img_url, [task])
# Assert
assert response == expected_response
mock_openai_client.chat.completions.create.assert_called_once()
def test_gpt4vision_call_single_task_multiple_images(gpt4vision, mock_openai_client):
# Arrange
img_urls = ["https://example.com/image1.jpg", "https://example.com/image2.jpg"]
task = "Describe these images."
expected_response = GPT4VisionResponse(answer="Descriptions of the images.")
mock_openai_client.chat.completions.create.return_value.choices[
0
].text = expected_response.answer
# Act
response = gpt4vision(img_urls, [task])
# Assert
assert response == expected_response
mock_openai_client.chat.completions.create.assert_called_once()
def test_gpt4vision_call_multiple_tasks_single_image(gpt4vision, mock_openai_client):
# Arrange
img_url = "https://images.unsplash.com/photo-1694734479942-8cc7f4660578?q=80&w=1287&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
tasks = ["Describe this image.", "What's in this picture?"]
expected_responses = [
GPT4VisionResponse(answer="A description of the image."),
GPT4VisionResponse(answer="It contains various objects."),
]
def create_mock_response(response):
return {"choices": [{"message": {"content": {"text": response.answer}}}]}
mock_openai_client.chat.completions.create.side_effect = [
create_mock_response(response) for response in expected_responses
]
# Act
responses = gpt4vision(img_url, tasks)
# Assert
assert responses == expected_responses
assert (
mock_openai_client.chat.completions.create.call_count == 1
) # Should be called only once
def test_gpt4vision_call_multiple_tasks_single_image(
gpt4vision, mock_openai_client
):
# Arrange
img_url = "https://images.unsplash.com/photo-1694734479942-8cc7f4660578?q=80&w=1287&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
tasks = ["Describe this image.", "What's in this picture?"]
expected_responses = [
GPT4VisionResponse(answer="A description of the image."),
GPT4VisionResponse(answer="It contains various objects."),
]
mock_openai_client.chat.completions.create.side_effect = [
{
"choices": [
{"message": {"content": {"text": expected_responses[i].answer}}}
]
}
for i in range(len(expected_responses))
]
# Act
responses = gpt4vision(img_url, tasks)
# Assert
assert responses == expected_responses
assert (
mock_openai_client.chat.completions.create.call_count == 1
) # Should be called only once
def test_gpt4vision_call_multiple_tasks_multiple_images(gpt4vision, mock_openai_client):
# Arrange
img_urls = [
"https://images.unsplash.com/photo-1694734479857-626882b6db37?q=80&w=1287&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
"https://images.unsplash.com/photo-1694734479898-6ac4633158ac?q=80&w=1287&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D",
]
tasks = ["Describe these images.", "What's in these pictures?"]
expected_responses = [
GPT4VisionResponse(answer="Descriptions of the images."),
GPT4VisionResponse(answer="They contain various objects."),
]
mock_openai_client.chat.completions.create.side_effect = [
{"choices": [{"message": {"content": {"text": response.answer}}}]}
for response in expected_responses
]
# Act
responses = gpt4vision(img_urls, tasks)
# Assert
assert responses == expected_responses
assert (
mock_openai_client.chat.completions.create.call_count == 1
) # Should be called only once
def test_gpt4vision_call_http_error(gpt4vision, mock_openai_client):
# Arrange
img_url = "https://images.unsplash.com/photo-1694734479942-8cc7f4660578?q=80&w=1287&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
task = "Describe this image."
mock_openai_client.chat.completions.create.side_effect = HTTPError("HTTP Error")
# Act and Assert
with pytest.raises(HTTPError):
gpt4vision(img_url, [task])
def test_gpt4vision_call_request_error(gpt4vision, mock_openai_client):
# Arrange
img_url = "https://images.unsplash.com/photo-1694734479942-8cc7f4660578?q=80&w=1287&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
task = "Describe this image."
mock_openai_client.chat.completions.create.side_effect = RequestException(
"Request Error"
)
# Act and Assert
with pytest.raises(RequestException):
gpt4vision(img_url, [task])
def test_gpt4vision_call_connection_error(gpt4vision, mock_openai_client):
# Arrange
img_url = "https://images.unsplash.com/photo-1694734479942-8cc7f4660578?q=80&w=1287&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
task = "Describe this image."
mock_openai_client.chat.completions.create.side_effect = ConnectionError(
"Connection Error"
)
# Act and Assert
with pytest.raises(ConnectionError):
gpt4vision(img_url, [task])
def test_gpt4vision_call_retry_with_success(gpt4vision, mock_openai_client):
# Arrange
img_url = "https://images.unsplash.com/photo-1694734479942-8cc7f4660578?q=80&w=1287&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D"
task = "Describe this image."
# Simulate success after a retry
mock_openai_client.chat.completions.create.side_effect = [
RequestException("Temporary error"),
{
"choices": [{"text": "A description of the image."}]
}, # fixed dictionary syntax
]
# Act
response = gpt4vision(img_url, [task])
# Assert
assert response.answer == "A description of the image."
assert (
mock_openai_client.chat.completions.create.call_count == 2
) # Should be called twice

@ -70,11 +70,14 @@ def test_llm_memory_consumption(llm_instance):
# Test different initialization parameters # Test different initialization parameters
@pytest.mark.parametrize("model_id, max_length", [ @pytest.mark.parametrize(
"model_id, max_length",
[
("gpt2-small", 100), ("gpt2-small", 100),
("gpt2-medium", 200), ("gpt2-medium", 200),
("gpt2-large", None) # None to check default behavior ("gpt2-large", None), # None to check default behavior
]) ],
)
def test_llm_initialization_params(model_id, max_length): def test_llm_initialization_params(model_id, max_length):
if max_length: if max_length:
instance = HuggingfaceLLM(model_id=model_id, max_length=max_length) instance = HuggingfaceLLM(model_id=model_id, max_length=max_length)
@ -157,11 +160,14 @@ def test_llm_timeout_handling(mock_run, llm_instance):
@patch("swarms.models.huggingface.HuggingfaceLLM.run") @patch("swarms.models.huggingface.HuggingfaceLLM.run")
def test_llm_response_time(mock_run, llm_instance): def test_llm_response_time(mock_run, llm_instance):
import time import time
mock_run.return_value = "mocked output" mock_run.return_value = "mocked output"
start_time = time.time() start_time = time.time()
llm_instance.run("test task for response time") llm_instance.run("test task for response time")
end_time = time.time() end_time = time.time()
assert end_time - start_time < 1 # Assuming the response should be faster than 1 second assert (
end_time - start_time < 1
) # Assuming the response should be faster than 1 second
# Test the logging of a warning for long inputs # Test the logging of a warning for long inputs
@ -173,7 +179,9 @@ def test_llm_long_input_warning(mock_warning, llm_instance):
# Test for run method behavior when model raises an exception # Test for run method behavior when model raises an exception
@patch("swarms.models.huggingface.HuggingfaceLLM._model.generate", side_effect=RuntimeError) @patch(
"swarms.models.huggingface.HuggingfaceLLM._model.generate", side_effect=RuntimeError
)
def test_llm_run_model_exception(mock_generate, llm_instance): def test_llm_run_model_exception(mock_generate, llm_instance):
with pytest.raises(RuntimeError): with pytest.raises(RuntimeError):
llm_instance.run("test task when model fails") llm_instance.run("test task when model fails")
@ -219,6 +227,7 @@ def test_llm_multilingual_input(mock_run, llm_instance):
result = llm_instance.run(multilingual_input) result = llm_instance.run(multilingual_input)
assert isinstance(result, str) # Simple check to ensure output is string type assert isinstance(result, str) # Simple check to ensure output is string type
# Test caching mechanism to prevent re-running the same inputs # Test caching mechanism to prevent re-running the same inputs
@patch("swarms.models.huggingface.HuggingfaceLLM.run") @patch("swarms.models.huggingface.HuggingfaceLLM.run")
def test_llm_caching_mechanism(mock_run, llm_instance): def test_llm_caching_mechanism(mock_run, llm_instance):

@ -0,0 +1,333 @@
import asyncio
import os
from unittest.mock import patch
import pytest
from swarms.models import OpenAIChat
from swarms.structs.flow import Flow
from swarms.structs.sequential_workflow import SequentialWorkflow, Task
# Mock the OpenAI API key using environment variables
os.environ["OPENAI_API_KEY"] = "mocked_api_key"
# Mock OpenAIChat class for testing
class MockOpenAIChat:
def __init__(self, *args, **kwargs):
pass
def run(self, *args, **kwargs):
return "Mocked result"
# Mock Flow class for testing
class MockFlow:
def __init__(self, *args, **kwargs):
pass
def run(self, *args, **kwargs):
return "Mocked result"
# Mock SequentialWorkflow class for testing
class MockSequentialWorkflow:
def __init__(self, *args, **kwargs):
pass
def add(self, *args, **kwargs):
pass
def run(self):
pass
# Test Task class
def test_task_initialization():
description = "Sample Task"
flow = MockOpenAIChat()
task = Task(description=description, flow=flow)
assert task.description == description
assert task.flow == flow
def test_task_execute():
description = "Sample Task"
flow = MockOpenAIChat()
task = Task(description=description, flow=flow)
task.execute()
assert task.result == "Mocked result"
# Test SequentialWorkflow class
def test_sequential_workflow_initialization():
workflow = SequentialWorkflow()
assert isinstance(workflow, SequentialWorkflow)
assert len(workflow.tasks) == 0
assert workflow.max_loops == 1
assert workflow.autosave == False
assert workflow.saved_state_filepath == "sequential_workflow_state.json"
assert workflow.restore_state_filepath == None
assert workflow.dashboard == False
def test_sequential_workflow_add_task():
workflow = SequentialWorkflow()
task_description = "Sample Task"
task_flow = MockOpenAIChat()
workflow.add(task_description, task_flow)
assert len(workflow.tasks) == 1
assert workflow.tasks[0].description == task_description
assert workflow.tasks[0].flow == task_flow
def test_sequential_workflow_reset_workflow():
workflow = SequentialWorkflow()
task_description = "Sample Task"
task_flow = MockOpenAIChat()
workflow.add(task_description, task_flow)
workflow.reset_workflow()
assert workflow.tasks[0].result == None
def test_sequential_workflow_get_task_results():
workflow = SequentialWorkflow()
task_description = "Sample Task"
task_flow = MockOpenAIChat()
workflow.add(task_description, task_flow)
workflow.run()
results = workflow.get_task_results()
assert len(results) == 1
assert task_description in results
assert results[task_description] == "Mocked result"
def test_sequential_workflow_remove_task():
workflow = SequentialWorkflow()
task1_description = "Task 1"
task2_description = "Task 2"
task1_flow = MockOpenAIChat()
task2_flow = MockOpenAIChat()
workflow.add(task1_description, task1_flow)
workflow.add(task2_description, task2_flow)
workflow.remove_task(task1_description)
assert len(workflow.tasks) == 1
assert workflow.tasks[0].description == task2_description
def test_sequential_workflow_update_task():
workflow = SequentialWorkflow()
task_description = "Sample Task"
task_flow = MockOpenAIChat()
workflow.add(task_description, task_flow)
workflow.update_task(task_description, max_tokens=1000)
assert workflow.tasks[0].kwargs["max_tokens"] == 1000
def test_sequential_workflow_save_workflow_state():
workflow = SequentialWorkflow()
task_description = "Sample Task"
task_flow = MockOpenAIChat()
workflow.add(task_description, task_flow)
workflow.save_workflow_state("test_state.json")
assert os.path.exists("test_state.json")
os.remove("test_state.json")
def test_sequential_workflow_load_workflow_state():
workflow = SequentialWorkflow()
task_description = "Sample Task"
task_flow = MockOpenAIChat()
workflow.add(task_description, task_flow)
workflow.save_workflow_state("test_state.json")
workflow.load_workflow_state("test_state.json")
assert len(workflow.tasks) == 1
assert workflow.tasks[0].description == task_description
os.remove("test_state.json")
def test_sequential_workflow_run():
workflow = SequentialWorkflow()
task_description = "Sample Task"
task_flow = MockOpenAIChat()
workflow.add(task_description, task_flow)
workflow.run()
assert workflow.tasks[0].result == "Mocked result"
def test_sequential_workflow_workflow_bootup(capfd):
workflow = SequentialWorkflow()
workflow.workflow_bootup()
out, _ = capfd.readouterr()
assert "Sequential Workflow Initializing..." in out
def test_sequential_workflow_workflow_dashboard(capfd):
workflow = SequentialWorkflow()
workflow.workflow_dashboard()
out, _ = capfd.readouterr()
assert "Sequential Workflow Dashboard" in out
# Mock Flow class for async testing
class MockAsyncFlow:
def __init__(self, *args, **kwargs):
pass
async def arun(self, *args, **kwargs):
return "Mocked result"
# Test async execution in SequentialWorkflow
@pytest.mark.asyncio
async def test_sequential_workflow_arun():
workflow = SequentialWorkflow()
task_description = "Sample Task"
task_flow = MockAsyncFlow()
workflow.add(task_description, task_flow)
await workflow.arun()
assert workflow.tasks[0].result == "Mocked result"
def test_real_world_usage_with_openai_key():
# Initialize the language model
llm = OpenAIChat()
assert isinstance(llm, OpenAIChat)
def test_real_world_usage_with_flow_and_openai_key():
# Initialize a flow with the language model
flow = Flow(llm=OpenAIChat())
assert isinstance(flow, Flow)
def test_real_world_usage_with_sequential_workflow():
# Initialize a sequential workflow
workflow = SequentialWorkflow()
assert isinstance(workflow, SequentialWorkflow)
def test_real_world_usage_add_tasks():
# Create a sequential workflow and add tasks
workflow = SequentialWorkflow()
task1_description = "Task 1"
task2_description = "Task 2"
task1_flow = OpenAIChat()
task2_flow = OpenAIChat()
workflow.add(task1_description, task1_flow)
workflow.add(task2_description, task2_flow)
assert len(workflow.tasks) == 2
assert workflow.tasks[0].description == task1_description
assert workflow.tasks[1].description == task2_description
def test_real_world_usage_run_workflow():
# Create a sequential workflow, add a task, and run the workflow
workflow = SequentialWorkflow()
task_description = "Sample Task"
task_flow = OpenAIChat()
workflow.add(task_description, task_flow)
workflow.run()
assert workflow.tasks[0].result is not None
def test_real_world_usage_dashboard_display():
# Create a sequential workflow, add tasks, and display the dashboard
workflow = SequentialWorkflow()
task1_description = "Task 1"
task2_description = "Task 2"
task1_flow = OpenAIChat()
task2_flow = OpenAIChat()
workflow.add(task1_description, task1_flow)
workflow.add(task2_description, task2_flow)
with patch("builtins.print") as mock_print:
workflow.workflow_dashboard()
mock_print.assert_called()
def test_real_world_usage_async_execution():
# Create a sequential workflow, add an async task, and run the workflow asynchronously
workflow = SequentialWorkflow()
task_description = "Sample Task"
async_task_flow = OpenAIChat()
async def async_run_workflow():
await workflow.arun()
workflow.add(task_description, async_task_flow)
asyncio.run(async_run_workflow())
assert workflow.tasks[0].result is not None
def test_real_world_usage_multiple_loops():
# Create a sequential workflow with multiple loops, add a task, and run the workflow
workflow = SequentialWorkflow(max_loops=3)
task_description = "Sample Task"
task_flow = OpenAIChat()
workflow.add(task_description, task_flow)
workflow.run()
assert workflow.tasks[0].result is not None
def test_real_world_usage_autosave_state():
# Create a sequential workflow with autosave, add a task, run the workflow, and check if state is saved
workflow = SequentialWorkflow(autosave=True)
task_description = "Sample Task"
task_flow = OpenAIChat()
workflow.add(task_description, task_flow)
workflow.run()
assert workflow.tasks[0].result is not None
assert os.path.exists("sequential_workflow_state.json")
os.remove("sequential_workflow_state.json")
def test_real_world_usage_load_state():
# Create a sequential workflow, add a task, save state, load state, and run the workflow
workflow = SequentialWorkflow()
task_description = "Sample Task"
task_flow = OpenAIChat()
workflow.add(task_description, task_flow)
workflow.run()
workflow.save_workflow_state("test_state.json")
workflow.load_workflow_state("test_state.json")
workflow.run()
assert workflow.tasks[0].result is not None
os.remove("test_state.json")
def test_real_world_usage_update_task_args():
# Create a sequential workflow, add a task, and update task arguments
workflow = SequentialWorkflow()
task_description = "Sample Task"
task_flow = OpenAIChat()
workflow.add(task_description, task_flow)
workflow.update_task(task_description, max_tokens=1000)
assert workflow.tasks[0].kwargs["max_tokens"] == 1000
def test_real_world_usage_remove_task():
# Create a sequential workflow, add tasks, remove a task, and run the workflow
workflow = SequentialWorkflow()
task1_description = "Task 1"
task2_description = "Task 2"
task1_flow = OpenAIChat()
task2_flow = OpenAIChat()
workflow.add(task1_description, task1_flow)
workflow.add(task2_description, task2_flow)
workflow.remove_task(task1_description)
workflow.run()
assert len(workflow.tasks) == 1
assert workflow.tasks[0].description == task2_description
def test_real_world_usage_with_environment_variables():
# Ensure that the OpenAI API key is set using environment variables
assert "OPENAI_API_KEY" in os.environ
assert os.environ["OPENAI_API_KEY"] == "mocked_api_key"
del os.environ["OPENAI_API_KEY"] # Clean up after the test
def test_real_world_usage_no_openai_key():
# Ensure that an exception is raised when the OpenAI API key is not set
with pytest.raises(ValueError):
llm = OpenAIChat() # API key not provided, should raise an exception

@ -1,11 +0,0 @@
from swarms.models import OpenAIChat
from swarms.structs import Workflow
llm = OpenAIChat(openai_api_key="")
workflow = Workflow(llm)
workflow.add("What's the weather in miami")
workflow.run()
Loading…
Cancel
Save