[FEAT][Tool Execution] [CLEANUP]

pull/491/head
Kye Gomez 7 months ago
parent 3297f7fc61
commit 68605261f0

@ -5,46 +5,16 @@ AI21_API_KEY="your_api_key_here"
COHERE_API_KEY="your_api_key_here" COHERE_API_KEY="your_api_key_here"
ALEPHALPHA_API_KEY="your_api_key_here" ALEPHALPHA_API_KEY="your_api_key_here"
HUGGINFACEHUB_API_KEY="your_api_key_here" HUGGINFACEHUB_API_KEY="your_api_key_here"
STABILITY_API_KEY="your_api_key_here"
POSTHOG_API_KEY=""
POSTHOG_HOST=""
WOLFRAM_ALPHA_APPID="your_wolfram_alpha_appid_here"
ZAPIER_NLA_API_KEY="your_zapier_nla_api_key_here"
EVAL_PORT=8000 EVAL_PORT=8000
MODEL_NAME="gpt-4" MODEL_NAME="gpt-4"
CELERY_BROKER_URL="redis://localhost:6379"
SERVER="http://localhost:8000"
USE_GPU=True USE_GPU=True
PLAYGROUND_DIR="playground" PLAYGROUND_DIR="playground"
LOG_LEVEL="INFO" LOG_LEVEL="INFO"
BOT_NAME="Orca" BOT_NAME="Orca"
WINEDB_HOST="your_winedb_host_here"
WINEDB_PASSWORD="your_winedb_password_here"
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="your_iftttkey_here"
BRAVE_API_KEY="your_brave_api_key_here"
SPOONACULAR_KEY="your_spoonacular_key_here"
HF_API_KEY="your_huggingface_api_key_here" HF_API_KEY="your_huggingface_api_key_here"
USE_TELEMTRY=True
REDIS_HOST=
REDIS_PORT=
#dbs
PINECONE_API_KEY=""
BING_COOKIE=""
PSG_CONNECTION_STRING="" USE_TELEMETRY=True
GITHUB_USERNAME="" AGENTOPS_API_KEY=""
GITHUB_REPO_NAME=""
GITHUB_TOKEN=""
USE_TELEMETRY=True

@ -1,27 +1,53 @@
from swarms import Agent, OpenAIChat from swarms import Agent, OpenAIChat
def calculate_profit(revenue: float, expenses: float):
"""
Calculates the profit by subtracting expenses from revenue.
Args:
revenue (float): The total revenue.
expenses (float): The total expenses.
Returns:
float: The calculated profit.
"""
return revenue - expenses
def generate_report(company_name: str, profit: float):
"""
Generates a report for a company's profit.
Args:
company_name (str): The name of the company.
profit (float): The calculated profit.
Returns:
str: The report for the company's profit.
"""
return f"The profit for {company_name} is ${profit}."
# Initialize the agent # Initialize the agent
agent = Agent( agent = Agent(
agent_name="Transcript Generator", agent_name="Accounting Assistant",
system_prompt="Generate a transcript for a youtube video on what swarms are!", system_prompt="You're the accounting agent, your purpose is to generate a profit report for a company!",
agent_description=( agent_description="Generate a profit report for a company!",
"Generate a transcript for a youtube video on what swarms" " are!"
),
llm=OpenAIChat(), llm=OpenAIChat(),
max_loops="auto", max_loops=1,
autosave=True, autosave=True,
dynamic_temperature_enabled=True,
dashboard=False, dashboard=False,
streaming_on=True,
verbose=True, verbose=True,
stopping_token="<DONE>", # interactive=True, # Set to False to disable interactive mode
interactive=True, # stopping_token="<DONE>",
state_save_file_type="json", # saved_state_path="accounting_agent.json",
saved_state_path="transcript_generator.json", tools=[calculate_profit, generate_report],
# docs_folder="docs",
# pdf_path="docs/accounting_agent.pdf",
) )
# Run the Agent on a task agent.run(
out = agent.run( "We're the Swarm Corporation, our total revenue is $100,000 and our total expenses are $50,000."
"Generate a transcript for a youtube video on what swarms are!"
) )
print(out)

