diff --git a/docs/mkdocs.yml b/docs/mkdocs.yml index df7314db..c8482b8b 100644 --- a/docs/mkdocs.yml +++ b/docs/mkdocs.yml @@ -228,7 +228,15 @@ nav: - Quickstart: "quickstart.md" - Agents: "swarms/agents/index.md" - Multi-Agent Architectures: "swarms/structs/index.md" + + - Protocol: + - Overview: "protocol/overview.md" + - SIPs: "protocol/sip.md" - Feature Set: "swarms/features.md" + - Swarms Ecosystem: "swarms/ecosystem.md" + - Technical Support: "swarms/support.md" + + - Agents: - Overview: "swarms/framework/agents_explained.md" - Quickstart: "swarms/agents/index.md" @@ -319,10 +327,6 @@ nav: - Communication Structure: "swarms/structs/conversation.md" - - Protocol: - - Overview: "protocol/overview.md" - - SIPs: "protocol/sip.md" - - Tools: - Overview: "swarms_tools/overview.md" - BaseTool Reference: "swarms/tools/base_tool.md" @@ -346,10 +350,6 @@ nav: - Deploy on Phala: "swarms_cloud/phala_deploy.md" # - Deploy on FastAPI: "swarms_cloud/fastapi_deploy.md" - - More About Us: - - Swarms Ecosystem: "swarms/ecosystem.md" - - Technical Support: "swarms/support.md" - - Examples: - Overview: "examples/index.md" @@ -491,7 +491,7 @@ nav: - Understanding Swarms Architecture: "swarms/concept/framework_architecture.md" - Development Philosophy & Principles: "swarms/concept/philosophy.md" - - About Swarms: - - Vision & Mission: "swarms/concept/vision.md" - - Swarm Ecosystem: "swarms/concept/swarm_ecosystem.md" - - Products: "swarms/products.md" + # - About Swarms: + # - Vision & Mission: "swarms/concept/vision.md" + # - Swarm Ecosystem: "swarms/concept/swarm_ecosystem.md" + # - Products: "swarms/products.md" diff --git a/docs/protocol/overview.md b/docs/protocol/overview.md index 43cdec2a..74445d17 100644 --- a/docs/protocol/overview.md +++ b/docs/protocol/overview.md @@ -24,30 +24,25 @@ The Swarms protocol is organized into several key layers, each responsible for a (stateful, with memory and reasoning capabilities). - Agents can be specialized for different tasks (e.g., reasoning agents, tool agents, judge agents, etc.). - - Example: A `ReasoningAgent` that can analyze data and make decisions, or a `ToolAgent` that wraps external APIs. - - [Quickstart for Agents](https://docs.swarms.world/en/latest/swarms/agents/) - - [Agent API Reference](https://docs.swarms.world/en/latest/swarms/structs/agent/) - 2. **Tools with Memory (`swarms/tools`, `swarms/utils`)** - Tools are modular components that agents use to interact with the outside world, perform computations, or access resources (APIs, databases, files, etc.). - Memory modules and utility functions allow agents to retain context, cache results, and manage state across interactions. - + - Example: A tool for calling an LLM API, a memory cache for conversation history, or a utility for parsing and formatting data. - + - [Tools Overview](https://docs.swarms.world/en/latest/swarms_tools/overview/) - + - [BaseTool Reference](https://docs.swarms.world/en/latest/swarms/tools/base_tool/) - 3. **Reasoning & Specialized Agents (`swarms/agents`)** - These agents build on the base agent class, adding advanced reasoning, self-consistency, and specialized logic for tasks like planning, evaluation, or multi-step workflows. @@ -58,12 +53,11 @@ The Swarms protocol is organized into several key layers, each responsible for a agents. - [Reasoning Agents Overview](https://docs.swarms.world/en/latest/swarms/agents/reasoning_agents_overview/) - + - [Self Consistency Agent](https://docs.swarms.world/en/latest/swarms/agents/consistency_agent/) - + - [Agent Judge](https://docs.swarms.world/en/latest/swarms/agents/agent_judge/) - 4. **Multi-Agent Structures (`swarms/structs`)** - Agents are composed into higher-order structures for collaboration, voting, parallelism, and workflow orchestration. @@ -73,16 +67,15 @@ The Swarms protocol is organized into several key layers, each responsible for a sub-agents. - [Multi-Agent Architectures Overview](https://docs.swarms.world/en/latest/swarms/concept/swarm_architectures/) - + - [MajorityVotingSwarm](https://docs.swarms.world/en/latest/swarms/structs/majorityvoting/) - + - [HierarchicalSwarm](https://docs.swarms.world/en/latest/swarms/structs/hierarchical_swarm/) - + - [Sequential Workflow](https://docs.swarms.world/en/latest/swarms/structs/sequential_workflow/) - + - [Concurrent Workflow](https://docs.swarms.world/en/latest/swarms/structs/concurrentworkflow/) - 5. **Supporting Components** - **Communication (`swarms/communication`)**: Provides wrappers for inter-agent communication, database access, message passing, and @@ -95,7 +88,7 @@ The Swarms protocol is organized into several key layers, each responsible for a [Prompts Management](https://docs.swarms.world/en/latest/swarms/prompts/main/) - **Telemetry (`swarms/telemetry`)**: Handles logging, monitoring, and bootup routines for observability and debugging. - + - **Schemas (`swarms/schemas`)**: Defines data schemas for agents, tools, completions, and communication protocols, ensuring type safety and consistency. @@ -104,6 +97,34 @@ The Swarms protocol is organized into several key layers, each responsible for a --- +## Proposing Large Improvements or Enhancements: Swarms Improvement Proposals (SIPs) + +For significant changes, new agent architectures, or radical new features, Swarms uses a formal process called **Swarms Improvement Proposals (SIPs)**. SIPs are design documents that describe new features, enhancements, or changes to the Swarms framework. They ensure that major changes are well-documented, discussed, and reviewed by the community before implementation. + +**When to use a SIP:** + +- Proposing new agent types, swarm patterns, or coordination mechanisms + +- Core framework changes or breaking changes + +- New integrations (LLM providers, tools, external services) + +- Any complex or multi-component feature + +**SIP Process Overview:** + +1. Discuss your idea in [GitHub Discussions](https://github.com/kyegomez/swarms/discussions) + +2. Submit a SIP as a GitHub Issue using the SIP template + +3. Engage with the community and iterate on your proposal + +4. Undergo review and, if accepted, proceed to implementation + +**Learn more:** See the full [SIP Guidelines and Template](https://docs.swarms.world/en/latest/protocol/sip/) + +--- + ## Detailed Architecture Diagram The following Mermaid diagram visualizes the protocol flow and the relationship between the main folders in the `swarms/` package: @@ -409,6 +430,8 @@ For more on the philosophy and architecture, see [Development Philosophy & Princ - [Understanding Swarms Architecture](https://docs.swarms.world/en/latest/swarms/concept/framework_architecture/) +- [SIP Guidelines and Template](https://docs.swarms.world/en/latest/protocol/sip/) + # Conclusion diff --git a/examples/multi_agent/concurrent_examples/streaming_concurrent_workflow.py b/examples/multi_agent/concurrent_examples/streaming_concurrent_workflow.py new file mode 100644 index 00000000..c8dc9366 --- /dev/null +++ b/examples/multi_agent/concurrent_examples/streaming_concurrent_workflow.py @@ -0,0 +1,62 @@ +from swarms import Agent, ConcurrentWorkflow, SwarmRouter + +# Initialize market research agent +market_researcher = Agent( + agent_name="Market-Researcher", + system_prompt="""You are a market research specialist. Your tasks include: + 1. Analyzing market trends and patterns + 2. Identifying market opportunities and threats + 3. Evaluating competitor strategies + 4. Assessing customer needs and preferences + 5. Providing actionable market insights""", + model_name="claude-3-5-sonnet-20240620", + max_loops=1, + streaming_on=True, + print_on=False, +) + +# Initialize financial analyst agent +financial_analyst = Agent( + agent_name="Financial-Analyst", + system_prompt="""You are a financial analysis expert. Your responsibilities include: + 1. Analyzing financial statements + 2. Evaluating investment opportunities + 3. Assessing risk factors + 4. Providing financial forecasts + 5. Recommending financial strategies""", + model_name="claude-3-5-sonnet-20240620", + max_loops=1, + streaming_on=True, + print_on=False, +) + +# Initialize technical analyst agent +technical_analyst = Agent( + agent_name="Technical-Analyst", + system_prompt="""You are a technical analysis specialist. Your focus areas include: + 1. Analyzing price patterns and trends + 2. Evaluating technical indicators + 3. Identifying support and resistance levels + 4. Assessing market momentum + 5. Providing trading recommendations""", + model_name="claude-3-5-sonnet-20240620", + max_loops=1, + streaming_on=True, + print_on=False, +) + +# Create list of agents +agents = [market_researcher, financial_analyst, technical_analyst] + +# Initialize the concurrent workflow +workflow = ConcurrentWorkflow( + name="market-analysis-workflow", + agents=agents, + max_loops=1, + show_dashboard=True, +) + +# Run the workflow +result = workflow.run( + "Analyze Tesla (TSLA) stock from market, financial, and technical perspectives" +) \ No newline at end of file diff --git a/swarms/structs/agent.py b/swarms/structs/agent.py index 8ed7707a..ce57c65f 100644 --- a/swarms/structs/agent.py +++ b/swarms/structs/agent.py @@ -996,6 +996,7 @@ class Agent: self, task: Optional[Union[str, Any]] = None, img: Optional[str] = None, + streaming_callback: Optional[Callable[[str], None]] = None, *args, **kwargs, ) -> Any: @@ -1077,6 +1078,7 @@ class Agent: task=task_prompt, img=img, current_loop=loop_count, + streaming_callback=streaming_callback, *args, **kwargs, ) @@ -1084,6 +1086,7 @@ class Agent: response = self.call_llm( task=task_prompt, current_loop=loop_count, + streaming_callback=streaming_callback, *args, **kwargs, ) @@ -2470,6 +2473,7 @@ class Agent: task: str, img: Optional[str] = None, current_loop: int = 0, + streaming_callback: Optional[Callable[[str], None]] = None, *args, **kwargs, ) -> str: @@ -2480,6 +2484,7 @@ class Agent: task (str): The task to be performed by the `llm` object. img (str, optional): Path or URL to an image file. audio (str, optional): Path or URL to an audio file. + streaming_callback (Optional[Callable[[str], None]]): Callback function to receive streaming tokens in real-time. *args: Variable length argument list. **kwargs: Arbitrary keyword arguments. @@ -2515,8 +2520,24 @@ class Agent: if hasattr( streaming_response, "__iter__" ) and not isinstance(streaming_response, str): + # Check if streaming_callback is provided (for ConcurrentWorkflow dashboard integration) + if streaming_callback is not None: + # Real-time callback streaming for dashboard integration + chunks = [] + for chunk in streaming_response: + if ( + hasattr(chunk, "choices") + and chunk.choices[0].delta.content + ): + content = chunk.choices[ + 0 + ].delta.content + chunks.append(content) + # Call the streaming callback with the new chunk + streaming_callback(content) + complete_response = "".join(chunks) # Check print_on parameter for different streaming behaviors - if self.print_on is False: + elif self.print_on is False: # Silent streaming - no printing, just collect chunks chunks = [] for chunk in streaming_response: @@ -2599,6 +2620,7 @@ class Agent: img: Optional[str] = None, imgs: Optional[List[str]] = None, correct_answer: Optional[str] = None, + streaming_callback: Optional[Callable[[str], None]] = None, *args, **kwargs, ) -> Any: @@ -2613,6 +2635,7 @@ class Agent: task (Optional[str], optional): The task to be executed. Defaults to None. img (Optional[str], optional): The image to be processed. Defaults to None. imgs (Optional[List[str]], optional): The list of images to be processed. Defaults to None. + streaming_callback (Optional[Callable[[str], None]], optional): Callback function to receive streaming tokens in real-time. Defaults to None. *args: Additional positional arguments to be passed to the execution method. **kwargs: Additional keyword arguments to be passed to the execution method. @@ -2644,6 +2667,7 @@ class Agent: output = self._run( task=task, img=img, + streaming_callback=streaming_callback, *args, **kwargs, ) diff --git a/swarms/structs/concurrent_workflow.py b/swarms/structs/concurrent_workflow.py index 7f0c0d65..e045441d 100644 --- a/swarms/structs/concurrent_workflow.py +++ b/swarms/structs/concurrent_workflow.py @@ -1,5 +1,6 @@ import concurrent.futures import os +import time from typing import Callable, List, Optional, Union from swarms.structs.agent import Agent @@ -450,8 +451,25 @@ class ConcurrentWorkflow(BaseSwarm): if self.show_dashboard: self.display_agent_dashboard() - # Run the agent - output = agent.run(task=task, img=img, imgs=imgs) + # Create a streaming callback for this agent with throttling + last_update_time = [0] # Use list to allow modification in nested function + update_interval = 0.1 # Update dashboard every 100ms for smooth streaming + + def streaming_callback(chunk: str): + """Update dashboard with streaming content""" + if self.show_dashboard: + # Append the chunk to the agent's current output + current_output = self.agent_statuses[agent.agent_name]["output"] + self.agent_statuses[agent.agent_name]["output"] = current_output + chunk + + # Throttle dashboard updates for better performance + current_time = time.time() + if current_time - last_update_time[0] >= update_interval: + self.display_agent_dashboard() + last_update_time[0] = current_time + + # Run the agent with streaming callback + output = agent.run(task=task, img=img, imgs=imgs, streaming_callback=streaming_callback) # Update status to completed self.agent_statuses[agent.agent_name][ diff --git a/swarms/structs/interactive_groupchat.py b/swarms/structs/interactive_groupchat.py index f87a2091..53e786ff 100644 --- a/swarms/structs/interactive_groupchat.py +++ b/swarms/structs/interactive_groupchat.py @@ -963,15 +963,21 @@ Remember: You are part of a team. Your response should reflect that you've read, to respond to the user query. """ # Filter out invalid agents - valid_agents = [name for name in mentioned_agents if name in self.agent_map] - + valid_agents = [ + name + for name in mentioned_agents + if name in self.agent_map + ] + if not valid_agents: - raise AgentNotFoundError("No valid agents found in the conversation") - + raise AgentNotFoundError( + "No valid agents found in the conversation" + ) + # Randomly select exactly one agent to respond random_agent = random.choice(valid_agents) logger.info(f"Random speaker selected: {random_agent}") - + # Get response from the randomly selected agent self._get_agent_response(random_agent, img, imgs) @@ -1015,7 +1021,7 @@ Remember: You are part of a team. Your response should reflect that you've read, # Use the specialized function for random_speaker self._process_random_speaker( mentioned_agents, img, imgs - ) + ) else: self._process_static_speakers( mentioned_agents, img, imgs