diff --git a/examples/onboard/agents.yaml b/examples/onboard/agents.yaml new file mode 100644 index 000000000..23a7c7142 --- /dev/null +++ b/examples/onboard/agents.yaml @@ -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 \ No newline at end of file diff --git a/examples/onboard/onboard-basic.py b/examples/onboard/onboard-basic.py new file mode 100644 index 000000000..96df9f353 --- /dev/null +++ b/examples/onboard/onboard-basic.py @@ -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) diff --git a/swarms/agents/create_agents_from_yaml.py b/swarms/agents/create_agents_from_yaml.py index d1eb3e953..76aab3466 100644 --- a/swarms/agents/create_agents_from_yaml.py +++ b/swarms/agents/create_agents_from_yaml.py @@ -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( @@ -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, @@ -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 @@ -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"] ) @@ -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 diff --git a/swarms/cli/main.py b/swarms/cli/main.py index 1acdfd469..4559ef9ba 100644 --- a/swarms/cli/main.py +++ b/swarms/cli/main.py @@ -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"