@ -0,0 +1,25 @@
from swarms import Agent, OpenAIChat
# Initialize the agent
agent = Agent(
agent_name="Transcript Generator",
system_prompt="Generate a transcript for a youtube video on what swarms are!",
agent_description=(
"Generate a transcript for a youtube video on what swarms" " are!"
),
llm=OpenAIChat(),
max_loops=1,
autosave=True,
dashboard=False,
streaming_on=True,
verbose=True,
stopping_token="<DONE>",
interactive=False,
state_save_file_type="json",
saved_state_path="transcript_generator.json",
agent_ops_on=True,
)
# Run the Agent on a task
agent.run("Generate a transcript for a youtube video on what swarms are!")

@ -0,0 +1,82 @@
from swarms import Agent, OpenAIChat
def calculate_profit(revenue: float, expenses: float):
"""
Calculates the profit by subtracting expenses from revenue.
Args:
revenue (float): The total revenue.
expenses (float): The total expenses.
Returns:
float: The calculated profit.
"""
return revenue - expenses
def generate_report(company_name: str, profit: float):
"""
Generates a report for a company's profit.
Args:
company_name (str): The name of the company.
profit (float): The calculated profit.
Returns:
str: The report for the company's profit.
"""
return f"The profit for {company_name} is ${profit}."
def account_agent(task: str = None):
"""
delegate a task to an agent!
Task: str (What task to give to an agent)
"""
agent = Agent(
agent_name="Finance Agent",
system_prompt="You're the Finance agent, your purpose is to generate a profit report for a company!",
agent_description="Generate a profit report for a company!",
llm=OpenAIChat(),
max_loops=1,
autosave=True,
dynamic_temperature_enabled=True,
dashboard=False,
verbose=True,
# interactive=True, # Set to False to disable interactive mode
# stopping_token="<DONE>",
# saved_state_path="accounting_agent.json",
# tools=[calculate_profit, generate_report],
# docs_folder="docs",
# pdf_path="docs/accounting_agent.pdf",
)
out = agent.run(task)
return out
# Initialize the agent
agent = Agent(
agent_name="Accounting Assistant",
system_prompt="You're the accounting agent, your purpose is to generate a profit report for a company!",
agent_description="Generate a profit report for a company!",
llm=OpenAIChat(),
max_loops=1,
autosave=True,
dynamic_temperature_enabled=True,
dashboard=False,
verbose=True,
# interactive=True, # Set to False to disable interactive mode
# stopping_token="<DONE>",
# saved_state_path="accounting_agent.json",
tools=[account_agent],
# docs_folder="docs",
# pdf_path="docs/accounting_agent.pdf",
)
agent.run(
"Delegate a task to the accounting agent: what are the best ways to read cashflow statements"
)

@ -5,7 +5,7 @@ build-backend = "poetry.core.masonry.api"
[tool.poetry] [tool.poetry]
name = "swarms" name = "swarms"
version = "5.1.6" version = "5.1.8"
description = "Swarms - Pytorch" description = "Swarms - Pytorch"
license = "MIT" license = "MIT"
authors = ["Kye Gomez <kye@apac.ai>"] authors = ["Kye Gomez <kye@apac.ai>"]

@ -31,4 +31,4 @@ def cleanup_json_logs(name: str = None):
# Call the function # Call the function
cleanup_json_logs("artifacts_seven") cleanup_json_logs("artifacts_three")

