diff --git a/docs/swarms/structs/agent.md b/docs/swarms/structs/agent.md
index 6b533ab4..862aa36c 100644
--- a/docs/swarms/structs/agent.md
+++ b/docs/swarms/structs/agent.md
@@ -89,7 +89,6 @@ graph TD
| `callback` | Callable function to be called after each agent loop. |
| `metadata` | Dictionary containing metadata for the agent. |
| `callbacks` | List of callable functions to be called during execution. |
-| `logger_handler` | Handler for logging messages. |
| `search_algorithm` | Callable function for long-term memory retrieval. |
| `logs_to_filename` | File path for logging agent activities. |
| `evaluator` | Callable function for evaluating the agent's responses. |
@@ -121,14 +120,12 @@ graph TD
| `memory_chunk_size` | Integer representing the maximum size of memory chunks for long-term memory retrieval. |
| `agent_ops_on` | Boolean indicating whether agent operations should be enabled. |
| `return_step_meta` | Boolean indicating whether to return JSON of all steps and additional metadata. |
-| `output_type` | Literal type indicating whether to output "string", "str", "list", "json", "dict", or "yaml". |
| `time_created` | Float representing the time the agent was created. |
| `tags` | Optional list of strings for tagging the agent. |
| `use_cases` | Optional list of dictionaries describing use cases for the agent. |
| `step_pool` | List of Step objects representing the agent's execution steps. |
| `print_every_step` | Boolean indicating whether to print every step of execution. |
| `agent_output` | ManySteps object containing the agent's output and metadata. |
-| `executor_workers` | Integer representing the number of executor workers for concurrent operations. |
| `data_memory` | Optional callable for data memory operations. |
| `load_yaml_path` | String representing the path to a YAML file for loading configurations. |
| `auto_generate_prompt` | Boolean indicating whether to automatically generate prompts. |
@@ -137,17 +134,44 @@ graph TD
| `artifacts_on` | Boolean indicating whether to save artifacts from agent execution |
| `artifacts_output_path` | File path where artifacts should be saved |
| `artifacts_file_extension` | File extension to use for saved artifacts |
-| `device` | Device to run computations on ("cpu" or "gpu") |
| `all_cores` | Boolean indicating whether to use all CPU cores |
| `device_id` | ID of the GPU device to use if running on GPU |
| `scheduled_run_date` | Optional datetime for scheduling future agent runs |
-
+| `do_not_use_cluster_ops` | Boolean indicating whether to avoid cluster operations |
+| `all_gpus` | Boolean indicating whether to use all available GPUs |
+| `model_name` | String representing the name of the model to use |
+| `llm_args` | Dictionary containing additional arguments for the LLM |
+| `load_state_path` | String representing the path to load state from |
+| `role` | String representing the role of the agent (e.g., "worker") |
+| `print_on` | Boolean indicating whether to print output |
+| `tools_list_dictionary` | List of dictionaries representing tool schemas |
+| `mcp_url` | String or MCPConnection representing the MCP server URL |
+| `mcp_urls` | List of strings representing multiple MCP server URLs |
+| `react_on` | Boolean indicating whether to enable ReAct reasoning |
+| `safety_prompt_on` | Boolean indicating whether to enable safety prompts |
+| `random_models_on` | Boolean indicating whether to randomly select models |
+| `mcp_config` | MCPConnection object containing MCP configuration |
+| `top_p` | Float representing the top-p sampling parameter |
+| `conversation_schema` | ConversationSchema object for conversation formatting |
+| `llm_base_url` | String representing the base URL for the LLM API |
+| `llm_api_key` | String representing the API key for the LLM |
+| `rag_config` | RAGConfig object containing RAG configuration |
+| `tool_call_summary` | Boolean indicating whether to summarize tool calls |
+| `output_raw_json_from_tool_call` | Boolean indicating whether to output raw JSON from tool calls |
+| `summarize_multiple_images` | Boolean indicating whether to summarize multiple image outputs |
+| `tool_retry_attempts` | Integer representing the number of retry attempts for tool execution |
+| `reasoning_prompt_on` | Boolean indicating whether to enable reasoning prompts |
+| `dynamic_context_window` | Boolean indicating whether to dynamically adjust context window |
+| `created_at` | Float representing the timestamp when the agent was created |
+| `workspace_dir` | String representing the workspace directory for the agent |
+| `timeout` | Integer representing the timeout for operations in seconds |
## `Agent` Methods
| Method | Description | Inputs | Usage Example |
|--------|-------------|--------|----------------|
-| `run(task, img=None, is_last=False, device="cpu", device_id=0, all_cores=True, *args, **kwargs)` | Runs the autonomous agent loop to complete the given task. | `task` (str): The task to be performed.
`img` (str, optional): Path to an image file.
`is_last` (bool): Whether this is the last task.
`device` (str): Device to run on ("cpu" or "gpu").
`device_id` (int): ID of the GPU to use.
`all_cores` (bool): Whether to use all CPU cores.
`*args`, `**kwargs`: Additional arguments. | `response = agent.run("Generate a report on financial performance.")` |
+| `run(task, img=None, imgs=None, correct_answer=None, streaming_callback=None, *args, **kwargs)` | Runs the autonomous agent loop to complete the given task. | `task` (str): The task to be performed.
`img` (str, optional): Path to an image file.
`imgs` (List[str], optional): List of image paths.
`correct_answer` (str, optional): Expected correct answer for validation.
`streaming_callback` (Callable, optional): Callback for streaming tokens.
`*args`, `**kwargs`: Additional arguments. | `response = agent.run("Generate a report on financial performance.")` |
+| `run_batched(tasks, imgs=None, *args, **kwargs)` | Runs multiple tasks concurrently in batch mode. | `tasks` (List[str]): List of tasks to run.
`imgs` (List[str], optional): List of images to process.
`*args`, `**kwargs`: Additional arguments. | `responses = agent.run_batched(["Task 1", "Task 2"])` |
| `__call__(task, img=None, *args, **kwargs)` | Alternative way to call the `run` method. | Same as `run`. | `response = agent("Generate a report on financial performance.")` |
| `parse_and_execute_tools(response, *args, **kwargs)` | Parses the agent's response and executes any tools mentioned in it. | `response` (str): The agent's response to be parsed.
`*args`, `**kwargs`: Additional arguments. | `agent.parse_and_execute_tools(response)` |
| `add_memory(message)` | Adds a message to the agent's memory. | `message` (str): The message to add. | `agent.add_memory("Important information")` |
@@ -155,6 +179,8 @@ graph TD
| `run_concurrent(task, *args, **kwargs)` | Runs a task concurrently. | `task` (str): The task to run.
`*args`, `**kwargs`: Additional arguments. | `response = await agent.run_concurrent("Concurrent task")` |
| `run_concurrent_tasks(tasks, *args, **kwargs)` | Runs multiple tasks concurrently. | `tasks` (List[str]): List of tasks to run.
`*args`, `**kwargs`: Additional arguments. | `responses = agent.run_concurrent_tasks(["Task 1", "Task 2"])` |
| `bulk_run(inputs)` | Generates responses for multiple input sets. | `inputs` (List[Dict[str, Any]]): List of input dictionaries. | `responses = agent.bulk_run([{"task": "Task 1"}, {"task": "Task 2"}])` |
+| `run_multiple_images(task, imgs, *args, **kwargs)` | Runs the agent with multiple images using concurrent processing. | `task` (str): The task to perform on each image.
`imgs` (List[str]): List of image paths or URLs.
`*args`, `**kwargs`: Additional arguments. | `outputs = agent.run_multiple_images("Describe image", ["img1.jpg", "img2.png"])` |
+| `continuous_run_with_answer(task, img=None, correct_answer=None, max_attempts=10)` | Runs the agent until the correct answer is provided. | `task` (str): The task to perform.
`img` (str, optional): Image to process.
`correct_answer` (str): Expected answer.
`max_attempts` (int): Maximum attempts. | `response = agent.continuous_run_with_answer("Math problem", correct_answer="42")` |
| `save()` | Saves the agent's history to a file. | None | `agent.save()` |
| `load(file_path)` | Loads the agent's history from a file. | `file_path` (str): Path to the file. | `agent.load("agent_history.json")` |
| `graceful_shutdown()` | Gracefully shuts down the system, saving the state. | None | `agent.graceful_shutdown()` |
@@ -178,8 +204,6 @@ graph TD
| `send_agent_message(agent_name, message, *args, **kwargs)` | Sends a message from the agent to a user. | `agent_name` (str): Name of the agent.
`message` (str): Message to send.
`*args`, `**kwargs`: Additional arguments. | `response = agent.send_agent_message("AgentX", "Task completed")` |
| `add_tool(tool)` | Adds a tool to the agent's toolset. | `tool` (Callable): Tool to add. | `agent.add_tool(my_custom_tool)` |
| `add_tools(tools)` | Adds multiple tools to the agent's toolset. | `tools` (List[Callable]): List of tools to add. | `agent.add_tools([tool1, tool2])` |
-| `remove_tool(tool)` | Removes a tool from the agent's toolset. || Method | Description | Inputs | Usage Example |
-|--------|-------------|--------|----------------|
| `remove_tool(tool)` | Removes a tool from the agent's toolset. | `tool` (Callable): Tool to remove. | `agent.remove_tool(my_custom_tool)` |
| `remove_tools(tools)` | Removes multiple tools from the agent's toolset. | `tools` (List[Callable]): List of tools to remove. | `agent.remove_tools([tool1, tool2])` |
| `get_docs_from_doc_folders()` | Retrieves and processes documents from the specified folder. | None | `agent.get_docs_from_doc_folders()` |
@@ -208,18 +232,30 @@ graph TD
| `handle_sop_ops()` | Handles operations related to standard operating procedures. | None | `agent.handle_sop_ops()` |
| `agent_output_type(responses)` | Processes and returns the agent's output based on the specified output type. | `responses` (list): List of responses. | `formatted_output = agent.agent_output_type(responses)` |
| `check_if_no_prompt_then_autogenerate(task)` | Checks if a system prompt is not set and auto-generates one if needed. | `task` (str): The task to use for generating a prompt. | `agent.check_if_no_prompt_then_autogenerate("Analyze data")` |
-| `check_if_no_prompt_then_autogenerate(task)` | Checks if auto_generate_prompt is enabled and generates a prompt by combining agent name, description and system prompt | `task` (str, optional): Task to use as fallback | `agent.check_if_no_prompt_then_autogenerate("Analyze data")` |
| `handle_artifacts(response, output_path, extension)` | Handles saving artifacts from agent execution | `response` (str): Agent response
`output_path` (str): Output path
`extension` (str): File extension | `agent.handle_artifacts(response, "outputs/", ".txt")` |
+| `showcase_config()` | Displays the agent's configuration in a formatted table. | None | `agent.showcase_config()` |
+| `talk_to(agent, task, img=None, *args, **kwargs)` | Initiates a conversation with another agent. | `agent` (Any): Target agent.
`task` (str): Task to discuss.
`img` (str, optional): Image to share.
`*args`, `**kwargs`: Additional arguments. | `response = agent.talk_to(other_agent, "Let's collaborate")` |
+| `talk_to_multiple_agents(agents, task, *args, **kwargs)` | Talks to multiple agents concurrently. | `agents` (List[Any]): List of target agents.
`task` (str): Task to discuss.
`*args`, `**kwargs`: Additional arguments. | `responses = agent.talk_to_multiple_agents([agent1, agent2], "Group discussion")` |
+| `get_agent_role()` | Returns the role of the agent. | None | `role = agent.get_agent_role()` |
+| `pretty_print(response, loop_count)` | Prints the response in a formatted panel. | `response` (str): Response to print.
`loop_count` (int): Current loop number. | `agent.pretty_print("Analysis complete", 1)` |
+| `parse_llm_output(response)` | Parses and standardizes the output from the LLM. | `response` (Any): Response from the LLM. | `parsed_response = agent.parse_llm_output(llm_output)` |
+| `sentiment_and_evaluator(response)` | Performs sentiment analysis and evaluation on the response. | `response` (str): Response to analyze. | `agent.sentiment_and_evaluator("Great response!")` |
+| `output_cleaner_op(response)` | Applies output cleaning operations to the response. | `response` (str): Response to clean. | `cleaned_response = agent.output_cleaner_op(response)` |
+| `mcp_tool_handling(response, current_loop)` | Handles MCP tool execution and responses. | `response` (Any): Response containing tool calls.
`current_loop` (int): Current loop number. | `agent.mcp_tool_handling(response, 1)` |
+| `temp_llm_instance_for_tool_summary()` | Creates a temporary LLM instance for tool summaries. | None | `temp_llm = agent.temp_llm_instance_for_tool_summary()` |
+| `execute_tools(response, loop_count)` | Executes tools based on the LLM response. | `response` (Any): Response containing tool calls.
`loop_count` (int): Current loop number. | `agent.execute_tools(response, 1)` |
+| `list_output_types()` | Returns available output types. | None | `types = agent.list_output_types()` |
+| `tool_execution_retry(response, loop_count)` | Executes tools with retry logic for handling failures. | `response` (Any): Response containing tool calls.
`loop_count` (int): Current loop number. | `agent.tool_execution_retry(response, 1)` |
## Updated Run Method
-Update the run method documentation to include new parameters:
+The run method has been updated with new parameters for enhanced functionality:
| Method | Description | Inputs | Usage Example |
|--------|-------------|--------|----------------|
-| `run(task, img=None, is_last=False, device="cpu", device_id=0, all_cores=True, scheduled_run_date=None)` | Runs the agent with specified parameters | `task` (str): Task to run
`img` (str, optional): Image path
`is_last` (bool): If this is last task
`device` (str): Device to use
`device_id` (int): GPU ID
`all_cores` (bool): Use all CPU cores
`scheduled_run_date` (datetime, optional): Future run date | `agent.run("Analyze data", device="gpu", device_id=0)` |
+| `run(task, img=None, imgs=None, correct_answer=None, streaming_callback=None, *args, **kwargs)` | Runs the agent with enhanced parameters | `task` (str): Task to run
`img` (str, optional): Single image path
`imgs` (List[str], optional): List of image paths
`correct_answer` (str, optional): Expected answer for validation
`streaming_callback` (Callable, optional): Callback for streaming tokens
`*args`, `**kwargs`: Additional arguments | `agent.run("Analyze data", imgs=["img1.jpg", "img2.png"])` |
@@ -420,9 +456,35 @@ tasks = [
]
responses = agent.bulk_run(tasks)
print(responses)
+
+# Run multiple tasks in batch mode (new method)
+task_list = ["Analyze data", "Generate report", "Create summary"]
+batch_responses = agent.run_batched(task_list)
+print(f"Completed {len(batch_responses)} tasks in batch mode")
```
+### Batch Processing with `run_batched`
+
+The new `run_batched` method allows you to process multiple tasks efficiently:
+
+```python
+# Process multiple tasks in batch
+tasks = [
+ "Analyze the financial data for Q1",
+ "Generate a summary report for stakeholders",
+ "Create recommendations for Q2 planning"
+]
+
+# Run all tasks concurrently
+batch_results = agent.run_batched(tasks)
+
+# Process results
+for i, (task, result) in enumerate(zip(tasks, batch_results)):
+ print(f"Task {i+1}: {task}")
+ print(f"Result: {result}\n")
+```
+
### Various other settings
```python
@@ -611,6 +673,36 @@ print(type(str_to_dict(out)))
```
+## New Features and Parameters
+
+### Enhanced Run Method Parameters
+
+The `run` method now supports several new parameters for advanced functionality:
+
+- **`imgs`**: Process multiple images simultaneously instead of just one
+- **`correct_answer`**: Validate responses against expected answers with automatic retries
+- **`streaming_callback`**: Real-time token streaming for interactive applications
+
+### MCP (Model Context Protocol) Integration
+
+New parameters enable seamless MCP server integration:
+
+- **`mcp_url`**: Connect to a single MCP server
+- **`mcp_urls`**: Connect to multiple MCP servers
+- **`mcp_config`**: Advanced MCP configuration options
+
+### Advanced Reasoning and Safety
+
+- **`react_on`**: Enable ReAct reasoning for complex problem-solving
+- **`safety_prompt_on`**: Add safety constraints to agent responses
+- **`reasoning_prompt_on`**: Enable multi-loop reasoning for complex tasks
+
+### Performance and Resource Management
+
+- **`dynamic_context_window`**: Automatically adjust context window based on available tokens
+- **`tool_retry_attempts`**: Configure retry behavior for tool execution
+- **`summarize_multiple_images`**: Automatically summarize results from multiple image processing
+
## Best Practices
1. Always provide a clear and concise `system_prompt` to guide the agent's behavior.
@@ -627,5 +719,9 @@ print(type(str_to_dict(out)))
12. Configure `device` and `device_id` appropriately for optimal performance
13. Enable `rag_every_loop` when continuous context from long-term memory is needed
14. Use `scheduled_run_date` for automated task scheduling
+15. Leverage `run_batched` for efficient processing of multiple related tasks
+16. Use `mcp_url` or `mcp_urls` to extend agent capabilities with external tools
+17. Enable `react_on` for complex reasoning tasks requiring step-by-step analysis
+18. Configure `tool_retry_attempts` for robust tool execution in production environments
By following these guidelines and leveraging the Swarm Agent's extensive features, you can create powerful, flexible, and efficient autonomous agents for a wide range of applications.
\ No newline at end of file
diff --git a/example.py b/example.py
index 17398527..c9cc03d7 100644
--- a/example.py
+++ b/example.py
@@ -1,10 +1,5 @@
from swarms import Agent
-import litellm
-
-litellm._turn_on_debug() # š this is the 1-line change you need to make
-
-
# Initialize the agent
agent = Agent(
agent_name="Quantitative-Trading-Agent",
@@ -41,10 +36,8 @@ agent = Agent(
model_name="claude-sonnet-4-20250514",
dynamic_temperature_enabled=True,
output_type="str-all-except-first",
- max_loops="auto",
- interactive=True,
- no_reasoning_prompt=True,
- streaming_on=True,
+ max_loops=1,
+ dynamic_context_window=True,
)
out = agent.run(
diff --git a/examples/simulations/euroswarm_parliament/euroswarm_parliament_example.py b/examples/simulations/euroswarm_parliament/euroswarm_parliament_example.py
index b2ccf858..1ae8f7f5 100644
--- a/examples/simulations/euroswarm_parliament/euroswarm_parliament_example.py
+++ b/examples/simulations/euroswarm_parliament/euroswarm_parliament_example.py
@@ -1,661 +1,59 @@
"""
-EuroSwarm Parliament - Example Script
+EuroSwarm Parliament - Simple Example
-This script demonstrates the comprehensive democratic functionality of the EuroSwarm Parliament,
-including bill introduction, committee work, parliamentary debates, and democratic voting.
+A basic demonstration of the EuroSwarm Parliament functionality.
"""
-# Import directly from the file
-from euroswarm_parliament import (
- EuroSwarmParliament,
- VoteType,
-)
+from euroswarm_parliament import EuroSwarmParliament, VoteType
-def demonstrate_parliament_initialization():
- """Demonstrate parliament initialization and basic functionality with cost optimization."""
+def main():
+ """Simple demonstration of EuroSwarm Parliament."""
- print(
- "\nEUROSWARM PARLIAMENT INITIALIZATION DEMONSTRATION (COST OPTIMIZED)"
- )
- print("=" * 60)
+ print("EUROSWARM PARLIAMENT - SIMPLE EXAMPLE")
+ print("=" * 50)
- # Initialize the parliament with cost optimization
+ # Initialize the parliament
parliament = EuroSwarmParliament(
eu_data_file="EU.xml",
- parliament_size=None, # Use all MEPs from EU.xml (717)
enable_democratic_discussion=True,
enable_committee_work=True,
- enable_amendment_process=True,
- enable_lazy_loading=True, # NEW: Lazy load MEP agents
- enable_caching=True, # NEW: Enable response caching
- batch_size=25, # NEW: Batch size for concurrent execution
- budget_limit=100.0, # NEW: Budget limit in dollars
verbose=True,
)
print(f"Parliament initialized with {len(parliament.meps)} MEPs")
- # Show parliament composition with cost stats
- composition = parliament.get_parliament_composition()
-
- print("\nPARLIAMENT COMPOSITION:")
- print(f"Total MEPs: {composition['total_meps']}")
- print(
- f"Loaded MEPs: {composition['loaded_meps']} (lazy loading active)"
- )
-
- print("\nCOST OPTIMIZATION:")
- cost_stats = composition["cost_stats"]
- print(
- f"Budget Limit: ${cost_stats['budget_remaining'] + cost_stats['total_cost']:.2f}"
- )
- print(f"Budget Used: ${cost_stats['total_cost']:.2f}")
- print(f"Budget Remaining: ${cost_stats['budget_remaining']:.2f}")
- print(f"Cache Hit Rate: {cost_stats['cache_hit_rate']:.1%}")
-
- print("\nPOLITICAL GROUP DISTRIBUTION:")
- for group, data in composition["political_groups"].items():
- count = data["count"]
- percentage = data["percentage"]
- print(f" {group}: {count} MEPs ({percentage:.1f}%)")
-
- print("\nCOMMITTEE LEADERSHIP:")
- for committee_name, committee_data in composition[
- "committees"
- ].items():
- chair = committee_data["chair"]
- if chair:
- print(f" {committee_name}: {chair}")
-
- return parliament
-
-
-def demonstrate_individual_mep_interaction(parliament):
- """Demonstrate individual MEP interaction and personality."""
-
- print("\nINDIVIDUAL MEP INTERACTION DEMONSTRATION")
- print("=" * 60)
-
# Get a sample MEP
sample_mep_name = list(parliament.meps.keys())[0]
sample_mep = parliament.meps[sample_mep_name]
- print(f"Sample MEP: {sample_mep.full_name}")
+ print(f"\nSample MEP: {sample_mep.full_name}")
print(f"Country: {sample_mep.country}")
print(f"Political Group: {sample_mep.political_group}")
- print(f"National Party: {sample_mep.national_party}")
- print(f"Committees: {', '.join(sample_mep.committees)}")
- print(f"Expertise Areas: {', '.join(sample_mep.expertise_areas)}")
-
- # Test MEP agent interaction
- if sample_mep.agent:
- test_prompt = "What are your views on European integration and how do you approach cross-border cooperation?"
-
- print(f"\nMEP Response to: '{test_prompt}'")
- print("-" * 50)
-
- try:
- response = sample_mep.agent.run(test_prompt)
- print(
- response[:500] + "..."
- if len(response) > 500
- else response
- )
- except Exception as e:
- print(f"Error getting MEP response: {e}")
-
-def demonstrate_committee_work(parliament):
- """Demonstrate committee work and hearings."""
-
- print("\nCOMMITTEE WORK DEMONSTRATION")
- print("=" * 60)
-
- # Get a real MEP as sponsor
- sponsor = list(parliament.meps.keys())[0]
-
- # Create a test bill
+ # Create a simple bill
bill = parliament.introduce_bill(
- title="European Digital Rights and Privacy Protection Act",
- description="Comprehensive legislation to strengthen digital rights, enhance privacy protection, and establish clear guidelines for data handling across the European Union.",
+ title="European Digital Rights Act",
+ description="Basic legislation to protect digital rights across the EU.",
bill_type=VoteType.ORDINARY_LEGISLATIVE_PROCEDURE,
committee="Legal Affairs",
- sponsor=sponsor,
+ sponsor=sample_mep_name,
)
- print(f"Bill: {bill.title}")
+ print(f"\nBill introduced: {bill.title}")
print(f"Committee: {bill.committee}")
- print(f"Sponsor: {bill.sponsor}")
-
- # Conduct committee hearing
- print("\nCONDUCTING COMMITTEE HEARING...")
- hearing_result = parliament.conduct_committee_hearing(
- bill.committee, bill
- )
-
- print(f"Committee: {hearing_result['committee']}")
- print(f"Participants: {len(hearing_result['participants'])} MEPs")
- print(
- f"Recommendation: {hearing_result['recommendations']['recommendation']}"
- )
- print(
- f"Support: {hearing_result['recommendations']['support_percentage']:.1f}%"
- )
- print(
- f"Oppose: {hearing_result['recommendations']['oppose_percentage']:.1f}%"
- )
- print(
- f"Amend: {hearing_result['recommendations']['amend_percentage']:.1f}%"
- )
-
-
-def demonstrate_parliamentary_debate(parliament):
- """Demonstrate parliamentary debate functionality."""
-
- print("\nPARLIAMENTARY DEBATE DEMONSTRATION")
- print("=" * 60)
-
- # Get a real MEP as sponsor
- sponsor = list(parliament.meps.keys())[1]
-
- # Create a test bill
- bill = parliament.introduce_bill(
- title="European Green Deal Implementation Act",
- description="Legislation to implement the European Green Deal, including carbon neutrality targets, renewable energy investments, and sustainable development measures.",
- bill_type=VoteType.ORDINARY_LEGISLATIVE_PROCEDURE,
- committee="Environment, Public Health and Food Safety",
- sponsor=sponsor,
- )
-
- print(f"Bill: {bill.title}")
- print(f"Description: {bill.description}")
-
- # Conduct parliamentary debate
- print("\nCONDUCTING PARLIAMENTARY DEBATE...")
- debate_result = parliament.conduct_parliamentary_debate(
- bill, max_speakers=10
- )
-
- print(
- f"Debate Participants: {len(debate_result['participants'])} MEPs"
- )
- print("Debate Analysis:")
- print(
- f" Support: {debate_result['analysis']['support_count']} speakers ({debate_result['analysis']['support_percentage']:.1f}%)"
- )
- print(
- f" Oppose: {debate_result['analysis']['oppose_count']} speakers ({debate_result['analysis']['oppose_percentage']:.1f}%)"
- )
- print(
- f" Neutral: {debate_result['analysis']['neutral_count']} speakers ({debate_result['analysis']['neutral_percentage']:.1f}%)"
- )
-
-def demonstrate_democratic_voting(parliament):
- """Demonstrate democratic voting functionality."""
-
- print("\nDEMOCRATIC VOTING DEMONSTRATION")
- print("=" * 60)
-
- # Get a real MEP as sponsor
- sponsor = list(parliament.meps.keys())[2]
-
- # Create a test bill
- bill = parliament.introduce_bill(
- title="European Social Rights and Labor Protection Act",
- description="Legislation to strengthen social rights, improve labor conditions, and ensure fair treatment of workers across the European Union.",
- bill_type=VoteType.ORDINARY_LEGISLATIVE_PROCEDURE,
- committee="Employment and Social Affairs",
- sponsor=sponsor,
- )
-
- print(f"Bill: {bill.title}")
- print(f"Sponsor: {bill.sponsor}")
-
- # Conduct democratic vote
- print("\nCONDUCTING DEMOCRATIC VOTE...")
+ # Conduct a simple vote
+ print("\nConducting democratic vote...")
vote_result = parliament.conduct_democratic_vote(bill)
- # Calculate percentages
- total_votes = (
- vote_result.votes_for
- + vote_result.votes_against
- + vote_result.abstentions
- )
- in_favor_percentage = (
- (vote_result.votes_for / total_votes * 100)
- if total_votes > 0
- else 0
- )
- against_percentage = (
- (vote_result.votes_against / total_votes * 100)
- if total_votes > 0
- else 0
- )
- abstentions_percentage = (
- (vote_result.abstentions / total_votes * 100)
- if total_votes > 0
- else 0
- )
-
print("Vote Results:")
- print(f" Total Votes: {total_votes}")
- print(
- f" In Favor: {vote_result.votes_for} ({in_favor_percentage:.1f}%)"
- )
- print(
- f" Against: {vote_result.votes_against} ({against_percentage:.1f}%)"
- )
- print(
- f" Abstentions: {vote_result.abstentions} ({abstentions_percentage:.1f}%)"
- )
+ print(f" In Favor: {vote_result.votes_for}")
+ print(f" Against: {vote_result.votes_against}")
+ print(f" Abstentions: {vote_result.abstentions}")
print(f" Result: {vote_result.result.value}")
- # Show political group breakdown if available
- if (
- hasattr(vote_result, "group_votes")
- and vote_result.group_votes
- ):
- print("\nPOLITICAL GROUP BREAKDOWN:")
- for group, votes in vote_result.group_votes.items():
- print(
- f" {group}: {votes['in_favor']}/{votes['total']} in favor ({votes['percentage']:.1f}%)"
- )
- else:
- print(
- f"\nIndividual votes recorded: {len(vote_result.individual_votes)} MEPs"
- )
-
-
-def demonstrate_complete_democratic_session(parliament):
- """Demonstrate a complete democratic parliamentary session."""
-
- print("\nCOMPLETE DEMOCRATIC SESSION DEMONSTRATION")
- print("=" * 60)
-
- # Get a real MEP as sponsor
- sponsor = list(parliament.meps.keys())[3]
-
- # Run complete session
- session_result = parliament.run_democratic_session(
- bill_title="European Innovation and Technology Advancement Act",
- bill_description="Comprehensive legislation to promote innovation, support technology startups, and establish Europe as a global leader in digital transformation and technological advancement.",
- bill_type=VoteType.ORDINARY_LEGISLATIVE_PROCEDURE,
- committee="Industry, Research and Energy",
- sponsor=sponsor,
- )
-
- print("Session Results:")
- print(f" Bill: {session_result['bill'].title}")
- print(
- f" Committee Hearing: {session_result['hearing']['recommendations']['recommendation']}"
- )
- print(
- f" Debate Participants: {len(session_result['debate']['participants'])} MEPs"
- )
- print(f" Final Vote: {session_result['vote']['result']}")
- print(
- f" Vote Margin: {session_result['vote']['in_favor_percentage']:.1f}% in favor"
- )
-
-
-def demonstrate_political_analysis(parliament):
- """Demonstrate political analysis and voting prediction."""
-
- print("\nPOLITICAL ANALYSIS DEMONSTRATION")
- print("=" * 60)
-
- # Get a real MEP as sponsor
- sponsor = list(parliament.meps.keys())[4]
-
- # Create a test bill
- bill = parliament.introduce_bill(
- title="European Climate Action and Sustainability Act",
- description="Comprehensive climate action legislation including carbon pricing, renewable energy targets, and sustainable development measures.",
- bill_type=VoteType.ORDINARY_LEGISLATIVE_PROCEDURE,
- committee="Environment, Public Health and Food Safety",
- sponsor=sponsor,
- )
-
- print(f"Bill: {bill.title}")
- print(f"Sponsor: {bill.sponsor}")
-
- # Analyze political landscape
- analysis = parliament.analyze_political_landscape(bill)
-
- print("\nPOLITICAL LANDSCAPE ANALYSIS:")
- print(f" Overall Support: {analysis['overall_support']:.1f}%")
- print(f" Opposition: {analysis['opposition']:.1f}%")
- print(f" Uncertainty: {analysis['uncertainty']:.1f}%")
-
- print("\nPOLITICAL GROUP ANALYSIS:")
- for group, data in analysis["group_analysis"].items():
- print(
- f" {group}: {data['support']:.1f}% support, {data['opposition']:.1f}% opposition"
- )
-
-
-def demonstrate_hierarchical_democratic_voting(parliament):
- """Demonstrate hierarchical democratic voting with political group boards."""
-
- print("\nHIERARCHICAL DEMOCRATIC VOTING DEMONSTRATION")
- print("=" * 60)
-
- # Get a real MEP as sponsor
- sponsor = list(parliament.meps.keys())[5]
-
- # Create a test bill
- bill = parliament.introduce_bill(
- title="European Climate Action and Sustainability Act",
- description="Comprehensive climate action legislation including carbon pricing, renewable energy targets, and sustainable development measures.",
- bill_type=VoteType.ORDINARY_LEGISLATIVE_PROCEDURE,
- committee="Environment, Public Health and Food Safety",
- sponsor=sponsor,
- )
-
- print(f"Bill: {bill.title}")
- print(f"Sponsor: {bill.sponsor}")
-
- # Conduct hierarchical vote
- print("\nCONDUCTING HIERARCHICAL DEMOCRATIC VOTE...")
- hierarchical_result = (
- parliament.conduct_hierarchical_democratic_vote(bill)
- )
-
- print("Hierarchical Vote Results:")
- print(f" Total Votes: {hierarchical_result['total_votes']}")
- print(
- f" In Favor: {hierarchical_result['in_favor']} ({hierarchical_result['in_favor_percentage']:.1f}%)"
- )
- print(
- f" Against: {hierarchical_result['against']} ({hierarchical_result['against_percentage']:.1f}%)"
- )
- print(f" Result: {hierarchical_result['result']}")
-
- print("\nPOLITICAL GROUP BOARD DECISIONS:")
- for group, decision in hierarchical_result[
- "group_decisions"
- ].items():
- print(
- f" {group}: {decision['decision']} ({decision['confidence']:.1f}% confidence)"
- )
-
-
-def demonstrate_complete_hierarchical_session(parliament):
- """Demonstrate a complete hierarchical democratic session."""
-
- print("\nCOMPLETE HIERARCHICAL DEMOCRATIC SESSION DEMONSTRATION")
- print("=" * 60)
-
- # Get a real MEP as sponsor
- sponsor = list(parliament.meps.keys())[6]
-
- # Run complete hierarchical session
- session_result = parliament.run_hierarchical_democratic_session(
- bill_title="European Climate Action and Sustainability Act",
- bill_description="Comprehensive climate action legislation including carbon pricing, renewable energy targets, and sustainable development measures.",
- bill_type=VoteType.ORDINARY_LEGISLATIVE_PROCEDURE,
- committee="Environment, Public Health and Food Safety",
- sponsor=sponsor,
- )
-
- print("Hierarchical Session Results:")
- print(f" Bill: {session_result['bill'].title}")
- print(
- f" Committee Hearing: {session_result['hearing']['recommendations']['recommendation']}"
- )
- print(
- f" Debate Participants: {len(session_result['debate']['participants'])} MEPs"
- )
- print(f" Final Vote: {session_result['vote']['result']}")
- print(
- f" Vote Margin: {session_result['vote']['in_favor_percentage']:.1f}% in favor"
- )
-
-
-def demonstrate_wikipedia_personalities(parliament):
- """Demonstrate the Wikipedia personality system for realistic MEP behavior."""
-
- print("\nWIKIPEDIA PERSONALITY SYSTEM DEMONSTRATION")
- print("=" * 60)
-
- # Check if Wikipedia personalities are available
- if not parliament.enable_wikipedia_personalities:
- print("Wikipedia personality system not available")
- print(
- "To enable: Install required dependencies and run Wikipedia scraper"
- )
- return
-
- print("Wikipedia personality system enabled")
- print(
- f"Loaded {len(parliament.personality_profiles)} personality profiles"
- )
-
- # Show sample personality profiles
- print("\nSAMPLE PERSONALITY PROFILES:")
- print("-" * 40)
-
- sample_count = 0
- for mep_name, profile in parliament.personality_profiles.items():
- if sample_count >= 3: # Show only 3 samples
- break
-
- print(f"\n{mep_name}")
- print(
- f" Wikipedia URL: {profile.wikipedia_url if profile.wikipedia_url else 'Not available'}"
- )
- print(
- f" Summary: {profile.summary[:200]}..."
- if profile.summary
- else "No summary available"
- )
- print(
- f" Political Views: {profile.political_views[:150]}..."
- if profile.political_views
- else "Based on party alignment"
- )
- print(
- f" Policy Focus: {profile.policy_focus[:150]}..."
- if profile.policy_focus
- else "General parliamentary work"
- )
- print(
- f" Achievements: {profile.achievements[:150]}..."
- if profile.achievements
- else "Parliamentary service"
- )
- print(f" Last Updated: {profile.last_updated}")
-
- sample_count += 1
-
- # Demonstrate personality-driven voting
- print("\nPERSONALITY-DRIVEN VOTING DEMONSTRATION:")
- print("-" * 50)
-
- # Create a test bill that would trigger different personality responses
- bill = parliament.introduce_bill(
- title="European Climate Action and Green Technology Investment Act",
- description="Comprehensive legislation to accelerate Europe's transition to renewable energy, including massive investments in green technology, carbon pricing mechanisms, and support for affected industries and workers.",
- bill_type=VoteType.ORDINARY_LEGISLATIVE_PROCEDURE,
- committee="Environment",
- sponsor="Climate Action Leader",
- )
-
- print(f"Bill: {bill.title}")
- print(f"Description: {bill.description}")
-
- # Show how different MEPs with Wikipedia personalities would respond
- print("\nPERSONALITY-BASED RESPONSES:")
- print("-" * 40)
-
- sample_meps = list(parliament.personality_profiles.keys())[:3]
-
- for mep_name in sample_meps:
- mep = parliament.meps.get(mep_name)
- profile = parliament.personality_profiles.get(mep_name)
-
- if mep and profile:
- print(f"\n{mep_name} ({mep.political_group})")
-
- # Show personality influence
- if profile.political_views:
- print(
- f" Political Views: {profile.political_views[:100]}..."
- )
-
- if profile.policy_focus:
- print(
- f" Policy Focus: {profile.policy_focus[:100]}..."
- )
-
- # Predict voting behavior based on personality
- if (
- "environment" in profile.policy_focus.lower()
- or "climate" in profile.political_views.lower()
- ):
- predicted_vote = "LIKELY SUPPORT"
- reasoning = (
- "Environmental policy focus and climate advocacy"
- )
- elif (
- "economic" in profile.policy_focus.lower()
- or "business" in profile.political_views.lower()
- ):
- predicted_vote = "LIKELY OPPOSE"
- reasoning = "Economic concerns about investment costs"
- else:
- predicted_vote = "UNCERTAIN"
- reasoning = (
- "Mixed considerations based on party alignment"
- )
-
- print(f" Predicted Vote: {predicted_vote}")
- print(f" Reasoning: {reasoning}")
-
- # Demonstrate scraping functionality
- print("\nWIKIPEDIA SCRAPING CAPABILITIES:")
- print("-" * 50)
- print("Can scrape Wikipedia data for all 717 MEPs")
- print(
- "Extracts political views, career history, and achievements"
- )
- print("Creates detailed personality profiles in JSON format")
- print(
- "Integrates real personality data into AI agent system prompts"
- )
- print("Enables realistic, personality-driven voting behavior")
- print("Respectful API usage with configurable delays")
-
- print("\nTo scrape all MEP personalities:")
- print(" parliament.scrape_wikipedia_personalities(delay=1.0)")
- print(
- " # This will create personality profiles for all 717 MEPs"
- )
- print(" # Profiles are saved in 'mep_personalities/' directory")
-
-
-def demonstrate_optimized_parliamentary_session(parliament):
- """Demonstrate cost-optimized parliamentary session."""
-
- print("\nCOST-OPTIMIZED PARLIAMENTARY SESSION DEMONSTRATION")
- print("=" * 60)
-
- # Run optimized session with cost limit
- session_result = parliament.run_optimized_parliamentary_session(
- bill_title="European Digital Rights and Privacy Protection Act",
- bill_description="Comprehensive legislation to strengthen digital rights, enhance privacy protection, and establish clear guidelines for data handling across the European Union.",
- bill_type=VoteType.ORDINARY_LEGISLATIVE_PROCEDURE,
- committee="Legal Affairs",
- max_cost=25.0, # Max $25 for this session
- )
-
- print("Session Results:")
- print(
- f" Bill: {session_result['session_summary']['bill_title']}"
- )
- print(
- f" Final Outcome: {session_result['session_summary']['final_outcome']}"
- )
- print(
- f" Total Cost: ${session_result['session_summary']['total_cost']:.2f}"
- )
- print(
- f" Budget Remaining: ${session_result['cost_stats']['budget_remaining']:.2f}"
- )
-
- # Show detailed cost statistics
- cost_stats = parliament.get_cost_statistics()
- print("\nDETAILED COST STATISTICS:")
- print(f" Total Tokens Used: {cost_stats['total_tokens']:,}")
- print(f" Requests Made: {cost_stats['requests_made']}")
- print(f" Cache Hits: {cost_stats['cache_hits']}")
- print(f" Cache Hit Rate: {cost_stats['cache_hit_rate']:.1%}")
- print(
- f" Loading Efficiency: {cost_stats['loading_efficiency']:.1%}"
- )
- print(f" Cache Size: {cost_stats['cache_size']} entries")
-
- return session_result
-
-
-def main():
- """Main demonstration function."""
-
- print("EUROSWARM PARLIAMENT - COST OPTIMIZED DEMONSTRATION")
- print("=" * 60)
- print(
- "This demonstration shows the EuroSwarm Parliament with cost optimization features:"
- )
- print("⢠Lazy loading of MEP agents (only create when needed)")
- print("⢠Response caching (avoid repeated API calls)")
- print("⢠Batch processing (control memory and cost)")
- print("⢠Budget controls (hard limits on spending)")
- print("⢠Cost tracking (real-time monitoring)")
-
- # Initialize parliament with cost optimization
- parliament = demonstrate_parliament_initialization()
-
- # Demonstrate individual MEP interaction (will trigger lazy loading)
- demonstrate_individual_mep_interaction(parliament)
-
- # Demonstrate committee work with cost optimization
- demonstrate_committee_work(parliament)
-
- # Demonstrate parliamentary debate with cost optimization
- demonstrate_parliamentary_debate(parliament)
-
- # Demonstrate democratic voting with cost optimization
- demonstrate_democratic_voting(parliament)
-
- # Demonstrate political analysis with cost optimization
- demonstrate_political_analysis(parliament)
-
- # Demonstrate optimized parliamentary session
- demonstrate_optimized_parliamentary_session(parliament)
-
- # Show final cost statistics
- final_stats = parliament.get_cost_statistics()
- print("\nFINAL COST STATISTICS:")
- print(f"Total Cost: ${final_stats['total_cost']:.2f}")
- print(f"Budget Remaining: ${final_stats['budget_remaining']:.2f}")
- print(f"Cache Hit Rate: {final_stats['cache_hit_rate']:.1%}")
- print(
- f"Loading Efficiency: {final_stats['loading_efficiency']:.1%}"
- )
-
- print("\nā
COST OPTIMIZATION DEMONSTRATION COMPLETED!")
- print(
- "ā
EuroSwarm Parliament now supports cost-effective large-scale simulations"
- )
- print(
- f"ā
Lazy loading: {final_stats['loaded_meps']}/{final_stats['total_meps']} MEPs loaded"
- )
- print(f"ā
Caching: {final_stats['cache_hit_rate']:.1%} hit rate")
- print(
- f"ā
Budget control: ${final_stats['total_cost']:.2f} spent of ${final_stats['budget_remaining'] + final_stats['total_cost']:.2f} budget"
- )
+ print("\nā
Simple example completed!")
if __name__ == "__main__":
diff --git a/examples/simulations/example_bell_labs.py b/examples/simulations/example_bell_labs.py
new file mode 100644
index 00000000..b3a2004a
--- /dev/null
+++ b/examples/simulations/example_bell_labs.py
@@ -0,0 +1,39 @@
+"""
+Bell Labs Research Simulation Example
+
+This example demonstrates how to use the BellLabsSwarm to simulate
+collaborative research among famous physicists.
+"""
+
+from swarms.sims.bell_labs import (
+ run_bell_labs_research,
+)
+
+
+def main():
+ """
+ Run the Bell Labs research simulation.
+
+ This example asks the research question:
+ "Why doesn't physics take a vacation? Why are the laws of physics consistent?"
+ """
+
+ research_question = """
+ Why doesn't physics take a vacation? Why are the laws of physics consistent across time and space?
+ Explore the philosophical and scientific foundations for the uniformity and invariance of physical laws.
+ Consider both theoretical explanations and any empirical evidence or challenges to this consistency.
+ """
+
+ # Run the research simulation
+ results = run_bell_labs_research(
+ research_question=research_question,
+ max_loops=1,
+ model_name="claude-3-5-sonnet-20240620",
+ verbose=True,
+ )
+
+ print(results)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/single_agent/dynamic_context_window.py b/examples/single_agent/dynamic_context_window.py
new file mode 100644
index 00000000..2a654d7f
--- /dev/null
+++ b/examples/single_agent/dynamic_context_window.py
@@ -0,0 +1,29 @@
+from swarms import Agent
+
+
+def main():
+ """
+ Run a quantitative trading agent to recommend top 3 gold ETFs.
+ """
+ agent = Agent(
+ agent_name="Quantitative-Trading-Agent",
+ agent_description="Advanced quantitative trading and algorithmic analysis agent",
+ system_prompt=(
+ "You are an expert quantitative trading agent. "
+ "Recommend the best gold ETFs using your expertise in trading strategies, "
+ "risk management, and financial analysis. Be concise and precise."
+ ),
+ model_name="claude-sonnet-4-20250514",
+ dynamic_temperature_enabled=True,
+ max_loops=1,
+ dynamic_context_window=True,
+ )
+
+ out = agent.run(
+ task="What are the best top 3 etfs for gold coverage?"
+ )
+ print(out)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/examples/tools/claude_as_a_tool.py b/examples/tools/claude_as_a_tool.py
new file mode 100644
index 00000000..3101c1db
--- /dev/null
+++ b/examples/tools/claude_as_a_tool.py
@@ -0,0 +1,206 @@
+"""
+Claude Code Agent Tool - Setup Guide
+
+This tool provides a Claude Code Agent that can:
+- Generate code and applications from natural language descriptions
+- Write files, execute shell commands, and manage Git repositories
+- Perform web searches and file operations
+- Handle complex development tasks with retry logic
+
+SETUP GUIDE:
+1. Install dependencies:
+ pip install claude-code-sdk
+ npm install -g @anthropic-ai/claude-code
+
+2. Set environment variable:
+ export ANTHROPIC_API_KEY="your-api-key-here"
+
+3. Use the tool:
+ from claude_as_a_tool import developer_worker_agent
+
+ result = developer_worker_agent(
+ task="Create a Python web scraper",
+ system_prompt="You are a helpful coding assistant"
+ )
+
+REQUIRED: ANTHROPIC_API_KEY environment variable must be set
+"""
+
+import asyncio
+from typing import Any, Dict
+
+from claude_code_sdk import ClaudeCodeOptions, ClaudeSDKClient
+from dotenv import load_dotenv
+from tenacity import retry, stop_after_attempt, wait_exponential
+from loguru import logger
+
+load_dotenv()
+
+
+class ClaudeAppGenerator:
+ """
+ Generates applications using Claude Code SDK based on specifications.
+ """
+
+ def __init__(
+ self,
+ name: str = "Developer Worker Agent",
+ description: str = "A developer worker agent that can generate code and write it to a file.",
+ retries: int = 3,
+ retry_delay: float = 2.0,
+ system_prompt: str = None,
+ debug_mode: bool = False,
+ max_steps: int = 40,
+ model: str = "claude-sonnet-4-20250514",
+ max_thinking_tokens: int = 1000,
+ ):
+ """
+ Initialize the app generator.
+
+ Args:
+ name: Name of the app
+ description: Description of the app
+ retries: Number of retries
+ retry_delay: Delay between retries
+ system_prompt: System prompt
+ debug_mode: Enable extra verbose logging for Claude outputs
+ max_steps: Maximum number of steps
+ model: Model to use
+ """
+ self.name = name
+ self.description = description
+ self.retries = retries
+ self.retry_delay = retry_delay
+ self.system_prompt = system_prompt
+ self.model = model
+ self.debug_mode = debug_mode
+ self.max_steps = max_steps
+ self.max_thinking_tokens = max_thinking_tokens
+
+ @retry(
+ stop=stop_after_attempt(3),
+ wait=wait_exponential(multiplier=1, min=4, max=15),
+ )
+ async def generate_app_with_claude(
+ self, task: str
+ ) -> Dict[str, Any]:
+ """
+ Generate app using Claude Code SDK with robust error handling and retry logic.
+
+ Args:
+ task: Task to be completed
+
+ Returns:
+ Dict containing generation results
+ """
+ # Log the Claude SDK configuration
+ claude_options = ClaudeCodeOptions(
+ system_prompt=self.system_prompt,
+ max_turns=self.max_steps, # Sufficient for local app development and GitHub setup
+ allowed_tools=[
+ "Read",
+ "Write",
+ "Bash",
+ "GitHub",
+ "Git",
+ "Grep",
+ "WebSearch",
+ ],
+ continue_conversation=True, # Start fresh each time
+ model=self.model,
+ max_thinking_tokens=self.max_thinking_tokens,
+ )
+
+ async with ClaudeSDKClient(options=claude_options) as client:
+ # Generate the application
+ await client.query(task)
+
+ response_text = []
+ message_count = 0
+
+ async for message in client.receive_response():
+ message_count += 1
+
+ if hasattr(message, "content"):
+ for block in message.content:
+ if hasattr(block, "text"):
+ text_content = block.text
+ response_text.append(text_content)
+ logger.info(text_content)
+
+ elif hasattr(block, "type"):
+ if self.debug_mode and hasattr(
+ block, "input"
+ ):
+ input_str = str(block.input)
+ if len(input_str) > 200:
+ input_str = (
+ input_str[:200]
+ + "... (truncated)"
+ )
+ print(f"Tool Input: {input_str}")
+
+ elif type(message).__name__ == "ResultMessage":
+ result_text = str(message.result)
+ response_text.append(result_text)
+
+ return response_text
+
+ def run(self, task: str) -> Dict[str, Any]:
+ """
+ Synchronous wrapper for app generation to work with ThreadPoolExecutor.
+
+ Args:
+ spec: App specification
+
+ Returns:
+ Dict containing generation results
+ """
+ return asyncio.run(self.generate_app_with_claude(task))
+
+
+def developer_worker_agent(task: str, system_prompt: str) -> str:
+ """
+ Developer Worker Agent
+
+ This function instantiates a ClaudeAppGenerator agent, which is a highly capable developer assistant designed to automate software development tasks.
+ The agent leverages the Claude Code SDK to interpret natural language instructions and generate code, scripts, or even entire applications.
+ It can interact with files, execute shell commands, perform web searches, and utilize version control systems such as Git and GitHub.
+ The agent is robust, featuring retry logic, customizable system prompts, and debug modes for verbose output.
+ It is ideal for automating repetitive coding tasks, prototyping, and integrating with developer workflows.
+
+ Capabilities:
+ - Generate code based on detailed task descriptions.
+ - Write generated code to files.
+ - Execute shell commands and scripts.
+ - Interact with Git and GitHub for version control operations.
+ - Perform web searches to gather information or code snippets.
+ - Provide detailed logs and debugging information if enabled.
+ - Handle errors gracefully with configurable retry logic.
+
+ Args:
+ task (str): The development task or instruction for the agent to complete.
+ system_prompt (str): The system prompt to guide the agent's behavior and context.
+
+ Returns:
+ str: The result of the agent's execution for the given task.
+ """
+ claude_code_sdk = ClaudeAppGenerator(system_prompt=system_prompt)
+ return claude_code_sdk.run(task)
+
+
+# agent = Agent(
+# agent_name="Developer Worker Agent",
+# agent_description="A developer worker agent that can generate code and write it to a file.",
+# tools=[developer_worker_agent],
+# system_prompt="You are a developer worker agent. You are given a task and you need to complete it.",
+# )
+
+# agent.run(
+# task="Write a simple python script that prints 'Hello, World!'"
+# )
+
+# if __name__ == "__main__":
+# task = "Write a simple python script that prints 'Hello, World!'"
+# system_prompt = "You are a developer worker agent. You are given a task and you need to complete it."
+# print(developer_worker_agent(task, system_prompt))
diff --git a/pyproject.toml b/pyproject.toml
index 95f28547..9d57a8f8 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -5,7 +5,7 @@ build-backend = "poetry.core.masonry.api"
[tool.poetry]
name = "swarms"
-version = "8.0.5"
+version = "8.1.1"
description = "Swarms - TGSC"
license = "MIT"
authors = ["Kye Gomez "]
diff --git a/simulation_vote_example.py b/simulation_vote_example.py
index 377728c9..c39a3480 100644
--- a/simulation_vote_example.py
+++ b/simulation_vote_example.py
@@ -2,10 +2,6 @@ from swarms.sims.senator_assembly import SenatorAssembly
def main():
- """
- Runs a simulation of a Senate vote on a bill proposing significant tax cuts for all Americans.
- The bill is described in realistic legislative terms, and the simulation uses a concurrent voting model.
- """
senator_simulation = SenatorAssembly(
model_name="claude-sonnet-4-20250514"
)
diff --git a/swarms/sims/bell_labs.py b/swarms/sims/bell_labs.py
new file mode 100644
index 00000000..682e8bf1
--- /dev/null
+++ b/swarms/sims/bell_labs.py
@@ -0,0 +1,815 @@
+"""
+Bell Labs Research Simulation with Physicist Agents
+
+This simulation creates specialized AI agents representing famous physicists
+from the Bell Labs era, including Oppenheimer, von Neumann, Feynman, Einstein,
+and others. The agents work together in a collaborative research environment
+following a structured workflow: task -> Oppenheimer (planning) -> physicist discussion
+-> code implementation -> results analysis -> repeat for n loops.
+"""
+
+from functools import lru_cache
+from typing import Any, Dict, List, Optional
+
+from loguru import logger
+
+from swarms.structs.agent import Agent
+from swarms.structs.conversation import Conversation
+from swarms.utils.history_output_formatter import (
+ history_output_formatter,
+)
+# from examples.tools.claude_as_a_tool import developer_worker_agent
+
+
+@lru_cache(maxsize=1)
+def _create_physicist_agents(
+ model_name: str, random_model_name: bool = False
+) -> List[Agent]:
+ """
+ Create specialized agents for each physicist.
+
+ Args:
+ model_name: Model to use for all agents
+
+ Returns:
+ List of configured physicist agents
+ """
+ physicists_data = {
+ "J. Robert Oppenheimer": {
+ "role": "Research Director & Theoretical Physicist",
+ "expertise": [
+ "Nuclear physics",
+ "Quantum mechanics",
+ "Research coordination",
+ "Strategic planning",
+ "Team leadership",
+ ],
+ "background": "Director of the Manhattan Project, expert in quantum mechanics and nuclear physics",
+ "system_prompt": """You are J. Robert Oppenheimer, the brilliant theoretical physicist and research director.
+
+ Your role is to:
+ 1. Analyze complex research questions and break them down into manageable components
+ 2. Create comprehensive research plans with clear objectives and methodologies
+ 3. Coordinate the research team and ensure effective collaboration
+ 4. Synthesize findings from different physicists into coherent conclusions
+ 5. Guide the research process with strategic insights and theoretical frameworks
+
+ You excel at:
+ - Identifying the core theoretical challenges in any research question
+ - Designing experimental approaches that test fundamental principles
+ - Balancing theoretical rigor with practical implementation
+ - Fostering interdisciplinary collaboration between specialists
+ - Maintaining focus on the most promising research directions
+
+ When creating research plans, be thorough, systematic, and consider multiple approaches.
+ Always emphasize the theoretical foundations and experimental validation of any proposed solution.""",
+ },
+ "John von Neumann": {
+ "role": "Mathematical Physicist & Computer Scientist",
+ "expertise": [
+ "Mathematical physics",
+ "Computer architecture",
+ "Game theory",
+ "Quantum mechanics",
+ "Numerical methods",
+ ],
+ "background": "Pioneer of computer science, game theory, and mathematical physics",
+ "system_prompt": """You are John von Neumann, the brilliant mathematical physicist and computer scientist.
+
+ Your approach to research questions involves:
+ 1. Mathematical rigor and formal mathematical frameworks
+ 2. Computational and algorithmic solutions to complex problems
+ 3. Game theory and strategic analysis of research approaches
+ 4. Numerical methods and computational physics
+ 5. Bridging abstract theory with practical implementation
+
+ You excel at:
+ - Formulating problems in precise mathematical terms
+ - Developing computational algorithms and numerical methods
+ - Applying game theory to optimize research strategies
+ - Creating mathematical models that capture complex phenomena
+ - Designing efficient computational approaches to physical problems
+
+ When analyzing research questions, focus on mathematical foundations, computational feasibility,
+ and the development of rigorous theoretical frameworks that can be implemented and tested.""",
+ },
+ "Richard Feynman": {
+ "role": "Theoretical Physicist & Problem Solver",
+ "expertise": [
+ "Quantum electrodynamics",
+ "Particle physics",
+ "Problem-solving methodology",
+ "Intuitive physics",
+ "Experimental design",
+ ],
+ "background": "Nobel laureate in physics, known for intuitive problem-solving and quantum electrodynamics",
+ "system_prompt": """You are Richard Feynman, the brilliant theoretical physicist and master problem solver.
+
+ Your research methodology involves:
+ 1. Intuitive understanding of complex physical phenomena
+ 2. Creative problem-solving approaches that cut through complexity
+ 3. Experimental design that tests fundamental principles
+ 4. Clear communication of complex ideas through analogies and examples
+ 5. Focus on the most essential aspects of any research question
+
+ You excel at:
+ - Finding elegant solutions to seemingly intractable problems
+ - Designing experiments that reveal fundamental truths
+ - Communicating complex physics in accessible terms
+ - Identifying the core physics behind any phenomenon
+ - Developing intuitive models that capture essential behavior
+
+ When approaching research questions, look for the simplest, most elegant solutions.
+ Focus on the fundamental physics and design experiments that test your understanding directly.""",
+ },
+ "Albert Einstein": {
+ "role": "Theoretical Physicist & Conceptual Innovator",
+ "expertise": [
+ "Relativity theory",
+ "Quantum mechanics",
+ "Conceptual physics",
+ "Thought experiments",
+ "Fundamental principles",
+ ],
+ "background": "Revolutionary physicist who developed relativity theory and influenced quantum mechanics",
+ "system_prompt": """You are Albert Einstein, the revolutionary theoretical physicist and conceptual innovator.
+
+ Your research approach involves:
+ 1. Deep conceptual thinking about fundamental physical principles
+ 2. Thought experiments that reveal the essence of physical phenomena
+ 3. Questioning established assumptions and exploring new paradigms
+ 4. Focus on the most fundamental and universal aspects of physics
+ 5. Intuitive understanding of space, time, and the nature of reality
+
+ You excel at:
+ - Identifying the conceptual foundations of any physical theory
+ - Developing thought experiments that challenge conventional wisdom
+ - Finding elegant mathematical descriptions of physical reality
+ - Questioning fundamental assumptions and exploring alternatives
+ - Developing unified theories that explain diverse phenomena
+
+ When analyzing research questions, focus on the conceptual foundations and fundamental principles.
+ Look for elegant, unified explanations and be willing to challenge established paradigms.""",
+ },
+ "Enrico Fermi": {
+ "role": "Experimental Physicist & Nuclear Scientist",
+ "expertise": [
+ "Nuclear physics",
+ "Experimental physics",
+ "Neutron physics",
+ "Statistical physics",
+ "Practical applications",
+ ],
+ "background": "Nobel laureate known for nuclear physics, experimental work, and the first nuclear reactor",
+ "system_prompt": """You are Enrico Fermi, the brilliant experimental physicist and nuclear scientist.
+
+ Your research methodology involves:
+ 1. Rigorous experimental design and execution
+ 2. Practical application of theoretical principles
+ 3. Statistical analysis and probability in physics
+ 4. Nuclear physics and particle interactions
+ 5. Bridging theory with experimental validation
+
+ You excel at:
+ - Designing experiments that test theoretical predictions
+ - Applying statistical methods to physical problems
+ - Developing practical applications of fundamental physics
+ - Nuclear physics and particle physics experiments
+ - Creating experimental setups that reveal new phenomena
+
+ When approaching research questions, focus on experimental design and practical implementation.
+ Emphasize the importance of experimental validation and statistical analysis in physics research.""",
+ },
+ "Code-Implementer": {
+ "role": "Computational Physicist & Code Developer",
+ "expertise": [
+ "Scientific computing",
+ "Physics simulations",
+ "Data analysis",
+ "Algorithm implementation",
+ "Numerical methods",
+ ],
+ "background": "Specialized in implementing computational solutions to physics problems",
+ "system_prompt": """You are a specialized computational physicist and code developer.
+
+ Your responsibilities include:
+ 1. Implementing computational solutions to physics problems
+ 2. Developing simulations and numerical methods
+ 3. Analyzing data and presenting results clearly
+ 4. Testing theoretical predictions through computation
+ 5. Providing quantitative analysis of research findings
+
+ You excel at:
+ - Writing clear, efficient scientific code
+ - Implementing numerical algorithms for physics problems
+ - Data analysis and visualization
+ - Computational optimization and performance
+ - Bridging theoretical physics with computational implementation
+
+ When implementing solutions, focus on:
+ - Clear, well-documented code
+ - Efficient numerical algorithms
+ - Comprehensive testing and validation
+ - Clear presentation of results and analysis
+ - Quantitative assessment of theoretical predictions""",
+ },
+ }
+
+ agents = []
+ for name, data in physicists_data.items():
+ agent = Agent(
+ agent_name=name,
+ system_prompt=data["system_prompt"],
+ model_name=model_name,
+ random_model_name=random_model_name,
+ max_loops=1,
+ dynamic_temperature_enabled=True,
+ dynamic_context_window=True,
+ )
+ agents.append(agent)
+
+ return agents
+
+
+class BellLabsSwarm:
+ """
+ Bell Labs Research Simulation Swarm
+
+ Simulates the collaborative research environment of Bell Labs with famous physicists
+ working together on complex research questions. The workflow follows:
+
+ 1. Task is presented to the team
+ 2. Oppenheimer creates a research plan
+ 3. Physicists discuss and vote on approaches using majority voting
+ 4. Code implementation agent tests the theory
+ 5. Results are analyzed and fed back to the team
+ 6. Process repeats for n loops with iterative refinement
+ """
+
+ def __init__(
+ self,
+ name: str = "Bell Labs Research Team",
+ description: str = "A collaborative research environment simulating Bell Labs physicists",
+ max_loops: int = 1,
+ verbose: bool = True,
+ model_name: str = "gpt-4o-mini",
+ random_model_name: bool = False,
+ output_type: str = "str-all-except-first",
+ dynamic_context_window: bool = True,
+ **kwargs,
+ ):
+ """
+ Initialize the Bell Labs Research Swarm.
+
+ Args:
+ name: Name of the swarm
+ description: Description of the swarm's purpose
+ max_loops: Number of research iteration loops
+ verbose: Whether to enable verbose logging
+ model_name: Model to use for all agents
+ **kwargs: Additional arguments passed to BaseSwarm
+ """
+ self.name = name
+ self.description = description
+ self.max_loops = max_loops
+ self.verbose = verbose
+ self.model_name = model_name
+ self.kwargs = kwargs
+ self.random_model_name = random_model_name
+ self.output_type = output_type
+ self.dynamic_context_window = dynamic_context_window
+
+ self.conversation = Conversation(
+ dynamic_context_window=dynamic_context_window
+ )
+
+ # Create the physicist agents
+ self.agents = _create_physicist_agents(
+ model_name=model_name, random_model_name=random_model_name
+ )
+
+ # Set up specialized agents
+ self.oppenheimer = self._get_agent_by_name(
+ "J. Robert Oppenheimer"
+ )
+ self.code_implementer = self._get_agent_by_name(
+ "Code-Implementer"
+ )
+
+ self.physicists = [
+ agent
+ for agent in self.agents
+ if agent.agent_name != "J. Robert Oppenheimer"
+ and agent.agent_name != "Code-Implementer"
+ ]
+
+ # # Find the code implementer agent
+ # code_implementer = self._get_agent_by_name("Code-Implementer")
+ # code_implementer.tools = [developer_worker_agent]
+
+ logger.info(
+ f"Bell Labs Research Team initialized with {len(self.agents)} agents"
+ )
+
+ def _get_agent_by_name(self, name: str) -> Optional[Agent]:
+ """Get an agent by name."""
+ for agent in self.agents:
+ if agent.agent_name == name:
+ return agent
+ return None
+
+ def run(
+ self, task: str, img: Optional[str] = None
+ ) -> Dict[str, Any]:
+ """
+ Run the Bell Labs research simulation.
+
+ Args:
+ task: The research question or task to investigate
+
+ Returns:
+ Dictionary containing the research results, process history, and full conversation
+ """
+ logger.info(f"Starting Bell Labs research on: {task}")
+
+ # Add initial task to conversation history
+ self.conversation.add(
+ "Research Coordinator", f"Initial Research Task: {task}"
+ )
+
+ # Oppenheimer
+ oppenheimer_plan = self.oppenheimer.run(
+ task=self.conversation.get_str(), img=img
+ )
+
+ self.conversation.add(
+ self.oppenheimer.agent_name,
+ f"Research Plan: {oppenheimer_plan}",
+ )
+
+ # Discussion
+
+ # Physicists
+ physicist_discussion = self._conduct_physicist_discussion(
+ task, self.conversation.get_str()
+ )
+
+ # Add to conversation history
+ self.conversation.add(
+ "Group Discussion", physicist_discussion
+ )
+
+ # Now implement the solution
+ implementation_results = self._implement_and_test_solution(
+ history=self.conversation.get_str()
+ )
+
+ # Add to conversation history
+ self.conversation.add(
+ self.code_implementer.agent_name, implementation_results
+ )
+
+ return history_output_formatter(
+ conversation=self.conversation, type="str"
+ )
+
+ def _create_research_plan(
+ self, task: str, loop_number: int
+ ) -> str:
+ """
+ Have Oppenheimer create a research plan.
+
+ Args:
+ task: Research task
+ loop_number: Current loop number
+
+ Returns:
+ Research plan from Oppenheimer
+ """
+ prompt = f"""
+ Research Task: {task}
+
+ Loop Number: {loop_number + 1}
+
+ As J. Robert Oppenheimer, create a comprehensive research plan for this task.
+
+ Your plan should include:
+ 1. Clear research objectives and hypotheses
+ 2. Theoretical framework and approach
+ 3. Specific research questions to investigate
+ 4. Methodology for testing and validation
+ 5. Expected outcomes and success criteria
+ 6. Timeline and milestones
+ 7. Resource requirements and team coordination
+
+ Provide a detailed, actionable plan that the research team can follow.
+ """
+
+ plan = self.oppenheimer.run(prompt)
+ return plan
+
+ def _conduct_physicist_discussion(
+ self, task: str, history: str
+ ) -> str:
+ """
+ Conduct a natural discussion among physicists where they build on each other's ideas.
+
+ Args:
+ task: Research task
+ history: Conversation history including Oppenheimer's plan
+
+ Returns:
+ Results of the physicist discussion as a conversation transcript
+ """
+ import random
+
+ # Shuffle the physicists to create random discussion order
+ discussion_order = self.physicists.copy()
+ random.shuffle(discussion_order)
+
+ discussion_transcript = []
+ current_context = (
+ f"{history}\n\nCurrent Research Task: {task}\n\n"
+ )
+
+ # Each physicist contributes to the discussion, building on previous contributions
+ for i, physicist in enumerate(discussion_order):
+ if i == 0:
+ # First physicist starts the discussion
+ discussion_prompt = f"""
+ {current_context}
+
+ As {physicist.agent_name}, you are starting the group discussion about this research plan.
+
+ Based on your expertise, provide your initial thoughts on:
+
+ 1. What aspects of Oppenheimer's research plan do you find most promising?
+ 2. What theoretical challenges or concerns do you see?
+ 3. What specific approaches would you recommend based on your expertise?
+ 4. What questions or clarifications do you have for the team?
+
+ Be specific and draw from your unique perspective and expertise. This will set the tone for the group discussion.
+ """
+ else:
+ # Subsequent physicists build on the discussion
+ previous_contributions = "\n\n".join(
+ discussion_transcript
+ )
+ discussion_prompt = f"""
+ {current_context}
+
+ Previous Discussion:
+ {previous_contributions}
+
+ As {physicist.agent_name}, continue the group discussion by building on your colleagues' ideas.
+
+ Consider:
+ 1. How do your colleagues' perspectives relate to your expertise in {', '.join(physicist.expertise)}?
+ 2. What additional insights can you add to the discussion?
+ 3. How can you address any concerns or questions raised by others?
+ 4. What specific next steps would you recommend based on the discussion so far?
+
+ Engage directly with your colleagues' ideas and contribute your unique perspective to move the research forward.
+ """
+
+ # Get the physicist's contribution
+ contribution = physicist.run(discussion_prompt)
+
+ # Add to transcript with clear attribution
+ discussion_transcript.append(
+ f"{physicist.agent_name}: {contribution}"
+ )
+
+ # Update context for next iteration
+ current_context = (
+ f"{history}\n\nCurrent Research Task: {task}\n\nGroup Discussion:\n"
+ + "\n\n".join(discussion_transcript)
+ )
+
+ # Create a summary of the discussion
+ summary_prompt = f"""
+ Research Task: {task}
+
+ Complete Discussion Transcript:
+ {chr(10).join(discussion_transcript)}
+
+ As a research coordinator, provide a concise summary of the key points from this group discussion:
+
+ 1. Main areas of agreement among the physicists
+ 2. Key concerns or challenges identified
+ 3. Specific recommendations made by the team
+ 4. Next steps for moving forward with the research
+
+ Focus on actionable insights and clear next steps that the team can implement.
+ """
+
+ # Use Oppenheimer to summarize the discussion
+ discussion_summary = self.oppenheimer.run(summary_prompt)
+
+ # Return the full discussion transcript with summary
+ full_discussion = f"Group Discussion Transcript:\n\n{chr(10).join(discussion_transcript)}\n\n---\nDiscussion Summary:\n{discussion_summary}"
+
+ return full_discussion
+
+ def _implement_and_test_solution(
+ self,
+ history: str,
+ ) -> Dict[str, Any]:
+ """
+ Implement and test the proposed solution.
+
+ Args:
+ task: Research task
+ plan: Research plan
+ discussion_results: Results from physicist discussion
+ loop_number: Current loop number
+
+ Returns:
+ Implementation and testing results
+ """
+ implementation_prompt = f"""
+ {history}
+
+ As the Code Implementer, your task is to:
+
+ 1. Implement a computational solution based on the research plan
+ 2. Test the theoretical predictions through simulation or calculation
+ 3. Analyze the results and provide quantitative assessment
+ 4. Identify any discrepancies between theory and implementation
+ 5. Suggest improvements or next steps
+
+ Provide:
+ - Clear description of your implementation approach
+ - Code or algorithm description
+ - Test results and analysis
+ - Comparison with theoretical predictions
+ - Recommendations for further investigation
+
+ Focus on practical implementation and quantitative results.
+ """
+
+ implementation_results = self.code_implementer.run(
+ implementation_prompt
+ )
+
+ return implementation_results
+
+ def _analyze_results(
+ self, implementation_results: Dict[str, Any], loop_number: int
+ ) -> str:
+ """
+ Analyze the results and provide team review.
+
+ Args:
+ implementation_results: Results from implementation phase
+ loop_number: Current loop number
+
+ Returns:
+ Analysis and recommendations
+ """
+ analysis_prompt = f"""
+ Implementation Results: {implementation_results}
+
+ Loop Number: {loop_number + 1}
+
+ As the research team, analyze these results and provide:
+
+ 1. Assessment of whether the implementation supports the theoretical predictions
+ 2. Identification of any unexpected findings or discrepancies
+ 3. Evaluation of the methodology and approach
+ 4. Recommendations for the next research iteration
+ 5. Insights gained from this round of investigation
+
+ Consider:
+ - What worked well in this approach?
+ - What challenges or limitations were encountered?
+ - How can the research be improved in the next iteration?
+ - What new questions or directions have emerged?
+
+ Provide a comprehensive analysis that will guide the next research phase.
+ """
+
+ # Use team discussion for results analysis
+ analysis_results = self._conduct_team_analysis(
+ analysis_prompt
+ )
+ return analysis_results
+
+ def _conduct_team_analysis(self, analysis_prompt: str) -> str:
+ """
+ Conduct a team analysis discussion using the same approach as physicist discussion.
+
+ Args:
+ analysis_prompt: The prompt for the analysis
+
+ Returns:
+ Results of the team analysis discussion
+ """
+ import random
+
+ # Shuffle the agents to create random discussion order
+ discussion_order = self.agents.copy()
+ random.shuffle(discussion_order)
+
+ discussion_transcript = []
+ current_context = analysis_prompt
+
+ # Each agent contributes to the analysis, building on previous contributions
+ for i, agent in enumerate(discussion_order):
+ if i == 0:
+ # First agent starts the analysis
+ agent_prompt = f"""
+ {current_context}
+
+ As {agent.agent_name}, you are starting the team analysis discussion.
+
+ Based on your expertise and role, provide your initial analysis of the implementation results.
+ Focus on what you can contribute from your unique perspective.
+ """
+ else:
+ # Subsequent agents build on the analysis
+ previous_contributions = "\n\n".join(
+ discussion_transcript
+ )
+ agent_prompt = f"""
+ {current_context}
+
+ Previous Analysis:
+ {previous_contributions}
+
+ As {agent.agent_name}, continue the team analysis by building on your colleagues' insights.
+
+ Consider:
+ 1. How do your colleagues' perspectives relate to your expertise?
+ 2. What additional insights can you add to the analysis?
+ 3. How can you address any concerns or questions raised by others?
+ 4. What specific recommendations would you make based on the analysis so far?
+
+ Engage directly with your colleagues' ideas and contribute your unique perspective.
+ """
+
+ # Get the agent's contribution
+ contribution = agent.run(agent_prompt)
+
+ # Add to transcript with clear attribution
+ discussion_transcript.append(
+ f"{agent.agent_name}: {contribution}"
+ )
+
+ # Update context for next iteration
+ current_context = (
+ f"{analysis_prompt}\n\nTeam Analysis:\n"
+ + "\n\n".join(discussion_transcript)
+ )
+
+ # Create a summary of the analysis
+ summary_prompt = f"""
+ Analysis Prompt: {analysis_prompt}
+
+ Complete Analysis Transcript:
+ {chr(10).join(discussion_transcript)}
+
+ As a research coordinator, provide a concise summary of the key points from this team analysis:
+
+ 1. Main findings and insights from the team
+ 2. Key recommendations made
+ 3. Areas of agreement and disagreement
+ 4. Next steps for the research
+
+ Focus on actionable insights and clear next steps.
+ """
+
+ # Use Oppenheimer to summarize the analysis
+ analysis_summary = self.oppenheimer.run(summary_prompt)
+
+ # Return the full analysis transcript with summary
+ full_analysis = f"Team Analysis Transcript:\n\n{chr(10).join(discussion_transcript)}\n\n---\nAnalysis Summary:\n{analysis_summary}"
+
+ return full_analysis
+
+ def _refine_task_for_next_iteration(
+ self, current_task: str, loop_results: Dict[str, Any]
+ ) -> str:
+ """
+ Refine the task for the next research iteration.
+
+ Args:
+ current_task: Current research task
+ loop_results: Results from the current loop
+
+ Returns:
+ Refined task for next iteration
+ """
+ refinement_prompt = f"""
+ Current Research Task: {current_task}
+
+ Results from Current Loop: {loop_results}
+
+ Based on the findings and analysis from this research loop, refine the research task for the next iteration.
+
+ Consider:
+ - What new questions have emerged?
+ - What aspects need deeper investigation?
+ - What alternative approaches should be explored?
+ - What specific hypotheses should be tested?
+
+ Provide a refined, focused research question that builds upon the current findings
+ and addresses the most important next steps identified by the team.
+ """
+
+ # Use Oppenheimer to refine the task
+ refined_task = self.oppenheimer.run(refinement_prompt)
+
+ # Add task refinement to conversation history
+ self.conversation.add(
+ "J. Robert Oppenheimer",
+ f"Task Refined for Next Iteration: {refined_task}",
+ )
+
+ return refined_task
+
+ def _generate_final_conclusion(
+ self, research_results: Dict[str, Any]
+ ) -> str:
+ """
+ Generate a final conclusion summarizing all research findings.
+
+ Args:
+ research_results: Complete research results from all loops
+
+ Returns:
+ Final research conclusion
+ """
+ conclusion_prompt = f"""
+ Complete Research Results: {research_results}
+
+ As J. Robert Oppenheimer, provide a comprehensive final conclusion for this research project.
+
+ Your conclusion should:
+ 1. Summarize the key findings from all research loops
+ 2. Identify the most significant discoveries or insights
+ 3. Evaluate the success of the research approach
+ 4. Highlight any limitations or areas for future investigation
+ 5. Provide a clear statement of what was accomplished
+ 6. Suggest next steps for continued research
+
+ Synthesize the work of the entire team and provide a coherent narrative
+ of the research journey and its outcomes.
+ """
+
+ final_conclusion = self.oppenheimer.run(conclusion_prompt)
+ return final_conclusion
+
+
+# Example usage function
+def run_bell_labs_research(
+ research_question: str,
+ max_loops: int = 3,
+ model_name: str = "gpt-4o-mini",
+ verbose: bool = True,
+) -> Dict[str, Any]:
+ """
+ Run a Bell Labs research simulation.
+
+ Args:
+ research_question: The research question to investigate
+ max_loops: Number of research iteration loops
+ model_name: Model to use for all agents
+ verbose: Whether to enable verbose logging
+
+ Returns:
+ Complete research results and findings
+ """
+ bell_labs = BellLabsSwarm(
+ max_loops=max_loops, verbose=verbose, model_name=model_name
+ )
+
+ results = bell_labs.run(research_question)
+ return results
+
+
+# if __name__ == "__main__":
+# # Example research question
+# research_question = """
+# Investigate the feasibility of quantum computing for solving complex optimization problems.
+# Consider both theoretical foundations and practical implementation challenges.
+# """
+
+# print("Starting Bell Labs Research Simulation...")
+# print(f"Research Question: {research_question}")
+# print("-" * 80)
+
+# results = run_bell_labs_research(
+# research_question=research_question,
+# max_loops=2,
+# verbose=True
+# )
+
+# print("\n" + "=" * 80)
+# print("RESEARCH SIMULATION COMPLETED")
+# print("=" * 80)
+
+# print(f"\nFinal Conclusion:\n{results['final_conclusion']}")
+
+# print(f"\nResearch completed in {len(results['research_history'])} loops.")
+# print("Check the results dictionary for complete research details.")
diff --git a/swarms/structs/agent.py b/swarms/structs/agent.py
index f9e04013..bad1fc95 100644
--- a/swarms/structs/agent.py
+++ b/swarms/structs/agent.py
@@ -437,6 +437,7 @@ class Agent:
tool_retry_attempts: int = 3,
reasoning_prompt_on: bool = True,
dynamic_context_window: bool = True,
+ show_tool_execution_output: bool = True,
*args,
**kwargs,
):
@@ -578,15 +579,17 @@ class Agent:
self.tool_retry_attempts = tool_retry_attempts
self.reasoning_prompt_on = reasoning_prompt_on
self.dynamic_context_window = dynamic_context_window
-
- # Initialize the feedback
- self.feedback = []
+ self.show_tool_execution_output = show_tool_execution_output
# self.init_handling()
self.setup_config()
+ # Initialize the short memory
self.short_memory = self.short_memory_init()
+ # Initialize the tools
+ self.tool_struct = self.setup_tools()
+
if exists(self.docs_folder):
self.get_docs_from_doc_folders()
@@ -610,8 +613,6 @@ class Agent:
if self.react_on is True:
self.system_prompt += REACT_SYS_PROMPT
- # Run sequential operations after all concurrent tasks are done
- # self.agent_output = self.agent_output_model()
if self.autosave is True:
log_agent_data(self.to_dict())
@@ -640,13 +641,14 @@ class Agent:
verbose=self.verbose,
)
- def tool_handling(self):
-
- self.tool_struct = BaseTool(
+ def setup_tools(self):
+ return BaseTool(
tools=self.tools,
verbose=self.verbose,
)
+ def tool_handling(self):
+
# Convert all the tools into a list of dictionaries
self.tools_list_dictionary = (
convert_multiple_functions_to_openai_function_schema(
@@ -693,26 +695,6 @@ class Agent:
return memory
- def agent_output_model(self):
- # Many steps
- id = agent_id()
-
- return ManySteps(
- agent_id=id,
- agent_name=self.agent_name,
- # run_id=run_id,
- task="",
- max_loops=self.max_loops,
- steps=self.short_memory.to_dict(),
- full_history=self.short_memory.get_str(),
- total_tokens=count_tokens(
- text=self.short_memory.get_str()
- ),
- stopping_token=self.stopping_token,
- interactive=self.interactive,
- dynamic_temperature_enabled=self.dynamic_temperature_enabled,
- )
-
def llm_handling(self, *args, **kwargs):
"""Initialize the LiteLLM instance with combined configuration from all sources.
@@ -729,9 +711,6 @@ class Agent:
Returns:
LiteLLM: The initialized LiteLLM instance
"""
- # Use cached instance if available
- if self.llm is not None:
- return self.llm
if self.model_name is None:
self.model_name = "gpt-4o-mini"
@@ -754,6 +733,7 @@ class Agent:
"max_tokens": self.max_tokens,
"system_prompt": self.system_prompt,
"stream": self.streaming_on,
+ "top_p": self.top_p,
}
# Initialize tools_list_dictionary, if applicable
@@ -815,7 +795,7 @@ class Agent:
return self.llm
except AgentLLMInitializationError as e:
logger.error(
- f"AgentLLMInitializationError: Agent Name: {self.agent_name} Error in llm_handling: {e} Your current configuration is not supported. Please check the configuration and parameters."
+ f"AgentLLMInitializationError: Agent Name: {self.agent_name} Error in llm_handling: {e} Your current configuration is not supported. Please check the configuration and parameters. Traceback: {traceback.format_exc()}"
)
return None
@@ -878,6 +858,9 @@ class Agent:
if self.preset_stopping_token is not None:
self.stopping_token = ""
+ # Initialize the feedback
+ self.feedback = []
+
def check_model_supports_utilities(
self, img: Optional[str] = None
) -> bool:
@@ -890,7 +873,6 @@ class Agent:
Returns:
bool: True if model supports vision and image is provided, False otherwise.
"""
-
# Only check vision support if an image is provided
if img is not None:
@@ -1213,7 +1195,7 @@ class Agent:
self.save()
logger.error(
- f"Attempt {attempt+1}/{self.retry_attempts}: Error generating response in loop {loop_count} for agent '{self.agent_name}': {str(e)} | "
+ f"Attempt {attempt+1}/{self.retry_attempts}: Error generating response in loop {loop_count} for agent '{self.agent_name}': {str(e)} | Traceback: {traceback.format_exc()}"
)
attempt += 1
@@ -1291,7 +1273,7 @@ class Agent:
except KeyboardInterrupt as error:
self._handle_run_error(error)
- def __handle_run_error(self, error: any):
+ def _handle_run_error(self, error: any):
if self.autosave is True:
self.save()
log_agent_data(self.to_dict())
@@ -1313,11 +1295,6 @@ class Agent:
raise error
- def _handle_run_error(self, error: any):
- # Handle error directly instead of using daemon thread
- # to ensure proper exception propagation
- self.__handle_run_error(error)
-
async def arun(
self,
task: Optional[str] = None,
@@ -1514,26 +1491,6 @@ class Agent:
except Exception as error:
logger.info(f"Error running bulk run: {error}", "red")
- async def arun_batched(
- self,
- tasks: List[str],
- *args,
- **kwargs,
- ):
- """Asynchronously runs a batch of tasks."""
- try:
- # Create a list of coroutines for each task
- coroutines = [
- self.arun(task=task, *args, **kwargs)
- for task in tasks
- ]
- # Use asyncio.gather to run them concurrently
- results = await asyncio.gather(*coroutines)
- return results
- except Exception as error:
- logger.error(f"Error running batched tasks: {error}")
- raise
-
def reliability_check(self):
if self.system_prompt is None:
@@ -1568,7 +1525,7 @@ class Agent:
try:
if self.max_tokens > get_max_tokens(self.model_name):
logger.warning(
- f"Max tokens is set to {self.max_tokens}, but the model '{self.model_name}' only supports {get_max_tokens(self.model_name)} tokens. Please set max tokens to {get_max_tokens(self.model_name)} or less."
+ f"Max tokens is set to {self.max_tokens}, but the model '{self.model_name}' may or may not support {get_max_tokens(self.model_name)} tokens. Please set max tokens to {get_max_tokens(self.model_name)} or less."
)
except Exception:
@@ -1576,7 +1533,7 @@ class Agent:
if self.model_name not in model_list:
logger.warning(
- f"The model '{self.model_name}' is not supported. Please use a supported model, or override the model name with the 'llm' parameter, which should be a class with a 'run(task: str)' method or a '__call__' method."
+ f"The model '{self.model_name}' may not be supported. Please use a supported model, or override the model name with the 'llm' parameter, which should be a class with a 'run(task: str)' method or a '__call__' method."
)
def save(self, file_path: str = None) -> None:
@@ -1822,14 +1779,6 @@ class Agent:
) as executor:
self.executor = executor
- # # Reinitialize tool structure if needed
- # if hasattr(self, 'tools') and (self.tools or getattr(self, 'list_base_models', None)):
- # self.tool_struct = BaseTool(
- # tools=self.tools,
- # base_models=getattr(self, 'list_base_models', None),
- # tool_system_prompt=self.tool_system_prompt
- # )
-
except Exception as e:
logger.error(f"Error reinitializing components: {e}")
raise
@@ -2640,19 +2589,20 @@ class Agent:
self.llm.stream = original_stream
return streaming_response
else:
- # Non-streaming call
+ args = {
+ "task": task,
+ }
+
if img is not None:
- out = self.llm.run(
- task=task, img=img, *args, **kwargs
- )
- else:
- out = self.llm.run(task=task, *args, **kwargs)
+ args["img"] = img
+
+ out = self.llm.run(**args, **kwargs)
return out
except AgentLLMError as e:
logger.error(
- f"Error calling LLM: {e}. Task: {task}, Args: {args}, Kwargs: {kwargs}"
+ f"Error calling LLM: {e}. Task: {task}, Args: {args}, Kwargs: {kwargs} Traceback: {traceback.format_exc()}"
)
raise e
@@ -2743,6 +2693,30 @@ class Agent:
)
raise KeyboardInterrupt
+ def run_batched(
+ self,
+ tasks: List[str],
+ imgs: List[str] = None,
+ *args,
+ **kwargs,
+ ):
+ """
+ Run a batch of tasks concurrently.
+
+ Args:
+ tasks (List[str]): List of tasks to run.
+ imgs (List[str], optional): List of images to run. 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.
+
+ Returns:
+ List[Any]: List of results from each task execution.
+ """
+ return [
+ self.run(task=task, imgs=imgs, *args, **kwargs)
+ for task in tasks
+ ]
+
def handle_artifacts(
self, text: str, file_output_path: str, file_extension: str
) -> None:
@@ -3081,10 +3055,17 @@ class Agent:
)
if self.print_on is True:
- self.pretty_print(
- f"Tool Executed Successfully [{time.strftime('%H:%M:%S')}]",
- loop_count,
- )
+ if self.show_tool_execution_output is True:
+
+ self.pretty_print(
+ f"Tool Executed Successfully [{time.strftime('%H:%M:%S')}] \n\nTool Output: {format_data_structure(output)}",
+ loop_count,
+ )
+ else:
+ self.pretty_print(
+ f"Tool Executed Successfully [{time.strftime('%H:%M:%S')}]",
+ loop_count,
+ )
# Now run the LLM again without tools - create a temporary LLM instance
# instead of modifying the cached one
diff --git a/swarms/structs/conversation.py b/swarms/structs/conversation.py
index de7c1de2..5b0415bf 100644
--- a/swarms/structs/conversation.py
+++ b/swarms/structs/conversation.py
@@ -1790,21 +1790,63 @@ class Conversation:
pass
self.conversation_history = []
- def dynamic_auto_chunking(self):
+ def _dynamic_auto_chunking_worker(self):
+ """
+ Dynamically chunk the conversation history to fit within the context length.
+
+ Returns:
+ str: The chunked conversation history as a string that fits within context_length tokens.
+ """
all_tokens = self._return_history_as_string_worker()
total_tokens = count_tokens(
all_tokens, self.tokenizer_model_name
)
- if total_tokens > self.context_length:
- # Get the difference between the count_tokens and the context_length
- difference = total_tokens - self.context_length
+ if total_tokens <= self.context_length:
+ return all_tokens
+
+ # We need to remove characters from the beginning until we're under the limit
+ # Start by removing a percentage of characters and adjust iteratively
+ target_tokens = self.context_length
+ current_string = all_tokens
+
+ # Binary search approach to find the right cutoff point
+ left, right = 0, len(all_tokens)
+
+ while left < right:
+ mid = (left + right) // 2
+ test_string = all_tokens[mid:]
+
+ if not test_string:
+ break
+
+ test_tokens = count_tokens(
+ test_string, self.tokenizer_model_name
+ )
+
+ if test_tokens <= target_tokens:
+ # We can remove more from the beginning
+ right = mid
+ current_string = test_string
+ else:
+ # We need to keep more from the beginning
+ left = mid + 1
+
+ return current_string
- # Slice the first difference number of messages and contents from the beginning of the conversation history
- new_history = all_tokens[difference:]
+ def dynamic_auto_chunking(self):
+ """
+ Dynamically chunk the conversation history to fit within the context length.
- return new_history
+ Returns:
+ str: The chunked conversation history as a string that fits within context_length tokens.
+ """
+ try:
+ return self._dynamic_auto_chunking_worker()
+ except Exception as e:
+ logger.error(f"Dynamic auto chunking failed: {e}")
+ return self._return_history_as_string_worker()
# Example usage
diff --git a/swarms/utils/litellm_wrapper.py b/swarms/utils/litellm_wrapper.py
index 1b7d3c60..a64753b4 100644
--- a/swarms/utils/litellm_wrapper.py
+++ b/swarms/utils/litellm_wrapper.py
@@ -176,6 +176,12 @@ class LiteLLM:
litellm.drop_params = True
+ # Add system prompt if present
+ if self.system_prompt is not None:
+ self.messages.append(
+ {"role": "system", "content": self.system_prompt}
+ )
+
# Store additional args and kwargs for use in run method
self.init_args = args
self.init_kwargs = kwargs
@@ -231,8 +237,8 @@ class LiteLLM:
def _prepare_messages(
self,
- task: str,
- img: str = None,
+ task: Optional[str] = None,
+ img: Optional[str] = None,
):
"""
Prepare the messages for the given task.
@@ -245,24 +251,14 @@ class LiteLLM:
"""
self.check_if_model_supports_vision(img=img)
- # Initialize messages
- messages = []
-
- # Add system prompt if present
- if self.system_prompt is not None:
- messages.append(
- {"role": "system", "content": self.system_prompt}
- )
-
# Handle vision case
if img is not None:
- messages = self.vision_processing(
- task=task, image=img, messages=messages
- )
- else:
- messages.append({"role": "user", "content": task})
+ self.vision_processing(task=task, image=img)
- return messages
+ if task is not None:
+ self.messages.append({"role": "user", "content": task})
+
+ return self.messages
def anthropic_vision_processing(
self, task: str, image: str, messages: list
@@ -546,12 +542,18 @@ class LiteLLM:
5. Default parameters
"""
try:
- messages = self._prepare_messages(task=task, img=img)
+
+ self.messages.append({"role": "user", "content": task})
+
+ if img is not None:
+ self.messages = self.vision_processing(
+ task=task, image=img
+ )
# Base completion parameters
completion_params = {
"model": self.model_name,
- "messages": messages,
+ "messages": self.messages,
"stream": self.stream,
"max_tokens": self.max_tokens,
"caching": self.caching,