Skip to content

Commit

Permalink
Merge branch 'kyegomez:master' into new_master
Browse files Browse the repository at this point in the history
  • Loading branch information
harshalmore31 authored Jan 18, 2025
2 parents f1ac870 + e97f95e commit c63c53a
Show file tree
Hide file tree
Showing 4 changed files with 246 additions and 19 deletions.
52 changes: 52 additions & 0 deletions examples/onboard/agents.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
agents:
- agent_name: "Financial-Analysis-Agent"
model:
model_name: "gpt-4"
temperature: 0.1
max_tokens: 2000
system_prompt: "financial_agent_sys_prompt"
max_loops: 1
autosave: true
dashboard: false
verbose: true
dynamic_temperature_enabled: true
saved_state_path: "finance_agent.json"
user_name: "swarms_corp"
retry_attempts: 1
context_length: 4000
return_step_meta: false
output_type: "str"
task: "How can I establish a ROTH IRA to buy stocks and get a tax break?"

- agent_name: "Stock-Analysis-Agent"
model:
model_name: "gpt-4"
temperature: 0.2
max_tokens: 1500
system_prompt: "stock_agent_sys_prompt"
max_loops: 2
autosave: true
dashboard: false
verbose: true
dynamic_temperature_enabled: false
saved_state_path: "stock_agent.json"
user_name: "stock_user"
retry_attempts: 3
context_length: 4000
return_step_meta: true
output_type: "json"
task: "What is the best strategy for long-term stock investment?"

swarm_architecture:
name: "Financial-Advisory-Swarm"
description: "A swarm of agents working together to provide comprehensive financial advice"
swarm_type: "SequentialWorkflow"
max_loops: 2
task: "Analyze ROTH IRA setup requirements and provide a comprehensive long-term investment strategy"
autosave: true
return_json: false
rules: |
1. Financial-Analysis-Agent first explains ROTH IRA setup process and requirements
2. Stock-Analysis-Agent then provides specific investment strategies suitable for ROTH IRA
3. Both agents should ensure advice is tax-aware and compliant with retirement account regulations
4. Focus on practical, actionable steps the user can take
37 changes: 37 additions & 0 deletions examples/onboard/onboard-basic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import os

from dotenv import load_dotenv
from loguru import logger
from swarm_models import OpenAIChat

from swarms.agents.create_agents_from_yaml import (
create_agents_from_yaml,
)

# Load environment variables
load_dotenv()

# Path to your YAML file
yaml_file = "agents.yaml"

# Get the OpenAI API key from the environment variable
api_key = os.getenv("OPENAI_API_KEY")

# Create an instance of the OpenAIChat class
model = OpenAIChat(
openai_api_key=api_key, model_name="gpt-4o-mini", temperature=0.1
)

print(model)

try:
# Create agents and run tasks (using 'both' to return agents and task results)
task_results = create_agents_from_yaml(
model=model, yaml_file=yaml_file, return_type="agents"
)