@ -3,15 +3,17 @@ from swarms.models.base_llm import BaseLLM # noqa: E402
from swarms.models.base_multimodal_model import BaseMultiModalModel from swarms.models.base_multimodal_model import BaseMultiModalModel
from swarms.models.fuyu import Fuyu # noqa: E402 from swarms.models.fuyu import Fuyu # noqa: E402
from swarms.models.gpt4_vision_api import GPT4VisionAPI # noqa: E402 from swarms.models.gpt4_vision_api import GPT4VisionAPI # noqa: E402
from swarms.models.gpt_o import GPT4o
from swarms.models.huggingface import HuggingfaceLLM # noqa: E402 from swarms.models.huggingface import HuggingfaceLLM # noqa: E402
from swarms.models.idefics import Idefics # noqa: E402 from swarms.models.idefics import Idefics # noqa: E402
from swarms.models.kosmos_two import Kosmos # noqa: E402 from swarms.models.kosmos_two import Kosmos # noqa: E402
from swarms.models.layoutlm_document_qa import LayoutLMDocumentQA from swarms.models.layoutlm_document_qa import LayoutLMDocumentQA
from swarms.models.llama3_hosted import llama3Hosted
from swarms.models.llava import LavaMultiModal # noqa: E402 from swarms.models.llava import LavaMultiModal # noqa: E402
from swarms.models.nougat import Nougat # noqa: E402 from swarms.models.nougat import Nougat # noqa: E402
from swarms.models.palm import GooglePalm as Palm # noqa: E402 from swarms.models.openai_embeddings import OpenAIEmbeddings
from swarms.models.openai_tts import OpenAITTS # noqa: E402 from swarms.models.openai_tts import OpenAITTS # noqa: E402
from swarms.models.palm import GooglePalm as Palm # noqa: E402
from swarms.models.popular_llms import Anthropic as Anthropic from swarms.models.popular_llms import Anthropic as Anthropic
from swarms.models.popular_llms import ( from swarms.models.popular_llms import (
AzureOpenAILLM as AzureOpenAI, AzureOpenAILLM as AzureOpenAI,
@ -19,15 +21,15 @@ from swarms.models.popular_llms import (
from swarms.models.popular_llms import ( from swarms.models.popular_llms import (
CohereChat as Cohere, CohereChat as Cohere,
) )
from swarms.models.popular_llms import OctoAIChat
from swarms.models.popular_llms import ( from swarms.models.popular_llms import (
OpenAIChatLLM as OpenAIChat, OpenAIChatLLM as OpenAIChat,
) )
from swarms.models.popular_llms import ( from swarms.models.popular_llms import (
OpenAILLM as OpenAI, OpenAILLM as OpenAI,
) )
from swarms.models.popular_llms import OctoAIChat
from swarms.models.qwen import QwenVLMultiModal # noqa: E402
from swarms.models.popular_llms import ReplicateChat as Replicate from swarms.models.popular_llms import ReplicateChat as Replicate
from swarms.models.qwen import QwenVLMultiModal # noqa: E402
from swarms.models.sampling_params import SamplingParams, SamplingType from swarms.models.sampling_params import SamplingParams, SamplingType
from swarms.models.together import TogetherLLM # noqa: E402 from swarms.models.together import TogetherLLM # noqa: E402
from swarms.models.types import ( # noqa: E402 from swarms.models.types import ( # noqa: E402
@ -38,9 +40,6 @@ from swarms.models.types import ( # noqa: E402
VideoModality, VideoModality,
) )
from swarms.models.vilt import Vilt # noqa: E402 from swarms.models.vilt import Vilt # noqa: E402
from swarms.models.openai_embeddings import OpenAIEmbeddings
from swarms.models.llama3_hosted import llama3Hosted
from swarms.models.gpt_o import GPT4o
__all__ = [ __all__ = [
"BaseEmbeddingModel", "BaseEmbeddingModel",

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

@ -1,3 +1,14 @@
from swarms.schemas.plan import Plan
from swarms.schemas.schemas import (
Artifact,
ArtifactUpload,
StepInput,
StepOutput,
StepRequestBody,
TaskInput,
TaskRequestBody,
)
from swarms.schemas.step import Step
from swarms.structs.agent import Agent from swarms.structs.agent import Agent
from swarms.structs.agent_job import AgentJob from swarms.structs.agent_job import AgentJob
from swarms.structs.agent_process import ( from swarms.structs.agent_process import (
@ -11,6 +22,7 @@ from swarms.structs.base_workflow import BaseWorkflow
from swarms.structs.concurrent_workflow import ConcurrentWorkflow from swarms.structs.concurrent_workflow import ConcurrentWorkflow
from swarms.structs.conversation import Conversation from swarms.structs.conversation import Conversation
from swarms.structs.groupchat import GroupChat from swarms.structs.groupchat import GroupChat
from swarms.structs.hiearchical_swarm import HiearchicalSwarm
from swarms.structs.majority_voting import ( from swarms.structs.majority_voting import (
MajorityVoting, MajorityVoting,
majority_voting, majority_voting,
@ -26,21 +38,13 @@ from swarms.structs.multi_process_workflow import (
from swarms.structs.multi_threaded_workflow import ( from swarms.structs.multi_threaded_workflow import (
MultiThreadedWorkflow, MultiThreadedWorkflow,
) )
from swarms.schemas.plan import Plan
from swarms.structs.rearrange import AgentRearrange, rearrange from swarms.structs.rearrange import AgentRearrange, rearrange
from swarms.structs.recursive_workflow import RecursiveWorkflow from swarms.structs.recursive_workflow import RecursiveWorkflow
from swarms.structs.round_robin import RoundRobinSwarm from swarms.structs.round_robin import RoundRobinSwarm
from swarms.schemas.schemas import (
Artifact,
ArtifactUpload,
StepInput,
StepOutput,
StepRequestBody,
TaskInput,
TaskRequestBody,
)
from swarms.structs.sequential_workflow import SequentialWorkflow from swarms.structs.sequential_workflow import SequentialWorkflow
from swarms.schemas.step import Step
# New Swarms
from swarms.structs.swarm_load_balancer import AgentLoadBalancer
from swarms.structs.swarm_net import SwarmNetwork from swarms.structs.swarm_net import SwarmNetwork
from swarms.structs.swarming_architectures import ( from swarms.structs.swarming_architectures import (
broadcast, broadcast,
@ -83,10 +87,6 @@ from swarms.structs.yaml_model import (
pydantic_type_to_yaml_schema, pydantic_type_to_yaml_schema,
) )
# New Swarms
from swarms.structs.swarm_load_balancer import AgentLoadBalancer
from swarms.structs.hiearchical_swarm import HiearchicalSwarm
__all__ = [ __all__ = [
"Agent", "Agent",
"AgentJob", "AgentJob",

@ -35,13 +35,13 @@ from swarms.utils.pdf_to_text import pdf_to_text
from swarms.tools.py_func_to_openai_func_str import ( from swarms.tools.py_func_to_openai_func_str import (
get_openai_function_schema_from_func, get_openai_function_schema_from_func,
) )
from swarms.tools.func_calling_executor import openai_tool_executor
from swarms.structs.base_structure import BaseStructure from swarms.structs.base_structure import BaseStructure
from swarms.prompts.tools import tool_sop_prompt from swarms.prompts.tools import tool_sop_prompt
from swarms.tools.func_calling_utils import ( from swarms.tools.func_calling_utils import (
pydantic_model_to_json_str, pydantic_model_to_json_str,
prepare_output_for_output_model, prepare_output_for_output_model,
) )
from swarms.tools.tool_parse_exec import parse_and_execute_json
# Utils # Utils
@ -285,6 +285,7 @@ class Agent(BaseStructure):
device: str = None, device: str = None,
custom_planning_prompt: str = None, custom_planning_prompt: str = None,
memory_chunk_size: int = 2000, memory_chunk_size: int = 2000,
agent_ops_on: bool = False,
*args, *args,
**kwargs, **kwargs,
): ):
@ -366,6 +367,7 @@ class Agent(BaseStructure):
self.rules = rules self.rules = rules
self.custom_tools_prompt = custom_tools_prompt self.custom_tools_prompt = custom_tools_prompt
self.memory_chunk_size = memory_chunk_size self.memory_chunk_size = memory_chunk_size
self.agent_ops_on = agent_ops_on
# Name # Name
self.name = agent_name self.name = agent_name
@ -376,12 +378,12 @@ class Agent(BaseStructure):
self.answer = "" self.answer = ""
# The max_loops will be set dynamically if the dynamic_loop # The max_loops will be set dynamically if the dynamic_loop
if self.dynamic_loops: if self.dynamic_loops is True:
logger.info("Dynamic loops enabled") logger.info("Dynamic loops enabled")
self.max_loops = "auto" self.max_loops = "auto"
# If multimodal = yes then set the sop to the multimodal sop # If multimodal = yes then set the sop to the multimodal sop
if self.multi_modal: if self.multi_modal is True:
self.sop = MULTI_MODAL_AUTO_AGENT_SYSTEM_PROMPT_1 self.sop = MULTI_MODAL_AUTO_AGENT_SYSTEM_PROMPT_1
# Memory # Memory
@ -403,54 +405,26 @@ class Agent(BaseStructure):
) )
# If the docs exist then ingest the docs # If the docs exist then ingest the docs
if self.docs is not None: if exists(self.docs):
self.ingest_docs(self.docs) self.ingest_docs(self.docs)
# If docs folder exists then get the docs from docs folder # If docs folder exists then get the docs from docs folder
if self.docs_folder: if exists(self.docs_folder):
self.get_docs_from_doc_folders() self.get_docs_from_doc_folders()
# If tokenizer and context length exists then:
# if self.tokenizer and self.context_length:
# self.truncate_history()
# If verbose is enabled then set the logger level to info
# if verbose is not False:
# logger.setLevel(logging.INFO)
if tools is not None: if tools is not None:
logger.info(
"Tools provided make sure the functions have documentation ++ type hints, otherwise tool execution won't be reliable."
)
# Add the tool prompt to the memory # Add the tool prompt to the memory
self.short_memory.add(role="System", content=tool_sop_prompt()) self.short_memory.add(role="System", content=tool_sop_prompt())
# Print number of tools # Print number of tools
logger.info("Tools granted, initializing tool protocol.")
logger.info(f"Number of tools: {len(tools)}") logger.info(f"Number of tools: {len(tools)}")
logger.info(
"Tools provided, Automatically converting to OpenAI function"
)
# Now the names of the tools
for tool in tools:
logger.info(f"Tool: {tool.__name__}")
# Transform the tools into an openai schema # Transform the tools into an openai schema
for tool in tools: self.convert_tool_into_openai_schema()
# Transform the tool into a openai function calling schema
tool_schema_list = get_openai_function_schema_from_func(
tool,
name=tool.__name__,
description=tool.__doc__,
)
# Transform the dictionary to a string
tool_schema_list = json.dumps(tool_schema_list, indent=4)
# print(tool_schema_list)
# Add the tool schema to the short memory
self.short_memory.add(
role="System", content=tool_schema_list
)
# Now create a function calling map for every tools # Now create a function calling map for every tools
self.function_map = {tool.__name__: tool for tool in tools} self.function_map = {tool.__name__: tool for tool in tools}
@ -522,6 +496,23 @@ class Agent(BaseStructure):
# If the device is not provided then get the device data # If the device is not provided then get the device data
# if agent ops is enabled then import agent ops
if agent_ops_on is True:
try:
from swarms.utils.agent_ops_check import (
try_import_agentops,
)
# Try importing agent ops
logger.info(
"Agent Ops Initializing, ensure that you have the agentops API key and the pip package installed."
)
try_import_agentops()
except ImportError:
logger.error(
"Could not import agentops, try installing agentops: $ pip3 install agentops"
)
def set_system_prompt(self, system_prompt: str): def set_system_prompt(self, system_prompt: str):
"""Set the system prompt""" """Set the system prompt"""
self.system_prompt = system_prompt self.system_prompt = system_prompt
@ -751,7 +742,7 @@ class Agent(BaseStructure):
loop_count = 0 loop_count = 0
# Clear the short memory # Clear the short memory
# response = None response = None
while self.max_loops == "auto" or loop_count < self.max_loops: while self.max_loops == "auto" or loop_count < self.max_loops:
loop_count += 1 loop_count += 1
@ -807,7 +798,17 @@ class Agent(BaseStructure):
# Check if tools is not None # Check if tools is not None
if self.tools is not None: if self.tools is not None:
self.parse_and_execute_tools(response) # self.parse_and_execute_tools(response)
tool_call_output = parse_and_execute_json(
self.tools, response, parse_md=True
)
logger.info(
f"Tool Call Output: {tool_call_output}"
)
self.short_memory.add(
role=self.agent_name,
content=tool_call_output,
)
if self.code_interpreter is not False: if self.code_interpreter is not False:
self.code_interpreter_execution(response) self.code_interpreter_execution(response)
@ -916,6 +917,8 @@ class Agent(BaseStructure):
print(f"Response after output model: {response}") print(f"Response after output model: {response}")
# print(response) # print(response)
if self.agent_ops_on is True:
self.check_end_session_agentops()
return response return response
except Exception as error: except Exception as error:
@ -937,7 +940,7 @@ class Agent(BaseStructure):
def parse_and_execute_tools(self, response: str, *args, **kwargs): def parse_and_execute_tools(self, response: str, *args, **kwargs):
# Extract json from markdown # Extract json from markdown
response = extract_code_from_markdown(response) # response = extract_code_from_markdown(response)
# Try executing the tool # Try executing the tool
if self.execute_tool is not False: if self.execute_tool is not False:
@ -945,11 +948,8 @@ class Agent(BaseStructure):
logger.info("Executing tool...") logger.info("Executing tool...")
# try to Execute the tool and return a string # try to Execute the tool and return a string
out = openai_tool_executor( out = parse_and_execute_json(
tools=response, self.tools, response, parse_md=True, *args, **kwargs
function_map=self.function_map,
*args,
**kwargs,
) )
print(f"Tool Output: {out}") print(f"Tool Output: {out}")
@ -980,6 +980,8 @@ class Agent(BaseStructure):
Returns: Returns:
str: The agent history prompt str: The agent history prompt
""" """
logger.info("Querying long term memory database")
# Query the long term memory database # Query the long term memory database
ltr = self.long_term_memory.query(query, *args, **kwargs) ltr = self.long_term_memory.query(query, *args, **kwargs)
ltr = str(ltr) ltr = str(ltr)
@ -987,7 +989,6 @@ class Agent(BaseStructure):
# Retrieve only the chunk size of the memory # Retrieve only the chunk size of the memory
ltr = retrieve_tokens(ltr, self.memory_chunk_size) ltr = retrieve_tokens(ltr, self.memory_chunk_size)
print(len(ltr))
# print(f"Long Term Memory Query: {ltr}") # print(f"Long Term Memory Query: {ltr}")
return ltr return ltr
@ -1633,3 +1634,59 @@ class Agent(BaseStructure):
"red", "red",
) )
) )
def check_end_session_agentops(self):
if self.agent_ops_on is True:
try:
from swarms.utils.agent_ops_check import (
end_session_agentops,
)
# Try ending the session
return end_session_agentops()
except ImportError:
logger.error(
"Could not import agentops, try installing agentops: $ pip3 install agentops"
)
def convert_tool_into_openai_schema(self):
# Transform the tools into an openai schema
try:
for tool in self.tools:
# Transform the tool into a openai function calling schema
name = tool.__name__
description = tool.__doc__
try:
logger.info(
"Tool -> OpenAI Schema Process Starting Now."
)
tool_schema_list = (
get_openai_function_schema_from_func(
tool, name=name, description=description
)
)
# Transform the dictionary to a string
tool_schema_list = json.dumps(
tool_schema_list, indent=4
)
# Add the tool schema to the short memory
self.short_memory.add(
role="System", content=tool_schema_list
)
logger.info(
f"Conversion process successful, the tool {name} has been integrated with the agent successfully."
)
except Exception as error:
logger.info(
f"There was an error converting your tool into a OpenAI certified function calling schema. Add documentation and type hints: {error}"
)
raise error
except Exception as error:
logger.info(
f"Error detected: {error} make sure you have inputted a callable and that it has documentation as docstrings"
)
raise error

@ -68,7 +68,7 @@ class BaseStructure:
self, self,
name: Optional[str] = None, name: Optional[str] = None,
description: Optional[str] = None, description: Optional[str] = None,
save_metadata: bool = True, save_metadata_on: bool = True,
save_artifact_path: Optional[str] = "./artifacts", save_artifact_path: Optional[str] = "./artifacts",
save_metadata_path: Optional[str] = "./metadata", save_metadata_path: Optional[str] = "./metadata",
save_error_path: Optional[str] = "./errors", save_error_path: Optional[str] = "./errors",
@ -76,7 +76,7 @@ class BaseStructure:
super().__init__() super().__init__()
self.name = name self.name = name
self.description = description self.description = description
self.save_metadata = save_metadata self.save_metadata_on = save_metadata_on
self.save_artifact_path = save_artifact_path self.save_artifact_path = save_artifact_path
self.save_metadata_path = save_metadata_path self.save_metadata_path = save_metadata_path
self.save_error_path = save_error_path self.save_error_path = save_error_path

@ -1,3 +1,4 @@
import uuid
import asyncio import asyncio
import json import json
from abc import ABC from abc import ABC
@ -17,11 +18,12 @@ from swarms.structs.agent import Agent
from swarms.structs.conversation import Conversation from swarms.structs.conversation import Conversation
from swarms.utils.loguru_logger import logger from swarms.utils.loguru_logger import logger
from swarms.structs.omni_agent_types import AgentType from swarms.structs.omni_agent_types import AgentType
from swarms.memory.base_vectordb import BaseVectorDatabase
class BaseSwarm(ABC): class BaseSwarm(ABC):
""" """
Abstract Swarm Class for multi-agent systems Base Swarm Class for all multi-agent systems
Attributes: Attributes:
agents (List[Agent]): A list of agents agents (List[Agent]): A list of agents
@ -83,6 +85,10 @@ class BaseSwarm(ABC):
stopping_function: Optional[Callable] = None, stopping_function: Optional[Callable] = None,
stopping_condition: Optional[str] = "stop", stopping_condition: Optional[str] = "stop",
stopping_condition_args: Optional[Dict] = None, stopping_condition_args: Optional[Dict] = None,
agentops_on: Optional[bool] = False,
speaker_selection_func: Optional[Callable] = None,
rules: Optional[str] = None,
collective_memory_system: Optional[BaseVectorDatabase] = False,
*args, *args,
**kwargs, **kwargs,
): ):
@ -100,10 +106,28 @@ class BaseSwarm(ABC):
self.stopping_function = stopping_function self.stopping_function = stopping_function
self.stopping_condition = stopping_condition self.stopping_condition = stopping_condition
self.stopping_condition_args = stopping_condition_args self.stopping_condition_args = stopping_condition_args
self.agentops_on = agentops_on
self.speaker_selection_func = speaker_selection_func
self.rules = rules
self.collective_memory_system = collective_memory_system
# Ensure that agents is exists
if self.agents is None:
raise ValueError("Agents must be provided.")
# Ensure that agents is a list
if not isinstance(self.agents, list):
logger.error("Agents must be a list.")
raise TypeError("Agents must be a list.")
# Ensure that agents is not empty
if len(self.agents) == 0:
logger.error("Agents list must not be empty.")
raise ValueError("Agents list must not be empty.")
# Initialize conversation # Initialize conversation
self.conversation = Conversation( self.conversation = Conversation(
time_enabled=True, *args, **kwargs time_enabled=True, rules=self.rules, *args, **kwargs
) )
# Handle callbacks # Handle callbacks
@ -116,12 +140,6 @@ class BaseSwarm(ABC):
if autosave: if autosave:
self.save_to_json(metadata_filename) self.save_to_json(metadata_filename)
# Handle logging
if self.agents:
logger.info(
f"Swarm initialized with {len(self.agents)} agents"
)
# Handle stopping function # Handle stopping function
if stopping_function is not None: if stopping_function is not None:
if not callable(stopping_function): if not callable(stopping_function):
@ -139,8 +157,27 @@ class BaseSwarm(ABC):
self.stopping_condition_args = stopping_condition_args self.stopping_condition_args = stopping_condition_args
self.stopping_condition = stopping_condition self.stopping_condition = stopping_condition
# If agentops is enabled, try to import agentops
if agentops_on is True:
for agent in self.agents:
agent.agent_ops_on = True
# Handle speaker selection function
if speaker_selection_func is not None:
if not callable(speaker_selection_func):
raise TypeError(
"Speaker selection function must be callable."
)
self.speaker_selection_func = speaker_selection_func
# Agents dictionary with agent name as key and agent object as value
self.agents_dict = {
agent.agent_name: agent for agent in self.agents
}
def communicate(self): def communicate(self):
"""Communicate with the swarm through the orchestrator, protocols, and the universal communication layer""" """Communicate with the swarm through the orchestrator, protocols, and the universal communication layer"""
...
def run(self): def run(self):
"""Run the swarm""" """Run the swarm"""
@ -221,6 +258,21 @@ class BaseSwarm(ABC):
return agent return agent
return None return None
def self_find_agent_by_id(self, id: uuid.UUID):
"""
Find an agent by its id.
Args:
id (str): The id of the agent to find.
Returns:
Agent: The Agent object if found, None otherwise.
"""
for agent in self.agents:
if agent.id == id:
return agent
return None
def agent_exists(self, name: str): def agent_exists(self, name: str):
""" """
Check if an agent exists in the swarm. Check if an agent exists in the swarm.
@ -391,24 +443,6 @@ class BaseSwarm(ABC):
""" """
return self.batched_run(tasks, *args, **kwargs) return self.batched_run(tasks, *args, **kwargs)
def reset_all_agents(self):
"""Reset all agents
Returns:
"""
for agent in self.agents:
agent.reset()
def select_agent(self, agent_id: str):
"""
Select an agent through their id
"""
# Find agent with id
for agent in self.agents:
if agent.id == agent_id:
return agent
def select_agent_by_name(self, agent_name: str): def select_agent_by_name(self, agent_name: str):
""" """
Select an agent through their name Select an agent through their name
@ -650,3 +684,6 @@ class BaseSwarm(ABC):
def __contains__(self, value): def __contains__(self, value):
return value in self.agents return value in self.agents
def __eq__(self, other):
return self.__dict__ == other.__dict__

@ -0,0 +1,48 @@
from typing import List
import json
import loguru
from swarms.utils.parse_code import extract_code_from_markdown
def parse_and_execute_json(
functions: List[callable] = None,
json_string: str = None,
parse_md: bool = False,
):
"""
Parses and executes a JSON string containing function name and parameters.
Args:
functions (List[callable]): A list of callable functions.
json_string (str): The JSON string to parse and execute.
parse_md (bool): Flag indicating whether to extract code from Markdown.
Returns:
The result of executing the function with the parsed parameters, or None if an error occurs.
"""
if parse_md:
json_string = extract_code_from_markdown(json_string)
try:
# Create a dictionary that maps function names to functions
function_dict = {func.__name__: func for func in functions}
loguru.logger.info(f"Extracted code: {json_string}")
data = json.loads(json_string)
function_name = data.get("function", {}).get("name")
parameters = data.get("function", {}).get("parameters")
# Check if the function name is in the function dictionary
if function_name in function_dict:
# Call the function with the parsed parameters
result = function_dict[function_name](**parameters)
return result
else:
loguru.logger.warning(
f"No function named '{function_name}' found."
)
return None
except Exception as e:
loguru.logger.error(f"Error: {e}")
return None

@ -0,0 +1,28 @@
from swarms.utils.loguru_logger import logger
import os
from dotenv import load_dotenv
def try_import_agentops(*args, **kwargs):
try:
load_dotenv()
logger.info("Trying to import agentops")
import agentops
agentops.init(os.getenv("AGENTOPS_API_KEY"), *args, **kwargs)
return "agentops imported successfully."
except ImportError:
logger.error("Could not import agentops")
def end_session_agentops():
try:
logger.info("Trying to end session")
import agentops
agentops.end_session("Success")
return "Session ended successfully."
except ImportError:
logger.error("Could not import agentops")
return "Could not end session."
Loading…
Cancel
Save