diff --git a/LICENSE b/LICENSE index 99448361..d7b6bd18 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,5 @@ - -# Creative Commons Attribution 4.0 International Public License +Creative Commons Attribution 4.0 International Public License By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons diff --git a/README.md b/README.md index 7abcc3a1..3a868771 100644 --- a/README.md +++ b/README.md @@ -213,6 +213,52 @@ print(out) ``` +# `Agent` with Long Term Memory ++ Tools! +An LLM equipped with long term memory and tools, a full stack agent capable of automating all and any digital tasks given a good prompt. + +```python +from swarms import Agent, ChromaDB, OpenAIChat, tool + +# Making an instance of the ChromaDB class +memory = ChromaDB( + metric="cosine", + n_results=3, + output_dir="results", + docs_folder="docs", +) + +# Initialize a tool +@tool +def search_api(query: str): + # Add your logic here + return query + +# Initializing the agent with the Gemini instance and other parameters +agent = Agent( + agent_name="Covid-19-Chat", + agent_description=( + "This agent provides information about COVID-19 symptoms." + ), + llm=OpenAIChat(), + max_loops="auto", + autosave=True, + verbose=True, + long_term_memory=memory, + stopping_condition="finish", + tools=[search_api], +) + +# Defining the task and image path +task = ("What are the symptoms of COVID-19?",) + +# Running the agent with the specified task and image +out = agent.run(task) +print(out) + +``` + + + @@ -873,6 +919,10 @@ agent = Agent( # Run the workflow on a task agent.run(task=task, img=img) ``` +---- + + +## Build your own LLMs, Agents, and Swarms! ### Swarms Compliant Model Interface ```python @@ -935,6 +985,16 @@ agent = MyCustomAgent() out = agent("Analyze and summarize these financial documents: ") print(out) +``` + + +### Compliant Interface for Multi-Agent Collaboration + +```python +from swarms import Agent, AbstractSwarm + + + ``` --- diff --git a/playground/agents/sales_team.py b/playground/agents/sales_team.py new file mode 100644 index 00000000..e69de29b diff --git a/pyproject.toml b/pyproject.toml index 32f9438d..4f54b588 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,7 @@ build-backend = "poetry.core.masonry.api" [tool.poetry] name = "swarms" -version = "4.6.1" +version = "4.6.7" description = "Swarms - Pytorch" license = "MIT" authors = ["Kye Gomez "] diff --git a/swarms/__init__.py b/swarms/__init__.py index db28200e..4d6eef0a 100644 --- a/swarms/__init__.py +++ b/swarms/__init__.py @@ -11,12 +11,10 @@ activate_sentry() from swarms.agents import * # noqa: E402, F403 from swarms.artifacts import * # noqa: E402, F403 -from swarms.chunkers import * # noqa: E402, F403 from swarms.memory import * # noqa: E402, F403 from swarms.models import * # noqa: E402, F403 from swarms.prompts import * # noqa: E402, F403 from swarms.structs import * # noqa: E402, F403 from swarms.telemetry import * # noqa: E402, F403 from swarms.tools import * # noqa: E402, F403 -from swarms.utils import * # noqa: E402, F403 -from swarms.schedulers import * # noqa: E402, F403 +from swarms.utils import * # noqa: E402, F403 \ No newline at end of file diff --git a/swarms/artifacts/text_artifact.py b/swarms/artifacts/text_artifact.py index 5fdfe4fa..13ca4dfd 100644 --- a/swarms/artifacts/text_artifact.py +++ b/swarms/artifacts/text_artifact.py @@ -1,9 +1,8 @@ from __future__ import annotations from dataclasses import dataclass, field - +from typing import Callable from swarms.artifacts.base_artifact import BaseArtifact -from swarms.tokenizers.base_tokenizer import BaseTokenizer @dataclass @@ -31,6 +30,7 @@ class TextArtifact(BaseArtifact): value: str encoding: str = "utf-8" encoding_error_handler: str = "strict" + tokenizer: Callable = None _embedding: list[float] = field(default_factory=list) @property @@ -49,8 +49,8 @@ class TextArtifact(BaseArtifact): return self.embedding - def token_count(self, tokenizer: BaseTokenizer) -> int: - return tokenizer.count_tokens(str(self.value)) + def token_count(self) -> int: + return self.tokenizer.count_tokens(str(self.value)) def to_bytes(self) -> bytes: return self.value.encode( diff --git a/swarms/models/__init__.py b/swarms/models/__init__.py index 18f25b53..8b60597f 100644 --- a/swarms/models/__init__.py +++ b/swarms/models/__init__.py @@ -38,7 +38,7 @@ from swarms.models.popular_llms import ( ReplicateLLM as Replicate, ) from swarms.models.qwen import QwenVLMultiModal # noqa: E402 -from swarms.models.sam_supervision import SegmentAnythingMarkGenerator +# from swarms.models.sam_supervision import SegmentAnythingMarkGenerator from swarms.models.sampling_params import SamplingParams, SamplingType from swarms.models.together import TogetherLLM # noqa: E402 from swarms.models.types import ( # noqa: E402 @@ -79,7 +79,6 @@ __all__ = [ "Replicate", "SamplingParams", "SamplingType", - "SegmentAnythingMarkGenerator", "TextModality", "TogetherLLM", "Vilt", diff --git a/swarms/models/base_embedding_model.py b/swarms/models/base_embedding_model.py index 4cdead11..04999f12 100644 --- a/swarms/models/base_embedding_model.py +++ b/swarms/models/base_embedding_model.py @@ -4,11 +4,8 @@ from abc import ABC, abstractmethod from dataclasses import dataclass, field import numpy as np - +from typing import Callable from swarms.artifacts.text_artifact import TextArtifact -from swarms.chunkers.base_chunker import BaseChunker -from swarms.chunkers.text_chunker import TextChunker -from swarms.tokenizers.base_tokenizer import BaseTokenizer from swarms.utils.exponential_backoff import ExponentialBackoffMixin @@ -25,12 +22,8 @@ class BaseEmbeddingModel( """ model: str = None - tokenizer: BaseTokenizer | None = None - chunker: BaseChunker = field(init=False) - - def __post_init__(self) -> None: - if self.tokenizer: - self.chunker = TextChunker(tokenizer=self.tokenizer) + tokenizer: Callable = None + chunker: Callable = None def embed_text_artifact( self, artifact: TextArtifact diff --git a/swarms/models/sam_supervision.py b/swarms/models/sam_supervision.py index 5649f187..1ee7824c 100644 --- a/swarms/models/sam_supervision.py +++ b/swarms/models/sam_supervision.py @@ -1,5 +1,4 @@ -from typing import Optional - +from typing import Optional, Callable import cv2 import numpy as np import supervision as sv @@ -12,7 +11,6 @@ from transformers import ( ) from swarms.models.base_multimodal_model import BaseMultiModalModel -from swarms.utils.supervision_masking import masks_to_marks class SegmentAnythingMarkGenerator(BaseMultiModalModel): @@ -30,6 +28,7 @@ class SegmentAnythingMarkGenerator(BaseMultiModalModel): device: str = "cpu", model_name: str = "facebook/sam-vit-huge", visualize_marks: bool = False, + masks_to_marks: Callable = sv.masks_to_marks, *args, **kwargs, ): @@ -37,6 +36,7 @@ class SegmentAnythingMarkGenerator(BaseMultiModalModel): self.device = device self.model_name = model_name self.visualize_marks = visualize_marks + self.masks_to_marks = masks_to_marks self.model = SamModel.from_pretrained( model_name, *args, **kwargs @@ -74,7 +74,7 @@ class SegmentAnythingMarkGenerator(BaseMultiModalModel): if mask is None: outputs = self.pipeline(image, points_per_batch=64) masks = np.array(outputs["masks"]) - return masks_to_marks(masks=masks) + return self.masks_to_marks(masks=masks) else: inputs = self.processor(image, return_tensors="pt").to( self.device @@ -112,6 +112,6 @@ class SegmentAnythingMarkGenerator(BaseMultiModalModel): ) masks.append(mask) masks = np.array(masks) - return masks_to_marks(masks=masks) + return self.masks_to_marks(masks=masks) # def visualize_img(self): diff --git a/swarms/structs/__init__.py b/swarms/structs/__init__.py index 2f6c9a70..39e8057e 100644 --- a/swarms/structs/__init__.py +++ b/swarms/structs/__init__.py @@ -69,7 +69,6 @@ from swarms.structs.task_queue_base import ( TaskQueueBase, synchronized_queue, ) -from swarms.structs.tool_json_schema import JSON from swarms.structs.utils import ( detect_markdown, distribute_tasks, @@ -80,39 +79,47 @@ from swarms.structs.utils import ( parse_tasks, ) + + __all__ = [ "Agent", - "SequentialWorkflow", + "AgentJob", + "AgentProcess", + "AgentProcessQueue", + "AutoSwarm", + "AutoSwarmRouter", "AutoScaler", - "Conversation", - "TaskInput", - "Artifact", - "ArtifactUpload", - "StepInput", - "SwarmNetwork", - "ModelParallelizer", - "MultiAgentCollaboration", + "BaseStructure", "AbstractSwarm", - "GroupChat", - "GroupChatManager", - "parse_tasks", - "find_agent_by_id", - "distribute_tasks", - "find_token_in_text", - "extract_key_from_json", - "extract_tokens_from_text", - "ConcurrentWorkflow", - "RecursiveWorkflow", - "NonlinearWorkflow", "BaseWorkflow", - "BaseStructure", - "detect_markdown", - "Task", "block", + "ConcurrentWorkflow", + "Conversation", "GraphWorkflow", - "Step", - "Plan", + "GroupChat", + "GroupChatManager", + "MajorityVoting", + "majority_voting", + "most_frequent", + "parse_code_completion", "Message", + "ModelParallelizer", + "MultiAgentCollaboration", + "MultiProcessWorkflow", + "MultiThreadedWorkflow", + "NonlinearWorkflow", + "Plan", + "RecursiveWorkflow", + "Artifact", + "ArtifactUpload", + "StepInput", + "StepOutput", + "StepRequestBody", + "TaskInput", + "TaskRequestBody", + "SequentialWorkflow", + "Step", + "SwarmNetwork", "broadcast", "circular_swarm", "exponential_swarm", @@ -131,21 +138,14 @@ __all__ = [ "sigmoid_swarm", "staircase_swarm", "star_swarm", - "StepOutput", - "StepRequestBody", - "TaskRequestBody", - "JSON", - "most_frequent", - "parse_code_completion", - "majority_voting", - "MajorityVoting", - "synchronized_queue", + "Task", "TaskQueueBase", - "MultiProcessWorkflow", - "MultiThreadedWorkflow", - "AgentJob", - "AutoSwarm", - "AutoSwarmRouter", - "AgentProcess", - "AgentProcessQueue", -] + "synchronized_queue", + "detect_markdown", + "distribute_tasks", + "extract_key_from_json", + "extract_tokens_from_text", + "find_agent_by_id", + "find_token_in_text", + "parse_tasks", +] \ No newline at end of file diff --git a/swarms/structs/agent.py b/swarms/structs/agent.py index 3b917d67..4dbca710 100644 --- a/swarms/structs/agent.py +++ b/swarms/structs/agent.py @@ -19,13 +19,11 @@ from swarms.prompts.multi_modal_autonomous_instruction_prompt import ( ) from swarms.prompts.worker_prompt import worker_tools_sop_promp from swarms.structs.conversation import Conversation -from swarms.tokenizers.base_tokenizer import BaseTokenizer from swarms.tools.tool import BaseTool from swarms.utils.code_interpreter import SubprocessCodeInterpreter from swarms.utils.data_to_text import data_to_text from swarms.utils.parse_code import extract_code_from_markdown from swarms.utils.pdf_to_text import pdf_to_text -from swarms.utils.token_count_tiktoken import limit_tokens_from_string # Utils @@ -184,7 +182,7 @@ class Agent: multi_modal: Optional[bool] = None, pdf_path: Optional[str] = None, list_of_pdf: Optional[str] = None, - tokenizer: Optional[BaseTokenizer] = None, + tokenizer: Optional[Any] = None, long_term_memory: Optional[AbstractVectorDatabase] = None, preset_stopping_token: Optional[bool] = False, traceback: Any = None, @@ -208,6 +206,7 @@ class Agent: sentiment_threshold: Optional[float] = None, custom_exit_command: Optional[str] = "exit", sentiment_analyzer: Optional[Callable] = None, + limit_tokens_from_string: Optional[Callable] = None, *args, **kwargs, ): @@ -267,6 +266,7 @@ class Agent: self.sentiment_threshold = sentiment_threshold self.custom_exit_command = custom_exit_command self.sentiment_analyzer = sentiment_analyzer + self.limit_tokens_from_string = limit_tokens_from_string # The max_loops will be set dynamically if the dynamic_loop if self.dynamic_loops: @@ -1262,7 +1262,7 @@ class Agent: _type_: _description_ """ text = text or self.pdf_connector() - text = limit_tokens_from_string(text, num_limits) + text = self.limit_tokens_from_string(text, num_limits) return text def ingest_docs(self, docs: List[str], *args, **kwargs): diff --git a/swarms/structs/agent_process.py b/swarms/structs/agent_process.py index cd9ca6e3..8f0523af 100644 --- a/swarms/structs/agent_process.py +++ b/swarms/structs/agent_process.py @@ -4,6 +4,7 @@ from pydantic import BaseModel from swarms.structs.omni_agent_types import agents from swarms.utils.loguru_logger import logger +from typing import Callable class AgentProcess(BaseModel): @@ -11,10 +12,11 @@ class AgentProcess(BaseModel): agent_name: str prompt: str response: str = None - time: callable = datetime.now().strftime("%Y-%m-%d %H:%M:%S") + time: Callable = datetime.now().strftime("%Y-%m-%d %H:%M:%S") priority: int = 0 status: str = "Waiting" pid: int = None + def set_pid(self, pid: int): self.pid = pid diff --git a/swarms/structs/conversation.py b/swarms/structs/conversation.py index 4f426cbf..bf0265f0 100644 --- a/swarms/structs/conversation.py +++ b/swarms/structs/conversation.py @@ -6,7 +6,7 @@ from termcolor import colored from swarms.memory.base_db import AbstractDatabase from swarms.structs.base import BaseStructure -from swarms.tokenizers.base_tokenizer import BaseTokenizer +from typing import Any class Conversation(BaseStructure): @@ -67,7 +67,7 @@ class Conversation(BaseStructure): database: AbstractDatabase = None, autosave: bool = False, save_filepath: str = None, - tokenizer: BaseTokenizer = None, + tokenizer: Any = None, context_length: int = 8192, *args, **kwargs, diff --git a/swarms/utils/__init__.py b/swarms/utils/__init__.py index 583f61d5..7a057975 100644 --- a/swarms/utils/__init__.py +++ b/swarms/utils/__init__.py @@ -41,7 +41,6 @@ from swarms.utils.remove_json_whitespace import ( ) from swarms.utils.save_logs import parse_log_file from swarms.utils.supervision_visualizer import MarkVisualizer -from swarms.utils.token_count_tiktoken import limit_tokens_from_string from swarms.utils.try_except_wrapper import try_except_wrapper from swarms.utils.yaml_output_parser import YamlOutputParser from swarms.utils.concurrent_utils import execute_concurrently @@ -79,7 +78,7 @@ __all__ = [ "remove_whitespace_from_yaml", "parse_log_file", "MarkVisualizer", - "limit_tokens_from_string", + # "limit_tokens_from_string", "try_except_wrapper", "YamlOutputParser", "execute_concurrently",