print(task_results)
logger.info(f"Results from agents: {task_results}")
except Exception as e:
logger.error(f"An error occurred: {e}")
print(e)
92 changes: 76 additions & 16 deletions swarms/agents/create_agents_from_yaml.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,21 +178,38 @@ def create_agents_from_yaml(
swarm_router = None

try:
logger.info("Starting agent creation process...")

# Load and validate configuration
if yaml_file:
logger.info(f"Loading configuration from {yaml_file}")
config = load_yaml_safely(yaml_file, yaml_string)

if not config.get("agents"):
raise ValueError(
"No agents defined in the YAML configuration. "
"Please add at least one agent under the 'agents' section."
)

logger.info(f"Found {len(config['agents'])} agent(s) to create")

# Create agents with retry logic
for agent_config in config["agents"]:
for idx, agent_config in enumerate(config["agents"], 1):
if not agent_config.get("agent_name"):
agent_config["agent_name"] = f"Agent_{idx}"

logger.info(
f"Creating agent: {agent_config['agent_name']}"
f"Creating agent {idx}/{len(config['agents'])}: {agent_config['agent_name']}"
)

if "model_name" in agent_config:
logger.info(f"Using specified model: {agent_config['model_name']}")
model_instance = LiteLLM(
model_name=agent_config["model_name"]
)
else:
model_name = "gpt-4o"
model_name = "gpt-4"
logger.info(f"No model specified, using default: {model_name}")
model_instance = LiteLLM(model_name=model_name)

agent = create_agent_with_retry(
Expand All @@ -203,12 +220,29 @@ def create_agents_from_yaml(
)
agents.append(agent)

logger.info(f"Successfully created {len(agents)} agent(s)")

# Create SwarmRouter if specified
if "swarm_architecture" in config:
logger.info("Setting up swarm architecture...")
try:
if not isinstance(config["swarm_architecture"], dict):
raise ValueError(
"swarm_architecture must be a dictionary containing swarm configuration"
)

required_fields = {"name", "description", "swarm_type"}
missing_fields = required_fields - set(config["swarm_architecture"].keys())
if missing_fields:
raise ValueError(
f"SwarmRouter creation failed: Missing required fields in swarm_architecture: {', '.join(missing_fields)}"
)

swarm_config = SwarmConfig(
**config["swarm_architecture"]
)

logger.info(f"Creating SwarmRouter with type: {swarm_config.swarm_type}")
swarm_router = SwarmRouter(
name=swarm_config.name,
description=swarm_config.description,
Expand All @@ -226,8 +260,14 @@ def create_agents_from_yaml(
)
except Exception as e:
logger.error(f"Error creating SwarmRouter: {str(e)}")
if "swarm_type" in str(e) and "valid_types" in str(e):
raise ValueError(
"Invalid swarm_type. Must be one of: SequentialWorkflow, ConcurrentWorkflow, "
"AgentRearrange, MixtureOfAgents, or auto"
)
raise ValueError(
f"Failed to create SwarmRouter: {str(e)}"
f"Failed to create SwarmRouter: {str(e)}. Make sure your YAML file "
"has a valid swarm_architecture section with required fields."
)

# Handle return types with improved error checking
Expand All @@ -244,12 +284,29 @@ def create_agents_from_yaml(
f"Invalid return_type. Must be one of: {valid_return_types}"
)

if return_type == "run_swarm" or "swarm":
logger.info(f"Processing with return type: {return_type}")

if return_type in ("run_swarm", "swarm"):
if not swarm_router:
if "swarm_architecture" not in config:
raise ValueError(
"Cannot run swarm: No swarm_architecture section found in YAML configuration.\n"
"Please add a swarm_architecture section with:\n"
" - name: your_swarm_name\n"
" - description: your_swarm_description\n"
" - swarm_type: one of [SequentialWorkflow, ConcurrentWorkflow, AgentRearrange, MixtureOfAgents, auto]\n"
" - task: your_task_description"
)
raise ValueError(
"Cannot run swarm: SwarmRouter not created."
"Cannot run swarm: SwarmRouter creation failed. Check the previous error messages."
)
try:
if not config["swarm_architecture"].get("task"):
raise ValueError(
"No task specified in swarm_architecture. Please add a 'task' field "
"to define what the swarm should do."
)
logger.info(f"Running swarm with task: {config['swarm_architecture']['task']}")
return swarm_router.run(
config["swarm_architecture"]["task"]
)
Expand All @@ -259,30 +316,33 @@ def create_agents_from_yaml(

# Return appropriate type based on configuration
if return_type == "auto":
return (
result = (
swarm_router
if swarm_router
else (agents[0] if len(agents) == 1 else agents)
)
elif return_type == "swarm":
return (
result = (
swarm_router
if swarm_router
else (agents[0] if len(agents) == 1 else agents)
)
elif return_type == "agents":
return agents[0] if len(agents) == 1 else agents
result = agents[0] if len(agents) == 1 else agents
elif return_type == "both":
return (
swarm_router
if swarm_router
else agents[0] if len(agents) == 1 else agents
), agents
result = (
(swarm_router if swarm_router else agents[0] if len(agents) == 1 else agents),
agents
)
elif return_type == "tasks":
return task_results
result = task_results

logger.info("Process completed successfully")
return result

except Exception as e:
logger.error(
f"Critical error in create_agents_from_yaml: {str(e)}"
f"Critical error in create_agents_from_yaml: {str(e)}\n"
"Please check your YAML configuration and try again."
)
raise
84 changes: 81 additions & 3 deletions swarms/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,9 +276,87 @@ def main():
elif args.command == "check-login":
check_login()
elif args.command == "run-agents":
create_agents_from_yaml(
yaml_file=args.yaml_file, return_type="tasks"
)
try:
console.print(f"[yellow]Loading agents from {args.yaml_file}...[/yellow]")

if not os.path.exists(args.yaml_file):
raise FileNotFoundError(
f"YAML file not found: {args.yaml_file}\n"
"Please make sure the file exists and you're in the correct directory."
)

# Create progress display
progress = Progress(
SpinnerColumn(),
TextColumn("[progress.description]{task.description}"),
console=console,
)

with progress:
# Add initial task
init_task = progress.add_task("Initializing...", total=None)

# Load and validate YAML
progress.update(init_task, description="Loading YAML configuration...")

# Create agents
progress.update(init_task, description="Creating agents...")
result = create_agents_from_yaml(
yaml_file=args.yaml_file,
return_type="run_swarm"
)

# Update progress on completion
progress.update(init_task, description="Processing complete!", completed=True)

if result:
# Format and display the results
if isinstance(result, str):
console.print("\n[bold green]Results:[/bold green]")
console.print(Panel(result, title="Agent Output", border_style="green"))
elif isinstance(result, dict):
console.print("\n[bold green]Results:[/bold green]")
for key, value in result.items():
console.print(f"[cyan]{key}:[/cyan] {value}")
else:
console.print("[green]✓ Agents completed their tasks successfully![/green]")
else:
console.print("[yellow]⚠ Agents completed but returned no results.[/yellow]")

except FileNotFoundError as e:
show_error("File Error", str(e))
except ValueError as e:
show_error(
"Configuration Error",
str(e) + "\n\nPlease check your agents.yaml file format."
)
except Exception as e:
# Enhanced error handling
error_msg = str(e)
if "context_length_exceeded" in error_msg:
show_error(
"Context Length Error",
"The model's context length was exceeded. Try:\n"
"1. Reducing max_tokens in your YAML config\n"
"2. Reducing context_length in your YAML config\n"
"3. Using a model with larger context window"
)
elif "api_key" in error_msg.lower():
show_error(
"API Key Error",
"There seems to be an issue with the API key. Please:\n"
"1. Check if your API key is set correctly\n"
"2. Verify the API key is valid\n"
"3. Run 'swarms get-api-key' to get a new key"
)
else:
show_error(
"Execution Error",
f"An unexpected error occurred: {error_msg}\n"
"1. Check your YAML configuration\n"
"2. Verify your API keys are set\n"
"3. Check network connectivity"
)
elif args.command == "book-call":
webbrowser.open(
"https://cal.com/swarms/swarms-strategy-session"
Expand Down

0 comments on commit c63c53a

Please sign in to comment.