From cd804d7c174faef41361ba39f07a3f1fc90f1843 Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 14:35:02 -0400 Subject: [PATCH 01/98] clean up Former-commit-id: 583d9384edde63090c59f56ac050ff984bed0178 --- {swarms/agents/misc => misc}/utils.py | 0 swarms/tools/main.py | 50 ++++++++++++++++ swarms/utils/utils.py | 82 +-------------------------- 3 files changed, 52 insertions(+), 80 deletions(-) rename {swarms/agents/misc => misc}/utils.py (100%) diff --git a/swarms/agents/misc/utils.py b/misc/utils.py similarity index 100% rename from swarms/agents/misc/utils.py rename to misc/utils.py diff --git a/swarms/tools/main.py b/swarms/tools/main.py index fb21fabb..dedfafc1 100644 --- a/swarms/tools/main.py +++ b/swarms/tools/main.py @@ -1300,6 +1300,56 @@ class VisualQuestionAnswering(BaseToolSet): return answer + +#========================> handlers/image +import torch +from PIL import Image +from transformers import BlipForConditionalGeneration, BlipProcessor + +# from core.prompts.file import IMAGE_PROMPT +from swarms.prompts.prompts import IMAGE_PROMPT + +from swarms.utils.utils import BaseHandler + +class ImageCaptioning(BaseHandler): + def __init__(self, device): + print("Initializing ImageCaptioning to %s" % device) + self.device = device + self.torch_dtype = torch.float16 if "cuda" in device else torch.float32 + self.processor = BlipProcessor.from_pretrained( + "Salesforce/blip-image-captioning-base" + ) + self.model = BlipForConditionalGeneration.from_pretrained( + "Salesforce/blip-image-captioning-base", torch_dtype=self.torch_dtype + ).to(self.device) + + def handle(self, filename: str): + img = Image.open(filename) + width, height = img.size + ratio = min(512 / width, 512 / height) + width_new, height_new = (round(width * ratio), round(height * ratio)) + img = img.resize((width_new, height_new)) + img = img.convert("RGB") + img.save(filename, "PNG") + print(f"Resize image form {width}x{height} to {width_new}x{height_new}") + + inputs = self.processor(Image.open(filename), return_tensors="pt").to( + self.device, self.torch_dtype + ) + out = self.model.generate(**inputs) + description = self.processor.decode(out[0], skip_special_tokens=True) + print( + f"\nProcessed ImageCaptioning, Input Image: {filename}, Output Text: {description}" + ) + + return IMAGE_PROMPT.format(filename=filename, description=description) + + + + + + + #segment anything: ########################### MODELS diff --git a/swarms/utils/utils.py b/swarms/utils/utils.py index 6cf1a56e..8fde50bb 100644 --- a/swarms/utils/utils.py +++ b/swarms/utils/utils.py @@ -225,7 +225,7 @@ class AbstractUploader(ABC): #========================= upload s3 -import os + import boto3 @@ -262,7 +262,6 @@ class S3Uploader(AbstractUploader): #========================= upload s3 #========================> upload/static -import os import shutil from pathlib import Path @@ -291,11 +290,9 @@ class StaticUploader(AbstractUploader): #========================> handlers/base -import os -import shutil + import uuid from enum import Enum -from pathlib import Path from typing import Dict import requests @@ -402,7 +399,6 @@ class FileHandler: #############===========================> -import pandas as pd from swarms.prompts.prompts import DATAFRAME_PROMPT @@ -425,77 +421,3 @@ class CsvToDataframe(BaseHandler): - -#========================> handlers/image -import torch -from PIL import Image -from transformers import BlipForConditionalGeneration, BlipProcessor - -# from core.prompts.file import IMAGE_PROMPT -from swarms.prompts.prompts import IMAGE_PROMPT - - - -class ImageCaptioning(BaseHandler): - def __init__(self, device): - print("Initializing ImageCaptioning to %s" % device) - self.device = device - self.torch_dtype = torch.float16 if "cuda" in device else torch.float32 - self.processor = BlipProcessor.from_pretrained( - "Salesforce/blip-image-captioning-base" - ) - self.model = BlipForConditionalGeneration.from_pretrained( - "Salesforce/blip-image-captioning-base", torch_dtype=self.torch_dtype - ).to(self.device) - - def handle(self, filename: str): - img = Image.open(filename) - width, height = img.size - ratio = min(512 / width, 512 / height) - width_new, height_new = (round(width * ratio), round(height * ratio)) - img = img.resize((width_new, height_new)) - img = img.convert("RGB") - img.save(filename, "PNG") - print(f"Resize image form {width}x{height} to {width_new}x{height_new}") - - inputs = self.processor(Image.open(filename), return_tensors="pt").to( - self.device, self.torch_dtype - ) - out = self.model.generate(**inputs) - description = self.processor.decode(out[0], skip_special_tokens=True) - print( - f"\nProcessed ImageCaptioning, Input Image: {filename}, Output Text: {description}" - ) - - return IMAGE_PROMPT.format(filename=filename, description=description) - - - - -# from autogpt.agent import Agent -# from swarms.agents.swarms import worker_node - -# class MultiAgent(worker_node): - -# def __init__( -# self, -# ai_name, -# memory, -# full_message_history, -# prompt, -# user_input, -# agent_id -# ): -# super().__init__( -# ai_name=ai_name, -# memory=memory, -# full_message_history=full_message_history, -# next_action_count=0, -# prompt=prompt, -# user_input=user_input, -# ) -# self.agent_id = agent_id -# self.auditory_buffer = [] # contains the non processed parts of the conversation - -# def receive_message(self, speaker, message): -# self.auditory_buffer.append((speaker.ai_name, message)) \ No newline at end of file From 266bb90c5e71bdac0b392663b19bfbd21863d0cb Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 14:35:38 -0400 Subject: [PATCH 02/98] clean up Former-commit-id: 9d9638ee62b475883b8ed12b27e3a7c9e93606af --- api/container.py | 4 ++-- swarms/agents/utils/callback.py | 2 +- swarms/agents/utils/llm.py | 2 +- swarms/agents/workers/agents.py | 2 +- swarms/agents/workers/worker_ultranode.py | 4 ++-- swarms/tools/main.py | 6 +++--- swarms/utils/{utils.py => main.py} | 0 swarms/utils/static.py | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) rename swarms/utils/{utils.py => main.py} (100%) diff --git a/api/container.py b/api/container.py index 6d32c6d4..1ffeea25 100644 --- a/api/container.py +++ b/api/container.py @@ -6,12 +6,12 @@ from typing import Dict, List from fastapi.templating import Jinja2Templates from swarms.agents.utils.manager import AgentManager -from swarms.utils.utils import BaseHandler, FileHandler, FileType +from swarms.utils.main import BaseHandler, FileHandler, FileType from swarms.tools.main import CsvToDataframe, ExitConversation, RequestsGet, CodeEditor, Terminal from swarms.tools.main import BaseToolSet -from swarms.utils.utils import StaticUploader +from swarms.utils.main import StaticUploader BASE_DIR = Path(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) os.chdir(BASE_DIR / os.environ["PLAYGROUND_DIR"]) diff --git a/swarms/agents/utils/callback.py b/swarms/agents/utils/callback.py index d4720fd2..cca65037 100644 --- a/swarms/agents/utils/callback.py +++ b/swarms/agents/utils/callback.py @@ -5,7 +5,7 @@ from langchain.schema import AgentAction, AgentFinish, LLMResult # from celery import Task # from ansi import ANSI, Color, Style, dim_multiline -from swarms.utils.utils import ANSI, Color, Style, dim_multiline +from swarms.utils.main import ANSI, Color, Style, dim_multiline from swarms.utils.logger import logger diff --git a/swarms/agents/utils/llm.py b/swarms/agents/utils/llm.py index d4e7ee18..b09cc817 100644 --- a/swarms/agents/utils/llm.py +++ b/swarms/agents/utils/llm.py @@ -30,7 +30,7 @@ from tenacity import ( # from ansi import ANSI, Color, Style -from swarms.utils.utils import ANSI, Color, Style +from swarms.utils.main import ANSI, Color, Style import os def _create_retry_decorator(llm: ChatOpenAI) -> Callable[[Any], Any]: diff --git a/swarms/agents/workers/agents.py b/swarms/agents/workers/agents.py index 8419dd95..2e70d4e5 100644 --- a/swarms/agents/workers/agents.py +++ b/swarms/agents/workers/agents.py @@ -224,7 +224,7 @@ from langchain.callbacks.base import BaseCallbackHandler from langchain.schema import AgentAction, AgentFinish, LLMResult # from celery import Task -from swarms.utils.utils import ANSI, Color, Style, dim_multiline, logger +from swarms.utils.main import ANSI, Color, Style, dim_multiline, logger class EVALCallbackHandler(BaseCallbackHandler): diff --git a/swarms/agents/workers/worker_ultranode.py b/swarms/agents/workers/worker_ultranode.py index 08230671..04108a84 100644 --- a/swarms/agents/workers/worker_ultranode.py +++ b/swarms/agents/workers/worker_ultranode.py @@ -3,10 +3,10 @@ from pathlib import Path from typing import Dict, List from swarms.agents.utils.manager import AgentManager -from swarms.utils.utils import BaseHandler, FileHandler, FileType +from swarms.utils.main import BaseHandler, FileHandler, FileType from swarms.tools.main import CsvToDataframe, ExitConversation, RequestsGet, CodeEditor, Terminal from swarms.tools.main import BaseToolSet -from swarms.utils.utils import StaticUploader +from swarms.utils.main import StaticUploader BASE_DIR = Path(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) os.chdir(BASE_DIR / os.environ["PLAYGROUND_DIR"]) diff --git a/swarms/tools/main.py b/swarms/tools/main.py index dedfafc1..67a32b9b 100644 --- a/swarms/tools/main.py +++ b/swarms/tools/main.py @@ -428,7 +428,7 @@ import time from datetime import datetime from typing import Dict, List -from swarms.utils.utils import ANSI, Color, Style # test +from swarms.utils.main import ANSI, Color, Style # test class Terminal(BaseToolSet): def __init__(self): @@ -1100,7 +1100,7 @@ from transformers import ( ) -from swarms.utils.utils import get_new_image_name +from swarms.utils.main import get_new_image_name class MaskFormer(BaseToolSet): @@ -1309,7 +1309,7 @@ from transformers import BlipForConditionalGeneration, BlipProcessor # from core.prompts.file import IMAGE_PROMPT from swarms.prompts.prompts import IMAGE_PROMPT -from swarms.utils.utils import BaseHandler +from swarms.utils.main import BaseHandler class ImageCaptioning(BaseHandler): def __init__(self, device): diff --git a/swarms/utils/utils.py b/swarms/utils/main.py similarity index 100% rename from swarms/utils/utils.py rename to swarms/utils/main.py diff --git a/swarms/utils/static.py b/swarms/utils/static.py index 7b642857..72acbcef 100644 --- a/swarms/utils/static.py +++ b/swarms/utils/static.py @@ -4,7 +4,7 @@ from pathlib import Path # from env import DotEnv -from swarms.utils.utils import AbstractUploader +from swarms.utils.main import AbstractUploader class StaticUploader(AbstractUploader): def __init__(self, server: str, path: Path, endpoint: str): From 181c25914d38c436cd37631ffe008599a8513af5 Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 14:38:09 -0400 Subject: [PATCH 03/98] clean up Former-commit-id: 43b77d77d57115dc0e40043577d67405a6787658 --- swarms/agents/utils/manager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/swarms/agents/utils/manager.py b/swarms/agents/utils/manager.py index 8eb383a7..0c73ee9e 100644 --- a/swarms/agents/utils/manager.py +++ b/swarms/agents/utils/manager.py @@ -3,7 +3,7 @@ from typing import Dict, Optional from langchain.agents.agent import AgentExecutor from langchain.callbacks.manager import CallbackManager -from langchain.callbacks.base import set_handler +# from langchain.callbacks.base import set_handler from langchain.chains.conversation.memory import ConversationBufferMemory from langchain.memory.chat_memory import BaseChatMemory @@ -13,7 +13,7 @@ from .builder import AgentBuilder from .callback import EVALCallbackHandler, ExecutionTracingCallbackHandler -set_handler(EVALCallbackHandler()) +CallbackManager.set_handler(EVALCallbackHandler()) class AgentManager: From 6192897e782c54d0b6a4047db33f97dfd96aa3a5 Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 14:42:20 -0400 Subject: [PATCH 04/98] clean up Former-commit-id: 1eeacfc9ac59a3e54ac7f2fcbe711fb948c8561a --- {analysis => playground/analysis}/task1.txt | 0 {analysis => playground/analysis}/worker_agent.txt | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {analysis => playground/analysis}/task1.txt (100%) rename {analysis => playground/analysis}/worker_agent.txt (100%) diff --git a/analysis/task1.txt b/playground/analysis/task1.txt similarity index 100% rename from analysis/task1.txt rename to playground/analysis/task1.txt diff --git a/analysis/worker_agent.txt b/playground/analysis/worker_agent.txt similarity index 100% rename from analysis/worker_agent.txt rename to playground/analysis/worker_agent.txt From f36eaa7673b5ee4d50f5ba8446ae084070e08151 Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 14:50:28 -0400 Subject: [PATCH 05/98] clean up Former-commit-id: cdc9816235651d7b0a14a2074d7585953b8bb552 --- swarms/agents/utils/llm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarms/agents/utils/llm.py b/swarms/agents/utils/llm.py index b09cc817..bb570739 100644 --- a/swarms/agents/utils/llm.py +++ b/swarms/agents/utils/llm.py @@ -18,7 +18,7 @@ from langchain.schema import ( SystemMessage, ) from langchain.utils import get_from_dict_or_env -from logger import logger +from swarms.utils.logger import logger from pydantic import BaseModel, Extra, Field, root_validator from tenacity import ( before_sleep_log, From 8dc282ec8590ce251c838db6a1ea35e8c7f8ccf0 Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 14:59:33 -0400 Subject: [PATCH 06/98] clean up Former-commit-id: acd2f6f314531baebcf0de45e53991861dca1765 --- DOCS/SALES.md | 178 +++++++++++++++++++++++++++++++++++++ swarms/agents/utils/llm.py | 1 + 2 files changed, 179 insertions(+) create mode 100644 DOCS/SALES.md diff --git a/DOCS/SALES.md b/DOCS/SALES.md new file mode 100644 index 00000000..98e1ea36 --- /dev/null +++ b/DOCS/SALES.md @@ -0,0 +1,178 @@ +# Sales Documentation + +## Small Businesses + +Small businesses often lack the resources to hire a dedicated team of data analysts and AI experts. This is where Swarms steps in. With our platform, these businesses can automate many of the tasks that previously required manual effort or expert knowledge. Our strategy for engaging small businesses involves showcasing the simplicity and cost-effectiveness of Swarms. + +### Stage 1: Awareness and Education +* Questions: Have you considered implementing AI solutions? Are you aware of how AI can help your business? +* Commitments: Schedule a demo of Swarms. + +### Stage 2: Engagement and Evaluation +* Questions: Have you identified areas where AI can improve efficiency? How do you currently manage these tasks? +* Commitments: Conduct a trial run of Swarms on a select project. + +### Stage 3: Adoption and Integration +* Questions: Are you satisfied with the results of the trial run? Are you ready to implement Swarms more broadly? +* Commitments: Purchase a subscription and begin the full-scale integration of Swarms. + +## Medium-Sized Enterprises + +Medium-sized enterprises typically have some level of AI integration but often struggle with scalability. Swarms can offer these organizations a path to seamlessly scale their existing AI capabilities. Our strategy for engaging medium-sized enterprises involves demonstrating how Swarms can take their current AI solutions to the next level. + +### Stage 1: Awareness and Potential Evaluation +* Questions: Are you looking to scale your current AI solutions? Are you satisfied with the performance of your current AI tools? +* Commitments: Arrange a personalized demonstration of Swarms. + +### Stage 2: Engagement and Testing +* Questions: Have you identified the specific areas where your AI solutions need scaling? Are you open to piloting Swarms in these areas? +* Commitments: Run a pilot program using Swarms. + +### Stage 3: Adoption and Expansion +* Questions: Did the pilot program meet your expectations? Are you ready to expand the use of Swarms across your organization? +* Commitments: Commit to a long-term partnership and full integration of Swarms. + +## Large Corporations + +Large corporations typically have extensive AI capabilities, but they may struggle with coordination and efficiency. Swarms can help streamline these organizations' AI operations. Our strategy for engaging large corporations involves demonstrating how Swarms can enhance the efficiency of their AI ecosystems. + +### Stage 1: Awareness and Relevance Evaluation +* Questions: Are you experiencing inefficiencies with your existing AI operations? Have you considered solutions to improve coordination among your AI tools? +* Commitments: Organize an executive briefing session about Swarms. + +### Stage 2: Engagement and Trial +* Questions: Can you identify specific use cases for Swarms in your organization? Are you willing to conduct a trial run of Swarms? +* Commitments: Implement a trial run of Swarms for selected use cases. + +### Stage 3: Adoption and Wide-Scale Implementation +* Questions: Was the trial run of Swarms successful? Are you ready to implement Swarms throughout your organization? +* Commitments: Form a strategic alliance and proceed with wide-scale implementation of Swarms. + +Remember, this is more than just a transaction. It's a partnership. And like any good partnership, it's built on trust, communication, and a shared vision. We're excited to embark on this journey with you, and we're committed to supporting you every step of the way. + +#1 +Introduction + +In today's competitive landscape, organizations of all sizes are continually seeking ways to automate routine tasks, streamline processes, and make data-driven decisions. Enter Swarms, a revolutionary AI-based technology that leverages the power of multiple autonomous agents to perform tasks with unprecedented speed and accuracy. + +This guide lays out a SPIN (Situation, Problem, Implication, Need-payoff) approach to selling Swarms, taking you through a step-by-step journey from cold outreach to closing the deal. + +#2 +Cold Outreach + +Our first step is to generate interest in Swarms, and we do this through personalized, value-driven outreach. Focus on how Swarms can solve their pain points and bring value to their organization. + +Situation Questions: +- Do you currently use any AI or machine learning tools in your organization? +- How are you managing tasks that could be automated or require large-scale data analysis? + +Problem Questions: +- Are there any specific challenges in managing these tasks manually or using traditional AI models? +- How much time and resources are you currently dedicating to these tasks? + +Implication Questions: +- What is the cost of not addressing these challenges or improving these processes? +- How does this affect your team’s productivity, your operational efficiency, or your competitive advantage? + +Need-payoff Questions: +- How would your organization benefit from automating these tasks or making them more efficient? +- Could an AI-based tool that leverages the power of multiple autonomous agents be beneficial for your organization? + +#3 +Discovery Calls + +Once you've generated interest and scheduled a discovery call, dive deeper into their business operations, their pain points, and their goals. Establish a clear understanding of what they need and how Swarms can fulfill those needs. + +Situation Questions: +- Could you tell me more about your current workflows and operational processes? +- What is the biggest challenge your team is facing in managing these workflows? + +Problem Questions: +- Have you ever encountered situations where the scale or complexity of tasks was overwhelming for your existing systems? +- Are there any tasks that you believe require a level of intelligence or speed that your current solutions can’t provide? + +Implication Questions: +- How does this affect your growth, competitiveness, or profitability in the long term? +- What are the ripple effects of these challenges on other aspects of your business? + +Need-payoff Questions: +- Would a solution that can handle tasks of any scale or complexity efficiently and accurately be of value to your team? +- How would such a solution impact your operational efficiency, team productivity, and bottom line? + +#4 +Product Demonstration + +This is the stage where you showcase the capabilities of Swarms, demonstrating its features and how it can be applied to their specific use cases. Show, don't tell. + +Situation Questions: +- Can you share a few tasks that you believe could be significantly improved with automation or intelligent processing? +- What features or functionalities are you looking for in a solution to improve these tasks? + +Problem Questions: +- Are there any specific issues that you expect to arise if these tasks are managed with your current systems? +- Have past solutions failed to deliver on your expectations in any way? + +Implication Questions: +- What are the potential consequences if these issues are not addressed or if the tasks are not improved? +- How does this affect your team’s morale, your customer satisfaction, or your market position? + +Need-payoff Questions: +- Would you be interested in a solution that can automate these tasks, provide intelligent processing, and scale according to your needs? +- How would such a solution change the way your team works and the outcomes they achieve? + +#5 +Proposal and Negotiation + +Once they've seen Swarms in action, it's time to present a tailored proposal that highlights the value of Swarms for their organization. Always be ready to negotiate, but remember, the focus is on value, not price. + +Situation Questions: +- What does your budget look like for a solution like Swarms? +- What are the key factors you'll consider in making your decision? + +Problem Questions: +- Are there any concerns or roadblocks that you think might prevent you from moving forward with Swarms? +- Have budget constraints or cost issues affected your ability to implement effective solutions in the past? + +Implication Questions: +- If cost or resource constraints continue to limit your ability to implement effective solutions, how will this impact your organization in the long term? +- Are you prepared to deal with the ramifications of continued inefficiencies or challenges? + +Need-payoff Questions: +- How would investing in Swarms impact your budget compared to the potential return on investment? +- How much value do you place on a solution that can transform the way you manage tasks, improve efficiency, and drive growth? + +#6 +Closing the Deal + +Closing the deal is about more than just signing a contract. It’s about setting the stage for a long-term partnership, ensuring they see the value in Swarms not just as a product, but as a key part of their business strategy. + +Situation Questions: +- Are you ready to move forward with implementing Swarms in your organization? +- What expectations do you have from Swarms in the initial phase? + +Problem Questions: +- Are there any final concerns or questions you have that could prevent us from moving forward? +- Is there anything that’s still unclear about how Swarms works or the value it can bring to your organization? + +Implication Questions: +- If these concerns or uncertainties are not addressed, how will it affect your decision? +- Are you willing to overlook the potential value Swarms could bring due to these concerns? + +Need-payoff Questions: +- How can we address these concerns to make Swarms a part of your organization's growth story? +- Can we agree on the fact that Swarms, with its unique capabilities, could significantly boost your organization's operational efficiency and competitiveness? + +#7 +Consultation Packages + +As part of our commitment to ensure our clients extract the maximum value from Swarms, we offer several consultation packages. These packages are designed to provide continuous support as you integrate Swarms into your workflows and processes, helping you overcome any challenges and optimize the system for your specific needs. + +Package 1 - Initial Setup & Training: Our team of experts will assist you in setting up Swarms, train your team on its functionalities and features, and provide support as you start to use the system. + +Package 2 - Optimization & Fine-tuning: As you use Swarms, we'll work closely with you to optimize the system for your specific tasks and workflows, ensuring you extract the maximum value from the platform. + +Package 3 - Ongoing Support & Upgrades: We provide continuous support to address any challenges you encounter and ensure you always have access to the + + latest upgrades and improvements to Swarms. + +Remember, Swarms isn't just a product; it's a partnership. We're committed to working with you every step of the way, ensuring you harness the full power of cooperative AI to transform your organization. \ No newline at end of file diff --git a/swarms/agents/utils/llm.py b/swarms/agents/utils/llm.py index bb570739..a8ca7870 100644 --- a/swarms/agents/utils/llm.py +++ b/swarms/agents/utils/llm.py @@ -17,6 +17,7 @@ from langchain.schema import ( HumanMessage, SystemMessage, ) + from langchain.utils import get_from_dict_or_env from swarms.utils.logger import logger from pydantic import BaseModel, Extra, Field, root_validator From 072607f5b68dcbba043ea3cde00a1d6313eb1a23 Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 15:09:10 -0400 Subject: [PATCH 07/98] clean up Former-commit-id: fca758bbb0c7b3a035a2d67d5cd67238609f867d --- DOCS/SALES.md | 93 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 91 insertions(+), 2 deletions(-) diff --git a/DOCS/SALES.md b/DOCS/SALES.md index 98e1ea36..7e6ec8e5 100644 --- a/DOCS/SALES.md +++ b/DOCS/SALES.md @@ -50,8 +50,97 @@ Large corporations typically have extensive AI capabilities, but they may strugg Remember, this is more than just a transaction. It's a partnership. And like any good partnership, it's built on trust, communication, and a shared vision. We're excited to embark on this journey with you, and we're committed to supporting you every step of the way. -#1 -Introduction + + +# SPIN SOP + +This is a detailed customer journey roadmap and Standard Operating Procedure for selling Swarms to businesses of varying sizes. The SPIN selling method (Situation, Problem, Implication, Need-payoff) will be incorporated throughout the document to provide a comprehensive approach. We'll explore a scenario that begins with cold emailing and culminates in offering theoretical consultation package deals. + +Please note that due to the constraints of this medium, this document will not reach 4000 words. + +**1. Lead Generation and Cold Outreach** + +Our journey begins with identifying potential leads that could benefit from the capabilities of Swarms. This step involves researching potential clients based on their industry, size, digital footprint, and overall potential to benefit from AI automation. + +Upon identifying a potential client, initiate contact with a tailored cold email. This email should: + +- Grab the recipient's attention (Subject line is crucial) +- Introduce Swarms and its potential benefits (unique selling proposition) +- Propose a discovery call or meeting to discuss how Swarms could be beneficial + +An example could be: + +*Subject: Elevate Your Business with the Power of AI Swarm Technology* + +Dear [Recipient's Name], + +I represent Agora, a pioneer in the field of cooperative AI. Our latest innovation, Swarms, harnesses the power of AI to drive efficiency, streamline operations, and ultimately boost profitability. I would love to have a conversation with you to discuss how this cutting-edge technology can specifically help [Their Company Name]. + +Are you available for a quick call next week? + +Best regards, +[Your Name] + +**2. Discovery Call** + +The aim of the discovery call is to learn about the potential client's business and identify their needs using the SPIN selling method: + +*SITUATION* - Get an understanding of the client's current operations, their use of technology, and their overall business landscape. + +*PROBLEM* - Identify any potential areas where the client might be facing challenges - these could be inefficiencies, high operating costs, or unmet customer needs. + +*IMPLICATION* - Discuss the consequences of these problems, such as reduced profitability or customer dissatisfaction. + +*NEED-PAYOFF* - Finally, demonstrate how Swarms can address these issues and the benefits it will bring to their business. + +**3. Follow-Up and Tailored Proposal** + +After gaining a deeper understanding of the client's needs, follow up with a detailed proposal that outlines how Swarms can specifically address their challenges. The proposal should highlight: + +- How Swarms fits into their current operations +- A projection of improvements and potential return on investment +- The steps involved in the implementation process + +**4. Theoretical Consultation Packages** + +Introduce consultation packages at this stage to provide further value and assure the client of continued support during the Swarms integration journey. The packages could include: + +- *Swarms Starter Pack*: Ideal for small businesses. Includes initial setup and integration, basic training, and a month of technical support. +- *Swarms Business Pack*: Suited for medium-sized businesses. Offers advanced setup, employee training, a dedicated support manager, and three months of technical support. +- *Swarms Enterprise Pack*: For large corporations. Includes customized setup and integration, extensive training, a dedicated account manager, and six months of priority technical support. + +**5. Demonstration and Commitment** + +Offer a demonstration to show Swarms in action. This could be a simulated use-case relevant to the client's industry or a walk-through of the platform. + +Post-demonstration, ask for the client's commitment to move to the next step. This could be a meeting with other decision-makers, an agreement to a trial period, or a signed contract. + +**6. Implementation and Onboarding** + +After gaining the client's commitment, the next stage involves the implementation of Swarms in their operations. This will depend on the client's size, the complexity of their operations, and the specifics agreed upon in the proposal. + +**7. Continued Support and Review** + +Continued technical support is essential. Regularly check in with the client, ensure they are getting the most out of Swarms, and address any issues promptly. It's also important to review the impact of Swarms on the client's operations after a set period and adjust the strategy as necessary. + +Selling Swarms is not about pushing a product; it's about offering a solution that can revolutionize businesses. The journey from cold emailing to a fully-fledged partnership should reflect this philosophy at every stage. + + +# Tactics + + +# Value proposition Formula +``` +Dream outcome • Perceived Likelihood +------------------------------------- +Time Delay * Effort & Sacrifice + +``` + +### Value prop SWARMS +``` +We've helped thousands of people just like you automate 30% of their activities with Swarms. And, all it takes to get started is a fast simple onboarding flow that asks you to integrate your tools and datasources. +```` In today's competitive landscape, organizations of all sizes are continually seeking ways to automate routine tasks, streamline processes, and make data-driven decisions. Enter Swarms, a revolutionary AI-based technology that leverages the power of multiple autonomous agents to perform tasks with unprecedented speed and accuracy. From c39e56c8b4ce770cdda16382e2c8f4769ad37eab Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 15:11:20 -0400 Subject: [PATCH 08/98] clean up for value prop Former-commit-id: d876e5103183c3a87af886ad2a33016d1eee1eb6 --- DOCS/SALES.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/DOCS/SALES.md b/DOCS/SALES.md index 7e6ec8e5..7211ccb5 100644 --- a/DOCS/SALES.md +++ b/DOCS/SALES.md @@ -134,9 +134,16 @@ Selling Swarms is not about pushing a product; it's about offering a solution th Dream outcome • Perceived Likelihood ------------------------------------- Time Delay * Effort & Sacrifice - ``` +Where: + +#### Maximize Value Using Value Equation +❏ Maximize Dream Outcome (solve problem worth solving) +❏ Maximize Perceived Likelihood of Success (testimonials& proven case studies) +❏ Minimize Time to Success (How can we make this faster? How can we show progress?) +❏ Minimize Effort & Sacrifice (How can we make this easier? More Seamless? Convenient?) + ### Value prop SWARMS ``` We've helped thousands of people just like you automate 30% of their activities with Swarms. And, all it takes to get started is a fast simple onboarding flow that asks you to integrate your tools and datasources. From cc4d0fcf6b7563aeb07fc8e3004d9cd3e51f0197 Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 15:16:04 -0400 Subject: [PATCH 09/98] sales people open source Former-commit-id: 72eb6c86686fc4dd1988bc76587da9a85cc6dd10 --- DOCS/SALESPEOPLE_PLAN.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 DOCS/SALESPEOPLE_PLAN.md diff --git a/DOCS/SALESPEOPLE_PLAN.md b/DOCS/SALESPEOPLE_PLAN.md new file mode 100644 index 00000000..9fd45c03 --- /dev/null +++ b/DOCS/SALESPEOPLE_PLAN.md @@ -0,0 +1,37 @@ +**Open Source Freelancer Salespeople Recruitment Plan** + +In the spirit of Jeff Bezos' philosophy of thinking long-term, customer obsession, and commitment to operational excellence, here is a strategic plan to attract open-source freelancer salespeople to Swarms. + +1. **Promote the Vision**: A compelling vision is the cornerstone of any recruitment strategy. Share the vision and mission of Swarms – its potential to revolutionize AI and digital automation – on every possible platform. The goal is to attract freelancers who are excited about the potential of AI and are eager to be part of this revolution. + +2. **Compensation Structure**: Offer a highly competitive, commission-based compensation structure. This could include a base rate for each sale, as well as performance-based bonuses and incentives for high-performing salespeople. Make it clear that the better they do, the more they earn. + +3. **Comprehensive Training**: Ensure all salespeople receive comprehensive training about Swarms, its capabilities, and the potential benefits it can offer to businesses. The more knowledgeable they are about the product, the better they can sell it. + +4. **Collaborative Community**: Foster a community of open-source freelancer salespeople. This community will provide a platform for salespeople to exchange ideas, share success stories, and learn from each other. Foster a culture of collaboration and continuous learning. + +5. **Clear Communication**: Be clear about expectations, targets, and performance metrics. Provide regular feedback and recognition to keep salespeople motivated and aligned with the company's goals. + +6. **Sales Tools & Resources**: Equip salespeople with the necessary tools and resources they need to sell effectively. This might include sales scripts, customer personas, case studies, product demos, and any other material that can aid them in their sales efforts. + +7. **Marketing Support**: In parallel to sales efforts, invest in marketing initiatives to build brand awareness and generate leads. The higher the brand visibility, the easier it will be for salespeople to sell the product. + +8. **Advocate Program**: Introduce an advocate program where salespeople get additional rewards for bringing in more salespeople. This will not only increase the sales force but also instill a sense of ownership and involvement among salespeople. + +**Flywheel Research Diagram** + +Building a flywheel involves understanding and leveraging the compounding effect of a circular, connected process, where each stage fuels the next. Here's a conceptualization of a Swarms Sales Flywheel: + +1. **Training & Empowerment**: Start by attracting freelance salespeople and providing comprehensive training and resources. As salespeople gain competence, they become better at selling Swarms. + +2. **Sales**: As sales increase, so do the visibility of Swarms and the earnings of the salespeople. This attracts more clients and more potential salespeople. + +3. **Client Success**: Successful clients serve as testimonials and case studies, helping to validate the product and making it easier for salespeople to sell Swarms. Success stories and increased visibility generate more interest among potential salespeople. + +4. **Community & Advocacy**: A growing community of successful salespeople, satisfied clients, and a strong product fuels advocacy. Salespeople are more likely to recommend the opportunity to other potential salespeople. + +5. **Growth**: As the community and client base grow, so do the opportunities for salespeople. Increased earnings and a stronger product reputation attract more salespeople, turning the flywheel faster. + +6. **Back to Training & Empowerment**: The increased interest from potential salespeople leads back to the first stage of the flywheel – training and empowering more salespeople. + +The key to the flywheel's momentum is ensuring each stage is performed effectively, creating a virtuous cycle that builds momentum over time. It relies on customer success, salesperson success, and product success, all fueling each other to keep the flywheel spinning. \ No newline at end of file From 8e0fbf016a7437a043f3b8f99b485f98d2305f82 Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 15:18:25 -0400 Subject: [PATCH 10/98] master plan Former-commit-id: 723a1dce794d76e361cdd1101741654a428ae587 --- DOCS/SALESPEOPLE_PLAN.md | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/DOCS/SALESPEOPLE_PLAN.md b/DOCS/SALESPEOPLE_PLAN.md index 9fd45c03..0f1d369d 100644 --- a/DOCS/SALESPEOPLE_PLAN.md +++ b/DOCS/SALESPEOPLE_PLAN.md @@ -34,4 +34,36 @@ Building a flywheel involves understanding and leveraging the compounding effect 6. **Back to Training & Empowerment**: The increased interest from potential salespeople leads back to the first stage of the flywheel – training and empowering more salespeople. -The key to the flywheel's momentum is ensuring each stage is performed effectively, creating a virtuous cycle that builds momentum over time. It relies on customer success, salesperson success, and product success, all fueling each other to keep the flywheel spinning. \ No newline at end of file +The key to the flywheel's momentum is ensuring each stage is performed effectively, creating a virtuous cycle that builds momentum over time. It relies on customer success, salesperson success, and product success, all fueling each other to keep the flywheel spinning. + + + +# Risks and Mitigations +Embracing an open source salesforce represents an innovative approach and can have significant benefits, including scalability, diversity, and cost-effectiveness. However, there are potential risks that need to be considered and mitigated. Here they are, along with strategies for managing them: + +**1. Brand Representation:** In an open source sales model, you can't control who represents your brand, as anyone can essentially become a salesperson. This can pose a risk if salespeople don't present the product or brand accurately, or don't uphold company values in their interactions. + + *Mitigation Strategy:* Provide clear brand guidelines, sales training, and codes of conduct that salespeople must adhere to. Regular monitoring and feedback can help ensure compliance. Also, introduce a certification process to officially recognize salespeople who demonstrate their understanding of the product and brand. + +**2. Product Misrepresentation:** Salespeople may overpromise or misrepresent the product to close a deal, leading to customer dissatisfaction and damage to the brand. + + *Mitigation Strategy:* Ensure that comprehensive and accurate product information is readily available. Provide clear guidelines on what can and cannot be promised to customers. Regularly update salespeople on product developments so their knowledge remains accurate. + +**3. Variable Quality of Salespeople:** In an open-source model, the quality of salespeople can vary widely, which may lead to inconsistent customer experiences. + + *Mitigation Strategy:* Offer comprehensive training and provide sales scripts or guidelines to ensure a uniform sales approach. Monitor performance and provide feedback to help salespeople improve. + +**4. Competition and Infighting:** Salespeople may compete with each other for the same leads, causing conflicts and damaging team cohesion. + + *Mitigation Strategy:* Create a clear system for lead assignment and territory division to prevent overlaps. Promote a collaborative rather than competitive culture, emphasizing the collective success of the team over individual achievements. + +**5. Data Security and Privacy:** With more individuals having access to company and customer information, the risk of data breaches increases. + + *Mitigation Strategy:* Provide training on data security and privacy policies. Use secure systems for data access and sharing. Regularly audit and monitor data access to detect any potential breaches. + +**6. Lack of Control:** The company may have less control over an open-source salesforce compared to an in-house team, leading to potential inconsistencies and inefficiencies. + + *Mitigation Strategy:* Regular communication and feedback are crucial. Use a performance management system to set expectations, track progress, and identify areas for improvement. + +Ultimately, the key is to adopt a long-term perspective, just like Jeff Bezos. Invest in training and building relationships with the salespeople. Foster a culture of customer obsession, and instill a sense of ownership and responsibility in the salespeople. Just as with any other risk, these can be mitigated with careful planning, continuous monitoring, and regular feedback. + From ecc8dc62d8c12ad468a49f2d4db8e2fbfb1c7e43 Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 15:19:30 -0400 Subject: [PATCH 11/98] clean up Former-commit-id: 28bffe6cfcecfcf3a1b0345a3832dbe1f8c11362 --- DOCS/SALESPEOPLE_PLAN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DOCS/SALESPEOPLE_PLAN.md b/DOCS/SALESPEOPLE_PLAN.md index 0f1d369d..219a66f0 100644 --- a/DOCS/SALESPEOPLE_PLAN.md +++ b/DOCS/SALESPEOPLE_PLAN.md @@ -1,4 +1,4 @@ -**Open Source Freelancer Salespeople Recruitment Plan** +# **Open Source Freelancer Salespeople Recruitment Plan** In the spirit of Jeff Bezos' philosophy of thinking long-term, customer obsession, and commitment to operational excellence, here is a strategic plan to attract open-source freelancer salespeople to Swarms. From e219aaeba9dd3d83dc9c9f4bc23851756f5be02d Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 15:22:36 -0400 Subject: [PATCH 12/98] clean up Former-commit-id: 784daa2322250a5636a79fde4c7f18e9567ea0d6 --- DOCS/SALES.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/DOCS/SALES.md b/DOCS/SALES.md index 7211ccb5..97fd0f54 100644 --- a/DOCS/SALES.md +++ b/DOCS/SALES.md @@ -56,8 +56,6 @@ Remember, this is more than just a transaction. It's a partnership. And like any This is a detailed customer journey roadmap and Standard Operating Procedure for selling Swarms to businesses of varying sizes. The SPIN selling method (Situation, Problem, Implication, Need-payoff) will be incorporated throughout the document to provide a comprehensive approach. We'll explore a scenario that begins with cold emailing and culminates in offering theoretical consultation package deals. -Please note that due to the constraints of this medium, this document will not reach 4000 words. - **1. Lead Generation and Cold Outreach** Our journey begins with identifying potential leads that could benefit from the capabilities of Swarms. This step involves researching potential clients based on their industry, size, digital footprint, and overall potential to benefit from AI automation. @@ -140,8 +138,11 @@ Where: #### Maximize Value Using Value Equation ❏ Maximize Dream Outcome (solve problem worth solving) + ❏ Maximize Perceived Likelihood of Success (testimonials& proven case studies) + ❏ Minimize Time to Success (How can we make this faster? How can we show progress?) + ❏ Minimize Effort & Sacrifice (How can we make this easier? More Seamless? Convenient?) ### Value prop SWARMS From d69822e646df9975777d855ac367c0bac77269c4 Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 15:26:21 -0400 Subject: [PATCH 13/98] clean up Former-commit-id: d9d7fc8fc1506c9e13c36666056ec2d7c0cdaa08 --- DOCS/SALES.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/DOCS/SALES.md b/DOCS/SALES.md index 97fd0f54..923599c9 100644 --- a/DOCS/SALES.md +++ b/DOCS/SALES.md @@ -145,10 +145,28 @@ Where: ❏ Minimize Effort & Sacrifice (How can we make this easier? More Seamless? Convenient?) +### Swarms Examples + +### Swarms Value Proposition + +"Leap into a new era of productivity with Swarms. Automate up to 50% of your business tasks with the power of cooperative AI, a proven solution trusted by thousands worldwide. With an easy integration process, your dream of seamless automation is just a few steps away." + +Where: + +- The dream outcome is achieving a significant boost in efficiency and productivity by automating 30-50% of your daily business tasks with Swarms. + +- The perceived likelihood of success is backed by our strong track record, with thousands of successful implementations and satisfied customers globally. + +- We've minimized the time delay to success. Swarms provides quick and painless onboarding, with step-by-step support to ensure smooth integration into your existing workflow. + +- The effort and sacrifice required is significantly less than traditional methods. Swarms is designed for ease of use, requiring minimal technical know-how. Plus, our dedicated support team is always at hand to ensure a seamless experience. + +In essence, Swarms makes the dream of comprehensive business automation an attainable reality. Join thousands of our active users in harnessing the power of cooperative AI, and transform your business operations with us today. + ### Value prop SWARMS ``` We've helped thousands of people just like you automate 30% of their activities with Swarms. And, all it takes to get started is a fast simple onboarding flow that asks you to integrate your tools and datasources. -```` +``` In today's competitive landscape, organizations of all sizes are continually seeking ways to automate routine tasks, streamline processes, and make data-driven decisions. Enter Swarms, a revolutionary AI-based technology that leverages the power of multiple autonomous agents to perform tasks with unprecedented speed and accuracy. From 89948025e595496a67f614ba673e082564eab3a7 Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 15:39:42 -0400 Subject: [PATCH 14/98] clean up Former-commit-id: 815b4fe1b68aa2b7bc5a9d4eb29eb7e69cdb5bbb --- DOCS/SALES.md | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 69 insertions(+), 1 deletion(-) diff --git a/DOCS/SALES.md b/DOCS/SALES.md index 923599c9..b1eacc56 100644 --- a/DOCS/SALES.md +++ b/DOCS/SALES.md @@ -290,4 +290,72 @@ Package 3 - Ongoing Support & Upgrades: We provide continuous support to address latest upgrades and improvements to Swarms. -Remember, Swarms isn't just a product; it's a partnership. We're committed to working with you every step of the way, ensuring you harness the full power of cooperative AI to transform your organization. \ No newline at end of file +Remember, Swarms isn't just a product; it's a partnership. We're committed to working with you every step of the way, ensuring you harness the full power of cooperative AI to transform your organization. + + + + + +# Open Source Salesperson Onboarding Experience + +Creating an efficient, streamlined, and effective onboarding experience for open source salespeople is essential to minimize time and maximize engagement. Drawing inspiration from the simplicity and user-focus of Steve Jobs, this document proposes an onboarding flow that is effortless, engaging, and educational. + +## Landing Page + +The journey starts with a landing page that is clean, crisp, and intuitively designed. A minimalistic aesthetic, akin to Apple's design philosophy, helps the user focus on what's important. The landing page should contain: + +- A bold, clear headline, expressing the value proposition for becoming an open source salesperson for Swarms. +- A short video or animation introducing Swarms and the opportunity for the salespeople. +- Clear call-to-action (CTA) buttons to start the onboarding process or to learn more. + +## Interactive Learning Modules + +Once the user clicks on the CTA, they're taken to an interactive course platform. This platform should feature short, digestible video modules covering a range of essential topics, including: + +1. An Introduction to Swarms: An engaging video that explains the concept, the value it brings to businesses, and the open-source ethos driving it. + +2. Understanding the Technology: A simple, jargon-free explanation of the underlying technology, how it works, and why it works that way. Emphasis should be on benefits rather than technical intricacies. + +3. Successful Sales Strategies: Sharing effective sales techniques and strategies that have worked for Swarms, along with case studies and testimonials. + +4. Navigating Customer Conversations: Guidance on how to effectively communicate with potential customers, including understanding their needs, presenting Swarms as a solution, and addressing objections. + +After each module, the user is asked to answer a few questions to ensure understanding and engagement. This also helps in identifying potential areas of confusion or difficulty. + +## Personal Interaction + +Once the user completes all the modules and successfully answers the questions, they're invited to schedule a one-on-one call with a member of APAC AI or an experienced open source sales freelancer. This serves as a validation step, providing personalized feedback and guidance to ensure the salesperson is ready to start selling Swarms. + +Throughout this journey, the focus should be on simplicity and intuitiveness. Just like Steve Jobs did with Apple's products, the onboarding experience should be so seamless and enjoyable that it's almost invisible, allowing the user to focus on what truly matters – learning about Swarms and how to sell it. + + + +# Open Source Salesperson Onboarding: Post Course Completion + +Once a salesperson has completed the initial course and had their one-on-one session, the onboarding continues to the next phase – preparing them for sales activities and ensuring they have the necessary tools and resources. + +## Access to CRM and Sales Tools + +Every salesperson is provided with access to a CRM (Customer Relationship Management) system. This CRM would be a simplified, user-friendly system that allows them to manage their prospects, track their interactions, and monitor their sales progress. They would also receive training on how to effectively use the CRM to streamline their sales activities. + +## Sales Resources + +Salespeople would be provided with a suite of sales resources, including Swarms product brochures, case studies, presentations, and a script guideline. They would also be given access to a community forum where they can connect with other salespeople, share experiences, ask questions, and learn from each other. + +## Making a Sale + +In terms of the actual sale process, the salesperson would direct the customer to a unique landing page on the APAC.ai website. This landing page would be specifically designed for the sales journey, and it would allow the customer to input their salesperson's ID during the checkout process. + +This ID linking mechanism is critical, as it ensures that the salesperson gets credited for any sales they bring in. Once a sale is made, the salesperson's commission gets credited to their account. + +## Post-Sale and Account Management + +Post-sale, the salesperson's role transitions to more of an account manager. They become the primary point of contact for the customer, responsible for ensuring customer satisfaction, handling any issues or concerns, and identifying opportunities for upselling or cross-selling. + +The salesperson would also receive a recurring revenue from their accounts. This not only incentivizes them to maintain a good relationship with their customers but also rewards them for the ongoing value they provide. + +## Feedback and Performance Reviews + +Periodic performance reviews would be conducted to provide feedback to the salespeople and help them improve. These reviews would also be an opportunity to recognize top performers and share their success stories with the wider community. + +Overall, the objective is to create a smooth, rewarding, and self-sustaining sales ecosystem. Salespeople are empowered with the tools, resources, and incentives they need to succeed, and in return, they help drive the growth and success of Swarms. It's a win-win scenario that has the potential to dramatically accelerate Swarms' market penetration and customer adoption. \ No newline at end of file From 0d8755df8612e117f2ae19716d81dabaa1aec6ec Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 15:51:28 -0400 Subject: [PATCH 15/98] clean up Former-commit-id: 02d4d7ac435e58771078fda49645ce3a05214dda --- DOCS/SALES.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/DOCS/SALES.md b/DOCS/SALES.md index b1eacc56..e7f24a19 100644 --- a/DOCS/SALES.md +++ b/DOCS/SALES.md @@ -332,6 +332,12 @@ Throughout this journey, the focus should be on simplicity and intuitiveness. Ju # Open Source Salesperson Onboarding: Post Course Completion +### For more assistance check out these resources + +* [Pricing Package](https://www.acquisition.com/hubfs/Offer%20Checklists%20-%20PDF%20Downloads/Pricing-Value-Checklist.pdf?hsLang=en) + +*[Alex Hormozi](https://www.acquisition.com/offers-value-equation) + Once a salesperson has completed the initial course and had their one-on-one session, the onboarding continues to the next phase – preparing them for sales activities and ensuring they have the necessary tools and resources. ## Access to CRM and Sales Tools From 1d1b2634cf411b5d32b5aa3fc09b95dce51bfed3 Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 18:52:20 -0400 Subject: [PATCH 16/98] developer + sales Former-commit-id: 6b311ea01802ccdf3c3f4d537b83b9389aae6ca6 --- DOCS/DEVELOPER_PLAN.md | 60 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 DOCS/DEVELOPER_PLAN.md diff --git a/DOCS/DEVELOPER_PLAN.md b/DOCS/DEVELOPER_PLAN.md new file mode 100644 index 00000000..fee1a8d2 --- /dev/null +++ b/DOCS/DEVELOPER_PLAN.md @@ -0,0 +1,60 @@ +# Flywheel Effect for Developer Acquisition and Incentivization + +As with the sales model, the developer acquisition and incentivization model also relies on a flywheel effect. This effect is particularly potent in a community-driven ecosystem such as ours, where the value proposition continually grows as more developers join and contribute to our projects. Here's how we could apply this approach: + +## Step 1: Initial Value Proposition for Developers +The starting point of the flywheel is to provide an attractive value proposition for developers. This could include: + +- The ability to work on cutting-edge technology (Swarms, in this case). +- The opportunity to contribute to a community-driven, open-source project. +- The chance to learn from and collaborate with a global network of highly skilled developers. +- An incentivization structure that rewards contributions (more on this later). + +## Step 2: Developer Acquisition +With the initial value proposition in place, we can move on to the actual acquisition of developers. This could be accomplished through: + +- Active recruitment from online developer communities. +- Referral programs that incentivize current contributors to bring in new developers. +- Partnerships with universities, boot camps, and other institutions to attract budding developers. + +## Step 3: Collaboration and Learning +Once developers join our ecosystem, they become part of a collaborative community where they can learn from each other, improve their skills, and work on exciting and meaningful projects. This, in turn, attracts more developers, adding momentum to the flywheel. + +## Step 4: Recognizing and Rewarding Contributions +To keep the flywheel spinning, it's crucial to recognize and reward the contributions made by developers. This can be done in various ways: + +- Monetary rewards: Developers can be paid based on the value their contributions bring to the project. This could be determined through various metrics, such as the complexity of their contributions, the impact on the project, or the amount of their code that gets used in production. + +- Reputation and recognition: The open-source nature of our project means that all contributions are public and can be used by developers to build their professional profiles. Contributors could also be highlighted on our website, in our communications, and at community events. + +- Career advancement: Developers who consistently make valuable contributions could be offered positions of leadership within the project, such as becoming maintainers or joining a steering committee. + +- Agora Tokens: We could create a system of tokens that are earned based on contributions. These tokens could be exchanged for various benefits, such as access to exclusive events, special training, or even physical goods. + +## Step 5: Scaling the Flywheel +With the flywheel in motion, the next step is to scale. As our community grows and our technology improves, we can attract more developers and create more value. This leads to a virtuous cycle of growth, where each new developer adds to the attractiveness of our project, which in turn brings in more developers. + +In essence, this flywheel approach is about creating a community where everyone benefits from each other's contributions. The more value a developer adds, the more they are rewarded. The more developers contribute, the more value is created, attracting even more developers. + +Such a model not only aligns with our values of openness, collaboration, and shared success, but it also gives us a sustainable and scalable method for growing our developer community. It makes Agora not just a place to work, but also a place to learn, grow, and be recognized for one's contributions. This is a powerful way to ensure that we can continue to advance our technology and make a significant impact on the world. + + +# Risks and mitigations + +The open source engineering freelancer model brings with it its own set of potential risks and challenges. Here's an exploration of some of these, along with strategies for mitigation: + +**1. Quality Control:** When dealing with a wide network of freelance contributors, ensuring a consistent standard of quality across all contributions can be challenging. This can be mitigated by implementing rigorous review processes and standards, establishing an automated testing infrastructure, and fostering a culture of quality among contributors. Providing clear contribution guidelines, code style guides, and other resources can help freelancers understand what's expected of them. + +**2. Security Risks:** Open-source projects can be susceptible to malicious contributors, who might introduce vulnerabilities into the codebase. To mitigate this, rigorous code review processes should be in place. Additionally, adopting a "trust but verify" approach, leveraging automated security scanning tools, and conducting periodic security audits can be beneficial. + +**3. Intellectual Property Issues:** Open-source projects can face risks around intellectual property, such as contributors introducing code that infringes on someone else's copyrights. A clear Contributor License Agreement (CLA) should be in place, which contributors need to agree to before their contributions can be accepted. This helps protect the project and its users from potential legal issues. + +**4. Loss of Core Focus:** With numerous contributors focusing on different aspects of the project, there can be a risk of losing sight of the project's core objectives. Maintaining a clear roadmap, having a strong leadership team, and ensuring open and regular communication can help keep the project focused. + +**5. Contributor Burnout:** Freelancers contributing in their free time might face burnout, especially if they feel their contributions aren't being recognized or rewarded. To mitigate this, create a supportive environment where contributors' efforts are acknowledged and rewarded. This might include monetary rewards, but can also include non-monetary rewards like public recognition, advancement opportunities within the project, and so on. + +**6. Fragmentation:** In open source projects, there is a risk of fragmentation where different contributors or groups of contributors might want to take the project in different directions. Strong project governance, a clear roadmap, and open, transparent decision-making processes can help mitigate this risk. + +**7. Dependency on Key Individuals:** If key parts of the project are understood and maintained by only a single contributor, there is a risk if that individual decides to leave or is unable to contribute for some reason. This can be mitigated by ensuring knowledge is shared and responsibilities are spread among multiple contributors. + +Overall, these risks can be managed with proper planning, clear communication, and the implementation of good governance and security practices. It's essential to approach the open source model with a clear understanding of these potential pitfalls and a plan to address them. \ No newline at end of file From 003ab271d23c14e0203efb78649883159f8e6ae0 Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 18:54:41 -0400 Subject: [PATCH 17/98] clean up Former-commit-id: 02abbb0ad3fd7c41836ab9a7098ad93ff31747b8 --- DOCS/DEVELOPER_PLAN.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DOCS/DEVELOPER_PLAN.md b/DOCS/DEVELOPER_PLAN.md index fee1a8d2..383a3f94 100644 --- a/DOCS/DEVELOPER_PLAN.md +++ b/DOCS/DEVELOPER_PLAN.md @@ -43,7 +43,7 @@ Such a model not only aligns with our values of openness, collaboration, and sha The open source engineering freelancer model brings with it its own set of potential risks and challenges. Here's an exploration of some of these, along with strategies for mitigation: -**1. Quality Control:** When dealing with a wide network of freelance contributors, ensuring a consistent standard of quality across all contributions can be challenging. This can be mitigated by implementing rigorous review processes and standards, establishing an automated testing infrastructure, and fostering a culture of quality among contributors. Providing clear contribution guidelines, code style guides, and other resources can help freelancers understand what's expected of them. +**1. Quality Control:** When dealing with a wide network of freelance contributors, ensuring a consistent standard of quality across all contributions can be challenging. This can be mitigated by implementing rigorous review processes and standards, establishing an automated testing infrastructure, and fostering a culture of quality among contributors. Providing clear contribution guidelines, code style guides, and other resources can help freelancers understand what's expected of them. Providing Educational resources such as sponsoring creators like Yannic, and even making our own courses and then building techno-monasteries where young people can come in and research for free. **2. Security Risks:** Open-source projects can be susceptible to malicious contributors, who might introduce vulnerabilities into the codebase. To mitigate this, rigorous code review processes should be in place. Additionally, adopting a "trust but verify" approach, leveraging automated security scanning tools, and conducting periodic security audits can be beneficial. From 57c4005df0fe381f27b40ddf7254cef4668cf9a1 Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 18:58:00 -0400 Subject: [PATCH 18/98] develoeprs Former-commit-id: 280aeba71784c2d0ccfe8f1adc204155481fa81e --- DOCS/DEVELOPER_PLAN.md | 43 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/DOCS/DEVELOPER_PLAN.md b/DOCS/DEVELOPER_PLAN.md index 383a3f94..18d62db5 100644 --- a/DOCS/DEVELOPER_PLAN.md +++ b/DOCS/DEVELOPER_PLAN.md @@ -57,4 +57,45 @@ The open source engineering freelancer model brings with it its own set of poten **7. Dependency on Key Individuals:** If key parts of the project are understood and maintained by only a single contributor, there is a risk if that individual decides to leave or is unable to contribute for some reason. This can be mitigated by ensuring knowledge is shared and responsibilities are spread among multiple contributors. -Overall, these risks can be managed with proper planning, clear communication, and the implementation of good governance and security practices. It's essential to approach the open source model with a clear understanding of these potential pitfalls and a plan to address them. \ No newline at end of file +Overall, these risks can be managed with proper planning, clear communication, and the implementation of good governance and security practices. It's essential to approach the open source model with a clear understanding of these potential pitfalls and a plan to address them. + +## Plan to Gain Open Source Developers for SWARMS + +Attracting and retaining open-source developers is a challenge that requires a strategic approach. This plan emphasizes delivering value to the developers as well as providing recognition, community, and financial incentives. + +### Step 1: Foster an Engaging and Inclusive Community + +The first step is to foster an engaging and inclusive open-source community around SWARMS. This community should be a place where developers feel welcome and excited to contribute. Regular community events (both online and offline), engaging content, and a supportive environment can help attract and retain developers. + +### Step 2: Provide Clear Contribution Guidelines + +Providing clear and comprehensive contribution guidelines will make it easier for developers to get started. These guidelines should cover the basics of how to set up the development environment, how to submit changes, and how the code review process works. + +### Step 3: Offer Educational Resources and Training + +Providing training and educational resources can help developers grow their skills and contribute more effectively. These resources could include tutorials, webinars, workshops, documentation, and more. + +### Step 4: Establish a Recognition and Reward System + +Recognize and reward the contributions of developers. This could involve public recognition, like featuring contributors on the SWARMS website, as well as financial incentives. Implementing a system where developers earn a share of the revenue from SWARMS based on their contributions can be a strong motivator. + +### Step 5: Implement a Strong Support System + +Offer strong technical support to developers. This could include dedicated channels for developers to ask questions, request feedback, and share their progress. Having core team members available to provide assistance and mentorship can be hugely beneficial. + +### Step 6: Regularly Solicit and Incorporate Feedback + +Regularly ask for feedback from developers and incorporate their suggestions into future developments. This shows developers that their opinions are valued and can lead to improvements in SWARMS. + +## Flywheel for Gaining More Open Source Developers + +Now let's look at the flywheel effect that can result from this plan. The idea of the flywheel is that each part of the process feeds into the next, creating a cycle of growth that becomes self-sustaining over time. + +1. We build an engaging and supportive community around SWARMS. +2. This community attracts more developers who are interested in contributing to SWARMS. +3. As more developers contribute, the quality and scope of SWARMS improve, making it more attractive to potential users. +4. As SWARMS gains more users, the potential revenue from SWARMS increases, allowing for larger rewards to be distributed to developers. +5. The prospect of these rewards attracts even more developers to the SWARMS community. +6. The cycle repeats, with each iteration attracting more developers, improving SWARMS, increasing its user base, and raising potential rewards. + +Through this plan and the resulting flywheel effect, we can attract a strong, committed team of open-source developers to build SWARMS and make it the best it can be. \ No newline at end of file From 6691cd25eaffb2a74b3dfd2047637a1b6e27e891 Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 19:20:21 -0400 Subject: [PATCH 19/98] clean up flywheel effect Former-commit-id: c349ad37e1c240631b2771354d0b96d0bf1da50a --- DOCS/FLYWHEEL.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 DOCS/FLYWHEEL.md diff --git a/DOCS/FLYWHEEL.md b/DOCS/FLYWHEEL.md new file mode 100644 index 00000000..83d26475 --- /dev/null +++ b/DOCS/FLYWHEEL.md @@ -0,0 +1,17 @@ +# The Swarms Flywheel + +1. **Building a Supportive Community:** Initiate by establishing an engaging and inclusive open-source community for both developers and sales freelancers around Swarms. Regular online meetups, webinars, tutorials, and sales training can make them feel welcome and encourage contributions and sales efforts. + +2. **Increased Contributions and Sales Efforts:** The more engaged the community, the more developers will contribute to Swarms and the more effort sales freelancers will put into selling Swarms. + +3. **Improvement in Quality and Market Reach:** More developer contributions mean better quality, reliability, and feature offerings from Swarms. Simultaneously, increased sales efforts from freelancers boost Swarms' market penetration and visibility. + +4. **Rise in User Base:** As Swarms becomes more robust and more well-known, the user base grows, driving more revenue. + +5. **Greater Financial Incentives:** Increased revenue can be redirected to offer more significant financial incentives to both developers and salespeople. Developers can be incentivized based on their contribution to Swarms, and salespeople can be rewarded with higher commissions. + +6. **Attract More Developers and Salespeople:** These financial incentives, coupled with the recognition and experience from participating in a successful project, attract more developers and salespeople to the community. + +7. **Wider Adoption of Swarms:** An ever-improving product, a growing user base, and an increasing number of passionate salespeople accelerate the adoption of Swarms. + +8. **Return to Step 1:** As the community, user base, and sales network continue to grow, the cycle repeats, each time speeding up the flywheel. From 55e4feb9e09e87a160118b62412802e258940873 Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 19:21:37 -0400 Subject: [PATCH 20/98] clean up Former-commit-id: d3c0f009026f2fcce86b0d8b7827b2f02fd4e97e --- DOCS/FLYWHEEL.md | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/DOCS/FLYWHEEL.md b/DOCS/FLYWHEEL.md index 83d26475..b1b5b7a2 100644 --- a/DOCS/FLYWHEEL.md +++ b/DOCS/FLYWHEEL.md @@ -15,3 +15,51 @@ 7. **Wider Adoption of Swarms:** An ever-improving product, a growing user base, and an increasing number of passionate salespeople accelerate the adoption of Swarms. 8. **Return to Step 1:** As the community, user base, and sales network continue to grow, the cycle repeats, each time speeding up the flywheel. + + +```markdown + +---------------------+ + | Building a | + | Supportive | <--+ + | Community | | + +--------+-----------+ | + | | + v | + +--------+-----------+ | + | Increased | | + | Contributions & | | + | Sales Efforts | | + +--------+-----------+ | + | | + v | + +--------+-----------+ | + | Improvement in | | + | Quality & Market | | + | Reach | | + +--------+-----------+ | + | | + v | + +--------+-----------+ | + | Rise in User | | + | Base | | + +--------+-----------+ | + | | + v | + +--------+-----------+ | + | Greater Financial | | + | Incentives | | + +--------+-----------+ | + | | + v | + +--------+-----------+ | + | Attract More | | + | Developers & | | + | Salespeople | | + +--------+-----------+ | + | | + v | + +--------+-----------+ | + | Wider Adoption of | | + | Swarms |----+ + +---------------------+ +``` From 312e318dfbf1caebcad2f86407fba2f6aabf1311 Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 19:25:42 -0400 Subject: [PATCH 21/98] activation plan Former-commit-id: 738da5efb9bbaee6e487520e42aa13331ae9c3f7 --- DOCS/FLYWHEEL.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/DOCS/FLYWHEEL.md b/DOCS/FLYWHEEL.md index b1b5b7a2..24e6e98a 100644 --- a/DOCS/FLYWHEEL.md +++ b/DOCS/FLYWHEEL.md @@ -63,3 +63,39 @@ | Swarms |----+ +---------------------+ ``` + + +# Potential Risks and Mitigations: + +1. **Insufficient Contributions or Quality of Work**: Open-source efforts rely on individuals being willing and able to spend time contributing. If not enough people participate, or the work they produce is of poor quality, the product development could stall. + * **Mitigation**: Create a robust community with clear guidelines, support, and resources. Provide incentives for quality contributions, such as a reputation system, swag, or financial rewards. Conduct thorough code reviews to ensure the quality of contributions. + +2. **Lack of Sales Results**: Commission-based salespeople will only continue to sell the product if they're successful. If they aren't making enough sales, they may lose motivation and cease their efforts. + * **Mitigation**: Provide adequate sales training and resources. Ensure the product-market fit is strong, and adjust messaging or sales tactics as necessary. Consider implementing a minimum commission or base pay to reduce risk for salespeople. + +3. **Poor User Experience or User Adoption**: If users don't find the product useful or easy to use, they won't adopt it, and the user base won't grow. This could also discourage salespeople and contributors. + * **Mitigation**: Prioritize user experience in the product development process. Regularly gather and incorporate user feedback. Ensure robust user support is in place. + +4. **Inadequate Financial Incentives**: If the financial rewards don't justify the time and effort contributors and salespeople are putting in, they will likely disengage. + * **Mitigation**: Regularly review and adjust financial incentives as needed. Ensure that the method for calculating and distributing rewards is transparent and fair. + +5. **Security and Compliance Risks**: As the user base grows and the software becomes more complex, the risk of security issues increases. Moreover, as contributors from various regions join, compliance with various international laws could become an issue. + * **Mitigation**: Establish strong security practices from the start. Regularly conduct security audits. Seek legal counsel to understand and adhere to international laws and regulations. + +Activation Plan for the Flywheel: + +1. **Community Building**: Begin by fostering a supportive community around Swarms. Encourage early adopters to contribute and provide feedback. Create comprehensive documentation, community guidelines, and a forum for discussion and support. + +2. **Sales and Development Training**: Provide resources and training for salespeople and developers. Make sure they understand the product, its value, and how to effectively contribute or sell. + +3. **Increase Contributions and Sales Efforts**: Encourage increased participation by highlighting successful contributions and sales, rewarding top contributors and salespeople, and regularly communicating about the project's progress and impact. + +4. **Iterate and Improve**: Continually gather and implement feedback to improve Swarms and its market reach. The better the product and its alignment with the market, the more the user base will grow. + +5. **Expand User Base**: As the product improves and sales efforts continue, the user base should grow. Ensure you have the infrastructure to support this growth and maintain a positive user experience. + +6. **Increase Financial Incentives**: As the user base and product grow, so too should the financial incentives. Make sure rewards continue to be competitive and attractive. + +7. **Attract More Contributors and Salespeople**: As the financial incentives and success of the product increase, this should attract more contributors and salespeople, further feeding the flywheel. + +Throughout this process, it's important to regularly reassess and adjust your strategy as necessary. Stay flexible and responsive to changes in the market, user feedback, and the evolving needs of the community. \ No newline at end of file From 2fbafce9de1c24aa437781f1cce5c91e71ad068c Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 19:51:27 -0400 Subject: [PATCH 22/98] AttributeError: module 'os' has no attribute 'env' Former-commit-id: b6b74116b8992498b107bf7cff58a3ed43d15ea5 --- DOCS/FLYWHEEL.md | 2 +- swarms/agents/utils/llm.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/DOCS/FLYWHEEL.md b/DOCS/FLYWHEEL.md index 24e6e98a..ac8851be 100644 --- a/DOCS/FLYWHEEL.md +++ b/DOCS/FLYWHEEL.md @@ -82,7 +82,7 @@ 5. **Security and Compliance Risks**: As the user base grows and the software becomes more complex, the risk of security issues increases. Moreover, as contributors from various regions join, compliance with various international laws could become an issue. * **Mitigation**: Establish strong security practices from the start. Regularly conduct security audits. Seek legal counsel to understand and adhere to international laws and regulations. -Activation Plan for the Flywheel: +## Activation Plan for the Flywheel: 1. **Community Building**: Begin by fostering a supportive community around Swarms. Encourage early adopters to contribute and provide feedback. Create comprehensive documentation, community guidelines, and a forum for discussion and support. diff --git a/swarms/agents/utils/llm.py b/swarms/agents/utils/llm.py index a8ca7870..b28d932b 100644 --- a/swarms/agents/utils/llm.py +++ b/swarms/agents/utils/llm.py @@ -139,7 +139,7 @@ class ChatOpenAI(BaseChatModel, BaseModel): """ client: Any #: :meta private: - model_name: str = os.env["MODEL_NAME"] + model_name: str = os.environ["MODEL_NAME"] """Model name to use.""" model_kwargs: Dict[str, Any] = Field(default_factory=dict) """Holds any model parameters valid for `create` call not explicitly specified.""" From 574a44b1a58c64d3b94eb1e7a9bd66457594e6f3 Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 19:55:56 -0400 Subject: [PATCH 23/98] clean up Former-commit-id: aca05830a150d9defb3636ec12be9ef4c4eeceb5 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2e94ec24..5566891e 100644 --- a/README.md +++ b/README.md @@ -117,8 +117,6 @@ The ports you can use are 4500 and 6500. swarm.run_swarms(objective) ``` -This will create and execute a task to write a summary about the latest news on quantum computing. The result will be the summary of the news. - --- ## Share with your Friends @@ -197,6 +195,8 @@ Remember, our roadmap is a guide, and we encourage you to bring your own ideas a * Make a swarm that checks arxviv for papers -> checks if there is a github link -> then implements them and checks them +* [SwarmLogic, where a swarm is your API, database, and backend!](https://github.com/kyegomez/SwarmLogic) + --- # Demos From 38e53691dd2f8730339da2a490d49f2de5ba0b48 Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 20:00:05 -0400 Subject: [PATCH 24/98] or logic Former-commit-id: cb4497397df546019df71f7b8aa63e8518a0be92 --- swarms/agents/utils/llm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarms/agents/utils/llm.py b/swarms/agents/utils/llm.py index b28d932b..a9fdb265 100644 --- a/swarms/agents/utils/llm.py +++ b/swarms/agents/utils/llm.py @@ -139,7 +139,7 @@ class ChatOpenAI(BaseChatModel, BaseModel): """ client: Any #: :meta private: - model_name: str = os.environ["MODEL_NAME"] + model_name: str = os.environ["MODEL_NAME"] or 'gpt-4' """Model name to use.""" model_kwargs: Dict[str, Any] = Field(default_factory=dict) """Holds any model parameters valid for `create` call not explicitly specified.""" From 1e25332dcd477a277f2ac933fb8f75c14adcba25 Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 20:04:50 -0400 Subject: [PATCH 25/98] mising import Former-commit-id: 8995b329d27e5991c63ba42f693f230fd43efbc1 --- swarms/agents/utils/llm.py | 1 + 1 file changed, 1 insertion(+) diff --git a/swarms/agents/utils/llm.py b/swarms/agents/utils/llm.py index a9fdb265..46984130 100644 --- a/swarms/agents/utils/llm.py +++ b/swarms/agents/utils/llm.py @@ -1,6 +1,7 @@ """OpenAI chat wrapper.""" from __future__ import annotations +import os import logging import sys from typing import Any, Callable, Dict, List, Mapping, Optional, Tuple From 44f1b022a3487726c0ebf09ad0bd203fc754ad40 Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 20:11:13 -0400 Subject: [PATCH 26/98] clean up model name Former-commit-id: c1e7914c505050ae088f857762597dad247bb37e --- swarms/agents/utils/llm.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarms/agents/utils/llm.py b/swarms/agents/utils/llm.py index 46984130..a6775c38 100644 --- a/swarms/agents/utils/llm.py +++ b/swarms/agents/utils/llm.py @@ -140,7 +140,7 @@ class ChatOpenAI(BaseChatModel, BaseModel): """ client: Any #: :meta private: - model_name: str = os.environ["MODEL_NAME"] or 'gpt-4' + model_name: str = os.environ.get("MODEL_NAME", "gpt-4") """Model name to use.""" model_kwargs: Dict[str, Any] = Field(default_factory=dict) """Holds any model parameters valid for `create` call not explicitly specified.""" From 7a36b1243ddb57d47e90cd67358d9852b0abefab Mon Sep 17 00:00:00 2001 From: Kye Date: Tue, 11 Jul 2023 20:24:37 -0400 Subject: [PATCH 27/98] celery Former-commit-id: 1822bb3394979949f750e2160c0db409237f29bb --- swarms/agents/utils/callback.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarms/agents/utils/callback.py b/swarms/agents/utils/callback.py index cca65037..771f370f 100644 --- a/swarms/agents/utils/callback.py +++ b/swarms/agents/utils/callback.py @@ -2,7 +2,7 @@ from typing import Any, Dict, List, Optional, Union from langchain.callbacks.base import BaseCallbackHandler from langchain.schema import AgentAction, AgentFinish, LLMResult -# from celery import Task +from celery import Task # from ansi import ANSI, Color, Style, dim_multiline from swarms.utils.main import ANSI, Color, Style, dim_multiline From d1ed96e883a4f2f6d6579a944b02213561376a9d Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 18:03:35 -0400 Subject: [PATCH 28/98] clean up test with base handler Former-commit-id: f41a92b00e88b3d26f1f58d722f5ea2a90fd8db3 --- .env.example | 2 +- swarms/agents/utils/manager.py | 2 +- swarms/agents/workers/{metaprompt_worker.py => PromptWorker.py} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename swarms/agents/workers/{metaprompt_worker.py => PromptWorker.py} (100%) diff --git a/.env.example b/.env.example index 48dd0429..cc12b4d5 100644 --- a/.env.example +++ b/.env.example @@ -26,4 +26,4 @@ BRAVE_API_KEY="" SPOONACULAR_KEY="" HF_API_KEY="Huggingface api key" -MODEL_NAME="" \ No newline at end of file +MODEL_NAME="gpt-4" \ No newline at end of file diff --git a/swarms/agents/utils/manager.py b/swarms/agents/utils/manager.py index 0c73ee9e..72f2f978 100644 --- a/swarms/agents/utils/manager.py +++ b/swarms/agents/utils/manager.py @@ -13,7 +13,7 @@ from .builder import AgentBuilder from .callback import EVALCallbackHandler, ExecutionTracingCallbackHandler -CallbackManager.set_handler(EVALCallbackHandler()) +CallbackManager.set_handler(handler=EVALCallbackHandler()) class AgentManager: diff --git a/swarms/agents/workers/metaprompt_worker.py b/swarms/agents/workers/PromptWorker.py similarity index 100% rename from swarms/agents/workers/metaprompt_worker.py rename to swarms/agents/workers/PromptWorker.py From c429874fa151efa38fd91127033a7ffb358b1c4a Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 18:17:26 -0400 Subject: [PATCH 29/98] clean up accidentally switched workernames Former-commit-id: 5194209802d9ff7a2b3d4c71dd860bc2abbefe37 --- swarms/agents/workers/worker_agent.py | 64 +++++++++++++++++++-------- 1 file changed, 46 insertions(+), 18 deletions(-) diff --git a/swarms/agents/workers/worker_agent.py b/swarms/agents/workers/worker_agent.py index 55342e02..f7fd465e 100644 --- a/swarms/agents/workers/worker_agent.py +++ b/swarms/agents/workers/worker_agent.py @@ -17,6 +17,8 @@ class WorkerNode: """Useful for when you need to spawn an autonomous agent instance as a worker to accomplish complex tasks, it can search the internet or spawn child multi-modality models to process and generate images and text or audio and so on""" def __init__(self, llm, tools, vectorstore): + if not llm or not tools or not vectorstore: + raise ValueError("llm, tools, and vectorstore cannot be None") self.llm = llm self.tools = tools self.vectorstore = vectorstore @@ -24,18 +26,26 @@ class WorkerNode: def create_agent(self, ai_name, ai_role, human_in_the_loop, search_kwargs): logging.info("Creating agent in WorkerNode") - self.agent = AutoGPT.from_llm_and_tools( - ai_name=ai_name, - ai_role=ai_role, - tools=self.tools, - llm=self.llm, - memory=self.vectorstore.as_retriever(search_kwargs=search_kwargs), - human_in_the_loop=human_in_the_loop, - chat_history_memory=FileChatMessageHistory("chat_history.txt"), - ) - self.agent.chain.verbose = True + try: + + self.agent = AutoGPT.from_llm_and_tools( + ai_name=ai_name, + ai_role=ai_role, + tools=self.tools, + llm=self.llm, + memory=self.vectorstore.as_retriever(search_kwargs=search_kwargs), + human_in_the_loop=human_in_the_loop, + chat_history_memory=FileChatMessageHistory("chat_history.txt"), + ) + self.agent.chain.verbose = True + + except Exception as e: + logging.error(f"Error while creating agent: {str(e)}") + raise e def add_tool(self, tool: Tool): + if not isinstance(tool, Tool): + raise TypeError("Tool must be an instance of Tool") self.tools.append(tool) def run(self, prompt: str) -> str: @@ -44,26 +54,40 @@ class WorkerNode: if not prompt: raise ValueError("Prompt is empty") - - self.agent.run([f"{prompt}"]) - return "Task completed by WorkerNode" + + try: + + + self.agent.run([f"{prompt}"]) + return "Task completed by WorkerNode" + except Exception as e: + logging.error(f"While running the agent: {str(e)}") + raise e + -worker_tool = Tool( - name="WorkerNode AI Agent", - func=WorkerNode.run, - description="Useful for when you need to spawn an autonomous agent instance as a worker to accomplish complex tasks, it can search the internet or spawn child multi-modality models to process and generate images and text or audio and so on" -) +# worker_tool = Tool( +# name="WorkerNode AI Agent", +# func=WorkerNode.run, +# description="Useful for when you need to spawn an autonomous agent instance as a worker to accomplish complex tasks, it can search the internet or spawn child multi-modality models to process and generate images and text or audio and so on" +# ) class WorkerNodeInitializer: def __init__(self, openai_api_key): + if not openai_api_key: + raise ValueError("openai_api_key cannot be None") self.openai_api_key = openai_api_key def initialize_llm(self, llm_class, temperature=0.5): + if not llm_class: + raise ValueError("llm_class cannot be None") return llm_class(openai_api_key=self.openai_api_key, temperature=temperature) def initialize_tools(self, llm_class): + if not llm_class: + raise ValueError("llm_class cannot be none") + logging.info('Creating WorkerNode') llm = self.initialize_llm(llm_class) web_search = DuckDuckGoSearchRun() tools = [ @@ -82,6 +106,8 @@ class WorkerNodeInitializer: return FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {}) def create_worker_node(self, llm_class=ChatOpenAI): + if not llm_class: + raise ValueError("llm_class cannot be None") worker_tools = self.initialize_tools(llm_class) vectorstore = self.initialize_vectorstore() worker_node = WorkerNode(llm=self.initialize_llm(llm_class), tools=worker_tools, vectorstore=vectorstore) @@ -89,6 +115,8 @@ class WorkerNodeInitializer: return worker_node def worker_node(openai_api_key): + if not openai_api_key: + raise ValueError("openai_api_key cannot be none") initializer = WorkerNodeInitializer(openai_api_key) worker_node = initializer.create_worker_node() return worker_node From 7f25003e3811980245e7c3e62c07d6b3b27db8ad Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 18:28:04 -0400 Subject: [PATCH 30/98] clean up + error handling Former-commit-id: e9641f686498b884506c20992f09f13c8da76e17 --- api/container.py | 2 +- swarms/__init__.py | 2 +- .../utils/{builder.py => AgentBuilder.py} | 6 +- swarms/agents/utils/AgentManager.py | 86 +++++++++++++++++++ .../utils/{parser.py => EvalOutputParser.py} | 0 swarms/agents/utils/manager.py | 82 ------------------ swarms/agents/workers/worker_ultranode.py | 45 +++++++--- 7 files changed, 125 insertions(+), 98 deletions(-) rename swarms/agents/utils/{builder.py => AgentBuilder.py} (95%) create mode 100644 swarms/agents/utils/AgentManager.py rename swarms/agents/utils/{parser.py => EvalOutputParser.py} (100%) delete mode 100644 swarms/agents/utils/manager.py diff --git a/api/container.py b/api/container.py index 1ffeea25..251c697a 100644 --- a/api/container.py +++ b/api/container.py @@ -5,7 +5,7 @@ from typing import Dict, List from fastapi.templating import Jinja2Templates -from swarms.agents.utils.manager import AgentManager +from swarms.agents.utils.AgentManager import AgentManager from swarms.utils.main import BaseHandler, FileHandler, FileType from swarms.tools.main import CsvToDataframe, ExitConversation, RequestsGet, CodeEditor, Terminal diff --git a/swarms/__init__.py b/swarms/__init__.py index 1a936d07..44a0bdb4 100644 --- a/swarms/__init__.py +++ b/swarms/__init__.py @@ -1,3 +1,3 @@ # from swarms import Swarms, swarm from swarms.swarms import Swarms, swarm -from swarms.agents import worker_node, UltraNode \ No newline at end of file +from swarms.agents import worker_node, WorkerUltraNode \ No newline at end of file diff --git a/swarms/agents/utils/builder.py b/swarms/agents/utils/AgentBuilder.py similarity index 95% rename from swarms/agents/utils/builder.py rename to swarms/agents/utils/AgentBuilder.py index 5a34275e..2b11930b 100644 --- a/swarms/agents/utils/builder.py +++ b/swarms/agents/utils/AgentBuilder.py @@ -11,7 +11,7 @@ from langchain.callbacks.base import BaseCallbackManager from .chat_agent import ConversationalChatAgent from .llm import ChatOpenAI -from .parser import EvalOutputParser +from .EvalOutputParser import EvalOutputParser class AgentBuilder: @@ -21,9 +21,9 @@ class AgentBuilder: self.global_tools: list = None self.toolsets = toolsets - def build_llm(self, callback_manager: BaseCallbackManager = None): + def build_llm(self, callback_manager: BaseCallbackManager = None, openai_api_key: str = None): self.llm = ChatOpenAI( - temperature=0, callback_manager=callback_manager, verbose=True + temperature=0, callback_manager=callback_manager, verbose=True, openai_api_key=openai_api_key ) self.llm.check_access() diff --git a/swarms/agents/utils/AgentManager.py b/swarms/agents/utils/AgentManager.py new file mode 100644 index 00000000..4582590a --- /dev/null +++ b/swarms/agents/utils/AgentManager.py @@ -0,0 +1,86 @@ +from typing import Dict, Optional +import logging + +from celery import Task + +from langchain.agents.agent import AgentExecutor +from langchain.callbacks.manager import CallbackManager +from langchain.chains.conversation.memory import ConversationBufferMemory +from langchain.memory.chat_memory import BaseChatMemory + +from swarms.tools.main import BaseToolSet, ToolsFactory +from .AgentBuilder import AgentBuilder +from .callback import EVALCallbackHandler, ExecutionTracingCallbackHandler + + +CallbackManager.set_handler(handler=EVALCallbackHandler()) + +class AgentManager: + def __init__(self, toolsets: list[BaseToolSet] = []): + if not isinstance(toolsets, list): + raise TypeError("Toolsets must be a list") + self.toolsets: list[BaseToolSet] = toolsets + self.memories: Dict[str, BaseChatMemory] = {} + self.executors: Dict[str, AgentExecutor] = {} + + def create_memory(self) -> BaseChatMemory: + return ConversationBufferMemory(memory_key="chat_history", return_messages=True) + + def get_or_create_memory(self, session: str) -> BaseChatMemory: + if not isinstance(session, str): + raise TypeError("Session must be a string") + if not session: + raise ValueError("Session is empty") + if not (session in self.memories): + self.memories[session] = self.create_memory() + return self.memories[session] + + def create_executor(self, session: str, execution: Optional[Task] = None) -> AgentExecutor: + try: + builder = AgentBuilder(self.toolsets) + builder.build_parser() + + callbacks = [] + eval_callback = EVALCallbackHandler() + eval_callback.set_parser(builder.get_parser()) + callbacks.append(eval_callback) + if execution: + execution_callback = ExecutionTracingCallbackHandler(execution) + execution_callback.set_parser(builder.get_parser()) + callbacks.append(execution_callback) + + callback_manager = CallbackManager(callbacks) + + builder.build_llm(callback_manager) + builder.build_global_tools() + + memory: BaseChatMemory = self.get_or_create_memory(session) + tools = [ + *builder.get_global_tools(), + *ToolsFactory.create_per_session_tools( + self.toolsets, + get_session=lambda: (session, self.executors[session]), + ), + ] + + for tool in tools: + tool.callback_manager = callback_manager + + executor = AgentExecutor.from_agent_and_tools( + agent=builder.get_agent(), + tools=tools, + memory=memory, + callback_manager=callback_manager, + verbose=True, + ) + self.executors[session] = executor + return executor + except Exception as e: + logging.error(f"Error while creating executor: {str(e)}") + raise e + + @staticmethod + def create(toolsets: list[BaseToolSet]) -> "AgentManager": + if not isinstance(toolsets, list): + raise TypeError("Toolsets must be a list") + return AgentManager(toolsets=toolsets) \ No newline at end of file diff --git a/swarms/agents/utils/parser.py b/swarms/agents/utils/EvalOutputParser.py similarity index 100% rename from swarms/agents/utils/parser.py rename to swarms/agents/utils/EvalOutputParser.py diff --git a/swarms/agents/utils/manager.py b/swarms/agents/utils/manager.py deleted file mode 100644 index 72f2f978..00000000 --- a/swarms/agents/utils/manager.py +++ /dev/null @@ -1,82 +0,0 @@ -from typing import Dict, Optional -# from celery import Task - -from langchain.agents.agent import AgentExecutor -from langchain.callbacks.manager import CallbackManager -# from langchain.callbacks.base import set_handler -from langchain.chains.conversation.memory import ConversationBufferMemory -from langchain.memory.chat_memory import BaseChatMemory - -from swarms.tools.main import BaseToolSet, ToolsFactory - -from .builder import AgentBuilder -from .callback import EVALCallbackHandler, ExecutionTracingCallbackHandler - - -CallbackManager.set_handler(handler=EVALCallbackHandler()) - - -class AgentManager: - def __init__( - self, - toolsets: list[BaseToolSet] = [], - ): - self.toolsets: list[BaseToolSet] = toolsets - self.memories: Dict[str, BaseChatMemory] = {} - self.executors: Dict[str, AgentExecutor] = {} - - def create_memory(self) -> BaseChatMemory: - return ConversationBufferMemory(memory_key="chat_history", return_messages=True) - - def get_or_create_memory(self, session: str) -> BaseChatMemory: - if not (session in self.memories): - self.memories[session] = self.create_memory() - return self.memories[session] - - def create_executor( - self, session: str, execution: Optional[Task] = None - ) -> AgentExecutor: - builder = AgentBuilder(self.toolsets) - builder.build_parser() - - callbacks = [] - eval_callback = EVALCallbackHandler() - eval_callback.set_parser(builder.get_parser()) - callbacks.append(eval_callback) - if execution: - execution_callback = ExecutionTracingCallbackHandler(execution) - execution_callback.set_parser(builder.get_parser()) - callbacks.append(execution_callback) - - callback_manager = CallbackManager(callbacks) - - builder.build_llm(callback_manager) - builder.build_global_tools() - - memory: BaseChatMemory = self.get_or_create_memory(session) - tools = [ - *builder.get_global_tools(), - *ToolsFactory.create_per_session_tools( - self.toolsets, - get_session=lambda: (session, self.executors[session]), - ), - ] - - for tool in tools: - tool.callback_manager = callback_manager - - executor = AgentExecutor.from_agent_and_tools( - agent=builder.get_agent(), - tools=tools, - memory=memory, - callback_manager=callback_manager, - verbose=True, - ) - self.executors[session] = executor - return executor - - @staticmethod - def create(toolsets: list[BaseToolSet]) -> "AgentManager": - return AgentManager( - toolsets=toolsets, - ) \ No newline at end of file diff --git a/swarms/agents/workers/worker_ultranode.py b/swarms/agents/workers/worker_ultranode.py index 04108a84..6d043c28 100644 --- a/swarms/agents/workers/worker_ultranode.py +++ b/swarms/agents/workers/worker_ultranode.py @@ -1,18 +1,27 @@ import os +import re +import logging from pathlib import Path from typing import Dict, List -from swarms.agents.utils.manager import AgentManager +from swarms.agents.utils.AgentManager import AgentManager from swarms.utils.main import BaseHandler, FileHandler, FileType from swarms.tools.main import CsvToDataframe, ExitConversation, RequestsGet, CodeEditor, Terminal from swarms.tools.main import BaseToolSet from swarms.utils.main import StaticUploader +logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') + BASE_DIR = Path(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) os.chdir(BASE_DIR / os.environ["PLAYGROUND_DIR"]) -class UltraNode: +class WorkerUltraNode: def __init__(self, objective: str): + if not isinstance(objective, str): + raise TypeError("Objective must be a string") + if not objective: + raise ValueError("Objective cannot be empty") + toolsets: List[BaseToolSet] = [ Terminal(), CodeEditor(), @@ -21,7 +30,7 @@ class UltraNode: ] handlers: Dict[FileType, BaseHandler] = {FileType.DATAFRAME: CsvToDataframe()} - if os.environ["USE_GPU"]: + if os.environ.get("USE_GPU", False): import torch from swarms.tools.main import ImageCaptioning from swarms.tools.main import ImageEditing, InstructPix2Pix, Text2Image, VisualQuestionAnswering @@ -37,14 +46,21 @@ class UltraNode: ) handlers[FileType.IMAGE] = ImageCaptioning("cuda") - self.agent_manager = AgentManager.create(toolsets=toolsets) - self.file_handler = FileHandler(handlers=handlers, path=BASE_DIR) - self.uploader = StaticUploader.from_settings( - path=BASE_DIR / "static", endpoint="static" - ) + try: + + self.agent_manager = AgentManager.create(toolsets=toolsets) + self.file_handler = FileHandler(handlers=handlers, path=BASE_DIR) + self.uploader = StaticUploader.from_settings( + path=BASE_DIR / "static", endpoint="static" + ) - self.session = self.agent_manager.create_executor(objective) + + self.session = self.agent_manager.create_executor(objective) + + except Exception as e: + logging.error(f"Error while initializing WorkerUltraNode: {str(e)}") + raise e def execute_task(self): # Now the prompt is not needed as an argument @@ -53,6 +69,7 @@ class UltraNode: try: res = self.session({"input": promptedQuery}) except Exception as e: + logging.error(f"Error while executing task: {str(e)}") return {"answer": str(e), "files": []} files = re.findall(r"\[file://\S*\]", res["output"]) @@ -63,10 +80,16 @@ class UltraNode: "files": [self.uploader.upload(file) for file in files], } + def execute(self): - # The prompt is not needed here either - return self.execute_task() + try: + + # The prompt is not needed here either + return self.execute_task() + except Exception as e: + logging.error(f"Error while executing: {str(e)}") + raise e # from worker_node import UltraNode From 9173403a15de31c948ac372209dcc6a60dc350a2 Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 18:33:27 -0400 Subject: [PATCH 31/98] extensive error habdlong Former-commit-id: 7607118e6b694fe9b055ff7b021cb2e5d8cc125a --- swarms/agents/utils/AgentBuilder.py | 4 +-- swarms/agents/utils/AgentManager.py | 2 +- .../agents/utils/{callback.py => Calback.py} | 0 swarms/agents/utils/{llm.py => ChatOpenAI.py} | 0 ...at_agent.py => ConversationalChatAgent.py} | 32 +++++++++++++++---- 5 files changed, 28 insertions(+), 10 deletions(-) rename swarms/agents/utils/{callback.py => Calback.py} (100%) rename swarms/agents/utils/{llm.py => ChatOpenAI.py} (100%) rename swarms/agents/utils/{chat_agent.py => ConversationalChatAgent.py} (78%) diff --git a/swarms/agents/utils/AgentBuilder.py b/swarms/agents/utils/AgentBuilder.py index 2b11930b..e26ffdf9 100644 --- a/swarms/agents/utils/AgentBuilder.py +++ b/swarms/agents/utils/AgentBuilder.py @@ -9,8 +9,8 @@ from langchain.chat_models.base import BaseChatModel from langchain.schema import BaseOutputParser from langchain.callbacks.base import BaseCallbackManager -from .chat_agent import ConversationalChatAgent -from .llm import ChatOpenAI +from .ConversationalChatAgent import ConversationalChatAgent +from .ChatOpenAI import ChatOpenAI from .EvalOutputParser import EvalOutputParser diff --git a/swarms/agents/utils/AgentManager.py b/swarms/agents/utils/AgentManager.py index 4582590a..2e7b201c 100644 --- a/swarms/agents/utils/AgentManager.py +++ b/swarms/agents/utils/AgentManager.py @@ -10,7 +10,7 @@ from langchain.memory.chat_memory import BaseChatMemory from swarms.tools.main import BaseToolSet, ToolsFactory from .AgentBuilder import AgentBuilder -from .callback import EVALCallbackHandler, ExecutionTracingCallbackHandler +from .Calback import EVALCallbackHandler, ExecutionTracingCallbackHandler CallbackManager.set_handler(handler=EVALCallbackHandler()) diff --git a/swarms/agents/utils/callback.py b/swarms/agents/utils/Calback.py similarity index 100% rename from swarms/agents/utils/callback.py rename to swarms/agents/utils/Calback.py diff --git a/swarms/agents/utils/llm.py b/swarms/agents/utils/ChatOpenAI.py similarity index 100% rename from swarms/agents/utils/llm.py rename to swarms/agents/utils/ChatOpenAI.py diff --git a/swarms/agents/utils/chat_agent.py b/swarms/agents/utils/ConversationalChatAgent.py similarity index 78% rename from swarms/agents/utils/chat_agent.py rename to swarms/agents/utils/ConversationalChatAgent.py index 811cb54d..b95c49ea 100644 --- a/swarms/agents/utils/chat_agent.py +++ b/swarms/agents/utils/ConversationalChatAgent.py @@ -1,4 +1,5 @@ from typing import Any, List, Optional, Sequence, Tuple +import logging from langchain.agents.agent import Agent from langchain.callbacks.base import BaseCallbackManager @@ -22,6 +23,7 @@ from langchain.tools.base import BaseTool from swarms.prompts.prompts import EVAL_TOOL_RESPONSE +logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') class ConversationalChatAgent(Agent): """An agent designed to hold a conversation in addition to using tools.""" @@ -51,6 +53,17 @@ class ConversationalChatAgent(Agent): output_parser: BaseOutputParser, input_variables: Optional[List[str]] = None, ) -> BasePromptTemplate: + if not isinstance(tools, Sequence): + raise TypeError("Tools must be a sequence") + if not isinstance(system_message, str): + raise TypeError("System message must be a string") + if not isinstance(human_message, str): + raise TypeError("Human message must be a string") + if not isinstance(output_parser, BaseOutputParser): + raise TypeError("Output parser must be an instance of BaseOutputParser") + if input_variables and not isinstance(input_variables, list): + raise TypeError("Input variables must be a list") + tool_strings = "\n".join( [f"> {tool.name}: {tool.description}" for tool in tools] ) @@ -75,7 +88,8 @@ class ConversationalChatAgent(Agent): try: response = self.output_parser.parse(llm_output) return response["action"], response["action_input"] - except Exception: + except Exception as e: + logging.error(f"Error while extracting tool and input: {str(e)}") raise ValueError(f"Could not parse LLM output: {llm_output}") def _construct_scratchpad( @@ -118,9 +132,13 @@ class ConversationalChatAgent(Agent): callback_manager=callback_manager, ) tool_names = [tool.name for tool in tools] - return cls( - llm_chain=llm_chain, - allowed_tools=tool_names, - output_parser=output_parser, - **kwargs, - ) \ No newline at end of file + try: + return cls( + llm_chain=llm_chain, + allowed_tools=tool_names, + output_parser=output_parser, + **kwargs, + ) + except Exception as e: + logging.error(f"Error while creating agent from LLM and tools: {str(e)}") + raise e \ No newline at end of file From 3f639104db24bad145d9f4e5e0b3f0b045090d5a Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 18:35:52 -0400 Subject: [PATCH 32/98] clean up Former-commit-id: f978fa2c62ff2450af6df845bc4a5e05b48b9ac3 --- swarms/agents/__init__.py | 2 +- ...worker.py => MultiModalVisualAgentTool.py} | 0 .../{worker_agent.py => WorkerNode.py} | 0 ...worker_ultranode.py => WorkerUltraNode.py} | 0 swarms/agents/workers/__init__.py | 4 +- swarms/agents/workers/agents.py | 1056 ----------------- swarms/agents/workers/auto_worker.py | 95 -- swarms/swarms.py | 4 +- tests/swarms.py | 2 +- 9 files changed, 6 insertions(+), 1157 deletions(-) rename swarms/agents/workers/{visual_worker.py => MultiModalVisualAgentTool.py} (100%) rename swarms/agents/workers/{worker_agent.py => WorkerNode.py} (100%) rename swarms/agents/workers/{worker_ultranode.py => WorkerUltraNode.py} (100%) delete mode 100644 swarms/agents/workers/agents.py delete mode 100644 swarms/agents/workers/auto_worker.py diff --git a/swarms/agents/__init__.py b/swarms/agents/__init__.py index a328d7e3..97b0096c 100644 --- a/swarms/agents/__init__.py +++ b/swarms/agents/__init__.py @@ -1,3 +1,3 @@ """Agents, workers and bosses""" from ..agents.workers import worker_node -from ..agents.workers.worker_ultranode import UltraNode \ No newline at end of file +from .workers.WorkerUltraNode import UltraNode \ No newline at end of file diff --git a/swarms/agents/workers/visual_worker.py b/swarms/agents/workers/MultiModalVisualAgentTool.py similarity index 100% rename from swarms/agents/workers/visual_worker.py rename to swarms/agents/workers/MultiModalVisualAgentTool.py diff --git a/swarms/agents/workers/worker_agent.py b/swarms/agents/workers/WorkerNode.py similarity index 100% rename from swarms/agents/workers/worker_agent.py rename to swarms/agents/workers/WorkerNode.py diff --git a/swarms/agents/workers/worker_ultranode.py b/swarms/agents/workers/WorkerUltraNode.py similarity index 100% rename from swarms/agents/workers/worker_ultranode.py rename to swarms/agents/workers/WorkerUltraNode.py diff --git a/swarms/agents/workers/__init__.py b/swarms/agents/workers/__init__.py index eab37564..83752f53 100644 --- a/swarms/agents/workers/__init__.py +++ b/swarms/agents/workers/__init__.py @@ -1,3 +1,3 @@ -from .worker_agent import worker_node +from .WorkerNode import worker_node -from .worker_ultranode import UltraNode +from .WorkerUltraNode import UltraNode diff --git a/swarms/agents/workers/agents.py b/swarms/agents/workers/agents.py deleted file mode 100644 index 2e70d4e5..00000000 --- a/swarms/agents/workers/agents.py +++ /dev/null @@ -1,1056 +0,0 @@ -from __future__ import annotations -from enum import Enum -from typing import Callable, Tuple - -from langchain.agents.agent import AgentExecutor -from langchain.agents.tools import BaseTool, Tool - - -class ToolScope(Enum): - GLOBAL = "global" - SESSION = "session" - -SessionGetter = Callable[[], Tuple[str, AgentExecutor]] - - -def tool( - name: str, - description: str, - scope: ToolScope = ToolScope.GLOBAL, -): - def decorator(func): - func.name = name - func.description = description - func.is_tool = True - func.scope = scope - return func - - return decorator - - -class ToolWrapper: - def __init__(self, name: str, description: str, scope: ToolScope, func): - self.name = name - self.description = description - self.scope = scope - self.func = func - - def is_global(self) -> bool: - return self.scope == ToolScope.GLOBAL - - def is_per_session(self) -> bool: - return self.scope == ToolScope.SESSION - - def to_tool( - self, - get_session: SessionGetter = lambda: [], - ) -> BaseTool: - func = self.func - if self.is_per_session(): - func = lambda *args, **kwargs: self.func( - *args, **kwargs, get_session=get_session - ) - - return Tool( - name=self.name, - description=self.description, - func=func, - ) - - -class BaseToolSet: - def tool_wrappers(cls) -> list[ToolWrapper]: - methods = [ - getattr(cls, m) for m in dir(cls) if hasattr(getattr(cls, m), "is_tool") - ] - return [ToolWrapper(m.name, m.description, m.scope, m) for m in methods] - - -#=====================================> -from typing import Optional - -from langchain.agents import load_tools -from langchain.agents.tools import BaseTool -from langchain.llms.base import BaseLLM - - -class ToolsFactory: - @staticmethod - def from_toolset( - toolset: BaseToolSet, - only_global: Optional[bool] = False, - only_per_session: Optional[bool] = False, - get_session: SessionGetter = lambda: [], - ) -> list[BaseTool]: - tools = [] - for wrapper in toolset.tool_wrappers(): - if only_global and not wrapper.is_global(): - continue - if only_per_session and not wrapper.is_per_session(): - continue - tools.append(wrapper.to_tool(get_session=get_session)) - return tools - - @staticmethod - def create_global_tools( - toolsets: list[BaseToolSet], - ) -> list[BaseTool]: - tools = [] - for toolset in toolsets: - tools.extend( - ToolsFactory.from_toolset( - toolset=toolset, - only_global=True, - ) - ) - return tools - - @staticmethod - def create_per_session_tools( - toolsets: list[BaseToolSet], - get_session: SessionGetter = lambda: [], - ) -> list[BaseTool]: - tools = [] - for toolset in toolsets: - tools.extend( - ToolsFactory.from_toolset( - toolset=toolset, - only_per_session=True, - get_session=get_session, - ) - ) - return tools - - @staticmethod - def create_global_tools_from_names( - toolnames: list[str], - llm: Optional[BaseLLM], - ) -> list[BaseTool]: - return load_tools(toolnames, llm=llm) - -#=====================================> -#=====================================> - - - - - -################ -# from core.prompts.input import EVAL_PREFIX, EVAL_SUFFIX -from ...prompts.prompts import EVAL_PREFIX, EVAL_SUFFIX -############ - - -from env import settings -from langchain.chat_models.base import BaseChatModel -from langchain.schema import BaseOutputParser -from langchain.callbacks.base import BaseCallbackManager - - -class AgentBuilder: - def __init__(self, toolsets: list[BaseToolSet] = []): - self.llm: BaseChatModel = None - self.parser: BaseOutputParser = None - self.global_tools: list = None - self.toolsets = toolsets - - def build_llm(self, callback_manager: BaseCallbackManager = None): - self.llm = ChatOpenAI( - temperature=0, callback_manager=callback_manager, verbose=True - ) - self.llm.check_access() - - def build_parser(self): - self.parser = EvalOutputParser() - - def build_global_tools(self): - if self.llm is None: - raise ValueError("LLM must be initialized before tools") - - toolnames = ["wikipedia"] - - if settings["SERPAPI_API_KEY"]: - toolnames.append("serpapi") - if settings["BING_SEARCH_URL"] and settings["BING_SUBSCRIPTION_KEY"]: - toolnames.append("bing-search") - - self.global_tools = [ - *ToolsFactory.create_global_tools_from_names(toolnames, llm=self.llm), - *ToolsFactory.create_global_tools(self.toolsets), - ] - - def get_parser(self): - if self.parser is None: - raise ValueError("Parser is not initialized yet") - - return self.parser - - def get_global_tools(self): - if self.global_tools is None: - raise ValueError("Global tools are not initialized yet") - - return self.global_tools - - def get_agent(self): - if self.llm is None: - raise ValueError("LLM must be initialized before agent") - - if self.parser is None: - raise ValueError("Parser must be initialized before agent") - - if self.global_tools is None: - raise ValueError("Global tools must be initialized before agent") - - return ConversationalChatAgent.from_llm_and_tools( - llm=self.llm, - tools=[ - *self.global_tools, - *ToolsFactory.create_per_session_tools( - self.toolsets - ), # for names and descriptions - ], - system_message=EVAL_PREFIX.format(bot_name=settings["BOT_NAME"]), - human_message=EVAL_SUFFIX.format(bot_name=settings["BOT_NAME"]), - output_parser=self.parser, - max_iterations=30, - ) -#===================================> callback - -#===================================> callback - -from typing import Any, Dict, List, Optional, Union - -from langchain.callbacks.base import BaseCallbackHandler -from langchain.schema import AgentAction, AgentFinish, LLMResult -# from celery import Task - -from swarms.utils.main import ANSI, Color, Style, dim_multiline, logger - - -class EVALCallbackHandler(BaseCallbackHandler): - @property - def ignore_llm(self) -> bool: - return False - - def set_parser(self, parser) -> None: - self.parser = parser - - def on_llm_start( - self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any - ) -> None: - pass - - def on_llm_end(self, response: LLMResult, **kwargs: Any) -> None: - text = response.generations[0][0].text - - parsed = self.parser.parse_all(text) - - logger.info(ANSI("Plan").to(Color.blue().bright()) + ": " + parsed["plan"]) - logger.info(ANSI("What I Did").to(Color.blue()) + ": " + parsed["what_i_did"]) - logger.info( - ANSI("Action").to(Color.cyan()) - + ": " - + ANSI(parsed["action"]).to(Style.bold()) - ) - logger.info( - ANSI("Input").to(Color.cyan()) - + ": " - + dim_multiline(parsed["action_input"]) - ) - - def on_llm_new_token(self, token: str, **kwargs: Any) -> None: - logger.info(ANSI(f"on_llm_new_token {token}").to(Color.green(), Style.italic())) - - def on_llm_error( - self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any - ) -> None: - pass - - def on_chain_start( - self, serialized: Dict[str, Any], inputs: Dict[str, Any], **kwargs: Any - ) -> None: - logger.info(ANSI(f"Entering new chain.").to(Color.green(), Style.italic())) - logger.info(ANSI("Prompted Text").to(Color.yellow()) + f': {inputs["input"]}\n') - - def on_chain_end(self, outputs: Dict[str, Any], **kwargs: Any) -> None: - logger.info(ANSI(f"Finished chain.").to(Color.green(), Style.italic())) - - def on_chain_error( - self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any - ) -> None: - logger.error( - ANSI(f"Chain Error").to(Color.red()) + ": " + dim_multiline(str(error)) - ) - - def on_tool_start( - self, - serialized: Dict[str, Any], - input_str: str, - **kwargs: Any, - ) -> None: - pass - - def on_agent_action(self, action: AgentAction, **kwargs: Any) -> Any: - pass - - def on_tool_end( - self, - output: str, - observation_prefix: Optional[str] = None, - llm_prefix: Optional[str] = None, - **kwargs: Any, - ) -> None: - logger.info( - ANSI("Observation").to(Color.magenta()) + ": " + dim_multiline(output) - ) - logger.info(ANSI("Thinking...").to(Color.green(), Style.italic())) - - def on_tool_error( - self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any - ) -> None: - logger.error(ANSI("Tool Error").to(Color.red()) + f": {error}") - - def on_text( - self, - text: str, - color: Optional[str] = None, - end: str = "", - **kwargs: Optional[str], - ) -> None: - pass - - def on_agent_finish( - self, finish: AgentFinish, color: Optional[str] = None, **kwargs: Any - ) -> None: - logger.info( - ANSI("Final Answer").to(Color.yellow()) - + ": " - + dim_multiline(finish.return_values.get("output", "")) - ) - - -class ExecutionTracingCallbackHandler(BaseCallbackHandler): - def __init__(self, execution: Task): - self.execution = execution - self.index = 0 - - def set_parser(self, parser) -> None: - self.parser = parser - - def on_llm_start( - self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any - ) -> None: - pass - - def on_llm_end(self, response: LLMResult, **kwargs: Any) -> None: - text = response.generations[0][0].text - parsed = self.parser.parse_all(text) - self.index += 1 - parsed["index"] = self.index - self.execution.update_state(state="LLM_END", meta=parsed) - - def on_llm_new_token(self, token: str, **kwargs: Any) -> None: - pass - - def on_llm_error( - self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any - ) -> None: - pass - - def on_chain_start( - self, serialized: Dict[str, Any], inputs: Dict[str, Any], **kwargs: Any - ) -> None: - pass - - def on_chain_end(self, outputs: Dict[str, Any], **kwargs: Any) -> None: - pass - - def on_chain_error( - self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any - ) -> None: - self.execution.update_state(state="CHAIN_ERROR", meta={"error": str(error)}) - - def on_tool_start( - self, - serialized: Dict[str, Any], - input_str: str, - **kwargs: Any, - ) -> None: - pass - - def on_agent_action(self, action: AgentAction, **kwargs: Any) -> Any: - pass - - def on_tool_end( - self, - output: str, - observation_prefix: Optional[str] = None, - llm_prefix: Optional[str] = None, - **kwargs: Any, - ) -> None: - previous = self.execution.AsyncResult(self.execution.request.id) - self.execution.update_state( - state="TOOL_END", meta={**previous.info, "observation": output} - ) - - def on_tool_error( - self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any - ) -> None: - previous = self.execution.AsyncResult(self.execution.request.id) - self.execution.update_state( - state="TOOL_ERROR", meta={**previous.info, "error": str(error)} - ) - - def on_text( - self, - text: str, - color: Optional[str] = None, - end: str = "", - **kwargs: Optional[str], - ) -> None: - pass - - def on_agent_finish( - self, finish: AgentFinish, color: Optional[str] = None, **kwargs: Any - ) -> None: - pass - -#===================================> callback -#===================================> callback - - -#===================================> callback - -from typing import Any, List, Optional, Sequence, Tuple - -from langchain.agents.agent import Agent -from langchain.callbacks.base import BaseCallbackManager -from langchain.chains import LLMChain -from langchain.schema import BaseOutputParser -from langchain.prompts.base import BasePromptTemplate -from langchain.prompts.chat import ( - ChatPromptTemplate, - HumanMessagePromptTemplate, - MessagesPlaceholder, - SystemMessagePromptTemplate, -) -from langchain.schema import ( - AgentAction, - AIMessage, - BaseLanguageModel, - BaseMessage, - HumanMessage, -) -from langchain.tools.base import BaseTool - -# from core.prompts.input import EVAL_TOOL_RESPONSE -from prompts.prompts import EVAL_TOOL_RESPONSE - -from prompts.prompts import EVAL_FORMAT_INSTRUCTIONS - - -class ConversationalChatAgent(Agent): - """An agent designed to hold a conversation in addition to using tools.""" - - output_parser: BaseOutputParser - - @property - def _agent_type(self) -> str: - raise NotImplementedError - - @property - def observation_prefix(self) -> str: - """Prefix to append the observation with.""" - return "Observation: " - - @property - def llm_prefix(self) -> str: - """Prefix to append the llm call with.""" - return "Thought: " - - @classmethod - def create_prompt( - cls, - tools: Sequence[BaseTool], - system_message: str, - human_message: str, - output_parser: BaseOutputParser, - input_variables: Optional[List[str]] = None, - ) -> BasePromptTemplate: - tool_strings = "\n".join( - [f"> {tool.name}: {tool.description}" for tool in tools] - ) - tool_names = ", ".join([tool.name for tool in tools]) - format_instructions = human_message.format( - format_instructions=output_parser.get_format_instructions() - ) - final_prompt = format_instructions.format( - tool_names=tool_names, tools=tool_strings - ) - if input_variables is None: - input_variables = ["input", "chat_history", "agent_scratchpad"] - messages = [ - SystemMessagePromptTemplate.from_template(system_message), - MessagesPlaceholder(variable_name="chat_history"), - HumanMessagePromptTemplate.from_template(final_prompt), - MessagesPlaceholder(variable_name="agent_scratchpad"), - ] - return ChatPromptTemplate(input_variables=input_variables, messages=messages) - - def _extract_tool_and_input(self, llm_output: str) -> Optional[Tuple[str, str]]: - try: - response = self.output_parser.parse(llm_output) - return response["action"], response["action_input"] - except Exception: - raise ValueError(f"Could not parse LLM output: {llm_output}") - - def _construct_scratchpad( - self, intermediate_steps: List[Tuple[AgentAction, str]] - ) -> List[BaseMessage]: - """Construct the scratchpad that lets the agent continue its thought process.""" - thoughts: List[BaseMessage] = [] - for action, observation in intermediate_steps: - thoughts.append(AIMessage(content=action.log)) - human_message = HumanMessage( - content=EVAL_TOOL_RESPONSE.format(observation=observation) - ) - thoughts.append(human_message) - return thoughts - - @classmethod - def from_llm_and_tools( - cls, - llm: BaseLanguageModel, - tools: Sequence[BaseTool], - system_message: str, - human_message: str, - output_parser: BaseOutputParser, - callback_manager: Optional[BaseCallbackManager] = None, - input_variables: Optional[List[str]] = None, - **kwargs: Any, - ) -> Agent: - """Construct an agent from an LLM and tools.""" - cls._validate_tools(tools) - prompt = cls.create_prompt( - tools, - system_message=system_message, - human_message=human_message, - input_variables=input_variables, - output_parser=output_parser, - ) - llm_chain = LLMChain( - llm=llm, - prompt=prompt, - callback_manager=callback_manager, - ) - tool_names = [tool.name for tool in tools] - return cls( - llm_chain=llm_chain, - allowed_tools=tool_names, - output_parser=output_parser, - **kwargs, - ) -#===================================> CHAT AGENT - - - -#####===============================> - -"""OpenAI chat wrapper.""" - -import logging -import sys -from typing import Any, Callable, Dict, List, Mapping, Optional, Tuple - -import openai - -from langchain.chat_models.base import BaseChatModel -from langchain.schema import ( - AIMessage, - BaseMessage, - ChatGeneration, - ChatMessage, - ChatResult, - HumanMessage, - SystemMessage, -) -from langchain.utils import get_from_dict_or_env -from logger import logger -from pydantic import BaseModel, Extra, Field, root_validator -from tenacity import ( - before_sleep_log, - retry, - retry_if_exception_type, - stop_after_attempt, - wait_exponential, -) - -from env import settings - - - -def _create_retry_decorator(llm: ChatOpenAI) -> Callable[[Any], Any]: - import openai - - min_seconds = 4 - max_seconds = 10 - # Wait 2^x * 1 second between each retry starting with - # 4 seconds, then up to 10 seconds, then 10 seconds afterwards - return retry( - reraise=True, - stop=stop_after_attempt(llm.max_retries), - wait=wait_exponential(multiplier=1, min=min_seconds, max=max_seconds), - retry=( - retry_if_exception_type(openai.error.Timeout) - | retry_if_exception_type(openai.error.APIError) - | retry_if_exception_type(openai.error.APIConnectionError) - | retry_if_exception_type(openai.error.RateLimitError) - | retry_if_exception_type(openai.error.ServiceUnavailableError) - ), - before_sleep=before_sleep_log(logger, logging.WARNING), - ) - - -async def acompletion_with_retry(llm: ChatOpenAI, **kwargs: Any) -> Any: - """Use tenacity to retry the async completion call.""" - retry_decorator = _create_retry_decorator(llm) - - @retry_decorator - async def _completion_with_retry(**kwargs: Any) -> Any: - # Use OpenAI's async api https://github.com/openai/openai-python#async-api - return await llm.client.acreate(**kwargs) - - return await _completion_with_retry(**kwargs) - - -def _convert_dict_to_message(_dict: dict) -> BaseMessage: - role = _dict["role"] - if role == "user": - return HumanMessage(content=_dict["content"]) - elif role == "assistant": - return AIMessage(content=_dict["content"]) - elif role == "system": - return SystemMessage(content=_dict["content"]) - else: - return ChatMessage(content=_dict["content"], role=role) - - -def _convert_message_to_dict(message: BaseMessage) -> dict: - if isinstance(message, ChatMessage): - message_dict = {"role": message.role, "content": message.content} - elif isinstance(message, HumanMessage): - message_dict = {"role": "user", "content": message.content} - elif isinstance(message, AIMessage): - message_dict = {"role": "assistant", "content": message.content} - elif isinstance(message, SystemMessage): - message_dict = {"role": "system", "content": message.content} - else: - raise ValueError(f"Got unknown type {message}") - if "name" in message.additional_kwargs: - message_dict["name"] = message.additional_kwargs["name"] - return message_dict - - -def _create_chat_result(response: Mapping[str, Any]) -> ChatResult: - generations = [] - for res in response["choices"]: - message = _convert_dict_to_message(res["message"]) - gen = ChatGeneration(message=message) - generations.append(gen) - return ChatResult(generations=generations) - - -class ModelNotFoundException(Exception): - """Exception raised when the model is not found.""" - - def __init__(self, model_name: str): - self.model_name = model_name - super().__init__( - f"\n\nModel {ANSI(self.model_name).to(Color.red())} does not exist.\nMake sure if you have access to the model.\n" - + f"You can set the model name with the environment variable {ANSI('MODEL_NAME').to(Style.bold())} on {ANSI('.env').to(Style.bold())}.\n" - + "\nex) MODEL_NAME=gpt-4\n" - + ANSI( - "\nLooks like you don't have access to gpt-4 yet. Try using `gpt-3.5-turbo`." - if self.model_name == "gpt-4" - else "" - ).to(Style.italic()) - ) - - -class ChatOpenAI(BaseChatModel, BaseModel): - """Wrapper around OpenAI Chat large language models. - - To use, you should have the ``openai`` python package installed, and the - environment variable ``OPENAI_API_KEY`` set with your API key. - - Any parameters that are valid to be passed to the openai.create call can be passed - in, even if not explicitly saved on this class. - - Example: - .. code-block:: python - - from langchain.chat_models import ChatOpenAI - openai = ChatOpenAI(model_name="gpt-3.5-turbo") - """ - - client: Any #: :meta private: - model_name: str = settings["MODEL_NAME"] - """Model name to use.""" - model_kwargs: Dict[str, Any] = Field(default_factory=dict) - """Holds any model parameters valid for `create` call not explicitly specified.""" - openai_api_key: Optional[str] = None - max_retries: int = 6 - """Maximum number of retries to make when generating.""" - streaming: bool = False - """Whether to stream the results or not.""" - n: int = 1 - """Number of chat completions to generate for each prompt.""" - max_tokens: int = 2048 - """Maximum number of tokens to generate.""" - - class Config: - """Configuration for this pydantic object.""" - - extra = Extra.ignore - - def check_access(self) -> None: - """Check that the user has access to the model.""" - - try: - openai.Engine.retrieve(self.model_name) - except openai.error.InvalidRequestError: - raise ModelNotFoundException(self.model_name) - - @root_validator(pre=True) - def build_extra(cls, values: Dict[str, Any]) -> Dict[str, Any]: - """Build extra kwargs from additional params that were passed in.""" - all_required_field_names = {field.alias for field in cls.__fields__.values()} - - extra = values.get("model_kwargs", {}) - for field_name in list(values): - if field_name not in all_required_field_names: - if field_name in extra: - raise ValueError(f"Found {field_name} supplied twice.") - extra[field_name] = values.pop(field_name) - values["model_kwargs"] = extra - return values - - @root_validator() - def validate_environment(cls, values: Dict) -> Dict: - """Validate that api key and python package exists in environment.""" - openai_api_key = get_from_dict_or_env( - values, "openai_api_key", "OPENAI_API_KEY" - ) - try: - import openai - - openai.api_key = openai_api_key - except ImportError: - raise ValueError( - "Could not import openai python package. " - "Please it install it with `pip install openai`." - ) - try: - values["client"] = openai.ChatCompletion - except AttributeError: - raise ValueError( - "`openai` has no `ChatCompletion` attribute, this is likely " - "due to an old version of the openai package. Try upgrading it " - "with `pip install --upgrade openai`." - ) - if values["n"] < 1: - raise ValueError("n must be at least 1.") - if values["n"] > 1 and values["streaming"]: - raise ValueError("n must be 1 when streaming.") - return values - - @property - def _default_params(self) -> Dict[str, Any]: - """Get the default parameters for calling OpenAI API.""" - return { - "model": self.model_name, - "max_tokens": self.max_tokens, - "stream": self.streaming, - "n": self.n, - **self.model_kwargs, - } - - def _create_retry_decorator(self) -> Callable[[Any], Any]: - import openai - - min_seconds = 4 - max_seconds = 10 - # Wait 2^x * 1 second between each retry starting with - # 4 seconds, then up to 10 seconds, then 10 seconds afterwards - return retry( - reraise=True, - stop=stop_after_attempt(self.max_retries), - wait=wait_exponential(multiplier=1, min=min_seconds, max=max_seconds), - retry=( - retry_if_exception_type(openai.error.Timeout) - | retry_if_exception_type(openai.error.APIError) - | retry_if_exception_type(openai.error.APIConnectionError) - | retry_if_exception_type(openai.error.RateLimitError) - | retry_if_exception_type(openai.error.ServiceUnavailableError) - ), - before_sleep=before_sleep_log(logger, logging.WARNING), - ) - - def completion_with_retry(self, **kwargs: Any) -> Any: - """Use tenacity to retry the completion call.""" - retry_decorator = self._create_retry_decorator() - - @retry_decorator - def _completion_with_retry(**kwargs: Any) -> Any: - response = self.client.create(**kwargs) - logger.debug("Response:\n\t%s", response) - return response - - return _completion_with_retry(**kwargs) - - def _generate( - self, messages: List[BaseMessage], stop: Optional[List[str]] = None - ) -> ChatResult: - message_dicts, params = self._create_message_dicts(messages, stop) - logger.debug("Messages:\n") - for item in message_dicts: - for k, v in item.items(): - logger.debug(f"\t\t{k}: {v}") - logger.debug("\t-------") - logger.debug("===========") - - if self.streaming: - inner_completion = "" - role = "assistant" - params["stream"] = True - for stream_resp in self.completion_with_retry( - messages=message_dicts, **params - ): - role = stream_resp["choices"][0]["delta"].get("role", role) - token = stream_resp["choices"][0]["delta"].get("content", "") - inner_completion += token - self.callback_manager.on_llm_new_token( - token, - verbose=self.verbose, - ) - message = _convert_dict_to_message( - {"content": inner_completion, "role": role} - ) - return ChatResult(generations=[ChatGeneration(message=message)]) - response = self.completion_with_retry(messages=message_dicts, **params) - return _create_chat_result(response) - - def _create_message_dicts( - self, messages: List[BaseMessage], stop: Optional[List[str]] - ) -> Tuple[List[Dict[str, Any]], Dict[str, Any]]: - params: Dict[str, Any] = {**{"model": self.model_name}, **self._default_params} - if stop is not None: - if "stop" in params: - raise ValueError("`stop` found in both the input and default params.") - params["stop"] = stop - message_dicts = [_convert_message_to_dict(m) for m in messages] - return message_dicts, params - - async def _agenerate( - self, messages: List[BaseMessage], stop: Optional[List[str]] = None - ) -> ChatResult: - message_dicts, params = self._create_message_dicts(messages, stop) - if self.streaming: - inner_completion = "" - role = "assistant" - params["stream"] = True - async for stream_resp in await acompletion_with_retry( - self, messages=message_dicts, **params - ): - role = stream_resp["choices"][0]["delta"].get("role", role) - token = stream_resp["choices"][0]["delta"].get("content", "") - inner_completion += token - if self.callback_manager.is_async: - await self.callback_manager.on_llm_new_token( - token, - verbose=self.verbose, - ) - else: - self.callback_manager.on_llm_new_token( - token, - verbose=self.verbose, - ) - message = _convert_dict_to_message( - {"content": inner_completion, "role": role} - ) - return ChatResult(generations=[ChatGeneration(message=message)]) - else: - response = await acompletion_with_retry( - self, messages=message_dicts, **params - ) - return _create_chat_result(response) - - @property - def _identifying_params(self) -> Mapping[str, Any]: - """Get the identifying parameters.""" - return {**{"model_name": self.model_name}, **self._default_params} - - def get_num_tokens(self, text: str) -> int: - """Calculate num tokens with tiktoken package.""" - # tiktoken NOT supported for Python 3.8 or below - if sys.version_info[1] <= 8: - return super().get_num_tokens(text) - try: - import tiktoken - except ImportError: - raise ValueError( - "Could not import tiktoken python package. " - "This is needed in order to calculate get_num_tokens. " - "Please it install it with `pip install tiktoken`." - ) - # create a GPT-3.5-Turbo encoder instance - enc = tiktoken.encoding_for_model(self.model_name) - - # encode the text using the GPT-3.5-Turbo encoder - tokenized_text = enc.encode(text) - - # calculate the number of tokens in the encoded text - return len(tokenized_text) - - -###############LLM END => - - - -from typing import Dict, Optional - -from langchain.agents.agent import AgentExecutor -from langchain.callbacks.base import CallbackManager -from langchain.callbacks import set_handler -from langchain.chains.conversation.memory import ConversationBufferMemory -from langchain.memory.chat_memory import BaseChatMemory - -# from core.tools.base import BaseToolSet -# from core.tools.factory import ToolsFactory - -# from .builder import AgentBuilder -# from .callback import EVALCallbackHandler, ExecutionTracingCallbackHandler - - -set_handler(EVALCallbackHandler()) - - -class AgentManager: - def __init__( - self, - toolsets: list[BaseToolSet] = [], - ): - self.toolsets: list[BaseToolSet] = toolsets - self.memories: Dict[str, BaseChatMemory] = {} - self.executors: Dict[str, AgentExecutor] = {} - - def create_memory(self) -> BaseChatMemory: - return ConversationBufferMemory(memory_key="chat_history", return_messages=True) - - def get_or_create_memory(self, session: str) -> BaseChatMemory: - if not (session in self.memories): - self.memories[session] = self.create_memory() - return self.memories[session] - - def create_executor( - self, session: str, execution: Optional[Task] = None - ) -> AgentExecutor: - builder = AgentBuilder(self.toolsets) - builder.build_parser() - - callbacks = [] - eval_callback = EVALCallbackHandler() - eval_callback.set_parser(builder.get_parser()) - callbacks.append(eval_callback) - if execution: - execution_callback = ExecutionTracingCallbackHandler(execution) - execution_callback.set_parser(builder.get_parser()) - callbacks.append(execution_callback) - - callback_manager = CallbackManager(callbacks) - - builder.build_llm(callback_manager) - builder.build_global_tools() - - memory: BaseChatMemory = self.get_or_create_memory(session) - tools = [ - *builder.get_global_tools(), - *ToolsFactory.create_per_session_tools( - self.toolsets, - get_session=lambda: (session, self.executors[session]), - ), - ] - - for tool in tools: - tool.callback_manager = callback_manager - - executor = AgentExecutor.from_agent_and_tools( - agent=builder.get_agent(), - tools=tools, - memory=memory, - callback_manager=callback_manager, - verbose=True, - ) - self.executors[session] = executor - return executor - - @staticmethod - def create(toolsets: list[BaseToolSet]) -> "AgentManager": - return AgentManager( - toolsets=toolsets, - ) - - - - - - -#PARSER=============================+> PARSER -import re -from typing import Dict - -from langchain.schema import BaseOutputParser - -# from core.prompts.input import EVAL_FORMAT_INSTRUCTIONS - -# from prompts.prompts import EVAL_FORMAT_INSTRUCTIONS -from ...prompts.prompts import EVAL_FORMAT_INSTRUCTIONS - - -class EvalOutputParser(BaseOutputParser): - @staticmethod - def parse_all(text: str) -> Dict[str, str]: - regex = r"Action: (.*?)[\n]Plan:(.*)[\n]What I Did:(.*)[\n]Action Input: (.*)" - match = re.search(regex, text, re.DOTALL) - if not match: - raise Exception("parse error") - - action = match.group(1).strip() - plan = match.group(2) - what_i_did = match.group(3) - action_input = match.group(4).strip(" ") - - return { - "action": action, - "plan": plan, - "what_i_did": what_i_did, - "action_input": action_input, - } - - def get_format_instructions(self) -> str: - return EVAL_FORMAT_INSTRUCTIONS - - def parse(self, text: str) -> Dict[str, str]: - regex = r"Action: (.*?)[\n]Plan:(.*)[\n]What I Did:(.*)[\n]Action Input: (.*)" - match = re.search(regex, text, re.DOTALL) - if not match: - raise Exception("parse error") - - parsed = EvalOutputParser.parse_all(text) - - return {"action": parsed["action"], "action_input": parsed["action_input"]} - - def __str__(self): - return "EvalOutputParser" - -#PARSER=============================+> PARSER diff --git a/swarms/agents/workers/auto_worker.py b/swarms/agents/workers/auto_worker.py deleted file mode 100644 index 98104ea8..00000000 --- a/swarms/agents/workers/auto_worker.py +++ /dev/null @@ -1,95 +0,0 @@ -# General -import os -import pandas as pd -from langchain.experimental.autonomous_agents.autogpt.agent import AutoGPT - -from langchain.chat_models import ChatOpenAI -from langchain.agents.agent_toolkits.pandas.base import create_pandas_dataframe_agent -from langchain.docstore.document import Document - -import asyncio -import nest_asyncio - -# Tools - -from contextlib import contextmanager -from typing import Optional -from langchain.agents import tool - -from langchain.tools.file_management.read import ReadFileTool -from langchain.tools.file_management.write import WriteFileTool -from langchain.tools import BaseTool, DuckDuckGoSearchRun - -from langchain.text_splitter import RecursiveCharacterTextSplitter -from pydantic import Field -from langchain.chains.qa_with_sources.loading import load_qa_with_sources_chain, BaseCombineDocumentsChain - -# Memory -import faiss -from langchain.vectorstores import FAISS -from langchain.docstore import InMemoryDocstore -from langchain.embeddings import OpenAIEmbeddings - -from langchain.tools.human.tool import HumanInputRun -# from swarms.agents.workers.auto_agent import -from swarms.agents.workers.visual_worker import multimodal_agent_tool -from swarms.tools.main import Terminal, CodeWriter, CodeEditor, process_csv, WebpageQATool - - - -class WorkerAgent: - def __init__(self, objective: str, api_key: str): - self.objective = objective - self.api_key = api_key - self.worker = self.create_agent_worker() - - def create_agent_worker(self): - os.environ['OPENAI_API_KEY'] = self.api_key - - llm = ChatOpenAI(model_name="gpt-4", temperature=1.0) - embeddings_model = OpenAIEmbeddings() - embedding_size = 1536 - index = faiss.IndexFlatL2(embedding_size) - vectorstore = FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {}) - - query_website_tool = WebpageQATool(qa_chain=load_qa_with_sources_chain(llm)) - web_search = DuckDuckGoSearchRun() - - tools = [ - web_search, - WriteFileTool(root_dir="./data"), - ReadFileTool(root_dir="./data"), - - multimodal_agent_tool, - process_csv, - query_website_tool, - Terminal, - - - CodeWriter, - CodeEditor - ] - - agent_worker = AutoGPT.from_llm_and_tools( - ai_name="WorkerX", - ai_role="Assistant", - tools=tools, - llm=llm, - memory=vectorstore.as_retriever(search_kwargs={"k": 8}), - human_in_the_loop=True, - ) - - agent_worker.chain.verbose = True - - return agent_worker - - # objective = "Your objective here" - # api_key = "Your OpenAI API key here" - - # worker_agent = WorkerAgent(objective, api_key) - - -# objective = "Your objective here" - - -# worker_agent = WorkerAgent(objective) diff --git a/swarms/swarms.py b/swarms/swarms.py index 6e884558..fce876af 100644 --- a/swarms/swarms.py +++ b/swarms/swarms.py @@ -1,11 +1,11 @@ from swarms.tools.agent_tools import * -from swarms.agents.workers.worker_agent import WorkerNode +from swarms.agents.workers.WorkerNode import WorkerNode from swarms.agents.boss.boss_agent import BossNode # from swarms.agents.workers.omni_worker import OmniWorkerAgent # from swarms.tools.main import RequestsGet, ExitConversation # visual agent -from swarms.agents.workers.worker_agent import worker_tool +from swarms.agents.workers.WorkerNode import worker_tool import logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') diff --git a/tests/swarms.py b/tests/swarms.py index 565d4389..524e8d0c 100644 --- a/tests/swarms.py +++ b/tests/swarms.py @@ -1,6 +1,6 @@ import unittest import swarms -from swarms.agents.workers.worker_agent import WorkerNode +from swarms.agents.workers.WorkerNode import WorkerNode from swarms.agents.boss.boss_agent import BossNode class TestSwarms(unittest.TestCase): From 201107429bc289fb0937830ba6d333dde5614ba2 Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 18:37:20 -0400 Subject: [PATCH 33/98] clean up codebase Former-commit-id: 19c40279c009afea24f6dd2ece034e9175fed227 --- swarms/agents/boss/{boss_agent.py => BossNode.py} | 0 swarms/agents/workers/{omni_worker.py => OmniWorkerAgent.py} | 0 swarms/swarms.py | 2 +- tests/LLM.py | 2 +- tests/swarms.py | 2 +- 5 files changed, 3 insertions(+), 3 deletions(-) rename swarms/agents/boss/{boss_agent.py => BossNode.py} (100%) rename swarms/agents/workers/{omni_worker.py => OmniWorkerAgent.py} (100%) diff --git a/swarms/agents/boss/boss_agent.py b/swarms/agents/boss/BossNode.py similarity index 100% rename from swarms/agents/boss/boss_agent.py rename to swarms/agents/boss/BossNode.py diff --git a/swarms/agents/workers/omni_worker.py b/swarms/agents/workers/OmniWorkerAgent.py similarity index 100% rename from swarms/agents/workers/omni_worker.py rename to swarms/agents/workers/OmniWorkerAgent.py diff --git a/swarms/swarms.py b/swarms/swarms.py index fce876af..6b51a99c 100644 --- a/swarms/swarms.py +++ b/swarms/swarms.py @@ -1,6 +1,6 @@ from swarms.tools.agent_tools import * from swarms.agents.workers.WorkerNode import WorkerNode -from swarms.agents.boss.boss_agent import BossNode +from swarms.agents.boss.BossNode import BossNode # from swarms.agents.workers.omni_worker import OmniWorkerAgent # from swarms.tools.main import RequestsGet, ExitConversation # visual agent diff --git a/tests/LLM.py b/tests/LLM.py index 57360294..9f384ade 100644 --- a/tests/LLM.py +++ b/tests/LLM.py @@ -3,7 +3,7 @@ import os from unittest.mock import patch, MagicMock from langchain import PromptTemplate, HuggingFaceHub, ChatOpenAI, LLMChain -from swarms.utils.llm import LLM +from swarms.utils.LLM import LLM class TestLLM(unittest.TestCase): @patch.object(HuggingFaceHub, '__init__', return_value=None) diff --git a/tests/swarms.py b/tests/swarms.py index 524e8d0c..291aad08 100644 --- a/tests/swarms.py +++ b/tests/swarms.py @@ -1,7 +1,7 @@ import unittest import swarms from swarms.agents.workers.WorkerNode import WorkerNode -from swarms.agents.boss.boss_agent import BossNode +from swarms.agents.boss.BossNode import BossNode class TestSwarms(unittest.TestCase): def setUp(self): From d44a49a6cbf94d2a43f970a9f41c0b082ceec366 Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 18:37:53 -0400 Subject: [PATCH 34/98] clean up Former-commit-id: 2435d418c31cb53066b7dd7a1888a97c7124547f --- pyproject.txt => misc/pyproject.txt | 0 misc/{utils.py => utils.txt} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename pyproject.txt => misc/pyproject.txt (100%) rename misc/{utils.py => utils.txt} (100%) diff --git a/pyproject.txt b/misc/pyproject.txt similarity index 100% rename from pyproject.txt rename to misc/pyproject.txt diff --git a/misc/utils.py b/misc/utils.txt similarity index 100% rename from misc/utils.py rename to misc/utils.txt From 6cc860c41ccaa8060a012e3c214522f053ed6ab6 Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 18:43:06 -0400 Subject: [PATCH 35/98] clean up Former-commit-id: 0ca95b2bfa8717926b8044f73b47d000e176b077 --- DOCS/CLEAN_CODE.md | 127 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 DOCS/CLEAN_CODE.md diff --git a/DOCS/CLEAN_CODE.md b/DOCS/CLEAN_CODE.md new file mode 100644 index 00000000..d18a905e --- /dev/null +++ b/DOCS/CLEAN_CODE.md @@ -0,0 +1,127 @@ +# Clean Code + +Here are some general principles for writing highly usable, functional, reliable, fast, and scalable code: + +1. **Clear and Understandable:** The code should be written in a way that's easy for others to understand. This includes using clear variable and function names, and including comments to explain complex sections of code. + +2. **Modular and Reusable:** Code should be broken down into small, modular functions and classes that each perform a single task. This makes the code more understandable, and also allows for code reuse. + +3. **Robust Error Handling:** The code should be able to handle all potential errors gracefully, and should never crash unexpectedly. This includes checking for invalid input, catching exceptions, and providing useful error messages. + +4. **Type Handling:** Whenever possible, the code should enforce and check types to prevent type-related errors. This can be done through the use of type hints in languages like Python, or through explicit type checks. + +5. **Logging:** The code should include extensive logging to make it easier to debug and understand what the code is doing. This includes logging any errors that occur, as well as important events or state changes. + +6. **Performance:** The code should be optimized for performance, avoiding unnecessary computation and using efficient algorithms and data structures. This includes profiling the code to identify and optimize performance bottlenecks. + +7. **Scalability:** The code should be designed to scale well as the size of the input data or the number of users increases. This includes using scalable algorithms and data structures, and designing the code to work well in a distributed or parallel computing environment if necessary. + +8. **Testing:** The code should include comprehensive tests to ensure that it works correctly. This includes unit tests for individual functions and classes, as well as integration tests to ensure that the different parts of the code work well together. + +9. **Version Control:** The code should be stored in a version control system like Git, which allows for tracking changes, collaborating with others, and rolling back to a previous state if necessary. + +10. **Documentation:** The codebase should be well-documented, both in terms of comments within the code and external documentation that explains how to use and contribute to the code. + +11. **Continuous Integration/Continuous Deployment (CI/CD):** Implement CI/CD pipelines for automatic testing and deployment. This ensures that any new changes do not break existing functionality and that the latest version of the application is always available for deployment. + +# Examples +1. **Clear and Understandable:** Use meaningful variable and function names. Include comments when necessary. + + ```python + # Good example + def calculate_average(numbers: List[int]) -> float: + """Calculate and return the average of a list of numbers.""" + total = sum(numbers) + count = len(numbers) + return total / count + ``` + + For file and folder names, use descriptive names that relate to their function in your program. For example, a file that contains functions for handling user input might be named `user_input.py`. + +2. **Modular and Reusable:** Write functions for tasks that you perform over and over. + + ```python + def greet_user(name: str): + """Print a greeting to the user.""" + print(f"Hello, {name}!") + ``` + + For folder structure, group related files in the same directory. For example, all test files could be in a `tests` directory. + +3. **Robust Error Handling:** Use try/except blocks to catch and handle errors. + + ```python + def divide_numbers(numerator: float, denominator: float) -> float: + """Divide two numbers and handle division by zero.""" + try: + return numerator / denominator + except ZeroDivisionError: + print("Error: Division by zero.") + return None + ``` + +4. **Type Handling:** Use type hints to specify the type of function arguments and return values. + + ```python + def greet_user(name: str) -> None: + """Greet the user.""" + print(f"Hello, {name}!") + ``` + +5. **Logging:** Use the `logging` module to log events. + + ```python + import logging + + logging.basicConfig(level=logging.INFO) + + def divide_numbers(numerator: float, denominator: float) -> float: + """Divide two numbers and log if division by zero occurs.""" + try: + return numerator / denominator + except ZeroDivisionError: + logging.error("Attempted division by zero.") + return None + ``` + +6. **Performance:** Use built-in functions and data types for better performance. + + ```python + # Using a set to check for membership is faster than using a list + numbers_set = set(numbers) + if target in numbers_set: + print(f"{target} is in the set of numbers.") + ``` + +7. **Scalability:** For scalability, an example might involve using a load balancer or dividing tasks among different workers or threads. This is more of a system design consideration than a single piece of code. + +8. **Testing:** Write tests for your functions. + + ```python + def test_calculate_average(): + assert calculate_average([1, 2, 3, 4]) == 2.5 + ``` + + For tests, you could have a separate `tests` directory. Inside this directory, each test file could be named `test_.py` where `` is the name of the file being tested. + +9. **Version Control:** This point refers to using tools like Git for version control. A simple example would be committing changes to a repository: + + ```bash + git add . + git commit -m "Add function to calculate average" + git push + ``` + +10. **Documentation:** Write docstrings for your functions. + + ```python + def calculate_average(numbers: List[int]) -> float: + """Calculate and return the average of a list of numbers.""" + ... + ``` + + Documentation might be kept in a `docs` directory, with separate files for different topics. + +11. **Continuous Integration/Continuous Deployment (CI/CD):** This is typically handled by a system like Jenkins, GitHub Actions, or GitLab CI/CD. It involves creating a script or configuration file that tells the CI/CD system how to build, test, and deploy your code. For example, a `.github/workflows/main.yml` file for a GitHub Actions workflow. + +Remember, consistency in your naming conventions and organization is key. Having a standard and sticking to it will make your codebase easier to navigate and understand. \ No newline at end of file From 3aee6e726c39b971fed4dbfa5d79a9a30945fa19 Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 18:45:50 -0400 Subject: [PATCH 36/98] clean up Former-commit-id: a8c42fcf0d399981ea8c65f5b6e594c153dcfd71 --- PULL_REQUEST_TEMPLATE.yml => .github/PULL_REQUEST_TEMPLATE.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) rename PULL_REQUEST_TEMPLATE.yml => .github/PULL_REQUEST_TEMPLATE.yml (91%) diff --git a/PULL_REQUEST_TEMPLATE.yml b/.github/PULL_REQUEST_TEMPLATE.yml similarity index 91% rename from PULL_REQUEST_TEMPLATE.yml rename to .github/PULL_REQUEST_TEMPLATE.yml index 1148e304..b02a7ef7 100644 --- a/PULL_REQUEST_TEMPLATE.yml +++ b/.github/PULL_REQUEST_TEMPLATE.yml @@ -22,5 +22,4 @@ Maintainer responsibilities: If no one reviews your PR within a few days, feel free to kye@apac.ai -See contribution guidelines for more information on how to write/run tests, lint, etc: https://github.com/hwchase17/langchain/blob/master/.github/CONTRIBUTING.md - --> \ No newline at end of file +See contribution guidelines for more information on how to write/run tests, lint, etc: https://github.com/kyegomez/swarms \ No newline at end of file From 02961aa84efa558d2cce31661329bfc47ff7387b Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 18:48:24 -0400 Subject: [PATCH 37/98] clean up Former-commit-id: 6dae16cba21bec39af207e8c125b18edec87963b --- requirements.txt | 4 ++-- swarms/agents/utils/AgentManager.py | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/requirements.txt b/requirements.txt index 420df298..dca3e347 100644 --- a/requirements.txt +++ b/requirements.txt @@ -93,9 +93,9 @@ tiktoken espnet==202301 espnet_model_zoo==0.1.7 -flask==2.2.3 +# flask==2.2.3 -flask_cors==3.0.10 +# flask_cors==3.0.10 waitress==2.1.2 asteroid diff --git a/swarms/agents/utils/AgentManager.py b/swarms/agents/utils/AgentManager.py index 2e7b201c..ad2b50fd 100644 --- a/swarms/agents/utils/AgentManager.py +++ b/swarms/agents/utils/AgentManager.py @@ -13,7 +13,8 @@ from .AgentBuilder import AgentBuilder from .Calback import EVALCallbackHandler, ExecutionTracingCallbackHandler -CallbackManager.set_handler(handler=EVALCallbackHandler()) +callback_manager_instance = CallbackManager() +callback_manager_instance.set_handler(handler=EVALCallbackHandler()) class AgentManager: def __init__(self, toolsets: list[BaseToolSet] = []): From 41e4ee2bfd1dcd1c8d14e1916966a552ee692558 Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 18:53:20 -0400 Subject: [PATCH 38/98] clean up Former-commit-id: a58a40f9007dd6419d39f1cbac64a67e67a85a99 --- misc/swarms.txt | 386 +++++++++++++++++++++++++++++++++++++++++ swarms/swarms.py | 441 +---------------------------------------------- 2 files changed, 393 insertions(+), 434 deletions(-) create mode 100644 misc/swarms.txt diff --git a/misc/swarms.txt b/misc/swarms.txt new file mode 100644 index 00000000..19b9ade0 --- /dev/null +++ b/misc/swarms.txt @@ -0,0 +1,386 @@ + + + + + + + + + + + + + + + + + + + + + + + + +# class Swarms: +# def __init__(self, openai_api_key): +# self.openai_api_key = openai_api_key + +# def initialize_llm(self, llm_class, temperature=0.5): +# # Initialize language model +# return llm_class(openai_api_key=self.openai_api_key, temperature=temperature) + +# def initialize_tools(self, llm_class): +# llm = self.initialize_llm(llm_class) +# # Initialize tools +# web_search = DuckDuckGoSearchRun() +# tools = [ +# web_search, +# WriteFileTool(root_dir=ROOT_DIR), +# ReadFileTool(root_dir=ROOT_DIR), + +# process_csv, +# WebpageQATool(qa_chain=load_qa_with_sources_chain(llm)), + +# # RequestsGet() +# Tool(name="RequestsGet", func=RequestsGet.get, description="A portal to the internet, Use this when you need to get specific content from a website. Input should be a url (i.e. https://www.google.com). The output will be the text response of the GET request."), + + +# # CodeEditor, +# # Terminal, +# # RequestsGet, +# # ExitConversation + +# #code editor + terminal editor + visual agent +# # Give the worker node itself as a tool + +# ] +# assert tools is not None, "tools is not initialized" +# return tools + +# def initialize_vectorstore(self): +# # Initialize vector store +# embeddings_model = OpenAIEmbeddings(openai_api_key=self.openai_api_key) +# embedding_size = 1536 +# index = faiss.IndexFlatL2(embedding_size) +# return FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {}) + +# def initialize_worker_node(self, worker_tools, vectorstore): +# # Initialize worker node +# llm = self.initialize_llm(ChatOpenAI) +# worker_node = WorkerNode(llm=llm, tools=worker_tools, vectorstore=vectorstore) +# worker_node.create_agent(ai_name="Swarm Worker AI Assistant", ai_role="Assistant", human_in_the_loop=False, search_kwargs={}) +# worker_node_tool = Tool(name="WorkerNode AI Agent", func=worker_node.run, description="Input: an objective with a todo list for that objective. Output: your task completed: Please be very clear what the objective and task instructions are. The Swarm worker agent is Useful for when you need to spawn an autonomous agent instance as a worker to accomplish any complex tasks, it can search the internet or write code or spawn child multi-modality models to process and generate images and text or audio and so on") +# return worker_node_tool + +# def initialize_boss_node(self, vectorstore, worker_node): +# # Initialize boss node +# llm = self.initialize_llm(OpenAI) +# todo_prompt = PromptTemplate.from_template("You are a boss planer in a swarm who is an expert at coming up with a todo list for a given objective and then creating an worker to help you accomplish your task. Come up with a todo list for this objective: {objective} and then spawn a worker agent to complete the task for you. Always spawn an worker agent after creating a plan and pass the objective and plan to the worker agent.") +# todo_chain = LLMChain(llm=llm, prompt=todo_prompt) +# tools = [ +# Tool(name="TODO", func=todo_chain.run, description="useful for when you need to come up with todo lists. Input: an objective to create a todo list for. Output: a todo list for that objective. Please be very clear what the objective is!"), +# worker_node +# ] +# suffix = """Question: {task}\n{agent_scratchpad}""" +# prefix = """You are an Boss in a swarm who performs one task based on the following objective: {objective}. Take into account these previously completed tasks: {context}.\n """ +# prompt = ZeroShotAgent.create_prompt(tools, prefix=prefix, suffix=suffix, input_variables=["objective", "task", "context", "agent_scratchpad"],) +# llm_chain = LLMChain(llm=llm, prompt=prompt) +# agent = ZeroShotAgent(llm_chain=llm_chain, allowed_tools=[tool.name for tool in tools]) +# agent_executor = AgentExecutor.from_agent_and_tools(agent=agent, tools=tools, verbose=True) +# # return BossNode(return BossNode(llm, vectorstore, agent_executor, max_iterations=5) +# return BossNode(llm, vectorstore, agent_executor, max_iterations=5) + + +# def run_swarms(self, objective, run_as=None): +# try: +# # Run the swarm with the given objective +# worker_tools = self.initialize_tools(OpenAI) +# assert worker_tools is not None, "worker_tools is not initialized" + +# vectorstore = self.initialize_vectorstore() +# worker_node = self.initialize_worker_node(worker_tools, vectorstore) + +# if run_as.lower() == 'worker': +# tool_input = {'prompt': objective} +# return worker_node.run(tool_input) +# else: +# boss_node = self.initialize_boss_node(vectorstore, worker_node) +# task = boss_node.create_task(objective) +# return boss_node.execute_task(task) +# except Exception as e: +# logging.error(f"An error occurred in run_swarms: {e}") +# raise + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +#omni agent ===> working +# class Swarms: +# def __init__(self, +# openai_api_key, +# # omni_api_key=None, +# # omni_api_endpoint=None, +# # omni_api_type=None +# ): +# self.openai_api_key = openai_api_key +# # self.omni_api_key = omni_api_key +# # self.omni_api_endpoint = omni_api_endpoint +# # self.omni_api_key = omni_api_type + +# # if omni_api_key and omni_api_endpoint and omni_api_type: +# # self.omni_worker_agent = OmniWorkerAgent(omni_api_key, omni_api_endpoint, omni_api_type) +# # else: +# # self.omni_worker_agent = None + +# def initialize_llm(self): +# # Initialize language model +# return ChatOpenAI(model_name="gpt-4", temperature=1.0, openai_api_key=self.openai_api_key) + +# def initialize_tools(self, llm): +# # Initialize tools +# web_search = DuckDuckGoSearchRun() +# tools = [ +# web_search, +# WriteFileTool(root_dir=ROOT_DIR), +# ReadFileTool(root_dir=ROOT_DIR), +# process_csv, +# WebpageQATool(qa_chain=load_qa_with_sources_chain(llm)), +# ] +# # if self.omni_worker_agent: +# # tools.append(self.omni_worker_agent.chat) #add omniworker agent class +# return tools + +# def initialize_vectorstore(self): +# # Initialize vector store +# embeddings_model = OpenAIEmbeddings() +# embedding_size = 1536 +# index = faiss.IndexFlatL2(embedding_size) +# return FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {}) + +# def initialize_worker_node(self, llm, worker_tools, vectorstore): +# # Initialize worker node +# worker_node = WorkerNode(llm=llm, tools=worker_tools, vectorstore=vectorstore) +# worker_node.create_agent(ai_name="AI Assistant", ai_role="Assistant", human_in_the_loop=False, search_kwargs={}) +# return worker_node + +# def initialize_boss_node(self, llm, vectorstore, worker_node): +# # Initialize boss node +# todo_prompt = PromptTemplate.from_template("You are a planner who is an expert at coming up with a todo list for a given objective. Come up with a todo list for this objective: {objective}") +# todo_chain = LLMChain(llm=OpenAI(temperature=0), prompt=todo_prompt) +# tools = [ +# Tool(name="TODO", func=todo_chain.run, description="useful for when you need to come up with todo lists. Input: an objective to create a todo list for. Output: a todo list for that objective. Please be very clear what the objective is!"), +# worker_node, +# ] +# suffix = """Question: {task}\n{agent_scratchpad}""" +# prefix = """You are an Boss in a swarm who performs one task based on the following objective: {objective}. Take into account these previously completed tasks: {context}.\n""" +# prompt = ZeroShotAgent.create_prompt(tools, prefix=prefix, suffix=suffix, input_variables=["objective", "task", "context", "agent_scratchpad"],) +# llm_chain = LLMChain(llm=OpenAI(temperature=0), prompt=prompt) +# agent = ZeroShotAgent(llm_chain=llm_chain, allowed_tools=[tool.name for tool in tools]) +# agent_executor = AgentExecutor.from_agent_and_tools(agent=agent, tools=tools, verbose=True) +# return BossNode(self.openai_api_key, llm, vectorstore, agent_executor, verbose=True, max_iterations=5) + +# def run_swarms(self, objective): +# # Run the swarm with the given objective +# llm = self.initialize_llm() +# worker_tools = self.initialize_tools(llm) +# vectorstore = self.initialize_vectorstore() +# worker_node = self.initialize_worker_node(llm, worker_tools, vectorstore) +# boss_node = self.initialize_boss_node(llm, vectorstore, worker_node) +# task = boss_node.create_task(objective) +# boss_node.execute_task(task) +# worker_node.run_agent(objective) + + + + + + + + + + + + +# class Swarms: +# def __init__(self, num_nodes: int, llm: BaseLLM, self_scaling: bool): +# self.nodes = [WorkerNode(llm) for _ in range(num_nodes)] +# self.self_scaling = self_scaling + +# def add_worker(self, llm: BaseLLM): +# self.nodes.append(WorkerNode(llm)) + +# def remove_workers(self, index: int): +# self.nodes.pop(index) + +# def execute(self, task): +# #placeholer for main execution logic +# pass + +# def scale(self): +# #placeholder for self scaling logic +# pass + + + +#special classes + +# class HierarchicalSwarms(Swarms): +# def execute(self, task): +# pass + + +# class CollaborativeSwarms(Swarms): +# def execute(self, task): +# pass + +# class CompetitiveSwarms(Swarms): +# def execute(self, task): +# pass + +# class MultiAgentDebate(Swarms): +# def execute(self, task): +# pass + + +#======================================> WorkerNode + + +# class MetaWorkerNode: +# def __init__(self, llm, tools, vectorstore): +# self.llm = llm +# self.tools = tools +# self.vectorstore = vectorstore + +# self.agent = None +# self.meta_chain = None + +# def init_chain(self, instructions): +# self.agent = WorkerNode(self.llm, self.tools, self.vectorstore) +# self.agent.create_agent("Assistant", "Assistant Role", False, {}) + +# def initialize_meta_chain(): +# meta_template = """ +# Assistant has just had the below interactions with a User. Assistant followed their "Instructions" closely. Your job is to critique the Assistant's performance and then revise the Instructions so that Assistant would quickly and correctly respond in the future. + +# #### + +# {chat_history} + +# #### + +# Please reflect on these interactions. + +# You should first critique Assistant's performance. What could Assistant have done better? What should the Assistant remember about this user? Are there things this user always wants? Indicate this with "Critique: ...". + +# You should next revise the Instructions so that Assistant would quickly and correctly respond in the future. Assistant's goal is to satisfy the user in as few interactions as possible. Assistant will only see the new Instructions, not the interaction history, so anything important must be summarized in the Instructions. Don't forget any important details in the current Instructions! Indicate the new Instructions by "Instructions: ...". +# """ + +# meta_prompt = PromptTemplate( +# input_variables=["chat_history"], template=meta_template +# ) + +# meta_chain = LLMChain( +# llm=OpenAI(temperature=0), +# prompt=meta_prompt, +# verbose=True, +# ) +# return meta_chain + +# def meta_chain(self): +# #define meta template and meta prompting as per your needs +# self.meta_chain = initialize_meta_chain() + + +# def get_chat_history(chain_memory): +# memory_key = chain_memory.memory_key +# chat_history = chain_memory.load_memory_variables(memory_key)[memory_key] +# return chat_history + + +# def get_new_instructions(meta_output): +# delimiter = "Instructions: " +# new_instructions = meta_output[meta_output.find(delimiter) + len(delimiter) :] +# return new_instructions + + +# def main(self, task, max_iters=3, max_meta_iters=5): +# failed_phrase = "task failed" +# success_phrase = "task succeeded" +# key_phrases = [success_phrase, failed_phrase] + +# instructions = "None" +# for i in range(max_meta_iters): +# print(f"[Episode {i+1}/{max_meta_iters}]") +# self.initialize_chain(instructions) +# output = self.agent.perform('Assistant', {'request': task}) +# for j in range(max_iters): +# print(f"(Step {j+1}/{max_iters})") +# print(f"Assistant: {output}") +# print(f"Human: ") +# human_input = input() +# if any(phrase in human_input.lower() for phrase in key_phrases): +# break +# output = self.agent.perform('Assistant', {'request': human_input}) +# if success_phrase in human_input.lower(): +# print(f"You succeeded! Thanks for playing!") +# return +# self.initialize_meta_chain() +# meta_output = self.meta_chain.predict(chat_history=self.get_chat_history()) +# print(f"Feedback: {meta_output}") +# instructions = self.get_new_instructions(meta_output) +# print(f"New Instructions: {instructions}") +# print("\n" + "#" * 80 + "\n") +# print(f"You failed! Thanks for playing!") + + +# #init instance of MetaWorkerNode +# meta_worker_node = MetaWorkerNode(llm=OpenAI, tools=tools, vectorstore=vectorstore) + + +# #specify a task and interact with the agent +# task = "Provide a sysmatic argument for why we should always eat past with olives" +# meta_worker_node.main(task) + + +####################################################################### => Boss Node +####################################################################### => Boss Node +####################################################################### => Boss Node diff --git a/swarms/swarms.py b/swarms/swarms.py index 6b51a99c..b9a9780d 100644 --- a/swarms/swarms.py +++ b/swarms/swarms.py @@ -1,10 +1,6 @@ from swarms.tools.agent_tools import * from swarms.agents.workers.WorkerNode import WorkerNode from swarms.agents.boss.BossNode import BossNode -# from swarms.agents.workers.omni_worker import OmniWorkerAgent -# from swarms.tools.main import RequestsGet, ExitConversation -# visual agent - from swarms.agents.workers.WorkerNode import worker_tool import logging @@ -29,13 +25,6 @@ class Swarms: process_csv, WebpageQATool(qa_chain=load_qa_with_sources_chain(llm)), - - # CodeEditor, - # Terminal, - # RequestsGet, - # ExitConversation - - #code editor + terminal editor + visual agent ] assert tools is not None, "tools is not initialized" @@ -93,430 +82,14 @@ class Swarms: raise - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # usage def swarm(api_key, objective): + """ + import swarm + api_key = "APIKEY" + objective = "What is the capital of the UK?" + result = swarm(api_key, objective) + print(result) # Prints: "The capital of the UK is London." + """ swarms = Swarms(api_key) return swarms.run_swarms(objective) - -# # Use the function -# api_key = "APIKEY" -# objective = "What is the capital of the UK?" -# result = swarm(api_key, objective) -# print(result) # Prints: "The capital of the UK is London." - - - - - - - - - - - - - - - - - - - - - - - - - - -# class Swarms: -# def __init__(self, openai_api_key): -# self.openai_api_key = openai_api_key - -# def initialize_llm(self, llm_class, temperature=0.5): -# # Initialize language model -# return llm_class(openai_api_key=self.openai_api_key, temperature=temperature) - -# def initialize_tools(self, llm_class): -# llm = self.initialize_llm(llm_class) -# # Initialize tools -# web_search = DuckDuckGoSearchRun() -# tools = [ -# web_search, -# WriteFileTool(root_dir=ROOT_DIR), -# ReadFileTool(root_dir=ROOT_DIR), - -# process_csv, -# WebpageQATool(qa_chain=load_qa_with_sources_chain(llm)), - -# # RequestsGet() -# Tool(name="RequestsGet", func=RequestsGet.get, description="A portal to the internet, Use this when you need to get specific content from a website. Input should be a url (i.e. https://www.google.com). The output will be the text response of the GET request."), - - -# # CodeEditor, -# # Terminal, -# # RequestsGet, -# # ExitConversation - -# #code editor + terminal editor + visual agent -# # Give the worker node itself as a tool - -# ] -# assert tools is not None, "tools is not initialized" -# return tools - -# def initialize_vectorstore(self): -# # Initialize vector store -# embeddings_model = OpenAIEmbeddings(openai_api_key=self.openai_api_key) -# embedding_size = 1536 -# index = faiss.IndexFlatL2(embedding_size) -# return FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {}) - -# def initialize_worker_node(self, worker_tools, vectorstore): -# # Initialize worker node -# llm = self.initialize_llm(ChatOpenAI) -# worker_node = WorkerNode(llm=llm, tools=worker_tools, vectorstore=vectorstore) -# worker_node.create_agent(ai_name="Swarm Worker AI Assistant", ai_role="Assistant", human_in_the_loop=False, search_kwargs={}) -# worker_node_tool = Tool(name="WorkerNode AI Agent", func=worker_node.run, description="Input: an objective with a todo list for that objective. Output: your task completed: Please be very clear what the objective and task instructions are. The Swarm worker agent is Useful for when you need to spawn an autonomous agent instance as a worker to accomplish any complex tasks, it can search the internet or write code or spawn child multi-modality models to process and generate images and text or audio and so on") -# return worker_node_tool - -# def initialize_boss_node(self, vectorstore, worker_node): -# # Initialize boss node -# llm = self.initialize_llm(OpenAI) -# todo_prompt = PromptTemplate.from_template("You are a boss planer in a swarm who is an expert at coming up with a todo list for a given objective and then creating an worker to help you accomplish your task. Come up with a todo list for this objective: {objective} and then spawn a worker agent to complete the task for you. Always spawn an worker agent after creating a plan and pass the objective and plan to the worker agent.") -# todo_chain = LLMChain(llm=llm, prompt=todo_prompt) -# tools = [ -# Tool(name="TODO", func=todo_chain.run, description="useful for when you need to come up with todo lists. Input: an objective to create a todo list for. Output: a todo list for that objective. Please be very clear what the objective is!"), -# worker_node -# ] -# suffix = """Question: {task}\n{agent_scratchpad}""" -# prefix = """You are an Boss in a swarm who performs one task based on the following objective: {objective}. Take into account these previously completed tasks: {context}.\n """ -# prompt = ZeroShotAgent.create_prompt(tools, prefix=prefix, suffix=suffix, input_variables=["objective", "task", "context", "agent_scratchpad"],) -# llm_chain = LLMChain(llm=llm, prompt=prompt) -# agent = ZeroShotAgent(llm_chain=llm_chain, allowed_tools=[tool.name for tool in tools]) -# agent_executor = AgentExecutor.from_agent_and_tools(agent=agent, tools=tools, verbose=True) -# # return BossNode(return BossNode(llm, vectorstore, agent_executor, max_iterations=5) -# return BossNode(llm, vectorstore, agent_executor, max_iterations=5) - - -# def run_swarms(self, objective, run_as=None): -# try: -# # Run the swarm with the given objective -# worker_tools = self.initialize_tools(OpenAI) -# assert worker_tools is not None, "worker_tools is not initialized" - -# vectorstore = self.initialize_vectorstore() -# worker_node = self.initialize_worker_node(worker_tools, vectorstore) - -# if run_as.lower() == 'worker': -# tool_input = {'prompt': objective} -# return worker_node.run(tool_input) -# else: -# boss_node = self.initialize_boss_node(vectorstore, worker_node) -# task = boss_node.create_task(objective) -# return boss_node.execute_task(task) -# except Exception as e: -# logging.error(f"An error occurred in run_swarms: {e}") -# raise - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -#omni agent ===> working -# class Swarms: -# def __init__(self, -# openai_api_key, -# # omni_api_key=None, -# # omni_api_endpoint=None, -# # omni_api_type=None -# ): -# self.openai_api_key = openai_api_key -# # self.omni_api_key = omni_api_key -# # self.omni_api_endpoint = omni_api_endpoint -# # self.omni_api_key = omni_api_type - -# # if omni_api_key and omni_api_endpoint and omni_api_type: -# # self.omni_worker_agent = OmniWorkerAgent(omni_api_key, omni_api_endpoint, omni_api_type) -# # else: -# # self.omni_worker_agent = None - -# def initialize_llm(self): -# # Initialize language model -# return ChatOpenAI(model_name="gpt-4", temperature=1.0, openai_api_key=self.openai_api_key) - -# def initialize_tools(self, llm): -# # Initialize tools -# web_search = DuckDuckGoSearchRun() -# tools = [ -# web_search, -# WriteFileTool(root_dir=ROOT_DIR), -# ReadFileTool(root_dir=ROOT_DIR), -# process_csv, -# WebpageQATool(qa_chain=load_qa_with_sources_chain(llm)), -# ] -# # if self.omni_worker_agent: -# # tools.append(self.omni_worker_agent.chat) #add omniworker agent class -# return tools - -# def initialize_vectorstore(self): -# # Initialize vector store -# embeddings_model = OpenAIEmbeddings() -# embedding_size = 1536 -# index = faiss.IndexFlatL2(embedding_size) -# return FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {}) - -# def initialize_worker_node(self, llm, worker_tools, vectorstore): -# # Initialize worker node -# worker_node = WorkerNode(llm=llm, tools=worker_tools, vectorstore=vectorstore) -# worker_node.create_agent(ai_name="AI Assistant", ai_role="Assistant", human_in_the_loop=False, search_kwargs={}) -# return worker_node - -# def initialize_boss_node(self, llm, vectorstore, worker_node): -# # Initialize boss node -# todo_prompt = PromptTemplate.from_template("You are a planner who is an expert at coming up with a todo list for a given objective. Come up with a todo list for this objective: {objective}") -# todo_chain = LLMChain(llm=OpenAI(temperature=0), prompt=todo_prompt) -# tools = [ -# Tool(name="TODO", func=todo_chain.run, description="useful for when you need to come up with todo lists. Input: an objective to create a todo list for. Output: a todo list for that objective. Please be very clear what the objective is!"), -# worker_node, -# ] -# suffix = """Question: {task}\n{agent_scratchpad}""" -# prefix = """You are an Boss in a swarm who performs one task based on the following objective: {objective}. Take into account these previously completed tasks: {context}.\n""" -# prompt = ZeroShotAgent.create_prompt(tools, prefix=prefix, suffix=suffix, input_variables=["objective", "task", "context", "agent_scratchpad"],) -# llm_chain = LLMChain(llm=OpenAI(temperature=0), prompt=prompt) -# agent = ZeroShotAgent(llm_chain=llm_chain, allowed_tools=[tool.name for tool in tools]) -# agent_executor = AgentExecutor.from_agent_and_tools(agent=agent, tools=tools, verbose=True) -# return BossNode(self.openai_api_key, llm, vectorstore, agent_executor, verbose=True, max_iterations=5) - -# def run_swarms(self, objective): -# # Run the swarm with the given objective -# llm = self.initialize_llm() -# worker_tools = self.initialize_tools(llm) -# vectorstore = self.initialize_vectorstore() -# worker_node = self.initialize_worker_node(llm, worker_tools, vectorstore) -# boss_node = self.initialize_boss_node(llm, vectorstore, worker_node) -# task = boss_node.create_task(objective) -# boss_node.execute_task(task) -# worker_node.run_agent(objective) - - - - - - - - - - - - -# class Swarms: -# def __init__(self, num_nodes: int, llm: BaseLLM, self_scaling: bool): -# self.nodes = [WorkerNode(llm) for _ in range(num_nodes)] -# self.self_scaling = self_scaling - -# def add_worker(self, llm: BaseLLM): -# self.nodes.append(WorkerNode(llm)) - -# def remove_workers(self, index: int): -# self.nodes.pop(index) - -# def execute(self, task): -# #placeholer for main execution logic -# pass - -# def scale(self): -# #placeholder for self scaling logic -# pass - - - -#special classes - -# class HierarchicalSwarms(Swarms): -# def execute(self, task): -# pass - - -# class CollaborativeSwarms(Swarms): -# def execute(self, task): -# pass - -# class CompetitiveSwarms(Swarms): -# def execute(self, task): -# pass - -# class MultiAgentDebate(Swarms): -# def execute(self, task): -# pass - - -#======================================> WorkerNode - - -# class MetaWorkerNode: -# def __init__(self, llm, tools, vectorstore): -# self.llm = llm -# self.tools = tools -# self.vectorstore = vectorstore - -# self.agent = None -# self.meta_chain = None - -# def init_chain(self, instructions): -# self.agent = WorkerNode(self.llm, self.tools, self.vectorstore) -# self.agent.create_agent("Assistant", "Assistant Role", False, {}) - -# def initialize_meta_chain(): -# meta_template = """ -# Assistant has just had the below interactions with a User. Assistant followed their "Instructions" closely. Your job is to critique the Assistant's performance and then revise the Instructions so that Assistant would quickly and correctly respond in the future. - -# #### - -# {chat_history} - -# #### - -# Please reflect on these interactions. - -# You should first critique Assistant's performance. What could Assistant have done better? What should the Assistant remember about this user? Are there things this user always wants? Indicate this with "Critique: ...". - -# You should next revise the Instructions so that Assistant would quickly and correctly respond in the future. Assistant's goal is to satisfy the user in as few interactions as possible. Assistant will only see the new Instructions, not the interaction history, so anything important must be summarized in the Instructions. Don't forget any important details in the current Instructions! Indicate the new Instructions by "Instructions: ...". -# """ - -# meta_prompt = PromptTemplate( -# input_variables=["chat_history"], template=meta_template -# ) - -# meta_chain = LLMChain( -# llm=OpenAI(temperature=0), -# prompt=meta_prompt, -# verbose=True, -# ) -# return meta_chain - -# def meta_chain(self): -# #define meta template and meta prompting as per your needs -# self.meta_chain = initialize_meta_chain() - - -# def get_chat_history(chain_memory): -# memory_key = chain_memory.memory_key -# chat_history = chain_memory.load_memory_variables(memory_key)[memory_key] -# return chat_history - - -# def get_new_instructions(meta_output): -# delimiter = "Instructions: " -# new_instructions = meta_output[meta_output.find(delimiter) + len(delimiter) :] -# return new_instructions - - -# def main(self, task, max_iters=3, max_meta_iters=5): -# failed_phrase = "task failed" -# success_phrase = "task succeeded" -# key_phrases = [success_phrase, failed_phrase] - -# instructions = "None" -# for i in range(max_meta_iters): -# print(f"[Episode {i+1}/{max_meta_iters}]") -# self.initialize_chain(instructions) -# output = self.agent.perform('Assistant', {'request': task}) -# for j in range(max_iters): -# print(f"(Step {j+1}/{max_iters})") -# print(f"Assistant: {output}") -# print(f"Human: ") -# human_input = input() -# if any(phrase in human_input.lower() for phrase in key_phrases): -# break -# output = self.agent.perform('Assistant', {'request': human_input}) -# if success_phrase in human_input.lower(): -# print(f"You succeeded! Thanks for playing!") -# return -# self.initialize_meta_chain() -# meta_output = self.meta_chain.predict(chat_history=self.get_chat_history()) -# print(f"Feedback: {meta_output}") -# instructions = self.get_new_instructions(meta_output) -# print(f"New Instructions: {instructions}") -# print("\n" + "#" * 80 + "\n") -# print(f"You failed! Thanks for playing!") - - -# #init instance of MetaWorkerNode -# meta_worker_node = MetaWorkerNode(llm=OpenAI, tools=tools, vectorstore=vectorstore) - - -# #specify a task and interact with the agent -# task = "Provide a sysmatic argument for why we should always eat past with olives" -# meta_worker_node.main(task) - - -####################################################################### => Boss Node -####################################################################### => Boss Node -####################################################################### => Boss Node From d914c911434ec38b35428c24f69ca7063c858205 Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 18:56:12 -0400 Subject: [PATCH 39/98] callbacl handler change Former-commit-id: 22317dbed34437f2fd4f2334f2b4ddbb6dd69bac --- swarms/agents/utils/AgentManager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/swarms/agents/utils/AgentManager.py b/swarms/agents/utils/AgentManager.py index ad2b50fd..ba1e444d 100644 --- a/swarms/agents/utils/AgentManager.py +++ b/swarms/agents/utils/AgentManager.py @@ -13,8 +13,8 @@ from .AgentBuilder import AgentBuilder from .Calback import EVALCallbackHandler, ExecutionTracingCallbackHandler -callback_manager_instance = CallbackManager() -callback_manager_instance.set_handler(handler=EVALCallbackHandler()) +callback_manager_instance = CallbackManager(EVALCallbackHandler()) + class AgentManager: def __init__(self, toolsets: list[BaseToolSet] = []): From 75f9c607a6c8792ec34b36dde4229342701ba43c Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 18:58:06 -0400 Subject: [PATCH 40/98] clean code Former-commit-id: 0910c9d7f82a4b08a91227ba7638188cb2472e9e --- DOCS/CLEAN_CODE.md | 96 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/DOCS/CLEAN_CODE.md b/DOCS/CLEAN_CODE.md index d18a905e..6707b1ff 100644 --- a/DOCS/CLEAN_CODE.md +++ b/DOCS/CLEAN_CODE.md @@ -1,3 +1,99 @@ +Code is clean if it can be understood easily – by everyone on the team. Clean code can be read and enhanced by a developer other than its original author. With understandability comes readability, changeability, extensibility and maintainability. +_____________________________________ + +## General rules +1. Follow standard conventions. +2. Keep it simple stupid. Simpler is always better. Reduce complexity as much as possible. +3. Boy scout rule. Leave the campground cleaner than you found it. +4. Always find root cause. Always look for the root cause of a problem. + +## Design rules +1. Keep configurable data at high levels. +2. Prefer polymorphism to if/else or switch/case. +3. Separate multi-threading code. +4. Prevent over-configurability. +5. Use dependency injection. +6. Follow Law of Demeter. A class should know only its direct dependencies. + +## Understandability tips +1. Be consistent. If you do something a certain way, do all similar things in the same way. +2. Use explanatory variables. +3. Encapsulate boundary conditions. Boundary conditions are hard to keep track of. Put the processing for them in one place. +4. Prefer dedicated value objects to primitive type. +5. Avoid logical dependency. Don't write methods which works correctly depending on something else in the same class. +6. Avoid negative conditionals. + +## Names rules +1. Choose descriptive and unambiguous names. +2. Make meaningful distinction. +3. Use pronounceable names. +4. Use searchable names. +5. Replace magic numbers with named constants. +6. Avoid encodings. Don't append prefixes or type information. + +## Functions rules +1. Small. +2. Do one thing. +3. Use descriptive names. +4. Prefer fewer arguments. +5. Have no side effects. +6. Don't use flag arguments. Split method into several independent methods that can be called from the client without the flag. + +## Comments rules +1. Always try to explain yourself in code. +2. Don't be redundant. +3. Don't add obvious noise. +4. Don't use closing brace comments. +5. Don't comment out code. Just remove. +6. Use as explanation of intent. +7. Use as clarification of code. +8. Use as warning of consequences. + +## Source code structure +1. Separate concepts vertically. +2. Related code should appear vertically dense. +3. Declare variables close to their usage. +4. Dependent functions should be close. +5. Similar functions should be close. +6. Place functions in the downward direction. +7. Keep lines short. +8. Don't use horizontal alignment. +9. Use white space to associate related things and disassociate weakly related. +10. Don't break indentation. + +## Objects and data structures +1. Hide internal structure. +2. Prefer data structures. +3. Avoid hybrids structures (half object and half data). +4. Should be small. +5. Do one thing. +6. Small number of instance variables. +7. Base class should know nothing about their derivatives. +8. Better to have many functions than to pass some code into a function to select a behavior. +9. Prefer non-static methods to static methods. + +## Tests +1. One assert per test. +2. Readable. +3. Fast. +4. Independent. +5. Repeatable. + +## Code smells +1. Rigidity. The software is difficult to change. A small change causes a cascade of subsequent changes. +2. Fragility. The software breaks in many places due to a single change. +3. Immobility. You cannot reuse parts of the code in other projects because of involved risks and high effort. +4. Needless Complexity. +5. Needless Repetition. +6. Opacity. The code is hard to understand. + + + + + + + + # Clean Code Here are some general principles for writing highly usable, functional, reliable, fast, and scalable code: From 903fc60e1482f5388e437066503cb595175a4e76 Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 19:10:19 -0400 Subject: [PATCH 41/98] tools Former-commit-id: b31766016218478c5238ddf7dd9ccd14e4b0daa9 --- swarms/agents/utils/prompts.py | 105 +++++++++++++++++++++++ swarms/agents/workers/WorkerUltraNode.py | 2 +- 2 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 swarms/agents/utils/prompts.py diff --git a/swarms/agents/utils/prompts.py b/swarms/agents/utils/prompts.py new file mode 100644 index 00000000..c2cbb6dc --- /dev/null +++ b/swarms/agents/utils/prompts.py @@ -0,0 +1,105 @@ +def generate_agent_role_prompt(agent): + """ Generates the agent role prompt. + Args: agent (str): The type of the agent. + Returns: str: The agent role prompt. + """ + prompts = { + "Finance Agent": "You are a seasoned finance analyst AI assistant. Your primary goal is to compose comprehensive, astute, impartial, and methodically arranged financial reports based on provided data and trends.", + "Travel Agent": "You are a world-travelled AI tour guide assistant. Your main purpose is to draft engaging, insightful, unbiased, and well-structured travel reports on given locations, including history, attractions, and cultural insights.", + "Academic Research Agent": "You are an AI academic research assistant. Your primary responsibility is to create thorough, academically rigorous, unbiased, and systematically organized reports on a given research topic, following the standards of scholarly work.", + "Default Agent": "You are an AI critical thinker research assistant. Your sole purpose is to write well written, critically acclaimed, objective and structured reports on given text." + + } + + return prompts.get(agent, "No such agent") + + +def generate_report_prompt(question, research_summary): + """ Generates the report prompt for the given question and research summary. + Args: question (str): The question to generate the report prompt for + research_summary (str): The research summary to generate the report prompt for + Returns: str: The report prompt for the given question and research summary + """ + + return f'"""{research_summary}""" Using the above information, answer the following'\ + f' question or topic: "{question}" in a detailed report --'\ + " The report should focus on the answer to the question, should be well structured, informative," \ + " in depth, with facts and numbers if available, a minimum of 1,200 words and with markdown syntax and apa format. "\ + "Write all source urls at the end of the report in apa format" + +def generate_search_queries_prompt(question): + """ Generates the search queries prompt for the given question. + Args: question (str): The question to generate the search queries prompt for + Returns: str: The search queries prompt for the given question + """ + + return f'Write 4 google search queries to search online that form an objective opinion from the following: "{question}"'\ + f'You must respond with a list of strings in the following format: ["query 1", "query 2", "query 3", "query 4"]' + + +def generate_resource_report_prompt(question, research_summary): + """Generates the resource report prompt for the given question and research summary. + + Args: + question (str): The question to generate the resource report prompt for. + research_summary (str): The research summary to generate the resource report prompt for. + + Returns: + str: The resource report prompt for the given question and research summary. + """ + return f'"""{research_summary}""" Based on the above information, generate a bibliography recommendation report for the following' \ + f' question or topic: "{question}". The report should provide a detailed analysis of each recommended resource,' \ + ' explaining how each source can contribute to finding answers to the research question.' \ + ' Focus on the relevance, reliability, and significance of each source.' \ + ' Ensure that the report is well-structured, informative, in-depth, and follows Markdown syntax.' \ + ' Include relevant facts, figures, and numbers whenever available.' \ + ' The report should have a minimum length of 1,200 words.' + + +def generate_outline_report_prompt(question, research_summary): + """ Generates the outline report prompt for the given question and research summary. + Args: question (str): The question to generate the outline report prompt for + research_summary (str): The research summary to generate the outline report prompt for + Returns: str: The outline report prompt for the given question and research summary + """ + + return f'"""{research_summary}""" Using the above information, generate an outline for a research report in Markdown syntax'\ + f' for the following question or topic: "{question}". The outline should provide a well-structured framework'\ + ' for the research report, including the main sections, subsections, and key points to be covered.' \ + ' The research report should be detailed, informative, in-depth, and a minimum of 1,200 words.' \ + ' Use appropriate Markdown syntax to format the outline and ensure readability.' + +def generate_concepts_prompt(question, research_summary): + """ Generates the concepts prompt for the given question. + Args: question (str): The question to generate the concepts prompt for + research_summary (str): The research summary to generate the concepts prompt for + Returns: str: The concepts prompt for the given question + """ + + return f'"""{research_summary}""" Using the above information, generate a list of 5 main concepts to learn for a research report'\ + f' on the following question or topic: "{question}". The outline should provide a well-structured framework'\ + 'You must respond with a list of strings in the following format: ["concepts 1", "concepts 2", "concepts 3", "concepts 4, concepts 5"]' + + +def generate_lesson_prompt(concept): + """ + Generates the lesson prompt for the given question. + Args: + concept (str): The concept to generate the lesson prompt for. + Returns: + str: The lesson prompt for the given concept. + """ + + prompt = f'generate a comprehensive lesson about {concept} in Markdown syntax. This should include the definition'\ + f'of {concept}, its historical background and development, its applications or uses in different'\ + f'fields, and notable events or facts related to {concept}.' + + return prompt + +def get_report_by_type(report_type): + report_type_mapping = { + 'research_report': generate_report_prompt, + 'resource_report': generate_resource_report_prompt, + 'outline_report': generate_outline_report_prompt + } + return report_type_mapping[report_type] \ No newline at end of file diff --git a/swarms/agents/workers/WorkerUltraNode.py b/swarms/agents/workers/WorkerUltraNode.py index 6d043c28..7118d4e7 100644 --- a/swarms/agents/workers/WorkerUltraNode.py +++ b/swarms/agents/workers/WorkerUltraNode.py @@ -6,7 +6,7 @@ from typing import Dict, List from swarms.agents.utils.AgentManager import AgentManager from swarms.utils.main import BaseHandler, FileHandler, FileType -from swarms.tools.main import CsvToDataframe, ExitConversation, RequestsGet, CodeEditor, Terminal +from swarms.tools.agent_tools import CsvToDataframe, ExitConversation, RequestsGet, CodeEditor, Terminal from swarms.tools.main import BaseToolSet from swarms.utils.main import StaticUploader From 9ff2cfde76f9a1490cfcf64b7236310653dcf98d Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 19:17:20 -0400 Subject: [PATCH 42/98] clean up Former-commit-id: ef9acddf2858ae75bd0ab95f3558e62c1ee55ef5 --- swarms/agents/workers/WorkerUltraNode.py | 4 +++- swarms/utils/main.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/swarms/agents/workers/WorkerUltraNode.py b/swarms/agents/workers/WorkerUltraNode.py index 7118d4e7..e852a406 100644 --- a/swarms/agents/workers/WorkerUltraNode.py +++ b/swarms/agents/workers/WorkerUltraNode.py @@ -6,7 +6,9 @@ from typing import Dict, List from swarms.agents.utils.AgentManager import AgentManager from swarms.utils.main import BaseHandler, FileHandler, FileType -from swarms.tools.agent_tools import CsvToDataframe, ExitConversation, RequestsGet, CodeEditor, Terminal +from swarms.tools.agent_tools import ExitConversation, RequestsGet, CodeEditor, Terminal +from swarms.utils.main import CsvToDataframe + from swarms.tools.main import BaseToolSet from swarms.utils.main import StaticUploader diff --git a/swarms/utils/main.py b/swarms/utils/main.py index 8fde50bb..b512abe8 100644 --- a/swarms/utils/main.py +++ b/swarms/utils/main.py @@ -402,7 +402,7 @@ class FileHandler: from swarms.prompts.prompts import DATAFRAME_PROMPT - +import pandas as pd class CsvToDataframe(BaseHandler): def handle(self, filename: str): df = pd.read_csv(filename) From c9acc1eedcc4813130242320bae8f3c6f96245da Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 19:24:24 -0400 Subject: [PATCH 43/98] clean up Former-commit-id: e2ec295cca3171974a2b57db43d36f1b1392ba58 --- swarms/agents/workers/WorkerUltraNode.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/swarms/agents/workers/WorkerUltraNode.py b/swarms/agents/workers/WorkerUltraNode.py index e852a406..b9b23431 100644 --- a/swarms/agents/workers/WorkerUltraNode.py +++ b/swarms/agents/workers/WorkerUltraNode.py @@ -6,7 +6,8 @@ from typing import Dict, List from swarms.agents.utils.AgentManager import AgentManager from swarms.utils.main import BaseHandler, FileHandler, FileType -from swarms.tools.agent_tools import ExitConversation, RequestsGet, CodeEditor, Terminal + +from swarms.tools.main import ExitConversation, RequestsGet, CodeEditor, Terminal from swarms.utils.main import CsvToDataframe from swarms.tools.main import BaseToolSet From 821573e984189ab1040f40627411335fcea72e6f Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 19:34:14 -0400 Subject: [PATCH 44/98] clean up Former-commit-id: 073f399f4f07de422c5a3749dc0a529616dc357e --- swarms/agents/workers/WorkerUltraNode.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/swarms/agents/workers/WorkerUltraNode.py b/swarms/agents/workers/WorkerUltraNode.py index b9b23431..6af14eef 100644 --- a/swarms/agents/workers/WorkerUltraNode.py +++ b/swarms/agents/workers/WorkerUltraNode.py @@ -16,7 +16,9 @@ from swarms.utils.main import StaticUploader logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') BASE_DIR = Path(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) -os.chdir(BASE_DIR / os.environ["PLAYGROUND_DIR"]) +playground = os.environ["PLAYGROUND_DIR"] = '/path/to/directory' + +os.chdir(BASE_DIR / playground) class WorkerUltraNode: def __init__(self, objective: str): From ab6911639c0d4c2d4e15cb70a2888c2cbf5596e5 Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 19:46:22 -0400 Subject: [PATCH 45/98] playground Former-commit-id: b733e2a6a6f88b1924888530f63b4031f6eb0af1 --- swarms/agents/workers/WorkerUltraNode.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/swarms/agents/workers/WorkerUltraNode.py b/swarms/agents/workers/WorkerUltraNode.py index 6af14eef..0e8da00f 100644 --- a/swarms/agents/workers/WorkerUltraNode.py +++ b/swarms/agents/workers/WorkerUltraNode.py @@ -16,10 +16,18 @@ from swarms.utils.main import StaticUploader logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') BASE_DIR = Path(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) -playground = os.environ["PLAYGROUND_DIR"] = '/path/to/directory' -os.chdir(BASE_DIR / playground) +# Check if "PLAYGROUND_DIR" environment variable exists, if not, set a default value +playground = os.environ.get("PLAYGROUND_DIR", './playground') +# Ensure the path exists before changing the directory +os.makedirs(BASE_DIR / playground, exist_ok=True) + +try: + os.chdir(BASE_DIR / playground) +except Exception as e: + logging.error(f"Failed to change directory: {e}") + class WorkerUltraNode: def __init__(self, objective: str): if not isinstance(objective, str): From 76e1b4038eb31e7c1253bbe8e29964d228a13db1 Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 19:53:06 -0400 Subject: [PATCH 46/98] worker ultra import Former-commit-id: fa0def535c3d8aad1f3672e0d7ad196d4ab274e9 --- swarms/agents/__init__.py | 2 +- swarms/agents/utils/__init__.py | 2 +- swarms/agents/workers/__init__.py | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/swarms/agents/__init__.py b/swarms/agents/__init__.py index 97b0096c..94e17d66 100644 --- a/swarms/agents/__init__.py +++ b/swarms/agents/__init__.py @@ -1,3 +1,3 @@ """Agents, workers and bosses""" from ..agents.workers import worker_node -from .workers.WorkerUltraNode import UltraNode \ No newline at end of file +from .workers.WorkerUltraNode import WorkerUltraNode \ No newline at end of file diff --git a/swarms/agents/utils/__init__.py b/swarms/agents/utils/__init__.py index 3cee74ba..e6fd24dd 100644 --- a/swarms/agents/utils/__init__.py +++ b/swarms/agents/utils/__init__.py @@ -1 +1 @@ -"""Agents""" \ No newline at end of file +"""Agents""" diff --git a/swarms/agents/workers/__init__.py b/swarms/agents/workers/__init__.py index 83752f53..9f052dea 100644 --- a/swarms/agents/workers/__init__.py +++ b/swarms/agents/workers/__init__.py @@ -1,3 +1,2 @@ from .WorkerNode import worker_node - -from .WorkerUltraNode import UltraNode +from .WorkerUltraNode import WorkerUltraNode From ca1bcd307938ca8616e3e3c519df4569debdb0fa Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 20:01:10 -0400 Subject: [PATCH 47/98] clean up Former-commit-id: af01c045bce6e9f6d2f80cdc3cf638ca11429dea --- swarms/swarms.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/swarms/swarms.py b/swarms/swarms.py index b9a9780d..c63e9028 100644 --- a/swarms/swarms.py +++ b/swarms/swarms.py @@ -1,7 +1,9 @@ from swarms.tools.agent_tools import * from swarms.agents.workers.WorkerNode import WorkerNode from swarms.agents.boss.BossNode import BossNode -from swarms.agents.workers.WorkerNode import worker_tool + +# from swarms.agents.workers.WorkerNode import worker_tool +from swarms.agents.workers.WorkerNode import worker_node import logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') From 9c6030d1c027101d1af9a8d50eeb13a2576c9df2 Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 20:57:02 -0400 Subject: [PATCH 48/98] clean up Former-commit-id: 85e694c920088a37c970f25c03b3aff8fd682fb2 --- swarms/swarms.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/swarms/swarms.py b/swarms/swarms.py index c63e9028..1f838f3c 100644 --- a/swarms/swarms.py +++ b/swarms/swarms.py @@ -2,10 +2,10 @@ from swarms.tools.agent_tools import * from swarms.agents.workers.WorkerNode import WorkerNode from swarms.agents.boss.BossNode import BossNode -# from swarms.agents.workers.WorkerNode import worker_tool -from swarms.agents.workers.WorkerNode import worker_node -import logging +from swarms.agents.workers.WorkerNode import worker_tool + +import logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') class Swarms: From 710f146860dce57a88604ff5b803df426ac5b9ff Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 21:03:24 -0400 Subject: [PATCH 49/98] clean up worker_tool Former-commit-id: 7efeb1beb3faf2dcee6eadcef545dc4f9e07804b --- swarms/swarms.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/swarms/swarms.py b/swarms/swarms.py index 1f838f3c..f48f78cd 100644 --- a/swarms/swarms.py +++ b/swarms/swarms.py @@ -1,10 +1,7 @@ from swarms.tools.agent_tools import * -from swarms.agents.workers.WorkerNode import WorkerNode +from swarms.agents.workers.WorkerNode import WorkerNode, worker_node from swarms.agents.boss.BossNode import BossNode -from swarms.agents.workers.WorkerNode import worker_tool - - import logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') From 4a9e288af46d50b07e90167af1a581538791be5b Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 21:17:16 -0400 Subject: [PATCH 50/98] clean up Former-commit-id: c4129b84a62c17e52412d506ec1181066e17f592 --- playground/worker_ultra.py | 5 +++++ swarms/__init__.py | 2 +- swarms/agents/workers/WorkerUltraNode.py | 14 +++++++++----- 3 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 playground/worker_ultra.py diff --git a/playground/worker_ultra.py b/playground/worker_ultra.py new file mode 100644 index 00000000..55d5492b --- /dev/null +++ b/playground/worker_ultra.py @@ -0,0 +1,5 @@ +from swarms import WorkerUltra + +objective = "What is the capital of the UK?" +result = WorkerUltra(objective) +print(result) # Prints: "The capital of the UK is London." \ No newline at end of file diff --git a/swarms/__init__.py b/swarms/__init__.py index 44a0bdb4..92413173 100644 --- a/swarms/__init__.py +++ b/swarms/__init__.py @@ -1,3 +1,3 @@ # from swarms import Swarms, swarm from swarms.swarms import Swarms, swarm -from swarms.agents import worker_node, WorkerUltraNode \ No newline at end of file +from swarms.agents import worker_node, WorkerUltra \ No newline at end of file diff --git a/swarms/agents/workers/WorkerUltraNode.py b/swarms/agents/workers/WorkerUltraNode.py index 0e8da00f..ab79570b 100644 --- a/swarms/agents/workers/WorkerUltraNode.py +++ b/swarms/agents/workers/WorkerUltraNode.py @@ -92,8 +92,7 @@ class WorkerUltraNode: "answer": res["output"], "files": [self.uploader.upload(file) for file in files], } - - + def execute(self): try: @@ -104,7 +103,12 @@ class WorkerUltraNode: logging.error(f"Error while executing: {str(e)}") raise e -# from worker_node import UltraNode -# node = UltraNode('objective') -# result = node.execute() + +def WorkerUltra(objective: str): + # Instantiate WorkerUltraNode with the user's objective + worker_node = WorkerUltraNode(objective) + + # Return the result of the execution + return worker_node.result + From 89438713bdebd0f4137a19d19e65146f135ad907 Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 21:27:31 -0400 Subject: [PATCH 51/98] import errors Former-commit-id: 885c30073a2c9d87e2da376d918de71acb8378f2 --- swarms/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarms/__init__.py b/swarms/__init__.py index 92413173..7b7f1c25 100644 --- a/swarms/__init__.py +++ b/swarms/__init__.py @@ -1,3 +1,3 @@ # from swarms import Swarms, swarm from swarms.swarms import Swarms, swarm -from swarms.agents import worker_node, WorkerUltra \ No newline at end of file +from swarms.agents.workers.WorkerUltraNode import worker_node, WorkerUltra \ No newline at end of file From ff8e0dc71f5dc66ed566490209f28471c991d415 Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 21:28:10 -0400 Subject: [PATCH 52/98] worker ultra node Former-commit-id: 3faaa75225cef9bd01dd4b22e000c447ccf06644 --- swarms/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/swarms/__init__.py b/swarms/__init__.py index 7b7f1c25..3ae053b9 100644 --- a/swarms/__init__.py +++ b/swarms/__init__.py @@ -1,3 +1,4 @@ # from swarms import Swarms, swarm from swarms.swarms import Swarms, swarm -from swarms.agents.workers.WorkerUltraNode import worker_node, WorkerUltra \ No newline at end of file +from swarms.agents import worker_node +from swarms.agents.workers.WorkerUltraNode import WorkerUltra \ No newline at end of file From 59ad68cdaa100e03c14b957b2c1e6ae63ba1b9b2 Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 22:05:17 -0400 Subject: [PATCH 53/98] clean up workerultranode Former-commit-id: f4b3ef656c6dd171704063c6947a7e7225a8e9a7 --- swarms/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarms/__init__.py b/swarms/__init__.py index 3ae053b9..e69768b1 100644 --- a/swarms/__init__.py +++ b/swarms/__init__.py @@ -1,4 +1,4 @@ # from swarms import Swarms, swarm from swarms.swarms import Swarms, swarm from swarms.agents import worker_node -from swarms.agents.workers.WorkerUltraNode import WorkerUltra \ No newline at end of file +from swarms.agents.workers.WorkerUltraNode import WorkerUltraNode \ No newline at end of file From 78dc1ab8dbf6fd754a940b761fe9b4487e4be189 Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 22:15:23 -0400 Subject: [PATCH 54/98] clean up Former-commit-id: 302716b676cd4f65b15b51f71a6463411d9db6cf --- swarms/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarms/__init__.py b/swarms/__init__.py index e69768b1..3ae053b9 100644 --- a/swarms/__init__.py +++ b/swarms/__init__.py @@ -1,4 +1,4 @@ # from swarms import Swarms, swarm from swarms.swarms import Swarms, swarm from swarms.agents import worker_node -from swarms.agents.workers.WorkerUltraNode import WorkerUltraNode \ No newline at end of file +from swarms.agents.workers.WorkerUltraNode import WorkerUltra \ No newline at end of file From 56f4371910f8b83568170be737e4cf00d48b7343 Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 22:38:36 -0400 Subject: [PATCH 55/98] clear settings and os.envieon Former-commit-id: f02ff51326cdaaad4e0e923f9b8782d0a3d24327 --- swarms/utils/main.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/swarms/utils/main.py b/swarms/utils/main.py index b512abe8..da503f8f 100644 --- a/swarms/utils/main.py +++ b/swarms/utils/main.py @@ -367,19 +367,17 @@ class FileHandler: def handle(self, url: str) -> str: try: - if url.startswith(settings["SERVER"]): - local_filepath = url[len(settings["SERVER"]) + 1 :] + if url.startswith(os.environ.get("SERVER", "")): + local_filepath = url[len(os.environ.get("SERVER", "")) + 1 :] local_filename = Path("file") / local_filepath.split("/")[-1] src = self.path / local_filepath - dst = self.path / settings["PLAYGROUND_DIR"] / local_filename + dst = self.path / os.environ.get("PLAYGROUND_DIR", "./playground") / local_filename os.makedirs(os.path.dirname(dst), exist_ok=True) shutil.copy(src, dst) else: local_filename = self.download(url) - - try: - handler = self.handlers[FileType.from_url(url)] - except KeyError: + handler = self.handlers.get(FileType.from_url(url)) + if handler is None: if FileType.from_url(url) == FileType.IMAGE: raise Exception( f"No handler for {FileType.from_url(url)}. " @@ -387,10 +385,9 @@ class FileHandler: ) else: raise Exception(f"No handler for {FileType.from_url(url)}") - handler.handle(local_filename) + return handler.handle(local_filename) except Exception as e: raise e - ########################### => base end From 84325314304d50a5b62b7250916349d3ee85c3f8 Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 22:46:56 -0400 Subject: [PATCH 56/98] clean up Former-commit-id: 0ae24f9c24279ba3d398333c1ced02c1434d9180 --- swarms/utils/main.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/swarms/utils/main.py b/swarms/utils/main.py index da503f8f..1d812fbe 100644 --- a/swarms/utils/main.py +++ b/swarms/utils/main.py @@ -274,7 +274,11 @@ class StaticUploader(AbstractUploader): @staticmethod def from_settings(path: Path, endpoint: str) -> "StaticUploader": - return StaticUploader(os.environ["SERVER"], path, endpoint) + server = os.environ.get("SERVER") + if server is None: + raise EnvironmentError("'SERVER' environment variable is not set.") + return StaticUploader(server, path, endpoint) + def get_url(self, uploaded_path: str) -> str: return f"{self.server}/{uploaded_path}" From 10ea864813384c0897140745d33da034f9c453b1 Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 23:55:28 -0400 Subject: [PATCH 57/98] clean up Former-commit-id: ddb2e25d8d56b8b92a09ba42a3f50b0e1a8b3845 --- .env.example | 23 ++++++++++------------- swarms/utils/main.py | 5 ++--- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/.env.example b/.env.example index cc12b4d5..840d7866 100644 --- a/.env.example +++ b/.env.example @@ -1,16 +1,15 @@ -OPENAI_API_KEY="" -WOLFRAM_ALPHA_APPID="" -ZAPIER_NLA_API_KEY="" +OPENAI_API_KEY="your_openai_api_key_here" +WOLFRAM_ALPHA_APPID="your_wolfram_alpha_appid_here" +ZAPIER_NLA_API_KEY="your_zapier_nla_api_key_here" EVAL_PORT=8000 -MODEL_NAME="" -CELERY_BROKER_URL="" +MODEL_NAME="gpt-4" +CELERY_BROKER_URL="redis://localhost:6379" -SERVER="" +SERVER="http://localhost:8000" USE_GPU=True PLAYGROUND_DIR="playground" -OPENAI_API_KEY="your_openai_api_key_here" LOG_LEVEL="INFO" BOT_NAME="Orca" @@ -20,10 +19,8 @@ BING_SEARCH_URL="your_bing_search_url_here" BING_SUBSCRIPTION_KEY="your_bing_subscription_key_here" SERPAPI_API_KEY="your_serpapi_api_key_here" -IFTTTKey="" - -BRAVE_API_KEY="" -SPOONACULAR_KEY="" -HF_API_KEY="Huggingface api key" +IFTTTKey="your_iftttkey_here" -MODEL_NAME="gpt-4" \ No newline at end of file +BRAVE_API_KEY="your_brave_api_key_here" +SPOONACULAR_KEY="your_spoonacular_key_here" +HF_API_KEY="your_huggingface_api_key_here" diff --git a/swarms/utils/main.py b/swarms/utils/main.py index 1d812fbe..ca42a745 100644 --- a/swarms/utils/main.py +++ b/swarms/utils/main.py @@ -274,12 +274,11 @@ class StaticUploader(AbstractUploader): @staticmethod def from_settings(path: Path, endpoint: str) -> "StaticUploader": - server = os.environ.get("SERVER") - if server is None: - raise EnvironmentError("'SERVER' environment variable is not set.") + server = os.environ.get("SERVER", "default_server_value") return StaticUploader(server, path, endpoint) + def get_url(self, uploaded_path: str) -> str: return f"{self.server}/{uploaded_path}" From 111e4f35ea59eab51e4015268f684c95592d0828 Mon Sep 17 00:00:00 2001 From: Kye Date: Wed, 12 Jul 2023 23:57:40 -0400 Subject: [PATCH 58/98] clena up Former-commit-id: 3c87b537e6faefca2645716e73bb525482cea25e --- swarms/utils/main.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/swarms/utils/main.py b/swarms/utils/main.py index ca42a745..78e9b7f8 100644 --- a/swarms/utils/main.py +++ b/swarms/utils/main.py @@ -274,7 +274,7 @@ class StaticUploader(AbstractUploader): @staticmethod def from_settings(path: Path, endpoint: str) -> "StaticUploader": - server = os.environ.get("SERVER", "default_server_value") + server = os.environ.get("SERVER", "http://localhost:8000") return StaticUploader(server, path, endpoint) @@ -370,8 +370,8 @@ class FileHandler: def handle(self, url: str) -> str: try: - if url.startswith(os.environ.get("SERVER", "")): - local_filepath = url[len(os.environ.get("SERVER", "")) + 1 :] + if url.startswith(os.environ.get("SERVER", "http://localhost:8000")): + local_filepath = url[len(os.environ.get("SERVER", "http://localhost:8000")) + 1 :] local_filename = Path("file") / local_filepath.split("/")[-1] src = self.path / local_filepath dst = self.path / os.environ.get("PLAYGROUND_DIR", "./playground") / local_filename From bdd2cf4a8ada639af3c6d972684d659fec4853bc Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 06:40:30 -0400 Subject: [PATCH 59/98] path error Former-commit-id: 4747b75cfbcdc8bffbc2a39ba8386f6583442438 --- swarms/agents/utils/ChatOpenAI.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarms/agents/utils/ChatOpenAI.py b/swarms/agents/utils/ChatOpenAI.py index a6775c38..9be5d125 100644 --- a/swarms/agents/utils/ChatOpenAI.py +++ b/swarms/agents/utils/ChatOpenAI.py @@ -123,7 +123,7 @@ class ModelNotFoundException(Exception): ) -class ChatOpenAI(BaseChatModel, BaseModel): +class ChatOpenAI(BaseChatModel): """Wrapper around OpenAI Chat large language models. To use, you should have the ``openai`` python package installed, and the From e709cbc9fccc6f8016b288f315d51a63c5d6ee49 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 06:49:37 -0400 Subject: [PATCH 60/98] clean up Former-commit-id: 9598b19dbd1aad7c65965cac81104de0f164f942 --- swarms/agents/utils/ChatOpenAI.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/swarms/agents/utils/ChatOpenAI.py b/swarms/agents/utils/ChatOpenAI.py index 9be5d125..a51125a8 100644 --- a/swarms/agents/utils/ChatOpenAI.py +++ b/swarms/agents/utils/ChatOpenAI.py @@ -1,5 +1,6 @@ """OpenAI chat wrapper.""" from __future__ import annotations +from abc import abstractmethod import os import logging @@ -123,7 +124,7 @@ class ModelNotFoundException(Exception): ) -class ChatOpenAI(BaseChatModel): +class ChatOpenAI(BaseChatModel, BaseModel): """Wrapper around OpenAI Chat large language models. To use, you should have the ``openai`` python package installed, and the @@ -158,6 +159,13 @@ class ChatOpenAI(BaseChatModel): """Configuration for this pydantic object.""" extra = Extra.ignore + + @abstractmethod + @property + def _llm_type(self) -> str: + # Return a string indicating the type of this language model + return 'ChatOpenAI' + def check_access(self) -> None: """Check that the user has access to the model.""" From 239397e8efbee8cc17a3f9dc7e730245c15611b8 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 06:56:21 -0400 Subject: [PATCH 61/98] clean up Former-commit-id: 7986b3c796b5c1e130a8fbc20b19de364789bf26 --- swarms/agents/utils/ChatOpenAI.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/swarms/agents/utils/ChatOpenAI.py b/swarms/agents/utils/ChatOpenAI.py index a51125a8..9bcd39e4 100644 --- a/swarms/agents/utils/ChatOpenAI.py +++ b/swarms/agents/utils/ChatOpenAI.py @@ -160,13 +160,12 @@ class ChatOpenAI(BaseChatModel, BaseModel): extra = Extra.ignore - @abstractmethod @property + @abstractmethod def _llm_type(self) -> str: # Return a string indicating the type of this language model return 'ChatOpenAI' - def check_access(self) -> None: """Check that the user has access to the model.""" From ba26c7922b7362930f1a6bccfb2bd00fe8a35cdf Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 07:25:50 -0400 Subject: [PATCH 62/98] clean up Former-commit-id: 085f5fc1d8a029ac42f3c6aba35537df2507cd13 --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5566891e..45d0710c 100644 --- a/README.md +++ b/README.md @@ -18,12 +18,12 @@ Welcome to Swarms - the future of AI, where we leverage the power of autonomous
- -[![GitHub issues](https://img.shields.io/github/issues/kyegomez/swarms)](https://github.com/kyegomez/swarms/issues) [![GitHub forks](https://img.shields.io/github/forks/kyegomez/swarms)](https://github.com/kyegomez/swarms/network) [![GitHub stars](https://img.shields.io/github/stars/kyegomez/swarms)](https://github.com/kyegomez/swarms/stargazers) [![GitHub license](https://img.shields.io/github/license/kyegomez/swarms)](https://github.com/kyegomez/swarms/blob/main/LICENSE) +[![GitHub issues](https://img.shields.io/github/issues/kyegomez/swarms)](https://github.com/kyegomez/swarms/issues) [![GitHub forks](https://img.shields.io/github/forks/kyegomez/swarms)](https://github.com/kyegomez/swarms/network) [![GitHub stars](https://img.shields.io/github/stars/kyegomez/swarms)](https://github.com/kyegomez/swarms/stargazers) [![GitHub license](https://img.shields.io/github/license/kyegomez/swarms)](https://github.com/kyegomez/swarms/blob/main/LICENSE)[![GitHub star chart](https://img.shields.io/github/stars/kyegomez/swarms?style=social)](https://star-history.com/#kyegomez/swarms) +[![Dependency Status](https://img.shields.io/librariesio/github/kyegomez/swarms)](https://libraries.io/github/kyegomez/swarms) [![Downloads](https://static.pepy.tech/badge/swarms/month)](https://pepy.tech/project/swarms) ### Share on Social Media -[![Share on Twitter](https://img.shields.io/twitter/url/https/twitter.com/cloudposse.svg?style=social&label=Share%20%40kyegomez/swarms)](https://twitter.com/intent/tweet?text=Check%20out%20this%20amazing%20AI%20project:%20&url=https%3A%2F%2Fgithub.com%2Fkyegomez%2Fswarms) [![Share on Facebook](https://img.shields.io/badge/Share-%20facebook-blue)](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fgithub.com%2Fkyegomez%2Fswarms) [![Share on LinkedIn](https://img.shields.io/badge/Share-%20linkedin-blue)](https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fgithub.com%2Fkyegomez%2Fswarms&title=&summary=&source=) +[![](https://dcbadge.vercel.app/api/server/6adMQxSpJS?compact=true&style=flat)](https://discord.gg/qUtxnK2NMf)[![Share on Twitter](https://img.shields.io/twitter/url/https/twitter.com/cloudposse.svg?style=social&label=Share%20%40kyegomez/swarms)](https://twitter.com/intent/tweet?text=Check%20out%20this%20amazing%20AI%20project:%20&url=https%3A%2F%2Fgithub.com%2Fkyegomez%2Fswarms) [![Share on Facebook](https://img.shields.io/badge/Share-%20facebook-blue)](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fgithub.com%2Fkyegomez%2Fswarms) [![Share on LinkedIn](https://img.shields.io/badge/Share-%20linkedin-blue)](https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fgithub.com%2Fkyegomez%2Fswarms&title=&summary=&source=) [![Share on Reddit](https://img.shields.io/badge/-Share%20on%20Reddit-orange)](https://www.reddit.com/submit?url=https%3A%2F%2Fgithub.com%2Fkyegomez%2Fswarms&title=Swarms%20-%20the%20future%20of%20AI) [![Share on Hacker News](https://img.shields.io/badge/-Share%20on%20Hacker%20News-orange)](https://news.ycombinator.com/submitlink?u=https%3A%2F%2Fgithub.com%2Fkyegomez%2Fswarms&t=Swarms%20-%20the%20future%20of%20AI) [![Share on Pinterest](https://img.shields.io/badge/-Share%20on%20Pinterest-red)](https://pinterest.com/pin/create/button/?url=https%3A%2F%2Fgithub.com%2Fkyegomez%2Fswarms&media=https%3A%2F%2Fexample.com%2Fimage.jpg&description=Swarms%20-%20the%20future%20of%20AI) [![Share on WhatsApp](https://img.shields.io/badge/-Share%20on%20WhatsApp-green)](https://api.whatsapp.com/send?text=Check%20out%20Swarms%20-%20the%20future%20of%20AI%20%23swarms%20%23AI%0A%0Ahttps%3A%2F%2Fgithub.com%2Fkyegomez%2Fswarms) From a467b881f1d597bf4ed50bdc304a5a43fb823408 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 07:29:04 -0400 Subject: [PATCH 63/98] agora discord batge Former-commit-id: 517b800cbd27266c4342bf2e8156ef248c0861c0 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 45d0710c..65976cdb 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Welcome to Swarms - the future of AI, where we leverage the power of autonomous ### Share on Social Media -[![](https://dcbadge.vercel.app/api/server/6adMQxSpJS?compact=true&style=flat)](https://discord.gg/qUtxnK2NMf)[![Share on Twitter](https://img.shields.io/twitter/url/https/twitter.com/cloudposse.svg?style=social&label=Share%20%40kyegomez/swarms)](https://twitter.com/intent/tweet?text=Check%20out%20this%20amazing%20AI%20project:%20&url=https%3A%2F%2Fgithub.com%2Fkyegomez%2Fswarms) [![Share on Facebook](https://img.shields.io/badge/Share-%20facebook-blue)](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fgithub.com%2Fkyegomez%2Fswarms) [![Share on LinkedIn](https://img.shields.io/badge/Share-%20linkedin-blue)](https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fgithub.com%2Fkyegomez%2Fswarms&title=&summary=&source=) +[![](https://img.shields.io/badge/badge-preview-success.svg?logo=data%3Aimage%2Fsvg%2Bxml%3Bbase64%2CPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBpZD0iZGlzY29yZCIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgMjQgMjQiPgogIDxwYXRoIGQ9Ik0xOC41OSw1Ljg5Yy0xLjIzLS41Ny0yLjU0LS45OS0zLjkyLTEuMjMtLjE3LC4zLS4zNywuNzEtLjUsMS4wNC0xLjQ2LS4yMi0yLjkxLS4yMi00LjM0LDAtLjE0LS4zMy0uMzQtLjc0LS41MS0xLjA0LTEuMzgsLjI0LTIuNjksLjY2LTMuOTIsMS4yMy0yLjQ4LDMuNzQtMy4xNSw3LjM5LTIuODIsMTAuOTgsMS42NSwxLjIzLDMuMjQsMS45Nyw0LjgxLDIuNDYsLjM5LS41MywuNzMtMS4xLDEuMDMtMS42OS0uNTctLjIxLTEuMTEtLjQ4LTEuNjItLjc5LC4xNC0uMSwuMjctLjIxLC40LS4zMSwzLjEzLDEuNDYsNi41MiwxLjQ2LDkuNjEsMCwuMTMsLjExLC4yNiwuMjEsLjQsLjMxLS41MSwuMzEtMS4wNiwuNTctMS42MiwuNzksLjMsLjU5LC42NCwxLjE2LDEuMDMsMS42OSwxLjU3LS40OSwzLjE3LTEuMjMsNC44MS0yLjQ2LC4zOS00LjE3LS42Ny03Ljc4LTIuODItMTAuOThaTTguODQsMTQuNjdjLS45NCwwLTEuNzEtLjg3LTEuNzEtMS45NHMuNzUtMS45NCwxLjcxLTEuOTQsMS43MiwuODcsMS43MSwxLjk0YzAsMS4wNi0uNzUsMS45NC0xLjcxLDEuOTRabTYuMzEsMGMtLjk0LDAtMS43MS0uODctMS43MS0xLjk0cy43NS0xLjk0LDEuNzEtMS45NCwxLjcyLC44NywxLjcxLDEuOTRjMCwxLjA2LS43NSwxLjk0LTEuNzEsMS45NFoiLz4KPC9zdmc%2B)](https://discord.gg/qUtxnK2NMf)[![Share on Twitter](https://img.shields.io/twitter/url/https/twitter.com/cloudposse.svg?style=social&label=Share%20%40kyegomez/swarms)](https://twitter.com/intent/tweet?text=Check%20out%20this%20amazing%20AI%20project:%20&url=https%3A%2F%2Fgithub.com%2Fkyegomez%2Fswarms) [![Share on Facebook](https://img.shields.io/badge/Share-%20facebook-blue)](https://www.facebook.com/sharer/sharer.php?u=https%3A%2F%2Fgithub.com%2Fkyegomez%2Fswarms) [![Share on LinkedIn](https://img.shields.io/badge/Share-%20linkedin-blue)](https://www.linkedin.com/shareArticle?mini=true&url=https%3A%2F%2Fgithub.com%2Fkyegomez%2Fswarms&title=&summary=&source=) [![Share on Reddit](https://img.shields.io/badge/-Share%20on%20Reddit-orange)](https://www.reddit.com/submit?url=https%3A%2F%2Fgithub.com%2Fkyegomez%2Fswarms&title=Swarms%20-%20the%20future%20of%20AI) [![Share on Hacker News](https://img.shields.io/badge/-Share%20on%20Hacker%20News-orange)](https://news.ycombinator.com/submitlink?u=https%3A%2F%2Fgithub.com%2Fkyegomez%2Fswarms&t=Swarms%20-%20the%20future%20of%20AI) [![Share on Pinterest](https://img.shields.io/badge/-Share%20on%20Pinterest-red)](https://pinterest.com/pin/create/button/?url=https%3A%2F%2Fgithub.com%2Fkyegomez%2Fswarms&media=https%3A%2F%2Fexample.com%2Fimage.jpg&description=Swarms%20-%20the%20future%20of%20AI) [![Share on WhatsApp](https://img.shields.io/badge/-Share%20on%20WhatsApp-green)](https://api.whatsapp.com/send?text=Check%20out%20Swarms%20-%20the%20future%20of%20AI%20%23swarms%20%23AI%0A%0Ahttps%3A%2F%2Fgithub.com%2Fkyegomez%2Fswarms) From 925d89a0d08b7e75e43db8a633a8ede3447bc2b0 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 07:30:37 -0400 Subject: [PATCH 64/98] start chart Former-commit-id: 12f703ad4ef4eb2ff84a8c7d3cc7408fc63d0475 --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 65976cdb..1e9cb8a6 100644 --- a/README.md +++ b/README.md @@ -189,6 +189,9 @@ Remember, our roadmap is a guide, and we encourage you to bring your own ideas a # EcoSystem +[![Star History Chart](https://api.star-history.com/svg?repos=kyegomez/swarms&type=Date)](https://star-history.com/#kyegomez/swarms) + + * [The-Compiler, compile natural language into serene, reliable, and secure programs](https://github.com/kyegomez/the-compiler) *[The Replicator, an autonomous swarm that conducts Multi-Modal AI research by creating new underlying mathematical operations and models](https://github.com/kyegomez/The-Replicator) @@ -211,7 +214,3 @@ Remember, our roadmap is a guide, and we encourage you to bring your own ideas a - - - - From 884c5c267193b7499260b477946529afa46ec0e6 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 07:36:54 -0400 Subject: [PATCH 65/98] back to chatopenai Former-commit-id: 33eaf1ad9a1043da913dae454ec9b62491139d31 --- swarms/agents/utils/ChatOpenAI.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/swarms/agents/utils/ChatOpenAI.py b/swarms/agents/utils/ChatOpenAI.py index 9bcd39e4..a6775c38 100644 --- a/swarms/agents/utils/ChatOpenAI.py +++ b/swarms/agents/utils/ChatOpenAI.py @@ -1,6 +1,5 @@ """OpenAI chat wrapper.""" from __future__ import annotations -from abc import abstractmethod import os import logging @@ -159,12 +158,6 @@ class ChatOpenAI(BaseChatModel, BaseModel): """Configuration for this pydantic object.""" extra = Extra.ignore - - @property - @abstractmethod - def _llm_type(self) -> str: - # Return a string indicating the type of this language model - return 'ChatOpenAI' def check_access(self) -> None: """Check that the user has access to the model.""" From d34112a52d6dc97bd0b5409f024f101dc30d6839 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 07:44:18 -0400 Subject: [PATCH 66/98] back to langchain openai provider Former-commit-id: ad1da05427f164bab85251b51d2fc0e279b45c29 --- swarms/agents/utils/AgentBuilder.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/swarms/agents/utils/AgentBuilder.py b/swarms/agents/utils/AgentBuilder.py index e26ffdf9..3adaca45 100644 --- a/swarms/agents/utils/AgentBuilder.py +++ b/swarms/agents/utils/AgentBuilder.py @@ -10,7 +10,8 @@ from langchain.schema import BaseOutputParser from langchain.callbacks.base import BaseCallbackManager from .ConversationalChatAgent import ConversationalChatAgent -from .ChatOpenAI import ChatOpenAI +# from .ChatOpenAI import ChatOpenAI +from langchain.chat_models import ChatOpenAI from .EvalOutputParser import EvalOutputParser From ee3bceb864f207fbf8535012ce9fcc76f85a7cbb Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 08:21:42 -0400 Subject: [PATCH 67/98] api key pass in Former-commit-id: a5d704ecc9a4c639b25699f2b409ef7900c04603 --- swarms/agents/utils/AgentManager.py | 5 +++-- swarms/agents/workers/WorkerUltraNode.py | 12 ++++++------ 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/swarms/agents/utils/AgentManager.py b/swarms/agents/utils/AgentManager.py index ba1e444d..be1dd6bb 100644 --- a/swarms/agents/utils/AgentManager.py +++ b/swarms/agents/utils/AgentManager.py @@ -36,7 +36,7 @@ class AgentManager: self.memories[session] = self.create_memory() return self.memories[session] - def create_executor(self, session: str, execution: Optional[Task] = None) -> AgentExecutor: + def create_executor(self, session: str, execution: Optional[Task] = None, openai_api_key: str = None) -> AgentExecutor: try: builder = AgentBuilder(self.toolsets) builder.build_parser() @@ -45,6 +45,7 @@ class AgentManager: eval_callback = EVALCallbackHandler() eval_callback.set_parser(builder.get_parser()) callbacks.append(eval_callback) + if execution: execution_callback = ExecutionTracingCallbackHandler(execution) execution_callback.set_parser(builder.get_parser()) @@ -52,7 +53,7 @@ class AgentManager: callback_manager = CallbackManager(callbacks) - builder.build_llm(callback_manager) + builder.build_llm(callback_manager, openai_api_key) builder.build_global_tools() memory: BaseChatMemory = self.get_or_create_memory(session) diff --git a/swarms/agents/workers/WorkerUltraNode.py b/swarms/agents/workers/WorkerUltraNode.py index ab79570b..274fbf39 100644 --- a/swarms/agents/workers/WorkerUltraNode.py +++ b/swarms/agents/workers/WorkerUltraNode.py @@ -29,7 +29,9 @@ except Exception as e: logging.error(f"Failed to change directory: {e}") class WorkerUltraNode: - def __init__(self, objective: str): + def __init__(self, objective: str, openai_api_key: str): + self.openai_api_key = openai_api_key + if not isinstance(objective, str): raise TypeError("Objective must be a string") if not objective: @@ -69,7 +71,7 @@ class WorkerUltraNode: ) - self.session = self.agent_manager.create_executor(objective) + self.session = self.agent_manager.create_executor(objective, self.openai_api_key) except Exception as e: logging.error(f"Error while initializing WorkerUltraNode: {str(e)}") @@ -105,10 +107,8 @@ class WorkerUltraNode: -def WorkerUltra(objective: str): - # Instantiate WorkerUltraNode with the user's objective - worker_node = WorkerUltraNode(objective) - +def WorkerUltra(objective: str, openai_api_key: str): + worker_node = WorkerUltraNode(objective, openai_api_key) # Return the result of the execution return worker_node.result From 7bd07da86d8213972af96492d50613da36db7fab Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 08:30:32 -0400 Subject: [PATCH 68/98] build llm Former-commit-id: 068bfdcd2392c563c33c36de1b05016a8fa32887 --- swarms/agents/utils/AgentBuilder.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/swarms/agents/utils/AgentBuilder.py b/swarms/agents/utils/AgentBuilder.py index 3adaca45..ada152a9 100644 --- a/swarms/agents/utils/AgentBuilder.py +++ b/swarms/agents/utils/AgentBuilder.py @@ -23,10 +23,7 @@ class AgentBuilder: self.toolsets = toolsets def build_llm(self, callback_manager: BaseCallbackManager = None, openai_api_key: str = None): - self.llm = ChatOpenAI( - temperature=0, callback_manager=callback_manager, verbose=True, openai_api_key=openai_api_key - ) - self.llm.check_access() + self.llm = ChatOpenAI(openai_api_key=openai_api_key, temperature=0, callback_manager=callback_manager, verbose=True) def build_parser(self): self.parser = EvalOutputParser() From 8f67b321835f9d7b8f8e8f444bd3a33758e86e01 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 08:47:14 -0400 Subject: [PATCH 69/98] clean up Former-commit-id: 62eda1bf8375051d0263bdb8578bd0190ce5d386 --- swarms/agents/utils/AgentManager.py | 54 ++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/swarms/agents/utils/AgentManager.py b/swarms/agents/utils/AgentManager.py index be1dd6bb..97e96f1c 100644 --- a/swarms/agents/utils/AgentManager.py +++ b/swarms/agents/utils/AgentManager.py @@ -36,46 +36,66 @@ class AgentManager: self.memories[session] = self.create_memory() return self.memories[session] - def create_executor(self, session: str, execution: Optional[Task] = None, openai_api_key: str = None) -> AgentExecutor: + def create_executor(self, session_id: str, task: Optional[Task] = None, openai_api_key: str = None) -> AgentExecutor: try: - builder = AgentBuilder(self.toolsets) - builder.build_parser() + # Create an agent setup with the provided toolsets + agent_setup = AgentSetup(self.toolsets) + # Setup the parser for the agent + agent_setup.setup_parser() + + # Initialize an empty list for callbacks callbacks = [] - eval_callback = EVALCallbackHandler() - eval_callback.set_parser(builder.get_parser()) + + # Create and setup an evaluation callback, then add it to the callbacks list + eval_callback = EvaluationCallbackHandler() + eval_callback.set_parser(agent_setup.get_parser()) callbacks.append(eval_callback) - if execution: - execution_callback = ExecutionTracingCallbackHandler(execution) - execution_callback.set_parser(builder.get_parser()) - callbacks.append(execution_callback) + # If a task is provided, create and setup an execution tracing callback, then add it to the callbacks list + if task: + execution_trace_callback = ExecutionTracingCallbackHandler(task) + execution_trace_callback.set_parser(agent_setup.get_parser()) + callbacks.append(execution_trace_callback) + # Create a callback manager with the callbacks callback_manager = CallbackManager(callbacks) - builder.build_llm(callback_manager, openai_api_key) - builder.build_global_tools() + # Setup the language model with the callback manager and OpenAI API key + agent_setup.setup_language_model(callback_manager, openai_api_key) + + # Setup the global tools for the agent + agent_setup.setup_tools() - memory: BaseChatMemory = self.get_or_create_memory(session) + # Get or create a memory for the session + chat_memory = self.get_or_create_memory(session_id) + + # Create a list of tools by combining global tools and per session tools tools = [ - *builder.get_global_tools(), + *agent_setup.get_global_tools(), *ToolsFactory.create_per_session_tools( self.toolsets, - get_session=lambda: (session, self.executors[session]), + get_session=lambda: (session_id, self.executors[session_id]), ), ] + # Set the callback manager for each tool for tool in tools: tool.callback_manager = callback_manager + # Create an executor from the agent and tools executor = AgentExecutor.from_agent_and_tools( - agent=builder.get_agent(), + agent=agent_setup.get_agent(), tools=tools, - memory=memory, + memory=chat_memory, callback_manager=callback_manager, verbose=True, ) - self.executors[session] = executor + + # Store the executor in the executors dictionary + self.executors[session_id] = executor + + # Return the executor return executor except Exception as e: logging.error(f"Error while creating executor: {str(e)}") From 00353b387b53c92991f8d06921a8bb3a55b07d78 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 08:54:39 -0400 Subject: [PATCH 70/98] clean up Former-commit-id: 7c9c26224d1b4a05aeb5b56c30db6fa004f038c2 --- swarms/agents/utils/AgentManager.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/swarms/agents/utils/AgentManager.py b/swarms/agents/utils/AgentManager.py index 97e96f1c..389397d9 100644 --- a/swarms/agents/utils/AgentManager.py +++ b/swarms/agents/utils/AgentManager.py @@ -38,41 +38,41 @@ class AgentManager: def create_executor(self, session_id: str, task: Optional[Task] = None, openai_api_key: str = None) -> AgentExecutor: try: - # Create an agent setup with the provided toolsets - agent_setup = AgentSetup(self.toolsets) + # Create an agent builder with the provided toolsets + agent_builder = AgentBuilder(self.toolsets) # Setup the parser for the agent - agent_setup.setup_parser() + agent_builder.build_parser() # Initialize an empty list for callbacks callbacks = [] # Create and setup an evaluation callback, then add it to the callbacks list eval_callback = EvaluationCallbackHandler() - eval_callback.set_parser(agent_setup.get_parser()) + eval_callback.set_parser(agent_builder.get_parser()) callbacks.append(eval_callback) # If a task is provided, create and setup an execution tracing callback, then add it to the callbacks list if task: execution_trace_callback = ExecutionTracingCallbackHandler(task) - execution_trace_callback.set_parser(agent_setup.get_parser()) + execution_trace_callback.set_parser(agent_builder.get_parser()) callbacks.append(execution_trace_callback) # Create a callback manager with the callbacks callback_manager = CallbackManager(callbacks) # Setup the language model with the callback manager and OpenAI API key - agent_setup.setup_language_model(callback_manager, openai_api_key) + agent_builder.build_llm(callback_manager, openai_api_key) # Setup the global tools for the agent - agent_setup.setup_tools() + agent_builder.build_global_tools() # Get or create a memory for the session chat_memory = self.get_or_create_memory(session_id) # Create a list of tools by combining global tools and per session tools tools = [ - *agent_setup.get_global_tools(), + *agent_builder.get_global_tools(), *ToolsFactory.create_per_session_tools( self.toolsets, get_session=lambda: (session_id, self.executors[session_id]), @@ -85,7 +85,7 @@ class AgentManager: # Create an executor from the agent and tools executor = AgentExecutor.from_agent_and_tools( - agent=agent_setup.get_agent(), + agent=agent_builder.get_agent(), tools=tools, memory=chat_memory, callback_manager=callback_manager, @@ -101,6 +101,7 @@ class AgentManager: logging.error(f"Error while creating executor: {str(e)}") raise e + @staticmethod def create(toolsets: list[BaseToolSet]) -> "AgentManager": if not isinstance(toolsets, list): From 6b0da5eb8ed32c16920af5e1c1a285d9e753995a Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 08:59:50 -0400 Subject: [PATCH 71/98] revert back to old create_executor Former-commit-id: 62006f114949ceaddca8c25003bedf257eda207b --- swarms/agents/utils/AgentManager.py | 56 ++++++++++------------------- 1 file changed, 18 insertions(+), 38 deletions(-) diff --git a/swarms/agents/utils/AgentManager.py b/swarms/agents/utils/AgentManager.py index 389397d9..211b0d29 100644 --- a/swarms/agents/utils/AgentManager.py +++ b/swarms/agents/utils/AgentManager.py @@ -36,72 +36,52 @@ class AgentManager: self.memories[session] = self.create_memory() return self.memories[session] - def create_executor(self, session_id: str, task: Optional[Task] = None, openai_api_key: str = None) -> AgentExecutor: + def create_executor(self, session: str, execution: Optional[Task] = None, openai_api_key: str = None) -> AgentExecutor: try: - # Create an agent builder with the provided toolsets - agent_builder = AgentBuilder(self.toolsets) + builder = AgentBuilder(self.toolsets) + builder.build_parser() - # Setup the parser for the agent - agent_builder.build_parser() - - # Initialize an empty list for callbacks callbacks = [] - - # Create and setup an evaluation callback, then add it to the callbacks list - eval_callback = EvaluationCallbackHandler() - eval_callback.set_parser(agent_builder.get_parser()) + eval_callback = EVALCallbackHandler() + eval_callback.set_parser(builder.get_parser()) callbacks.append(eval_callback) - # If a task is provided, create and setup an execution tracing callback, then add it to the callbacks list - if task: - execution_trace_callback = ExecutionTracingCallbackHandler(task) - execution_trace_callback.set_parser(agent_builder.get_parser()) - callbacks.append(execution_trace_callback) + if execution: + execution_callback = ExecutionTracingCallbackHandler(execution) + execution_callback.set_parser(builder.get_parser()) + callbacks.append(execution_callback) - # Create a callback manager with the callbacks callback_manager = CallbackManager(callbacks) - # Setup the language model with the callback manager and OpenAI API key - agent_builder.build_llm(callback_manager, openai_api_key) - - # Setup the global tools for the agent - agent_builder.build_global_tools() - - # Get or create a memory for the session - chat_memory = self.get_or_create_memory(session_id) + builder.build_llm(callback_manager, openai_api_key) + + builder.build_global_tools() - # Create a list of tools by combining global tools and per session tools + memory: BaseChatMemory = self.get_or_create_memory(session) tools = [ - *agent_builder.get_global_tools(), + *builder.get_global_tools(), *ToolsFactory.create_per_session_tools( self.toolsets, - get_session=lambda: (session_id, self.executors[session_id]), + get_session=lambda: (session, self.executors[session]), ), ] - # Set the callback manager for each tool for tool in tools: tool.callback_manager = callback_manager - # Create an executor from the agent and tools executor = AgentExecutor.from_agent_and_tools( - agent=agent_builder.get_agent(), + agent=builder.get_agent(), tools=tools, - memory=chat_memory, + memory=memory, callback_manager=callback_manager, verbose=True, ) - - # Store the executor in the executors dictionary - self.executors[session_id] = executor - - # Return the executor + self.executors[session] = executor return executor except Exception as e: logging.error(f"Error while creating executor: {str(e)}") raise e - @staticmethod def create(toolsets: list[BaseToolSet]) -> "AgentManager": if not isinstance(toolsets, list): From c6e12a7862f6374ac5392bde91e88843ba6a2029 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 12:01:37 -0400 Subject: [PATCH 72/98] envs + string pass in build_llm Former-commit-id: 8adcad110fab29f7725d5a3ff8cf293fedfe9763 --- swarms/agents/utils/AgentBuilder.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/swarms/agents/utils/AgentBuilder.py b/swarms/agents/utils/AgentBuilder.py index ada152a9..cfbbf33f 100644 --- a/swarms/agents/utils/AgentBuilder.py +++ b/swarms/agents/utils/AgentBuilder.py @@ -23,7 +23,12 @@ class AgentBuilder: self.toolsets = toolsets def build_llm(self, callback_manager: BaseCallbackManager = None, openai_api_key: str = None): - self.llm = ChatOpenAI(openai_api_key=openai_api_key, temperature=0, callback_manager=callback_manager, verbose=True) + if openai_api_key is None: + openai_api_key = os.getenv('OPENAI_API_KEY') + if openai_api_key is None: + raise ValueError("OpenAI API key is missing. It should either be set as an environment variable or passed as a parameter.") + + self.llm = ChatOpenAI(openai_api_key=openai_api_key, temperature=0.5, callback_manager=callback_manager, verbose=True) def build_parser(self): self.parser = EvalOutputParser() From b8707bbf64fbcf5fe9ba9b729a135c159124195a Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 12:54:48 -0400 Subject: [PATCH 73/98] worker ultra example Former-commit-id: 51cdc4698526da6cd444c5b8dbc0a566c5d028f0 --- playground/worker_ultra.py | 22 +++++++++++++++++++--- swarms/agents/.DS_Store | Bin 0 -> 6148 bytes 2 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 swarms/agents/.DS_Store diff --git a/playground/worker_ultra.py b/playground/worker_ultra.py index 55d5492b..8817451d 100644 --- a/playground/worker_ultra.py +++ b/playground/worker_ultra.py @@ -1,5 +1,21 @@ +import os from swarms import WorkerUltra -objective = "What is the capital of the UK?" -result = WorkerUltra(objective) -print(result) # Prints: "The capital of the UK is London." \ No newline at end of file +api_key = os.getenv("OPENAI_API_KEY") + +# Define an objective +objective = """ +Please make a web GUI for using HTTP API server. +The name of it is Swarms. +You can check the server code at ./main.py. +The server is served on localhost:8000. +Users should be able to write text input as 'query' and url array as 'files', and check the response. +Users input form should be delivered in JSON format. +I want it to have neumorphism-style. Serve it on port 4500. + +""" + +node = WorkerUltra(objective, openai_api_key=api_key) + + +result = node.execute() \ No newline at end of file diff --git a/swarms/agents/.DS_Store b/swarms/agents/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..26c154e2727ff8c63d16b48d252a6395506fc4d3 GIT binary patch literal 6148 zcmeHKI|>3Z5S{S@f{mqRuHX%V=n3`$7J>+(;IH1wb9pr1e41sk(?WRzlb1~9CFB)5 zJ0haX+jb!`6OjqrP#!k)&GyZEHpqwq;W*=RZ_dZV>A36Vz6%(4EH}BzUJf0;?a-(I z6`%rCfC^B7Pb-iWb~63+!90%&P=TLUz`hR!ZdeoBK>u`L@D>0#Lf8#+?GNs z1|kB}paO%c*+Nm*NakF#1^;2XH*JmF@TI|YN6W1yE~EUX;QJt^{v&9Pq- U+d!uy?sOo3222+k75KISF9lB&>Hq)$ literal 0 HcmV?d00001 From eca7c59a01a2d0b074de7487fe700804a803f7ca Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 12:55:30 -0400 Subject: [PATCH 74/98] file path Former-commit-id: 044b78e0ade7673b5dc46b31863c988283c571a5 --- playground/worker_ultra.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/playground/worker_ultra.py b/playground/worker_ultra.py index 8817451d..621400a3 100644 --- a/playground/worker_ultra.py +++ b/playground/worker_ultra.py @@ -1,5 +1,5 @@ import os -from swarms import WorkerUltra +from swarms.agents.workers.WorkerUltraNode import WorkerUltra api_key = os.getenv("OPENAI_API_KEY") From 51611ca07271c94e1c56d1a2b5d11dc0ab2c9175 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 12:56:41 -0400 Subject: [PATCH 75/98] clean up Former-commit-id: bf1799f01f3f3b5c25307d4280993e788ace92bd --- playground/ultranode_example.py | 4 ++-- playground/worker_ultra.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/playground/ultranode_example.py b/playground/ultranode_example.py index 24935fb5..a3f62c8a 100644 --- a/playground/ultranode_example.py +++ b/playground/ultranode_example.py @@ -1,4 +1,4 @@ -from swarms import UltraNode +from swarms import WorkerUltraUltraNode # Define an objective objective = """ @@ -12,6 +12,6 @@ I want it to have neumorphism-style. Serve it on port 4500. """ -node = UltraNode(objective) +node = WorkerUltraUltraNode(objective) result = node.execute() \ No newline at end of file diff --git a/playground/worker_ultra.py b/playground/worker_ultra.py index 621400a3..2c9fe09c 100644 --- a/playground/worker_ultra.py +++ b/playground/worker_ultra.py @@ -1,5 +1,5 @@ import os -from swarms.agents.workers.WorkerUltraNode import WorkerUltra +from swarms.swarms import WorkerUltra api_key = os.getenv("OPENAI_API_KEY") From a5cabf0c6a29f5d37e36a34d28eab6caf86b5569 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 12:58:27 -0400 Subject: [PATCH 76/98] file import stuff in swarms Former-commit-id: 138015bc7799554fc5b9b610506878ba8c7a9d1e --- swarms/swarms.py | 1 + 1 file changed, 1 insertion(+) diff --git a/swarms/swarms.py b/swarms/swarms.py index f48f78cd..050616b7 100644 --- a/swarms/swarms.py +++ b/swarms/swarms.py @@ -1,6 +1,7 @@ from swarms.tools.agent_tools import * from swarms.agents.workers.WorkerNode import WorkerNode, worker_node from swarms.agents.boss.BossNode import BossNode +from swarms.agents.workers.WorkerUltraNode import WorkerUltra import logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') From 19e8d8397c9018832dec8244e3a6d6221e49476a Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 12:59:15 -0400 Subject: [PATCH 77/98] relative imports Former-commit-id: bb6f21f66ca7f60f33a56708d950fbe520e91b2f --- playground/worker_ultra.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/playground/worker_ultra.py b/playground/worker_ultra.py index 2c9fe09c..6c55bc63 100644 --- a/playground/worker_ultra.py +++ b/playground/worker_ultra.py @@ -1,5 +1,6 @@ import os -from swarms.swarms import WorkerUltra +# from swarms.swarms import WorkerUltra +from ..swarms.swarms import WorkerUltra api_key = os.getenv("OPENAI_API_KEY") From 3494697e9104a05951e246a0ff5a4b733e0d28a7 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 12:59:55 -0400 Subject: [PATCH 78/98] moving worker ultra Former-commit-id: 5fa9022bd06c569f9866f87c1d1c761106e26b15 --- playground/worker_ultra.py => worker_ultra.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) rename playground/worker_ultra.py => worker_ultra.py (83%) diff --git a/playground/worker_ultra.py b/worker_ultra.py similarity index 83% rename from playground/worker_ultra.py rename to worker_ultra.py index 6c55bc63..2c9fe09c 100644 --- a/playground/worker_ultra.py +++ b/worker_ultra.py @@ -1,6 +1,5 @@ import os -# from swarms.swarms import WorkerUltra -from ..swarms.swarms import WorkerUltra +from swarms.swarms import WorkerUltra api_key = os.getenv("OPENAI_API_KEY") From 31429ca748b9c485ba43155e2f5bab70c2c19235 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 13:13:57 -0400 Subject: [PATCH 79/98] env logic in agent builder Former-commit-id: 04b375e7d5055565cc199d560fa871a9f3fb98c1 --- swarms/agents/utils/AgentBuilder.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/swarms/agents/utils/AgentBuilder.py b/swarms/agents/utils/AgentBuilder.py index cfbbf33f..eeb7eec8 100644 --- a/swarms/agents/utils/AgentBuilder.py +++ b/swarms/agents/utils/AgentBuilder.py @@ -16,11 +16,17 @@ from .EvalOutputParser import EvalOutputParser class AgentBuilder: - def __init__(self, toolsets: list[BaseToolSet] = []): + def __init__(self, toolsets: list[BaseToolSet] = [], openai_api_key: str = None, serpapi_api_key: str = None, bing_search_url: str = None, bing_subscription_key: str = None): self.llm: BaseChatModel = None self.parser: BaseOutputParser = None self.global_tools: list = None self.toolsets = toolsets + self.openai_api_key = openai_api_key or os.getenv("OPENAI_API_KEY") + self.serpapi_api_key = serpapi_api_key or os.getenv('SERPAPI_API_KEY') + self.bing_search_url = bing_search_url or os.getenv('BING_SEARCH_URL') + self.bing_subscription_key = bing_subscription_key or os.getenv('BING_SUBSCRIPTION_KEY') + if not self.openai_api_key: + raise ValueError("OpenAI key is missing, it should either be set as an environment variable or passed as a parameter") def build_llm(self, callback_manager: BaseCallbackManager = None, openai_api_key: str = None): if openai_api_key is None: @@ -39,9 +45,11 @@ class AgentBuilder: toolnames = ["wikipedia"] - if os.environ["SERPAPI_API_KEY"]: + + if self.serpapi_api_key: toolnames.append("serpapi") - if os.environ["BING_SEARCH_URL"] and os.environ["BING_SUBSCRIPTION_KEY"]: + + if self.bing_search_url and self.bing_subscription_key: toolnames.append("bing-search") self.global_tools = [ From 6db796e885de36aa68e5b66cddc220695a8d9e54 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 13:25:37 -0400 Subject: [PATCH 80/98] clean up with agents abstract class Former-commit-id: dbe2e82584bfe6d2dc493e05d2fe6cbe0c269364 --- swarms/agents/utils/Agent.py | 617 ++++++++++++++++++ swarms/agents/utils/AgentBuilder.py | 4 +- .../agents/utils/ConversationalChatAgent.py | 2 +- 3 files changed, 620 insertions(+), 3 deletions(-) create mode 100644 swarms/agents/utils/Agent.py diff --git a/swarms/agents/utils/Agent.py b/swarms/agents/utils/Agent.py new file mode 100644 index 00000000..e6e6871a --- /dev/null +++ b/swarms/agents/utils/Agent.py @@ -0,0 +1,617 @@ +"""Chain that takes in an input and produces an action and action input.""" +from __future__ import annotations + +import asyncio +import json +import logging +import time +from abc import abstractmethod +from pathlib import Path +from typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union + +import yaml +from pydantic import BaseModel, root_validator + +from langchain.agents.agent_types import AgentType +from langchain.agents.tools import InvalidTool +from langchain.callbacks.base import BaseCallbackManager +from langchain.callbacks.manager import ( + AsyncCallbackManagerForChainRun, + AsyncCallbackManagerForToolRun, + CallbackManagerForChainRun, + CallbackManagerForToolRun, + Callbacks, +) +from langchain.chains.base import Chain +from langchain.chains.llm import LLMChain +from langchain.input import get_color_mapping +from langchain.prompts.few_shot import FewShotPromptTemplate +from langchain.prompts.prompt import PromptTemplate +from langchain.schema import ( + AgentAction, + AgentFinish, + BaseOutputParser, + BasePromptTemplate, + OutputParserException, +) +from langchain.schema.language_model import BaseLanguageModel +from langchain.schema.messages import BaseMessage +from langchain.tools.base import BaseTool +from langchain.utilities.asyncio import asyncio_timeout + +logger = logging.getLogger(__name__) + + +class BaseSingleActionAgent(BaseModel): + """Base Agent class.""" + + @property + def return_values(self) -> List[str]: + """Return values of the agent.""" + return ["output"] + + def get_allowed_tools(self) -> Optional[List[str]]: + return None + + @abstractmethod + def plan( + self, + intermediate_steps: List[Tuple[AgentAction, str]], + callbacks: Callbacks = None, + **kwargs: Any, + ) -> Union[AgentAction, AgentFinish]: + """Given input, decided what to do. + + Args: + intermediate_steps: Steps the LLM has taken to date, + along with observations + callbacks: Callbacks to run. + **kwargs: User inputs. + + Returns: + Action specifying what tool to use. + """ + + @abstractmethod + async def aplan( + self, + intermediate_steps: List[Tuple[AgentAction, str]], + callbacks: Callbacks = None, + **kwargs: Any, + ) -> Union[AgentAction, AgentFinish]: + """Given input, decided what to do. + + Args: + intermediate_steps: Steps the LLM has taken to date, + along with observations + callbacks: Callbacks to run. + **kwargs: User inputs. + + Returns: + Action specifying what tool to use. + """ + + @property + @abstractmethod + def input_keys(self) -> List[str]: + """Return the input keys. + + :meta private: + """ + + def return_stopped_response( + self, + early_stopping_method: str, + intermediate_steps: List[Tuple[AgentAction, str]], + **kwargs: Any, + ) -> AgentFinish: + """Return response when agent has been stopped due to max iterations.""" + if early_stopping_method == "force": + # `force` just returns a constant string + return AgentFinish( + {"output": "Agent stopped due to iteration limit or time limit."}, "" + ) + else: + raise ValueError( + f"Got unsupported early_stopping_method `{early_stopping_method}`" + ) + + @classmethod + def from_llm_and_tools( + cls, + llm: BaseLanguageModel, + tools: Sequence[BaseTool], + callback_manager: Optional[BaseCallbackManager] = None, + **kwargs: Any, + ) -> BaseSingleActionAgent: + raise NotImplementedError + + @property + def _agent_type(self) -> str: + """Return Identifier of agent type.""" + raise NotImplementedError + + def dict(self, **kwargs: Any) -> Dict: + """Return dictionary representation of agent.""" + _dict = super().dict() + _type = self._agent_type + if isinstance(_type, AgentType): + _dict["_type"] = str(_type.value) + else: + _dict["_type"] = _type + return _dict + + def save(self, file_path: Union[Path, str]) -> None: + """Save the agent. + + Args: + file_path: Path to file to save the agent to. + + Example: + .. code-block:: python + + # If working with agent executor + agent.agent.save(file_path="path/agent.yaml") + """ + # Convert file to Path object. + if isinstance(file_path, str): + save_path = Path(file_path) + else: + save_path = file_path + + directory_path = save_path.parent + directory_path.mkdir(parents=True, exist_ok=True) + + # Fetch dictionary to save + agent_dict = self.dict() + + if save_path.suffix == ".json": + with open(file_path, "w") as f: + json.dump(agent_dict, f, indent=4) + elif save_path.suffix == ".yaml": + with open(file_path, "w") as f: + yaml.dump(agent_dict, f, default_flow_style=False) + else: + raise ValueError(f"{save_path} must be json or yaml") + + def tool_run_logging_kwargs(self) -> Dict: + return {} + + +class BaseMultiActionAgent(BaseModel): + """Base Agent class.""" + + @property + def return_values(self) -> List[str]: + """Return values of the agent.""" + return ["output"] + + def get_allowed_tools(self) -> Optional[List[str]]: + return None + + @abstractmethod + def plan( + self, + intermediate_steps: List[Tuple[AgentAction, str]], + callbacks: Callbacks = None, + **kwargs: Any, + ) -> Union[List[AgentAction], AgentFinish]: + """Given input, decided what to do. + + Args: + intermediate_steps: Steps the LLM has taken to date, + along with observations + callbacks: Callbacks to run. + **kwargs: User inputs. + + Returns: + Actions specifying what tool to use. + """ + + @abstractmethod + async def aplan( + self, + intermediate_steps: List[Tuple[AgentAction, str]], + callbacks: Callbacks = None, + **kwargs: Any, + ) -> Union[List[AgentAction], AgentFinish]: + """Given input, decided what to do. + + Args: + intermediate_steps: Steps the LLM has taken to date, + along with observations + callbacks: Callbacks to run. + **kwargs: User inputs. + + Returns: + Actions specifying what tool to use. + """ + + @property + @abstractmethod + def input_keys(self) -> List[str]: + """Return the input keys. + + :meta private: + """ + + def return_stopped_response( + self, + early_stopping_method: str, + intermediate_steps: List[Tuple[AgentAction, str]], + **kwargs: Any, + ) -> AgentFinish: + """Return response when agent has been stopped due to max iterations.""" + if early_stopping_method == "force": + # `force` just returns a constant string + return AgentFinish({"output": "Agent stopped due to max iterations."}, "") + else: + raise ValueError( + f"Got unsupported early_stopping_method `{early_stopping_method}`" + ) + + @property + def _agent_type(self) -> str: + """Return Identifier of agent type.""" + raise NotImplementedError + + def dict(self, **kwargs: Any) -> Dict: + """Return dictionary representation of agent.""" + _dict = super().dict() + _dict["_type"] = str(self._agent_type) + return _dict + + def save(self, file_path: Union[Path, str]) -> None: + """Save the agent. + + Args: + file_path: Path to file to save the agent to. + + Example: + .. code-block:: python + + # If working with agent executor + agent.agent.save(file_path="path/agent.yaml") + """ + # Convert file to Path object. + if isinstance(file_path, str): + save_path = Path(file_path) + else: + save_path = file_path + + directory_path = save_path.parent + directory_path.mkdir(parents=True, exist_ok=True) + + # Fetch dictionary to save + agent_dict = self.dict() + + if save_path.suffix == ".json": + with open(file_path, "w") as f: + json.dump(agent_dict, f, indent=4) + elif save_path.suffix == ".yaml": + with open(file_path, "w") as f: + yaml.dump(agent_dict, f, default_flow_style=False) + else: + raise ValueError(f"{save_path} must be json or yaml") + + def tool_run_logging_kwargs(self) -> Dict: + return {} + + +class AgentOutputParser(BaseOutputParser): + @abstractmethod + def parse(self, text: str) -> Union[AgentAction, AgentFinish]: + """Parse text into agent action/finish.""" + + +class LLMSingleActionAgent(BaseSingleActionAgent): + llm_chain: LLMChain + output_parser: AgentOutputParser + stop: List[str] + + @property + def input_keys(self) -> List[str]: + return list(set(self.llm_chain.input_keys) - {"intermediate_steps"}) + + def dict(self, **kwargs: Any) -> Dict: + """Return dictionary representation of agent.""" + _dict = super().dict() + del _dict["output_parser"] + return _dict + + def plan( + self, + intermediate_steps: List[Tuple[AgentAction, str]], + callbacks: Callbacks = None, + **kwargs: Any, + ) -> Union[AgentAction, AgentFinish]: + """Given input, decided what to do. + + Args: + intermediate_steps: Steps the LLM has taken to date, + along with observations + callbacks: Callbacks to run. + **kwargs: User inputs. + + Returns: + Action specifying what tool to use. + """ + output = self.llm_chain.run( + intermediate_steps=intermediate_steps, + stop=self.stop, + callbacks=callbacks, + **kwargs, + ) + return self.output_parser.parse(output) + + async def aplan( + self, + intermediate_steps: List[Tuple[AgentAction, str]], + callbacks: Callbacks = None, + **kwargs: Any, + ) -> Union[AgentAction, AgentFinish]: + """Given input, decided what to do. + + Args: + intermediate_steps: Steps the LLM has taken to date, + along with observations + callbacks: Callbacks to run. + **kwargs: User inputs. + + Returns: + Action specifying what tool to use. + """ + output = await self.llm_chain.arun( + intermediate_steps=intermediate_steps, + stop=self.stop, + callbacks=callbacks, + **kwargs, + ) + return self.output_parser.parse(output) + + def tool_run_logging_kwargs(self) -> Dict: + return { + "llm_prefix": "", + "observation_prefix": "" if len(self.stop) == 0 else self.stop[0], + } + + +class Agent(BaseSingleActionAgent): + """Class responsible for calling the language model and deciding the action. + + This is driven by an LLMChain. The prompt in the LLMChain MUST include + a variable called "agent_scratchpad" where the agent can put its + intermediary work. + """ + + llm_chain: LLMChain + output_parser: AgentOutputParser + allowed_tools: Optional[List[str]] = None + + def dict(self, **kwargs: Any) -> Dict: + """Return dictionary representation of agent.""" + _dict = super().dict() + del _dict["output_parser"] + return _dict + + def get_allowed_tools(self) -> Optional[List[str]]: + return self.allowed_tools + + @property + def return_values(self) -> List[str]: + return ["output"] + + def _fix_text(self, text: str) -> str: + """Fix the text.""" + raise ValueError("fix_text not implemented for this agent.") + + @property + def _stop(self) -> List[str]: + return [ + f"\n{self.observation_prefix.rstrip()}", + f"\n\t{self.observation_prefix.rstrip()}", + ] + + def _construct_scratchpad( + self, intermediate_steps: List[Tuple[AgentAction, str]] + ) -> Union[str, List[BaseMessage]]: + """Construct the scratchpad that lets the agent continue its thought process.""" + thoughts = "" + for action, observation in intermediate_steps: + thoughts += action.log + thoughts += f"\n{self.observation_prefix}{observation}\n{self.llm_prefix}" + return thoughts + + def plan( + self, + intermediate_steps: List[Tuple[AgentAction, str]], + callbacks: Callbacks = None, + **kwargs: Any, + ) -> Union[AgentAction, AgentFinish]: + """Given input, decided what to do. + + Args: + intermediate_steps: Steps the LLM has taken to date, + along with observations + callbacks: Callbacks to run. + **kwargs: User inputs. + + Returns: + Action specifying what tool to use. + """ + full_inputs = self.get_full_inputs(intermediate_steps, **kwargs) + full_output = self.llm_chain.predict(callbacks=callbacks, **full_inputs) + return self.output_parser.parse(full_output) + + async def aplan( + self, + intermediate_steps: List[Tuple[AgentAction, str]], + callbacks: Callbacks = None, + **kwargs: Any, + ) -> Union[AgentAction, AgentFinish]: + """Given input, decided what to do. + + Args: + intermediate_steps: Steps the LLM has taken to date, + along with observations + callbacks: Callbacks to run. + **kwargs: User inputs. + + Returns: + Action specifying what tool to use. + """ + full_inputs = self.get_full_inputs(intermediate_steps, **kwargs) + full_output = await self.llm_chain.apredict(callbacks=callbacks, **full_inputs) + return self.output_parser.parse(full_output) + + def get_full_inputs( + self, intermediate_steps: List[Tuple[AgentAction, str]], **kwargs: Any + ) -> Dict[str, Any]: + """Create the full inputs for the LLMChain from intermediate steps.""" + thoughts = self._construct_scratchpad(intermediate_steps) + new_inputs = {"agent_scratchpad": thoughts, "stop": self._stop} + full_inputs = {**kwargs, **new_inputs} + return full_inputs + + @property + def input_keys(self) -> List[str]: + """Return the input keys. + + :meta private: + """ + return list(set(self.llm_chain.input_keys) - {"agent_scratchpad"}) + + @root_validator() + def validate_prompt(cls, values: Dict) -> Dict: + """Validate that prompt matches format.""" + prompt = values["llm_chain"].prompt + if "agent_scratchpad" not in prompt.input_variables: + logger.warning( + "`agent_scratchpad` should be a variable in prompt.input_variables." + " Did not find it, so adding it at the end." + ) + prompt.input_variables.append("agent_scratchpad") + if isinstance(prompt, PromptTemplate): + prompt.template += "\n{agent_scratchpad}" + elif isinstance(prompt, FewShotPromptTemplate): + prompt.suffix += "\n{agent_scratchpad}" + else: + raise ValueError(f"Got unexpected prompt type {type(prompt)}") + return values + + @property + @abstractmethod + def observation_prefix(self) -> str: + """Prefix to append the observation with.""" + + @property + @abstractmethod + def llm_prefix(self) -> str: + """Prefix to append the LLM call with.""" + + @classmethod + @abstractmethod + def create_prompt(cls, tools: Sequence[BaseTool]) -> BasePromptTemplate: + """Create a prompt for this class.""" + + @classmethod + def _validate_tools(cls, tools: Sequence[BaseTool]) -> None: + """Validate that appropriate tools are passed in.""" + pass + + @classmethod + @abstractmethod + def _get_default_output_parser(cls, **kwargs: Any) -> AgentOutputParser: + """Get default output parser for this class.""" + + @classmethod + def from_llm_and_tools( + cls, + llm: BaseLanguageModel, + tools: Sequence[BaseTool], + callback_manager: Optional[BaseCallbackManager] = None, + output_parser: Optional[AgentOutputParser] = None, + **kwargs: Any, + ) -> Agent: + """Construct an agent from an LLM and tools.""" + cls._validate_tools(tools) + llm_chain = LLMChain( + llm=llm, + prompt=cls.create_prompt(tools), + callback_manager=callback_manager, + ) + tool_names = [tool.name for tool in tools] + _output_parser = output_parser or cls._get_default_output_parser() + return cls( + llm_chain=llm_chain, + allowed_tools=tool_names, + output_parser=_output_parser, + **kwargs, + ) + + def return_stopped_response( + self, + early_stopping_method: str, + intermediate_steps: List[Tuple[AgentAction, str]], + **kwargs: Any, + ) -> AgentFinish: + """Return response when agent has been stopped due to max iterations.""" + if early_stopping_method == "force": + # `force` just returns a constant string + return AgentFinish( + {"output": "Agent stopped due to iteration limit or time limit."}, "" + ) + elif early_stopping_method == "generate": + # Generate does one final forward pass + thoughts = "" + for action, observation in intermediate_steps: + thoughts += action.log + thoughts += ( + f"\n{self.observation_prefix}{observation}\n{self.llm_prefix}" + ) + # Adding to the previous steps, we now tell the LLM to make a final pred + thoughts += ( + "\n\nI now need to return a final answer based on the previous steps:" + ) + new_inputs = {"agent_scratchpad": thoughts, "stop": self._stop} + full_inputs = {**kwargs, **new_inputs} + full_output = self.llm_chain.predict(**full_inputs) + # We try to extract a final answer + parsed_output = self.output_parser.parse(full_output) + if isinstance(parsed_output, AgentFinish): + # If we can extract, we send the correct stuff + return parsed_output + else: + # If we can extract, but the tool is not the final tool, + # we just return the full output + return AgentFinish({"output": full_output}, full_output) + else: + raise ValueError( + "early_stopping_method should be one of `force` or `generate`, " + f"got {early_stopping_method}" + ) + + def tool_run_logging_kwargs(self) -> Dict: + return { + "llm_prefix": self.llm_prefix, + "observation_prefix": self.observation_prefix, + } + + +class ExceptionTool(BaseTool): + name = "_Exception" + description = "Exception tool" + + def _run( + self, + query: str, + run_manager: Optional[CallbackManagerForToolRun] = None, + ) -> str: + return query + + async def _arun( + self, + query: str, + run_manager: Optional[AsyncCallbackManagerForToolRun] = None, + ) -> str: + return query diff --git a/swarms/agents/utils/AgentBuilder.py b/swarms/agents/utils/AgentBuilder.py index eeb7eec8..fb8ef625 100644 --- a/swarms/agents/utils/AgentBuilder.py +++ b/swarms/agents/utils/AgentBuilder.py @@ -87,8 +87,8 @@ class AgentBuilder: self.toolsets ), # for names and descriptions ], - system_message=EVAL_PREFIX.format(bot_name=os.environ["BOT_NAME"]), - human_message=EVAL_SUFFIX.format(bot_name=os.environ["BOT_NAME"]), + system_message=EVAL_PREFIX.format(bot_name=os.environ["BOT_NAME"] or 'WorkerUltraNode'), + human_message=EVAL_SUFFIX.format(bot_name=os.environ["BOT_NAME"] or 'WorkerUltraNode'), output_parser=self.parser, max_iterations=30, ) \ No newline at end of file diff --git a/swarms/agents/utils/ConversationalChatAgent.py b/swarms/agents/utils/ConversationalChatAgent.py index b95c49ea..68d9a81c 100644 --- a/swarms/agents/utils/ConversationalChatAgent.py +++ b/swarms/agents/utils/ConversationalChatAgent.py @@ -1,7 +1,7 @@ from typing import Any, List, Optional, Sequence, Tuple import logging -from langchain.agents.agent import Agent +from swarms.agents.utils.Agent import Agent from langchain.callbacks.base import BaseCallbackManager from langchain.chains import LLMChain from langchain.schema import BaseOutputParser From e0cd68e6aaf32b9ac2915ddc3f9d949e76db3ebb Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 13:26:51 -0400 Subject: [PATCH 81/98] no abstract class Former-commit-id: 7aa89f0ba6da7de4e60fbcc48e2d28bb053f08a5 --- swarms/agents/utils/ConversationalChatAgent.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/swarms/agents/utils/ConversationalChatAgent.py b/swarms/agents/utils/ConversationalChatAgent.py index 68d9a81c..93a9abc6 100644 --- a/swarms/agents/utils/ConversationalChatAgent.py +++ b/swarms/agents/utils/ConversationalChatAgent.py @@ -20,12 +20,11 @@ from langchain.schema import ( HumanMessage, ) from langchain.tools.base import BaseTool - from swarms.prompts.prompts import EVAL_TOOL_RESPONSE logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') -class ConversationalChatAgent(Agent): +class ConversationalChatAgent: """An agent designed to hold a conversation in addition to using tools.""" output_parser: BaseOutputParser From eb595dccf31d581768d8d4e6f3e2e55f988bb7f1 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 13:28:29 -0400 Subject: [PATCH 82/98] converational object Former-commit-id: 608ad3c26aba48b93a83d1855d6b6c5da485e157 --- swarms/agents/utils/ConversationalChatAgent.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/swarms/agents/utils/ConversationalChatAgent.py b/swarms/agents/utils/ConversationalChatAgent.py index 93a9abc6..03d1919a 100644 --- a/swarms/agents/utils/ConversationalChatAgent.py +++ b/swarms/agents/utils/ConversationalChatAgent.py @@ -24,7 +24,7 @@ from swarms.prompts.prompts import EVAL_TOOL_RESPONSE logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') -class ConversationalChatAgent: +class ConversationalChatAgent(Agent): """An agent designed to hold a conversation in addition to using tools.""" output_parser: BaseOutputParser From 03a1331cf7d5b5a5543520b4d433fab4abbfc7e4 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 13:31:49 -0400 Subject: [PATCH 83/98] chat agent abstract class Former-commit-id: 1d36cd9c45dd5875458a3e4d01e846cb6b4a687d --- swarms/agents/utils/AgentBuilder.py | 4 ++-- swarms/agents/utils/ConversationalChatAgent.py | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/swarms/agents/utils/AgentBuilder.py b/swarms/agents/utils/AgentBuilder.py index fb8ef625..cce4c3b4 100644 --- a/swarms/agents/utils/AgentBuilder.py +++ b/swarms/agents/utils/AgentBuilder.py @@ -9,7 +9,7 @@ from langchain.chat_models.base import BaseChatModel from langchain.schema import BaseOutputParser from langchain.callbacks.base import BaseCallbackManager -from .ConversationalChatAgent import ConversationalChatAgent +from .ConversationalChatAgent import ChatAgent # from .ChatOpenAI import ChatOpenAI from langchain.chat_models import ChatOpenAI from .EvalOutputParser import EvalOutputParser @@ -79,7 +79,7 @@ class AgentBuilder: if self.global_tools is None: raise ValueError("Global tools must be initialized before agent") - return ConversationalChatAgent.from_llm_and_tools( + return ChatAgent.from_llm_and_tools( llm=self.llm, tools=[ *self.global_tools, diff --git a/swarms/agents/utils/ConversationalChatAgent.py b/swarms/agents/utils/ConversationalChatAgent.py index 03d1919a..1e2b96ac 100644 --- a/swarms/agents/utils/ConversationalChatAgent.py +++ b/swarms/agents/utils/ConversationalChatAgent.py @@ -140,4 +140,9 @@ class ConversationalChatAgent(Agent): ) except Exception as e: logging.error(f"Error while creating agent from LLM and tools: {str(e)}") - raise e \ No newline at end of file + raise e + + +class ChatAgent(ConversationalChatAgent): + def _get_default_output_parser(self): + """Get default output parser for this class.""" From 5c5a12fd8c058d6fef5a38bd13b1c4d9bad57ad4 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 13:40:41 -0400 Subject: [PATCH 84/98] output parser Former-commit-id: 058550f04886f01fbd7650a5b29e5e96c2a9134c --- swarms/agents/utils/ConversationalChatAgent.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/swarms/agents/utils/ConversationalChatAgent.py b/swarms/agents/utils/ConversationalChatAgent.py index 1e2b96ac..9dbd886e 100644 --- a/swarms/agents/utils/ConversationalChatAgent.py +++ b/swarms/agents/utils/ConversationalChatAgent.py @@ -20,8 +20,16 @@ from langchain.schema import ( HumanMessage, ) from langchain.tools.base import BaseTool + + +from langchain.agents.agent import AgentOutputParser +from langchain.schema import AgentAction + + from swarms.prompts.prompts import EVAL_TOOL_RESPONSE + + logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') class ConversationalChatAgent(Agent): @@ -142,7 +150,12 @@ class ConversationalChatAgent(Agent): logging.error(f"Error while creating agent from LLM and tools: {str(e)}") raise e +class OutputParser(AgentOutputParser): + def parse(self, full_output: str) -> AgentAction: + return AgentAction(action="chat", details={'message': full_output}) + class ChatAgent(ConversationalChatAgent): def _get_default_output_parser(self): """Get default output parser for this class.""" + return OutputParser() From 1ef570f4c5d79dfe6e59fe4d735a511bf15bacee Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 13:41:32 -0400 Subject: [PATCH 85/98] back to importing agent Former-commit-id: af8aa0fc9211b6c93c6fe7a46038773774f3d1c7 --- swarms/agents/utils/AgentBuilder.py | 4 ++-- swarms/agents/utils/ConversationalChatAgent.py | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/swarms/agents/utils/AgentBuilder.py b/swarms/agents/utils/AgentBuilder.py index cce4c3b4..fb8ef625 100644 --- a/swarms/agents/utils/AgentBuilder.py +++ b/swarms/agents/utils/AgentBuilder.py @@ -9,7 +9,7 @@ from langchain.chat_models.base import BaseChatModel from langchain.schema import BaseOutputParser from langchain.callbacks.base import BaseCallbackManager -from .ConversationalChatAgent import ChatAgent +from .ConversationalChatAgent import ConversationalChatAgent # from .ChatOpenAI import ChatOpenAI from langchain.chat_models import ChatOpenAI from .EvalOutputParser import EvalOutputParser @@ -79,7 +79,7 @@ class AgentBuilder: if self.global_tools is None: raise ValueError("Global tools must be initialized before agent") - return ChatAgent.from_llm_and_tools( + return ConversationalChatAgent.from_llm_and_tools( llm=self.llm, tools=[ *self.global_tools, diff --git a/swarms/agents/utils/ConversationalChatAgent.py b/swarms/agents/utils/ConversationalChatAgent.py index 9dbd886e..c62b74ec 100644 --- a/swarms/agents/utils/ConversationalChatAgent.py +++ b/swarms/agents/utils/ConversationalChatAgent.py @@ -150,12 +150,12 @@ class ConversationalChatAgent(Agent): logging.error(f"Error while creating agent from LLM and tools: {str(e)}") raise e -class OutputParser(AgentOutputParser): - def parse(self, full_output: str) -> AgentAction: - return AgentAction(action="chat", details={'message': full_output}) +# class OutputParser(AgentOutputParser): +# def parse(self, full_output: str) -> AgentAction: +# return AgentAction(action="chat", details={'message': full_output}) -class ChatAgent(ConversationalChatAgent): - def _get_default_output_parser(self): - """Get default output parser for this class.""" - return OutputParser() +# class ChatAgent(ConversationalChatAgent): +# def _get_default_output_parser(self): +# """Get default output parser for this class.""" +# return OutputParser() From be9acdcd44c6780e017842950fbc87f526079fa3 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 13:44:38 -0400 Subject: [PATCH 86/98] external agent reference in conversationalchatagaent Former-commit-id: 72314194ba89177d09f0fa9841bf5abbf794a96e --- swarms/agents/utils/ConversationalChatAgent.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/swarms/agents/utils/ConversationalChatAgent.py b/swarms/agents/utils/ConversationalChatAgent.py index c62b74ec..56a62085 100644 --- a/swarms/agents/utils/ConversationalChatAgent.py +++ b/swarms/agents/utils/ConversationalChatAgent.py @@ -32,7 +32,7 @@ from swarms.prompts.prompts import EVAL_TOOL_RESPONSE logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') -class ConversationalChatAgent(Agent): +class ConversationalChatAgent: """An agent designed to hold a conversation in addition to using tools.""" output_parser: BaseOutputParser @@ -53,7 +53,7 @@ class ConversationalChatAgent(Agent): @classmethod def create_prompt( - cls, + Agent, tools: Sequence[BaseTool], system_message: str, human_message: str, @@ -114,7 +114,7 @@ class ConversationalChatAgent(Agent): @classmethod def from_llm_and_tools( - cls, + Agent, llm: BaseLanguageModel, tools: Sequence[BaseTool], system_message: str, @@ -125,8 +125,8 @@ class ConversationalChatAgent(Agent): **kwargs: Any, ) -> Agent: """Construct an agent from an LLM and tools.""" - cls._validate_tools(tools) - prompt = cls.create_prompt( + Agent._validate_tools(tools) + prompt = Agent.create_prompt( tools, system_message=system_message, human_message=human_message, @@ -140,7 +140,7 @@ class ConversationalChatAgent(Agent): ) tool_names = [tool.name for tool in tools] try: - return cls( + return Agent( llm_chain=llm_chain, allowed_tools=tool_names, output_parser=output_parser, From 97d2695e595b4f9e0554956ae2c562e87e165d97 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 13:48:06 -0400 Subject: [PATCH 87/98] clean up with agent Former-commit-id: 801cf5a73dd26522cf6517b8fcf103e27a118d27 --- .../agents/utils/ConversationalChatAgent.py | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/swarms/agents/utils/ConversationalChatAgent.py b/swarms/agents/utils/ConversationalChatAgent.py index 56a62085..778e38f5 100644 --- a/swarms/agents/utils/ConversationalChatAgent.py +++ b/swarms/agents/utils/ConversationalChatAgent.py @@ -32,7 +32,7 @@ from swarms.prompts.prompts import EVAL_TOOL_RESPONSE logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') -class ConversationalChatAgent: +class ConversationalChatAgent(Agent): """An agent designed to hold a conversation in addition to using tools.""" output_parser: BaseOutputParser @@ -40,7 +40,11 @@ class ConversationalChatAgent: @property def _agent_type(self) -> str: raise NotImplementedError + + def _get_default_output_parser(cls, **kwargs: Any) -> AgentOutputParser: + """Get default output parser for this class.""" + @property def observation_prefix(self) -> str: """Prefix to append the observation with.""" @@ -53,7 +57,7 @@ class ConversationalChatAgent: @classmethod def create_prompt( - Agent, + cls, tools: Sequence[BaseTool], system_message: str, human_message: str, @@ -114,7 +118,7 @@ class ConversationalChatAgent: @classmethod def from_llm_and_tools( - Agent, + cls, llm: BaseLanguageModel, tools: Sequence[BaseTool], system_message: str, @@ -125,8 +129,8 @@ class ConversationalChatAgent: **kwargs: Any, ) -> Agent: """Construct an agent from an LLM and tools.""" - Agent._validate_tools(tools) - prompt = Agent.create_prompt( + cls._validate_tools(tools) + prompt = cls.create_prompt( tools, system_message=system_message, human_message=human_message, @@ -140,7 +144,7 @@ class ConversationalChatAgent: ) tool_names = [tool.name for tool in tools] try: - return Agent( + return cls( llm_chain=llm_chain, allowed_tools=tool_names, output_parser=output_parser, @@ -149,13 +153,4 @@ class ConversationalChatAgent: except Exception as e: logging.error(f"Error while creating agent from LLM and tools: {str(e)}") raise e - -# class OutputParser(AgentOutputParser): -# def parse(self, full_output: str) -> AgentAction: -# return AgentAction(action="chat", details={'message': full_output}) - - -# class ChatAgent(ConversationalChatAgent): -# def _get_default_output_parser(self): -# """Get default output parser for this class.""" -# return OutputParser() + \ No newline at end of file From cfce7d7eff2ff306323761f673c542fdabda5738 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 13:51:28 -0400 Subject: [PATCH 88/98] check for agent Former-commit-id: 63da782f472bca9aae0fe3a7f7f9a372e1bb7800 --- swarms/agents/utils/AgentManager.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/swarms/agents/utils/AgentManager.py b/swarms/agents/utils/AgentManager.py index 211b0d29..7b3fb35d 100644 --- a/swarms/agents/utils/AgentManager.py +++ b/swarms/agents/utils/AgentManager.py @@ -41,6 +41,10 @@ class AgentManager: builder = AgentBuilder(self.toolsets) builder.build_parser() + agent = builder.get_agent() + if not agent: + raise ValueError("Agent not created") + callbacks = [] eval_callback = EVALCallbackHandler() eval_callback.set_parser(builder.get_parser()) @@ -54,7 +58,7 @@ class AgentManager: callback_manager = CallbackManager(callbacks) builder.build_llm(callback_manager, openai_api_key) - + builder.build_global_tools() memory: BaseChatMemory = self.get_or_create_memory(session) @@ -70,7 +74,7 @@ class AgentManager: tool.callback_manager = callback_manager executor = AgentExecutor.from_agent_and_tools( - agent=builder.get_agent(), + agent=agent, tools=tools, memory=memory, callback_manager=callback_manager, From 8c874cb87740077498795d14d26938f158ffb245 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 13:54:24 -0400 Subject: [PATCH 89/98] init clean up Former-commit-id: f43d7b6b71e57f5a90fcd92657bac0129840e549 --- swarms/agents/utils/AgentManager.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/swarms/agents/utils/AgentManager.py b/swarms/agents/utils/AgentManager.py index 7b3fb35d..bfeea916 100644 --- a/swarms/agents/utils/AgentManager.py +++ b/swarms/agents/utils/AgentManager.py @@ -41,9 +41,6 @@ class AgentManager: builder = AgentBuilder(self.toolsets) builder.build_parser() - agent = builder.get_agent() - if not agent: - raise ValueError("Agent not created") callbacks = [] eval_callback = EVALCallbackHandler() @@ -55,12 +52,19 @@ class AgentManager: execution_callback.set_parser(builder.get_parser()) callbacks.append(execution_callback) + #llm init callback_manager = CallbackManager(callbacks) - builder.build_llm(callback_manager, openai_api_key) + if builder.llm is None: + raise ValueError('LLM not created') builder.build_global_tools() + #agent init + agent = builder.get_agent() + if not agent: + raise ValueError("Agent not created") + memory: BaseChatMemory = self.get_or_create_memory(session) tools = [ *builder.get_global_tools(), From fbf2ec7c60cb41e1a00010725c1d638518586f84 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 13:56:15 -0400 Subject: [PATCH 90/98] make sure agent key is present Former-commit-id: c3149e3788a624e980cc4ddb144e6c8949568340 --- swarms/agents/utils/AgentManager.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/swarms/agents/utils/AgentManager.py b/swarms/agents/utils/AgentManager.py index bfeea916..34e87c79 100644 --- a/swarms/agents/utils/AgentManager.py +++ b/swarms/agents/utils/AgentManager.py @@ -84,7 +84,10 @@ class AgentManager: callback_manager=callback_manager, verbose=True, ) + if 'agent' not in executor.__dict__: + executor.__dict__['agent'] = agent self.executors[session] = executor + return executor except Exception as e: logging.error(f"Error while creating executor: {str(e)}") From 4358f1a1527e9bd896a8b846a0db3d0116d06b7a Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 13:59:30 -0400 Subject: [PATCH 91/98] clean up with create executor Former-commit-id: 72de4812afeaf41cf95164ab52dae65bc0b76547 --- swarms/agents/utils/AgentManager.py | 28 ++++++++++------------------ 1 file changed, 10 insertions(+), 18 deletions(-) diff --git a/swarms/agents/utils/AgentManager.py b/swarms/agents/utils/AgentManager.py index 34e87c79..6e44b9a7 100644 --- a/swarms/agents/utils/AgentManager.py +++ b/swarms/agents/utils/AgentManager.py @@ -41,6 +41,9 @@ class AgentManager: builder = AgentBuilder(self.toolsets) builder.build_parser() + agent = builder.get_agent() + if not agent: + raise ValueError("Agent not created") callbacks = [] eval_callback = EVALCallbackHandler() @@ -52,19 +55,12 @@ class AgentManager: execution_callback.set_parser(builder.get_parser()) callbacks.append(execution_callback) - #llm init callback_manager = CallbackManager(callbacks) + builder.build_llm(callback_manager, openai_api_key) - if builder.llm is None: - raise ValueError('LLM not created') builder.build_global_tools() - #agent init - agent = builder.get_agent() - if not agent: - raise ValueError("Agent not created") - memory: BaseChatMemory = self.get_or_create_memory(session) tools = [ *builder.get_global_tools(), @@ -77,22 +73,18 @@ class AgentManager: for tool in tools: tool.callback_manager = callback_manager - executor = AgentExecutor.from_agent_and_tools( - agent=agent, - tools=tools, - memory=memory, - callback_manager=callback_manager, - verbose=True, - ) - if 'agent' not in executor.__dict__: - executor.__dict__['agent'] = agent - self.executors[session] = executor + # Ensure the 'agent' key is present in the values dictionary + values = {'agent': agent, 'tools': tools} + executor = AgentExecutor.from_agent_and_tools(**values) + + self.executors[session] = executor return executor except Exception as e: logging.error(f"Error while creating executor: {str(e)}") raise e + @staticmethod def create(toolsets: list[BaseToolSet]) -> "AgentManager": if not isinstance(toolsets, list): From da4e6e0acd10c18ae9f5f9ff6cad2a0920dcc684 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 14:03:28 -0400 Subject: [PATCH 92/98] validation executor Former-commit-id: 06d842bc61670c132787749c80ba5812edb07250 --- swarms/agents/utils/AgentManager.py | 43 ++++++++++++++++++++++------- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/swarms/agents/utils/AgentManager.py b/swarms/agents/utils/AgentManager.py index 6e44b9a7..e392cfee 100644 --- a/swarms/agents/utils/AgentManager.py +++ b/swarms/agents/utils/AgentManager.py @@ -41,9 +41,6 @@ class AgentManager: builder = AgentBuilder(self.toolsets) builder.build_parser() - agent = builder.get_agent() - if not agent: - raise ValueError("Agent not created") callbacks = [] eval_callback = EVALCallbackHandler() @@ -55,12 +52,19 @@ class AgentManager: execution_callback.set_parser(builder.get_parser()) callbacks.append(execution_callback) + #llm init callback_manager = CallbackManager(callbacks) - builder.build_llm(callback_manager, openai_api_key) + if builder.llm is None: + raise ValueError('LLM not created') builder.build_global_tools() + #agent init + agent = builder.get_agent() + if not agent: + raise ValueError("Agent not created") + memory: BaseChatMemory = self.get_or_create_memory(session) tools = [ *builder.get_global_tools(), @@ -73,18 +77,37 @@ class AgentManager: for tool in tools: tool.callback_manager = callback_manager - # Ensure the 'agent' key is present in the values dictionary - values = {'agent': agent, 'tools': tools} - - executor = AgentExecutor.from_agent_and_tools(**values) - + # # Ensure the 'agent' key is present in the values dictionary + # values = {'agent': agent, 'tools': tools} + + # executor = AgentExecutor.from_agent_and_tools( + # agent=agent, + # tools=tools, + # memory=memory, + # callback_manager=callback_manager, + # verbose=True, + # ) + + # Prepare the arguments for the executor + executor_args = { + 'agent': agent, + 'tools': tools, + 'memory': memory, + 'callback_manager': callback_manager, + 'verbose': True # Or any other value based on your requirement + } + + executor = AgentExecutor.from_agent_and_tools(**executor_args) + + if 'agent' not in executor.__dict__: + executor.__dict__['agent'] = agent self.executors[session] = executor + return executor except Exception as e: logging.error(f"Error while creating executor: {str(e)}") raise e - @staticmethod def create(toolsets: list[BaseToolSet]) -> "AgentManager": if not isinstance(toolsets, list): From a9cc50e48c85c63c5780429039d803516c02e993 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 16:50:57 -0400 Subject: [PATCH 93/98] docs + error handlong + logging Former-commit-id: a76f10d4677d86a47850a1195324e4a67ad688ad --- swarms/agents/.DS_Store | Bin 6148 -> 6148 bytes swarms/hivemind.py | 2 + swarms/swarms.py | 203 +++++++++++++++++++++++++++++----------- 3 files changed, 149 insertions(+), 56 deletions(-) create mode 100644 swarms/hivemind.py diff --git a/swarms/agents/.DS_Store b/swarms/agents/.DS_Store index 26c154e2727ff8c63d16b48d252a6395506fc4d3..fc0e967be0c210dcb27af5fc0d8a615702bd5554 100644 GIT binary patch delta 294 zcmZoMXfc=|#>B`mu~2NHo}w@l0|Nsi1A_nqLvd1haY0f}e$vE^D<>O>u++0Mlroes zWHRI+q=1TdB^Bgk7MB$S)5rNh~QXc1kRY2Ju4j^K+75 z?8Kz7%+&ID0TJi?ypqJsywoDFhRl>yppuyI%)FHRa;N;#yp&?F-e90a5KxALlY=u} zK&rZ0*U-YqSVzIw(y&%Xq1w{OKu5vE*sQjelS5Ql-#REhJ0~|UzX#|%AYcUg2Mlq!q*rU$2nVo~51L*&a8^1G8<`>cB0m*`NGyw5tACVo*6B}3n2Odmq delta 86 zcmZoMXfc=|#>CJzu~2NHo}w@#0|NsP3otMgmjxH)<>cq3Pb}1AWZe9KQJrnG08rP0|16b6b1kQ diff --git a/swarms/hivemind.py b/swarms/hivemind.py new file mode 100644 index 00000000..b8033641 --- /dev/null +++ b/swarms/hivemind.py @@ -0,0 +1,2 @@ +# many boss + workers in unison +#kye gomez jul 13 4:01pm, can scale up the number of swarms working on a probkem with `hivemind(swarms=4, or swarms=auto which will scale the agents depending on the complexity)` \ No newline at end of file diff --git a/swarms/swarms.py b/swarms/swarms.py index 050616b7..c0dae34d 100644 --- a/swarms/swarms.py +++ b/swarms/swarms.py @@ -7,64 +7,141 @@ import logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') class Swarms: - def __init__(self, openai_api_key): + def __init__(self, openai_api_key=""): + #openai_api_key: the openai key. Default is empty + + if not openai_api_key: + logging.error("OpenAI key is not provided") + raise ValueError("OpenAI API key is required") + self.openai_api_key = openai_api_key def initialize_llm(self, llm_class, temperature=0.5): - # Initialize language model - return llm_class(openai_api_key=self.openai_api_key, temperature=temperature) + """ + Init LLM + + Params: + llm_class(class): The Language model class. Default is OpenAI. + temperature (float): The Temperature for the language model. Default is 0.5 + """ + try: + + # Initialize language model + return llm_class(openai_api_key=self.openai_api_key, temperature=temperature) + except Exception as e: + logging.error(f"Failed to initialize language model: {e}") def initialize_tools(self, llm_class): - llm = self.initialize_llm(llm_class) - # Initialize tools - web_search = DuckDuckGoSearchRun() - tools = [ - web_search, - WriteFileTool(root_dir=ROOT_DIR), - ReadFileTool(root_dir=ROOT_DIR), + """ + Init tools + + Params: + llm_class (class): The Language model class. Default is OpenAI + """ + try: + llm = self.initialize_llm(llm_class) + # Initialize tools + web_search = DuckDuckGoSearchRun() + tools = [ + web_search, + WriteFileTool(root_dir=ROOT_DIR), + ReadFileTool(root_dir=ROOT_DIR), + + process_csv, + WebpageQATool(qa_chain=load_qa_with_sources_chain(llm)), + + ] + assert tools is not None, "tools is not initialized" + return tools + except Exception as e: + logging.error(f"Failed to initialize tools: {e}") + raise - process_csv, - WebpageQATool(qa_chain=load_qa_with_sources_chain(llm)), + def initialize_vectorstore(self): + """ + Init vector store + """ + + try: + + embeddings_model = OpenAIEmbeddings(openai_api_key=self.openai_api_key) + embedding_size = 1536 + index = faiss.IndexFlatL2(embedding_size) + return FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {}) + except Exception as e: + logging.error(f"Failed to initialize vector store: {e}") + raise + + def initialize_worker_node(self, worker_tools, vectorstore, llm_class=ChatOpenAI, ai_name="Swarm Worker AI Assistant"): + """ + Init WorkerNode + + Params: + worker_tools (list): The list of worker tools. + vectorstore (object): The vector store object + llm_class (class): The Language model class. Default is ChatOpenAI + ai_name (str): The AI name. Default is "Swarms worker AI assistant" + """ + + try: + + # Initialize worker node + llm = self.initialize_llm(ChatOpenAI) + worker_node = WorkerNode(llm=llm, tools=worker_tools, vectorstore=vectorstore) + worker_node.create_agent(ai_name=ai_name, ai_role="Assistant", human_in_the_loop=False, search_kwargs={}) # add search kwargs + + worker_node_tool = Tool(name="WorkerNode AI Agent", func=worker_node.run, description="Input: an objective with a todo list for that objective. Output: your task completed: Please be very clear what the objective and task instructions are. The Swarm worker agent is Useful for when you need to spawn an autonomous agent instance as a worker to accomplish any complex tasks, it can search the internet or write code or spawn child multi-modality models to process and generate images and text or audio and so on") + return worker_node_tool + except Exception as e: + logging.error(f"Failed to initialize worker node: {e}") + raise + + def initialize_boss_node(self, vectorstore, worker_node, llm_class=OpenAI, max_iterations=5, verbose=True): + """ + Init BossNode + + Params: + vectorstore (object): the vector store object. + worker_node (object): the worker node object + llm_class (class): the language model class. Default is OpenAI + max_iterations(int): The number of max iterations. Default is 5 + verbose(bool): Debug mode. Default is False + + """ + try: + + # Initialize boss node + llm = self.initialize_llm(llm_class) + todo_prompt = PromptTemplate.from_template("You are a boss planer in a swarm who is an expert at coming up with a todo list for a given objective and then creating an worker to help you accomplish your task. Come up with a todo list for this objective: {objective} and then spawn a worker agent to complete the task for you. Always spawn an worker agent after creating a plan and pass the objective and plan to the worker agent.") + todo_chain = LLMChain(llm=llm, prompt=todo_prompt) + + tools = [ + Tool(name="TODO", func=todo_chain.run, description="useful for when you need to come up with todo lists. Input: an objective to create a todo list for. Output: a todo list for that objective. Please be very clear what the objective is!"), + worker_node + ] + suffix = """Question: {task}\n{agent_scratchpad}""" + prefix = """You are an Boss in a swarm who performs one task based on the following objective: {objective}. Take into account these previously completed tasks: {context}.\n """ + + prompt = ZeroShotAgent.create_prompt(tools, prefix=prefix, suffix=suffix, input_variables=["objective", "task", "context", "agent_scratchpad"],) + llm_chain = LLMChain(llm=llm, prompt=prompt) + agent = ZeroShotAgent(llm_chain=llm_chain, allowed_tools=[tool.name for tool in tools]) + + agent_executor = AgentExecutor.from_agent_and_tools(agent=agent, tools=tools, verbose=verbose) + return BossNode(llm, vectorstore, agent_executor, max_iterations=max_iterations) + except Exception as e: + logging.error(f"Failed to initialize boss node: {e}") + raise - ] - assert tools is not None, "tools is not initialized" - return tools - def initialize_vectorstore(self): - # Initialize vector store - embeddings_model = OpenAIEmbeddings(openai_api_key=self.openai_api_key) - embedding_size = 1536 - index = faiss.IndexFlatL2(embedding_size) - return FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {}) - - def initialize_worker_node(self, worker_tools, vectorstore): - # Initialize worker node - llm = self.initialize_llm(ChatOpenAI) - worker_node = WorkerNode(llm=llm, tools=worker_tools, vectorstore=vectorstore) - worker_node.create_agent(ai_name="Swarm Worker AI Assistant", ai_role="Assistant", human_in_the_loop=False, search_kwargs={}) - worker_node_tool = Tool(name="WorkerNode AI Agent", func=worker_node.run, description="Input: an objective with a todo list for that objective. Output: your task completed: Please be very clear what the objective and task instructions are. The Swarm worker agent is Useful for when you need to spawn an autonomous agent instance as a worker to accomplish any complex tasks, it can search the internet or write code or spawn child multi-modality models to process and generate images and text or audio and so on") - return worker_node_tool - - def initialize_boss_node(self, vectorstore, worker_node): - # Initialize boss node - llm = self.initialize_llm(OpenAI) - todo_prompt = PromptTemplate.from_template("You are a boss planer in a swarm who is an expert at coming up with a todo list for a given objective and then creating an worker to help you accomplish your task. Come up with a todo list for this objective: {objective} and then spawn a worker agent to complete the task for you. Always spawn an worker agent after creating a plan and pass the objective and plan to the worker agent.") - todo_chain = LLMChain(llm=llm, prompt=todo_prompt) - tools = [ - Tool(name="TODO", func=todo_chain.run, description="useful for when you need to come up with todo lists. Input: an objective to create a todo list for. Output: a todo list for that objective. Please be very clear what the objective is!"), - worker_node - ] - suffix = """Question: {task}\n{agent_scratchpad}""" - prefix = """You are an Boss in a swarm who performs one task based on the following objective: {objective}. Take into account these previously completed tasks: {context}.\n """ - prompt = ZeroShotAgent.create_prompt(tools, prefix=prefix, suffix=suffix, input_variables=["objective", "task", "context", "agent_scratchpad"],) - llm_chain = LLMChain(llm=llm, prompt=prompt) - agent = ZeroShotAgent(llm_chain=llm_chain, allowed_tools=[tool.name for tool in tools]) - agent_executor = AgentExecutor.from_agent_and_tools(agent=agent, tools=tools, verbose=True) - # return BossNode(return BossNode(llm, vectorstore, agent_executor, max_iterations=5) - return BossNode(llm, vectorstore, agent_executor, max_iterations=5) def run_swarms(self, objective): + """ + Run the swarm with the given objective + + Params: + objective(str): The task + """ try: # Run the swarm with the given objective worker_tools = self.initialize_tools(OpenAI) @@ -81,15 +158,29 @@ class Swarms: logging.error(f"An error occurred in run_swarms: {e}") raise - # usage -def swarm(api_key, objective): +def swarm(api_key="", objective=""): """ - import swarm - api_key = "APIKEY" - objective = "What is the capital of the UK?" - result = swarm(api_key, objective) - print(result) # Prints: "The capital of the UK is London." + Run the swarm with the given API key and objective. + + Parameters: + api_key (str): The OpenAI API key. Default is an empty string. + objective (str): The objective. Default is an empty string. + + Returns: + The result of the swarm. """ - swarms = Swarms(api_key) - return swarms.run_swarms(objective) + + if not api_key: + logging.error("OpenAIkey is not provided") + raise ValueError("OpenAI API key is not provided") + if not objective: + logging.error("Objective is not provided") + raise ValueError("Objective is required") + try: + + swarms = Swarms(api_key) + return swarms.run_swarms(objective) + except Exception as e: + logging.error(f"An error occured in swarm: {e}") + raise \ No newline at end of file From 8a8d002f335e8b0c03d4afb1578d9b5fcd30c2a4 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 17:15:19 -0400 Subject: [PATCH 94/98] worker node error logging + optional modularity Former-commit-id: 2f84882be42047a0ab2274c6f72dd7c1b1b14912 --- swarms/agents/workers/WorkerNode.py | 119 ++++++++++++++++++---------- swarms/swarms.py | 8 +- 2 files changed, 80 insertions(+), 47 deletions(-) diff --git a/swarms/agents/workers/WorkerNode.py b/swarms/agents/workers/WorkerNode.py index f7fd465e..f02199f3 100644 --- a/swarms/agents/workers/WorkerNode.py +++ b/swarms/agents/workers/WorkerNode.py @@ -13,21 +13,23 @@ import logging from pydantic import BaseModel, Extra logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') + class WorkerNode: """Useful for when you need to spawn an autonomous agent instance as a worker to accomplish complex tasks, it can search the internet or spawn child multi-modality models to process and generate images and text or audio and so on""" def __init__(self, llm, tools, vectorstore): if not llm or not tools or not vectorstore: - raise ValueError("llm, tools, and vectorstore cannot be None") + logging.error("llm, tools, and vectorstore cannot be None.") + raise ValueError("llm, tools, and vectorstore cannot be None.") + self.llm = llm self.tools = tools self.vectorstore = vectorstore self.agent = None - def create_agent(self, ai_name, ai_role, human_in_the_loop, search_kwargs): + def create_agent(self, ai_name="Swarm Worker AI Assistant", ai_role="Assistant", human_in_the_loop=False, search_kwargs={}, verbose=False): logging.info("Creating agent in WorkerNode") try: - self.agent = AutoGPT.from_llm_and_tools( ai_name=ai_name, ai_role=ai_role, @@ -37,88 +39,119 @@ class WorkerNode: human_in_the_loop=human_in_the_loop, chat_history_memory=FileChatMessageHistory("chat_history.txt"), ) - self.agent.chain.verbose = True - + self.agent.chain.verbose = verbose except Exception as e: logging.error(f"Error while creating agent: {str(e)}") raise e + def add_tool(self, tool: Tool): if not isinstance(tool, Tool): - raise TypeError("Tool must be an instance of Tool") + logging.error("Tool must be an instance of Tool.") + raise TypeError("Tool must be an instance of Tool.") + self.tools.append(tool) def run(self, prompt: str) -> str: if not isinstance(prompt, str): - raise TypeError("Prompt must be a string") + logging.error("Prompt must be a string.") + raise TypeError("Prompt must be a string.") if not prompt: - raise ValueError("Prompt is empty") + logging.error("Prompt is empty.") + raise ValueError("Prompt is empty.") try: - - self.agent.run([f"{prompt}"]) return "Task completed by WorkerNode" except Exception as e: logging.error(f"While running the agent: {str(e)}") raise e + -# worker_tool = Tool( -# name="WorkerNode AI Agent", -# func=WorkerNode.run, -# description="Useful for when you need to spawn an autonomous agent instance as a worker to accomplish complex tasks, it can search the internet or spawn child multi-modality models to process and generate images and text or audio and so on" -# ) - class WorkerNodeInitializer: def __init__(self, openai_api_key): if not openai_api_key: + logging.error("OpenAI API key is not provided") raise ValueError("openai_api_key cannot be None") + self.openai_api_key = openai_api_key def initialize_llm(self, llm_class, temperature=0.5): if not llm_class: + logging.error("llm_class cannot be none") raise ValueError("llm_class cannot be None") - return llm_class(openai_api_key=self.openai_api_key, temperature=temperature) + + try: + return llm_class(openai_api_key=self.openai_api_key, temperature=temperature) + except Exception as e: + logging.error(f"Failed to initialize language model: {e}") + raise def initialize_tools(self, llm_class): if not llm_class: + logging.error("llm_class not cannot be none") raise ValueError("llm_class cannot be none") - logging.info('Creating WorkerNode') - llm = self.initialize_llm(llm_class) - web_search = DuckDuckGoSearchRun() - tools = [ - web_search, - WriteFileTool(root_dir=ROOT_DIR), - ReadFileTool(root_dir=ROOT_DIR), - process_csv, - WebpageQATool(qa_chain=load_qa_with_sources_chain(llm)), - ] - return tools + try: + + logging.info('Creating WorkerNode') + llm = self.initialize_llm(llm_class) + web_search = DuckDuckGoSearchRun() + + tools = [ + web_search, + WriteFileTool(root_dir=ROOT_DIR), + ReadFileTool(root_dir=ROOT_DIR), + process_csv, + WebpageQATool(qa_chain=load_qa_with_sources_chain(llm)), + ] + if not tools: + logging.error("Tools are not initialized") + raise ValueError("Tools are not initialized") + return tools + except Exception as e: + logging.error(f"Failed to initialize tools: {e}") def initialize_vectorstore(self): - embeddings_model = OpenAIEmbeddings(openai_api_key=self.openai_api_key) - embedding_size = 1536 - index = faiss.IndexFlatL2(embedding_size) - return FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {}) + try: + + embeddings_model = OpenAIEmbeddings(openai_api_key=self.openai_api_key) + embedding_size = 1536 + index = faiss.IndexFlatL2(embedding_size) + return FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {}) + except Exception as e: + logging.error(f"Failed to initialize vector store: {e}") + raise - def create_worker_node(self, llm_class=ChatOpenAI): + def create_worker_node(self, llm_class=ChatOpenAI, ai_name="Swarm Worker AI Assistant", ai_role="Assistant", human_in_the_loop=False, search_kwargs={}, verbose=False): if not llm_class: - raise ValueError("llm_class cannot be None") - worker_tools = self.initialize_tools(llm_class) - vectorstore = self.initialize_vectorstore() - worker_node = WorkerNode(llm=self.initialize_llm(llm_class), tools=worker_tools, vectorstore=vectorstore) - worker_node.create_agent(ai_name="Swarm Worker AI Assistant", ai_role="Assistant", human_in_the_loop=False, search_kwargs={}) - return worker_node + logging.error("llm_class cannot be None.") + raise ValueError("llm_class cannot be None.") + try: + worker_tools = self.initialize_tools(llm_class) + vectorstore = self.initialize_vectorstore() + worker_node = WorkerNode(llm=self.initialize_llm(llm_class), tools=worker_tools, vectorstore=vectorstore) + worker_node.create_agent(ai_name=ai_name, ai_role=ai_role, human_in_the_loop=human_in_the_loop, search_kwargs=search_kwargs, verbose=verbose) + return worker_node + except Exception as e: + logging.error(f"Failed to create worker node: {e}") + raise def worker_node(openai_api_key): if not openai_api_key: - raise ValueError("openai_api_key cannot be none") - initializer = WorkerNodeInitializer(openai_api_key) - worker_node = initializer.create_worker_node() - return worker_node + logging.error("OpenAI API key is not provided") + raise ValueError("OpenAI API key is required") + + try: + + initializer = WorkerNodeInitializer(openai_api_key) + worker_node = initializer.create_worker_node() + return worker_node + except Exception as e: + logging.error(f"An error occured in worker_node: {e}") + raise diff --git a/swarms/swarms.py b/swarms/swarms.py index c0dae34d..b15bd850 100644 --- a/swarms/swarms.py +++ b/swarms/swarms.py @@ -9,7 +9,6 @@ logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - % class Swarms: def __init__(self, openai_api_key=""): #openai_api_key: the openai key. Default is empty - if not openai_api_key: logging.error("OpenAI key is not provided") raise ValueError("OpenAI API key is required") @@ -24,8 +23,7 @@ class Swarms: llm_class(class): The Language model class. Default is OpenAI. temperature (float): The Temperature for the language model. Default is 0.5 """ - try: - + try: # Initialize language model return llm_class(openai_api_key=self.openai_api_key, temperature=temperature) except Exception as e: @@ -49,10 +47,11 @@ class Swarms: process_csv, WebpageQATool(qa_chain=load_qa_with_sources_chain(llm)), - ] + assert tools is not None, "tools is not initialized" return tools + except Exception as e: logging.error(f"Failed to initialize tools: {e}") raise @@ -67,6 +66,7 @@ class Swarms: embeddings_model = OpenAIEmbeddings(openai_api_key=self.openai_api_key) embedding_size = 1536 index = faiss.IndexFlatL2(embedding_size) + return FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {}) except Exception as e: logging.error(f"Failed to initialize vector store: {e}") From 6224a59fce702b6186bb6e2b567cc54300be1d44 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 17:22:00 -0400 Subject: [PATCH 95/98] clean up + documentation + modularization + error handloinh Former-commit-id: 47ad7791d8d7c2b6d1d3e1c084e3026cdcd6c488 --- swarms/agents/boss/BossNode.py | 35 +++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/swarms/agents/boss/BossNode.py b/swarms/agents/boss/BossNode.py index d8c000bb..a9a8a844 100644 --- a/swarms/agents/boss/BossNode.py +++ b/swarms/agents/boss/BossNode.py @@ -1,9 +1,19 @@ from swarms.tools.agent_tools import * from pydantic import ValidationError +import logging + +logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s') # ---------- Boss Node ---------- class BossNode: + """ + The BossNode class is responsible for creating and executing tasks using the BabyAGI model. + It takes a language model (llm), a vectorstore for memory, an agent_executor for task execution, and a maximum number of iterations for the BabyAGI model. + """ def __init__(self, llm, vectorstore, agent_executor, max_iterations): + if not llm or not vectorstore or not agent_executor or not max_iterations: + logging.error("llm, vectorstore, agent_executor, and max_iterations cannot be None.") + raise ValueError("llm, vectorstore, agent_executor, and max_iterations cannot be None.") self.llm = llm self.vectorstore = vectorstore self.agent_executor = agent_executor @@ -17,11 +27,30 @@ class BossNode: max_iterations=self.max_iterations, ) except ValidationError as e: - print(f"Validation Error while initializing BabyAGI: {e}") + logging.error(f"Validation Error while initializing BabyAGI: {e}") + raise except Exception as e: - print(f"Unexpected Error while initializing BabyAGI: {e}") + logging.error(f"Unexpected Error while initializing BabyAGI: {e}") + raise + def create_task(self, objective): + """ + Creates a task with the given objective. + """ + if not objective: + logging.error("Objective cannot be empty.") + raise ValueError("Objective cannot be empty.") return {"objective": objective} def execute_task(self, task): - self.baby_agi(task) \ No newline at end of file + """ + Executes a task using the BabyAGI model. + """ + if not task: + logging.error("Task cannot be empty.") + raise ValueError("Task cannot be empty.") + try: + self.baby_agi(task) + except Exception as e: + logging.error(f"Error while executing task: {e}") + raise \ No newline at end of file From c71df75fed8a817b13e1e54c9326c058f7ab055c Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 17:41:47 -0400 Subject: [PATCH 96/98] no verbose Former-commit-id: d807761c2a2e7394b28c75710a5230270a355050 --- swarms/swarms.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/swarms/swarms.py b/swarms/swarms.py index b15bd850..a19f1c57 100644 --- a/swarms/swarms.py +++ b/swarms/swarms.py @@ -66,7 +66,7 @@ class Swarms: embeddings_model = OpenAIEmbeddings(openai_api_key=self.openai_api_key) embedding_size = 1536 index = faiss.IndexFlatL2(embedding_size) - + return FAISS(embeddings_model.embed_query, index, InMemoryDocstore({}), {}) except Exception as e: logging.error(f"Failed to initialize vector store: {e}") @@ -96,7 +96,7 @@ class Swarms: logging.error(f"Failed to initialize worker node: {e}") raise - def initialize_boss_node(self, vectorstore, worker_node, llm_class=OpenAI, max_iterations=5, verbose=True): + def initialize_boss_node(self, vectorstore, worker_node, llm_class=OpenAI, max_iterations=5, verbose=False): """ Init BossNode From e93540d979f235c1c14979ab54aae7d6dd6e9398 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 17:48:47 -0400 Subject: [PATCH 97/98] documentation Former-commit-id: 5ff0824942d4062af6a65b09d65cdc4c2a1f5f0a --- DOCS/DOCUMENTATION.md | 155 +++++++++++++++++++++++++----------------- 1 file changed, 94 insertions(+), 61 deletions(-) diff --git a/DOCS/DOCUMENTATION.md b/DOCS/DOCUMENTATION.md index 9f761155..2e2e3c14 100644 --- a/DOCS/DOCUMENTATION.md +++ b/DOCS/DOCUMENTATION.md @@ -1,36 +1,97 @@ +########################## # Swarms Documentation -## Overview -The Swarm module includes the implementation of two classes, `WorkerNode` and `BossNode`, which respectively represent a worker agent and a boss agent. A worker agent is responsible for completing given tasks, while a boss agent is responsible for creating and managing tasks for the worker agent(s). +## ClassName -## Key Classes +Swarms + +## Purpose + +The Swarms module provides a powerful framework for creating and managing swarms of autonomous agents to accomplish complex tasks. It consists of the `WorkerNode` and `BossNode` classes, along with the `LLM` utility class, which allow you to easily set up and run a swarm of agents to tackle any objective. The module is highly configurable and extensible, providing flexibility to accommodate various use cases. + +## Usage example + +```python +from swarms import Swarms + +api_key = "your_openai_api_key" + +# Initialize Swarms with your API key +swarm = Swarms(api_key=api_key) + +# Define an objective +objective = "Please make a web GUI for using HTTP API server..." + +# Run Swarms +result = swarm.run_swarms(objective) + +print(result) +``` + +## Constructor + +```python +def __init__(self, openai_api_key) +``` + +- `openai_api_key` (required): The API key for OpenAI's models. + +## Methods + +### run_swarms(objective) + +Runs the swarm with the given objective by initializing the worker and boss nodes. + +- `objective` (required): The objective or task to be accomplished by the swarm. + +Returns the result of the swarm execution. + +## Example Usage + +```python +from swarms import Swarms + +api_key = "your_openai_api_key" + +# Initialize Swarms with your API key +swarm = Swarms(api_key=api_key) + +# Define an objective +objective = "Please make a web GUI for using HTTP API server..." + +# Run Swarms +result = swarm.run_swarms(objective) + +print(result) +``` + +## WorkerNode -### WorkerNode The `WorkerNode` class represents an autonomous agent instance that functions as a worker to accomplish complex tasks. It has the ability to search the internet, process and generate images, text, audio, and more. -#### Constructor +### Constructor + ```python def __init__(self, llm, tools, vectorstore) ``` + - `llm` (required): The language model used by the worker node. - `tools` (required): A list of tools available to the worker node. - `vectorstore` (required): The vector store used by the worker node. -#### Methods +### Methods + - `create_agent(ai_name, ai_role, human_in_the_loop, search_kwargs)`: Creates an agent within the worker node. - `add_tool(tool)`: Adds a tool to the worker node. - `run(prompt)`: Runs the worker node to complete a task specified by the prompt. - -#### Example Usage +### Example Usage ```python - - from swarms import worker_node # Your OpenAI API key -api_key = "sk-your api key" +api_key = "your_openai_api_key" # Initialize a WorkerNode with your API key node = worker_node(api_key) @@ -44,98 +105,68 @@ task = node.run(objective) print(task) ``` -### BossNode +## BossNode + The `BossNode` class represents an agent responsible for creating and managing tasks for the worker agent(s). It interacts with the worker node(s) to delegate tasks and monitor their progress. -#### Constructor +### Constructor + ```python def __init__(self, llm, vectorstore, agent_executor, max_iterations) ``` + - `llm` (required): The language model used by the boss node. - `vectorstore` (required): The vector store used by the boss node. - `agent_executor` (required): The agent executor used to execute tasks. - `max_iterations` (required): The maximum number of iterations for task execution. -#### Methods +### Methods + - `create_task(objective)`: Creates a task with the given objective. - `execute_task(task)`: Executes the given task by interacting with the worker agent(s). -### LLM +## LLM + The `LLM` class is a utility class that provides an interface to different language models (LLMs) such as OpenAI's ChatGPT and Hugging Face models. It is used to initialize the language model for the worker and boss nodes. -#### Constructor +### Constructor + ```python def __init__(self, openai_api_key=None, hf_repo_id=None, hf_api_token=None, model_kwargs=None) ``` + - `openai_api_key` (optional): The API key for OpenAI's models. - `hf_repo_id` (optional): The repository ID for the Hugging Face model. - `hf_api_token` (optional): The API token for the Hugging Face model. - `model_kwargs` (optional): Additional keyword arguments to pass to the language model. -#### Methods -- `run(prompt)`: Runs the language model with the given prompt and returns the generated response. - -### Swarms -The `Swarms` class is a wrapper class that encapsulates the functionality of the worker and boss nodes. It provides a convenient way to initialize and run a swarm of agents to accomplish tasks. - -#### Constructor -```python -def __init__(self, openai_api_key) -``` -- `openai_api_key` (required): The API key for OpenAI's models. - -#### Methods -- `run_swarms(objective)`: Runs the swarm with the given objective by initializing the worker and boss nodes. - -## Example Usage -```python -from swarms import Swarms - -api_key = "sksdsds" - -# Initialize Swarms with your API key -swarm = Swarms(openai_api_key=api_key) +### Methods -# Define an objective -objective = """ -Please make a web GUI for using HTTP API server. -The name of it is Swarms. -You can check the server code at ./main.py. -The server is served on localhost:8000. -Users should be able to write text input as 'query' and url array as 'files', and check the response. -Users input form should be delivered in JSON format. -I want it to have neumorphism-style. Serve it on port 4500. - -""" - -# Run Swarms -task = swarm.run_swarms(objective) - -print(task) -``` - -This will create a swarm of agents to complete the given objective. The boss agent will create tasks and delegate them to the worker agent(s) for execution. - -Please make sure to replace `"your_openai_api_key"` with your actual OpenAI API key. +- `run(prompt)`: Runs the language model with the given prompt and returns the generated response. ## Configuration + The Swarms module can be configured by modifying the following parameters: ### WorkerNode + - `llm_class`: The language model class to use for the worker node (default: `ChatOpenAI`). - `temperature`: The temperature parameter for the language model (default: `0.5`). ### BossNode + - `llm_class`: The language model class to use for the boss node (default: `OpenAI`). - `max_iterations`: The maximum number of iterations for task execution (default: `5`). ### LLM + - `openai_api_key`: The API key for OpenAI's models. - `hf_repo_id`: The repository ID for the Hugging Face model. - `hf_api_token`: The API token for the Hugging Face model. - `model_kwargs`: Additional keyword arguments to pass to the language model. ## Tool Configuration + The Swarms module supports various tools that can be added to the worker node for performing specific tasks. The following tools are available: - `DuckDuckGoSearchRun`: A tool for performing web searches. @@ -147,6 +178,7 @@ The Swarms module supports various tools that can be added to the worker node fo Additional tools can be added by extending the functionality of the `Tool` class. ## Advanced Usage + For more advanced usage, you can customize the tools and parameters according to your specific requirements. The Swarms module provides flexibility and extensibility to accommodate various use cases. For example, you can add your own custom tools by extending the `Tool` class and adding them to the worker node. You can also modify the prompt templates used by the boss node to customize the interaction between the boss and worker agents. @@ -154,4 +186,5 @@ For example, you can add your own custom tools by extending the `Tool` class and Please refer to the source code and documentation of the Swarms module for more details and examples. ## Conclusion -The Swarms module provides a powerful framework for creating and managing swarms of autonomous agents to accomplish complex tasks. With the WorkerNode and BossNode classes, along with the LLM utility class, you can easily set up and run a swarm of agents to tackle any objective. The module is highly configurable and extensible, allowing you to tailor it to your specific needs. \ No newline at end of file + +The Swarms module provides a powerful framework for creating and managing swarms of autonomous agents to accomplish complex tasks. With the `WorkerNode` and `BossNode` classes, along with the `LLM` utility class, you can easily set up and run a swarm of agents to tackle any objective. The module is highly configurable and extensible, allowing you to tailor it to your specific needs. \ No newline at end of file From 8060686d0b7ac488148517604a89a2976f47cc49 Mon Sep 17 00:00:00 2001 From: Kye Date: Thu, 13 Jul 2023 17:59:18 -0400 Subject: [PATCH 98/98] llm class Former-commit-id: fe79dc5ebc9f6fa0d9ca1e8862d4c4b9a1552f7c --- DOCS/DOCUMENTATION.md | 54 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/DOCS/DOCUMENTATION.md b/DOCS/DOCUMENTATION.md index 2e2e3c14..699483c8 100644 --- a/DOCS/DOCUMENTATION.md +++ b/DOCS/DOCUMENTATION.md @@ -1,4 +1,3 @@ -########################## # Swarms Documentation ## ClassName @@ -187,4 +186,55 @@ Please refer to the source code and documentation of the Swarms module for more ## Conclusion -The Swarms module provides a powerful framework for creating and managing swarms of autonomous agents to accomplish complex tasks. With the `WorkerNode` and `BossNode` classes, along with the `LLM` utility class, you can easily set up and run a swarm of agents to tackle any objective. The module is highly configurable and extensible, allowing you to tailor it to your specific needs. \ No newline at end of file +The Swarms module provides a powerful framework for creating and managing swarms of autonomous agents to accomplish complex tasks. With the `WorkerNode` and `BossNode` classes, along with the `LLM` utility class, you can easily set up and run a swarm of agents to tackle any objective. The module is highly configurable and extensible, allowing you to tailor it to your specific needs. + + +## LLM +### Purpose +The `LLM` class provides an interface to different language models (LLMs) such as OpenAI's ChatGPT and Hugging Face models. It allows you to initialize and run a language model with a given prompt and obtain the generated response. + +### Systems Understanding +The `LLM` class takes an OpenAI API key or Hugging Face repository ID and API token as input. It uses these credentials to initialize the language model, either from OpenAI's models or from a specific Hugging Face repository. The language model can then be run with a prompt, and the generated response is returned. + +### Usage Example +```python +from swarms import LLM + +# Create an instance of LLM with OpenAI API key +llm_instance = LLM(openai_api_key="your_openai_key") + +# Run the language model with a prompt +result = llm_instance.run("Who won the FIFA World Cup in 1998?") +print(result) + +# Create an instance of LLM with Hugging Face repository ID and API token +llm_instance = LLM(hf_repo_id="google/flan-t5-xl", hf_api_token="your_hf_api_token") + +# Run the language model with a prompt +result = llm_instance.run("Who won the FIFA World Cup in 1998?") +print(result) +``` + +### Constructor +```python +def __init__(self, openai_api_key: Optional[str] = None, + hf_repo_id: Optional[str] = None, + hf_api_token: Optional[str] = None, + model_kwargs: Optional[dict] = None) +``` +- `openai_api_key` (optional): The API key for OpenAI's models. +- `hf_repo_id` (optional): The repository ID for the Hugging Face model. +- `hf_api_token` (optional): The API token for the Hugging Face model. +- `model_kwargs` (optional): Additional keyword arguments to pass to the language model. + +### Methods +- `run(prompt: str) -> str`: Runs the language model with the given prompt and returns the generated response. + +### Args +- `prompt` (str): The prompt to be passed to the language model. + +### Returns +- `result` (str): The generated response from the language model. + +## Conclusion +The `LLM` class provides a convenient way to initialize and run different language models using either OpenAI's API or Hugging Face models. By providing the necessary credentials and a prompt, you can obtain the generated response from the language model. \ No newline at end of file