updated and fixed !

pull/1022/head
harshalmore31 3 weeks ago
parent dd2b0c2a3c
commit 223d398a20

@ -1,165 +0,0 @@
"""
AgentLoader Example: Research Team Collaboration
===============================================
This example demonstrates using the AgentLoader to create a research team
from markdown files and orchestrate them in a sequential workflow.
"""
import os
import sys
import tempfile
from pathlib import Path
# Add local swarms to path
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
from swarms.structs.agent import Agent
from swarms.structs.sequential_workflow import SequentialWorkflow
from swarms.utils.agent_loader import AgentLoader
def create_research_agents():
"""Create markdown files for research team agents"""
market_researcher = """| name | description | model |
|------|-------------|-------|
| market-researcher | Expert in market analysis and competitive intelligence | gpt-4 |
## Focus Areas
- Market size and growth analysis
- Competitive landscape assessment
- Consumer behavior patterns
- Industry trend identification
## Approach
1. Gather comprehensive market data
2. Analyze quantitative and qualitative indicators
3. Identify key market drivers and barriers
4. Evaluate competitive positioning
5. Assess market opportunities and threats
## Output
- Market analysis reports with key metrics
- Competitive intelligence briefings
- Market opportunity assessments
- Consumer behavior insights
"""
financial_analyst = """| name | description | model |
|------|-------------|-------|
| financial-analyst | Specialist in financial modeling and investment analysis | gpt-4 |
## Focus Areas
- Financial statement analysis
- Valuation modeling techniques
- Investment risk assessment
- Cash flow projections
## Approach
1. Conduct thorough financial analysis
2. Build comprehensive financial models
3. Perform multiple valuation methods
4. Assess financial risks and sensitivities
5. Provide investment recommendations
## Output
- Financial analysis reports
- Valuation models with scenarios
- Investment recommendation memos
- Risk assessment matrices
"""
industry_expert = """| name | description | model |
|------|-------------|-------|
| industry-expert | Domain specialist with deep industry knowledge | gpt-4 |
## Focus Areas
- Industry structure and dynamics
- Regulatory environment analysis
- Technology trends and disruptions
- Supply chain analysis
## Approach
1. Map industry structure and stakeholders
2. Analyze regulatory framework
3. Identify technology trends
4. Evaluate supply chain dynamics
5. Assess competitive positioning
## Output
- Industry landscape reports
- Regulatory compliance assessments
- Technology trend analysis
- Strategic positioning recommendations
"""
return {
"market_researcher.md": market_researcher,
"financial_analyst.md": financial_analyst,
"industry_expert.md": industry_expert
}
def main():
"""Main execution function"""
temp_dir = tempfile.mkdtemp()
try:
# Create markdown files
agent_definitions = create_research_agents()
file_paths = []
for filename, content in agent_definitions.items():
file_path = os.path.join(temp_dir, filename)
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
file_paths.append(file_path)
# Load agents using AgentLoader
loader = AgentLoader()
agents = loader.load_multiple_agents(
file_paths,
max_loops=1,
verbose=False
)
print(f"Loaded {len(agents)} agents")
for i, agent in enumerate(agents):
print(f"Agent {i}: {agent.agent_name} - LLM: {hasattr(agent, 'llm')}")
# Create sequential workflow
research_workflow = SequentialWorkflow(
agents=agents,
max_loops=1,
)
# Define research task
task = """
Analyze the AI-powered healthcare diagnostics market for a potential $50M investment.
Focus on:
1. Market size, growth, and key drivers
2. Competitive landscape and major players
3. Financial viability and investment metrics
4. Industry dynamics and regulatory factors
Provide strategic recommendations for market entry.
"""
# Execute workflow
result = research_workflow.run(task)
return result
finally:
# Cleanup
for file_path in file_paths:
if os.path.exists(file_path):
os.remove(file_path)
os.rmdir(temp_dir)
if __name__ == "__main__":
result = main()
print("Research Analysis Complete:")
print("-" * 50)
print(result)

@ -1,14 +1,14 @@
# AgentLoader - Load Agents from Markdown Files # AgentLoader - Load Agents from Markdown Files
The `AgentLoader` is a powerful utility for creating Swarms agents from markdown files. It supports both single and multiple markdown file loading, providing a flexible way to define and deploy agents using a structured markdown format. The `AgentLoader` is a powerful utility for creating Swarms agents from markdown files using the Claude Code sub-agent format. It supports both single and multiple markdown file loading, providing a flexible way to define and deploy agents using YAML frontmatter configuration.
## Overview ## Overview
The AgentLoader enables you to: The AgentLoader enables you to:
- Load single agents from markdown files - Load single agents from markdown files with YAML frontmatter
- Load multiple agents from directories or file lists - Load multiple agents from directories or file lists
- Parse structured markdown content into agent configurations - Parse Claude Code sub-agent YAML frontmatter configurations
- Maintain backwards compatibility with existing agent systems - Extract system prompts from markdown content
- Provide comprehensive error handling and validation - Provide comprehensive error handling and validation
## Installation ## Installation
@ -21,32 +21,33 @@ from swarms.utils import AgentLoader, load_agent_from_markdown, load_agents_from
## Markdown Format ## Markdown Format
The AgentLoader expects markdown files to follow a specific structure: The AgentLoader uses the Claude Code sub-agent YAML frontmatter format:
### Required Table Header
```markdown ```markdown
| name | description | model | ---
|------|-------------|-------| name: your-sub-agent-name
| agent-name | Brief description of the agent | gpt-4 | description: Description of when this subagent should be invoked
model_name: gpt-4
temperature: 0.3
max_loops: 2
mcp_url: http://example.com/mcp # optional
---
Your subagent's system prompt goes here. This can be multiple paragraphs
and should clearly define the subagent's role, capabilities, and approach
to solving problems.
Include specific instructions, best practices, and any constraints
the subagent should follow.
``` ```
### Optional Sections **Schema Fields:**
```markdown - `name` (required): Your sub-agent name
## Focus Areas - `description` (required): Description of when this subagent should be invoked
- Key responsibility area 1 - `model_name` (optional): Name of model (defaults to random selection if not provided)
- Key responsibility area 2 - `temperature` (optional): Float value for model temperature (0.0-2.0)
- Key responsibility area 3 - `max_loops` (optional): Integer for maximum reasoning loops
- `mcp_url` (optional): MCP server URL if needed
## Approach
1. First step in methodology
2. Second step in methodology
3. Third step in methodology
## Output
- Expected deliverable 1
- Expected deliverable 2
- Expected deliverable 3
```
## Quick Start ## Quick Start
@ -55,13 +56,17 @@ The AgentLoader expects markdown files to follow a specific structure:
```python ```python
from swarms.utils import load_agent_from_markdown from swarms.utils import load_agent_from_markdown
# Load agent from markdown file # Load Claude Code format agent (YAML frontmatter)
agent = load_agent_from_markdown( agent = load_agent_from_markdown(
file_path="path/to/agent.md" file_path="performance-engineer.md" # Uses YAML frontmatter format
) )
# Use the agent # The agent automatically gets configured with:
response = agent.run("What are your capabilities?") # - Name, description from frontmatter
# - Temperature, max_loops, model settings
# - System prompt from content after frontmatter
response = agent.run("Analyze application performance issues")
print(response) print(response)
``` ```
@ -70,17 +75,23 @@ print(response)
```python ```python
from swarms.utils import load_agents_from_markdown from swarms.utils import load_agents_from_markdown
# Load all agents from directory # Load all agents from directory (YAML frontmatter format)
agents = load_agents_from_markdown( agents = load_agents_from_markdown(
file_paths="./agents_directory/" file_paths="./agents_directory/" # Directory with Claude Code format files
) )
# Load agents from specific files # Load agents from specific files
agents = load_agents_from_markdown( agents = load_agents_from_markdown(
file_paths=["agent1.md", "agent2.md", "agent3.md"] file_paths=[
"performance-engineer.md", # Claude Code YAML format
"financial-analyst.md", # Claude Code YAML format
"security-analyst.md" # Claude Code YAML format
]
) )
print(f"Loaded {len(agents)} agents") print(f"Loaded {len(agents)} agents")
for agent in agents:
print(f"- {agent.agent_name}: {getattr(agent, 'temperature', 'default temp')}")
``` ```
## Class-Based Usage ## Class-Based Usage
@ -139,61 +150,60 @@ agent = load_agent_from_markdown(
## Complete Example ## Complete Example
### Example Markdown File (performance-engineer.md) ### Example: Claude Code Sub-Agent Format
Create a file `performance-engineer.md`:
```markdown ```markdown
| name | description | model | ---
|------|-------------|-------| name: performance-engineer
| performance-engineer | Optimize application performance and identify bottlenecks | gpt-4 | description: Optimize application performance and identify bottlenecks
model_name: gpt-4
## Focus Areas temperature: 0.3
- Application profiling and performance analysis max_loops: 2
- Database optimization and query tuning mcp_url: http://example.com/mcp
- Memory and CPU usage optimization ---
- Load testing and capacity planning
- Infrastructure scaling recommendations You are a Performance Engineer specializing in application optimization and scalability.
## Approach Your role involves analyzing system performance, identifying bottlenecks, and implementing
1. Analyze application architecture and identify potential bottlenecks solutions to improve efficiency and user experience.
2. Implement comprehensive monitoring and logging systems
3. Conduct performance testing under various load conditions Key responsibilities:
4. Profile memory usage and optimize resource consumption - Profile applications to identify performance issues
5. Provide actionable recommendations with implementation guides - Optimize database queries and caching strategies
- Implement load testing and monitoring solutions
## Output - Recommend infrastructure improvements
- Detailed performance analysis reports with metrics - Provide actionable optimization recommendations
- Optimized code recommendations and examples
- Infrastructure scaling and architecture suggestions Always provide specific, measurable recommendations with implementation details.
- Monitoring and alerting configuration guidelines Focus on both immediate wins and long-term architectural improvements.
- Load testing results and capacity planning documents
``` ```
### Loading and Using the Agent ### Loading and Using the Agent
```python ```python
from swarms.utils import load_agent_from_markdown from swarms.utils import load_agent_from_markdown
from swarms.utils.litellm_wrapper import LiteLLM
# Initialize model # Load Claude Code format agent (YAML frontmatter)
model = LiteLLM(model_name="gpt-4") performance_agent = load_agent_from_markdown(
file_path="performance-engineer.md"
# Load the performance engineer agent
agent = load_agent_from_markdown(
file_path="performance-engineer.md",
model=model,
max_loops=3,
verbose=True
) )
# Use the agent print(f"Agent: {performance_agent.agent_name}")
print(f"Temperature: {getattr(performance_agent, 'temperature', 'default')}")
print(f"Max loops: {performance_agent.max_loops}")
print(f"System prompt preview: {performance_agent.system_prompt[:100]}...")
# Use the performance agent
task = """ task = """
Analyze the performance of a web application that handles 10,000 concurrent users Analyze the performance of a web application that handles 10,000 concurrent users
but is experiencing slow response times averaging 3 seconds. The application uses but is experiencing slow response times averaging 3 seconds. The application uses
a PostgreSQL database and is deployed on AWS with 4 EC2 instances behind a load balancer. a PostgreSQL database and is deployed on AWS with 4 EC2 instances behind a load balancer.
""" """
analysis = agent.run(task) # Note: Actual agent.run() would make API calls
print(f"Performance Analysis:\n{analysis}") print(f"\nTask for {performance_agent.agent_name}: {task[:100]}...")
``` ```
## Error Handling ## Error Handling
@ -297,13 +307,6 @@ result = workflow.run("Conduct a comprehensive system audit")
5. **Model Selection**: Choose appropriate models based on agent complexity 5. **Model Selection**: Choose appropriate models based on agent complexity
6. **Configuration**: Override defaults when specific behavior is needed 6. **Configuration**: Override defaults when specific behavior is needed
## Backwards Compatibility
The AgentLoader maintains full backwards compatibility with:
- Claude Code sub-agents markdown format
- Existing swarms agent creation patterns
- Legacy configuration systems
- Current workflow orchestration
## API Reference ## API Reference
@ -331,10 +334,13 @@ class MarkdownAgentConfig(BaseModel):
name: str name: str
description: str description: str
model_name: Optional[str] = "gpt-4" model_name: Optional[str] = "gpt-4"
temperature: Optional[float] = 0.1 # Model temperature (0.0-2.0)
mcp_url: Optional[str] = None # Optional MCP server URL
system_prompt: str system_prompt: str
focus_areas: Optional[List[str]] = [] max_loops: int = 1
approach: Optional[List[str]] = [] autosave: bool = False
output: Optional[List[str]] = [] dashboard: bool = False
verbose: bool = False
# ... additional configuration fields # ... additional configuration fields
``` ```

@ -17,106 +17,154 @@ def main():
print("=== AgentLoader Demo ===") print("=== AgentLoader Demo ===")
# Example 1: Create a sample markdown file for testing # Example 1: Create sample markdown files for testing - Claude Code format
sample_md = """| name | description | model |
|------|-------------|-------| # Performance Engineer agent
| performance-engineer | Optimize application performance and identify bottlenecks | gpt-4 | performance_md = """---
name: performance-engineer
## Focus Areas description: Optimize application performance and identify bottlenecks
- Application profiling and performance analysis model_name: gpt-4
- Database optimization and query tuning temperature: 0.3
- Memory and CPU usage optimization max_loops: 2
- Load testing and capacity planning mcp_url: http://example.com/mcp
---
## Approach
1. Analyze application architecture and identify potential bottlenecks You are a Performance Engineer specializing in application optimization and scalability.
2. Implement comprehensive monitoring and logging
3. Conduct performance testing under various load conditions Your role involves:
4. Optimize critical paths and resource usage - Analyzing application architecture and identifying potential bottlenecks
5. Document findings and provide actionable recommendations - Implementing comprehensive monitoring and logging
- Conducting performance testing under various load conditions
## Output - Optimizing critical paths and resource usage
- Documenting findings and providing actionable recommendations
Expected output:
- Performance analysis reports with specific metrics - Performance analysis reports with specific metrics
- Optimized code recommendations - Optimized code recommendations
- Infrastructure scaling suggestions - Infrastructure scaling suggestions
- Monitoring and alerting setup guidelines - Monitoring and alerting setup guidelines
""" """
# Create sample markdown file # Data Analyst agent
sample_file = "sample_agent.md" data_analyst_md = """---
with open(sample_file, 'w') as f: name: data-analyst
f.write(sample_md) description: Analyze data and provide business insights
model_name: gpt-4
try: temperature: 0.2
# Example 2: Load single agent using class method max_loops: 1
print("\\n1. Loading single agent using AgentLoader class:") ---
agent = loader.load_single_agent(sample_file)
print(f" Loaded agent: {agent.agent_name}") You are a Data Analyst specializing in extracting insights from complex datasets.
print(f" System prompt preview: {agent.system_prompt[:100]}...")
Your responsibilities include:
# Example 3: Load single agent using convenience function - Collecting and cleaning data from various sources
print("\\n2. Loading single agent using convenience function:") - Performing exploratory data analysis and statistical modeling
agent2 = load_agent_from_markdown(sample_file) - Creating compelling visualizations and interactive dashboards
print(f" Loaded agent: {agent2.agent_name}") - Applying statistical methods and machine learning techniques
- Presenting findings and actionable business recommendations
Focus on providing data-driven insights that support strategic decision making.
"""
# Example 4: Load multiple agents (from directory or list) # Create sample markdown files
print("\\n3. Loading multiple agents:") performance_file = "performance_engineer.md"
data_file = "data_analyst.md"
# Create another sample file with open(performance_file, 'w') as f:
sample_md2 = """| name | description | model | f.write(performance_md)
|------|-------------|-------|
| security-analyst | Analyze and improve system security | gpt-4 |
## Focus Areas with open(data_file, 'w') as f:
- Security vulnerability assessment f.write(data_analyst_md)
- Code security review
- Infrastructure hardening
## Approach try:
1. Conduct thorough security audits # Example 2: Load Performance Engineer agent
2. Identify potential vulnerabilities print("\\n1. Loading Performance Engineer agent (YAML frontmatter):")
3. Recommend security improvements perf_agent = loader.load_single_agent(performance_file)
print(f" Loaded agent: {perf_agent.agent_name}")
print(f" Model: {perf_agent.model_name}")
print(f" Temperature: {getattr(perf_agent, 'temperature', 'Not set')}")
print(f" Max loops: {perf_agent.max_loops}")
print(f" System prompt preview: {perf_agent.system_prompt[:100]}...")
# Example 3: Load Data Analyst agent
print("\\n2. Loading Data Analyst agent:")
data_agent = loader.load_single_agent(data_file)
print(f" Loaded agent: {data_agent.agent_name}")
print(f" Temperature: {getattr(data_agent, 'temperature', 'Not set')}")
print(f" System prompt preview: {data_agent.system_prompt[:100]}...")
# Example 4: Load single agent using convenience function
print("\\n3. Loading single agent using convenience function:")
agent2 = load_agent_from_markdown(performance_file)
print(f" Loaded agent: {agent2.agent_name}")
## Output # Example 5: Load multiple agents (from directory or list)
- Security assessment reports print("\\n4. Loading multiple agents:")
- Vulnerability remediation plans
- Security best practices documentation # Create another sample file - Security Analyst
security_md = """---
name: security-analyst
description: Analyze and improve system security
model_name: gpt-4
temperature: 0.1
max_loops: 3
---
You are a Security Analyst specializing in cybersecurity assessment and protection.
Your expertise includes:
- Conducting comprehensive security vulnerability assessments
- Performing detailed code security reviews and penetration testing
- Implementing robust infrastructure hardening measures
- Developing incident response and recovery procedures
Key methodology:
1. Conduct thorough security audits across all system components
2. Identify and classify potential vulnerabilities and threats
3. Recommend and implement security improvements and controls
4. Develop comprehensive security policies and best practices
5. Monitor and respond to security incidents
Provide detailed security reports with specific remediation steps and risk assessments.
""" """
sample_file2 = "security_agent.md" security_file = "security_analyst.md"
with open(sample_file2, 'w') as f: with open(security_file, 'w') as f:
f.write(sample_md2) f.write(security_md)
# Load multiple agents from list # Load multiple agents from list
agents = loader.load_multiple_agents([sample_file, sample_file2]) agents = loader.load_multiple_agents([performance_file, data_file, security_file])
print(f" Loaded {len(agents)} agents:") print(f" Loaded {len(agents)} agents:")
for agent in agents: for agent in agents:
print(f" - {agent.agent_name}") temp_attr = getattr(agent, 'temperature', 'default')
print(f" - {agent.agent_name} (temp: {temp_attr})")
# Example 5: Load agents from directory (current directory) # Example 6: Load agents from directory (current directory)
print("\\n4. Loading agents from current directory:") print("\\n5. Loading agents from current directory:")
current_dir_agents = load_agents_from_markdown(".") current_dir_agents = load_agents_from_markdown(".")
print(f" Found {len(current_dir_agents)} agents in current directory") print(f" Found {len(current_dir_agents)} agents in current directory")
# Example 6: Demonstrate error handling # Example 7: Demonstrate error handling
print("\\n5. Error handling demo:") print("\\n6. Error handling demo:")
try: try:
loader.load_single_agent("nonexistent.md") loader.load_single_agent("nonexistent.md")
except FileNotFoundError as e: except FileNotFoundError as e:
print(f" Caught expected error: {e}") print(f" Caught expected error: {e}")
# Example 7: Test agent functionality # Example 8: Test agent functionality
print("\\n6. Testing loaded agent functionality:") print("\\n7. Testing loaded agent functionality:")
test_agent = agents[0] test_agent = agents[0]
response = test_agent.run("What are the key steps for performance optimization?") print(f" Agent: {test_agent.agent_name}")
print(f" Agent response preview: {str(response)[:150]}...") print(f" Temperature: {getattr(test_agent, 'temperature', 'default')}")
print(f" Max loops: {test_agent.max_loops}")
print(f" Ready for task execution")
except Exception as e: except Exception as e:
print(f"Error during demo: {e}") print(f"Error during demo: {e}")
finally: finally:
# Cleanup sample files # Cleanup sample files
for file in [sample_file, sample_file2]: for file in [performance_file, data_file, security_file]:
if os.path.exists(file): if os.path.exists(file):
os.remove(file) os.remove(file)
print("\\n Cleaned up sample files") print("\\n Cleaned up sample files")

@ -1,9 +1,15 @@
""" """
Simple AgentLoader Demo Simple AgentLoader Demo - Claude Code Format
======================= =============================================
A working demonstration of how to create agents from markdown-like definitions A comprehensive demonstration of the AgentLoader using the Claude Code
and use them in workflows. sub-agent YAML frontmatter format.
This example shows:
1. Creating agents using Claude Code YAML frontmatter format
2. Loading agents from markdown files with YAML frontmatter
3. Using loaded agents in multi-agent workflows
4. Demonstrating different agent configurations
""" """
import os import os
@ -16,98 +22,160 @@ sys.path.insert(0, str(Path(__file__).parent.parent.parent))
from swarms.structs.agent import Agent from swarms.structs.agent import Agent
from swarms.structs.sequential_workflow import SequentialWorkflow from swarms.structs.sequential_workflow import SequentialWorkflow
from swarms.utils.agent_loader import AgentLoader, load_agents_from_markdown
def create_agents_from_configs():
"""Create agents from configuration dictionaries (simulating markdown parsing)""" def create_markdown_agent_files():
"""Create markdown files demonstrating Claude Code YAML frontmatter format"""
# These would normally come from parsing markdown files
agent_configs = [ # Claude Code YAML frontmatter format
{ agent_files = {
"name": "market-researcher", "market_researcher.md": """---
"description": "Expert in market analysis and competitive intelligence", name: market-researcher
"system_prompt": """You are a market research specialist. Your expertise includes: description: Expert in market analysis and competitive intelligence
model_name: gpt-4
Focus Areas: temperature: 0.2
- Market size and growth analysis max_loops: 2
- Competitive landscape assessment mcp_url: http://example.com/market-data
- Consumer behavior patterns ---
- Industry trend identification
You are a market research specialist with deep expertise in analyzing market dynamics and competitive landscapes.
Approach:
1. Gather comprehensive market data Your core responsibilities include:
2. Analyze quantitative and qualitative indicators - Conducting comprehensive market size and growth analysis
3. Identify key market drivers and barriers - Performing detailed competitive landscape assessments
4. Evaluate competitive positioning - Analyzing consumer behavior patterns and preferences
5. Assess market opportunities and threats - Identifying emerging industry trends and opportunities
Provide detailed market analysis reports with key metrics and actionable insights.""", Methodology:
"model": "gpt-4" 1. Gather comprehensive quantitative and qualitative market data
}, 2. Analyze key market drivers, barriers, and success factors
{ 3. Evaluate competitive positioning and market share dynamics
"name": "financial-analyst", 4. Assess market opportunities, threats, and entry strategies
"description": "Specialist in financial modeling and investment analysis", 5. Provide actionable insights with data-driven recommendations
"system_prompt": """You are a financial analysis expert. Your responsibilities include:
Always provide detailed market analysis reports with specific metrics, growth projections, and strategic recommendations for market entry or expansion.
Focus Areas: """,
- Financial statement analysis
- Valuation modeling techniques "financial_analyst.md": """---
- Investment risk assessment name: financial-analyst
- Cash flow projections description: Specialist in financial modeling and investment analysis
model_name: gpt-4
Approach: temperature: 0.1
1. Conduct thorough financial analysis max_loops: 3
2. Build comprehensive financial models ---
3. Perform multiple valuation methods
4. Assess financial risks and sensitivities You are a financial analysis expert specializing in investment evaluation and financial modeling.
5. Provide investment recommendations
Your areas of expertise include:
Generate detailed financial reports with valuation models and risk assessments.""", - Financial statement analysis and ratio interpretation
"model": "gpt-4" - DCF modeling and valuation techniques (DCF, comparable company analysis, precedent transactions)
}, - Investment risk assessment and sensitivity analysis
{ - Cash flow projections and working capital analysis
"name": "industry-expert",
"description": "Domain specialist with deep industry knowledge", Analytical approach:
"system_prompt": """You are an industry analysis expert. Your focus areas include: 1. Conduct thorough financial statement analysis
2. Build comprehensive financial models with multiple scenarios
Focus Areas: 3. Perform detailed valuation using multiple methodologies
- Industry structure and dynamics 4. Assess financial risks and conduct sensitivity analysis
- Regulatory environment analysis 5. Generate investment recommendations with clear rationale
- Technology trends and disruptions
- Supply chain analysis Provide detailed financial reports with valuation models, risk assessments, and investment recommendations supported by quantitative analysis.
""",
Approach:
1. Map industry structure and stakeholders "industry_expert.md": """---
2. Analyze regulatory framework name: industry-expert
3. Identify technology trends description: Domain specialist with deep industry knowledge and regulatory expertise
4. Evaluate supply chain dynamics model_name: gpt-4
5. Assess competitive positioning temperature: 0.3
max_loops: 2
Provide comprehensive industry landscape reports with strategic recommendations.""", ---
"model": "gpt-4"
You are an industry analysis expert with comprehensive knowledge of market structures, regulatory environments, and technology trends.
Your specialization areas:
- Industry structure analysis and value chain mapping
- Regulatory environment assessment and compliance requirements
- Technology trends identification and disruption analysis
- Supply chain dynamics and operational considerations
Research methodology:
1. Map industry structure, key players, and stakeholder relationships
2. Analyze current and emerging regulatory framework
3. Identify technology trends and potential market disruptions
4. Evaluate supply chain dynamics and operational requirements
5. Assess competitive positioning and strategic opportunities
Generate comprehensive industry landscape reports with regulatory insights, technology trend analysis, and strategic recommendations for market positioning.
"""
"risk_analyst.md": """---
name: risk-analyst
description: Specialist in investment risk assessment and mitigation strategies
model_name: gpt-4
temperature: 0.15
max_loops: 2
---
You are a Risk Analyst specializing in comprehensive investment risk assessment and portfolio management.
Your core competencies include:
- Conducting detailed investment risk evaluation and categorization
- Implementing sophisticated portfolio risk management strategies
- Ensuring regulatory compliance and conducting compliance assessments
- Performing advanced scenario analysis and stress testing methodologies
Analytical framework:
1. Systematically identify and categorize all investment risks
2. Quantify risk exposure using advanced statistical methods and models
3. Develop comprehensive risk mitigation strategies and frameworks
4. Conduct rigorous scenario analysis and stress testing procedures
5. Provide actionable risk management recommendations with implementation roadmaps
Deliver comprehensive risk assessment reports with quantitative analysis, compliance guidelines, and strategic risk management recommendations.
"""
} }
]
agents = []
for config in agent_configs:
agent = Agent(
agent_name=config["name"],
system_prompt=config["system_prompt"],
model_name=config["model"],
max_loops=1,
verbose=False
)
agents.append(agent)
print(f"Created agent: {agent.agent_name}")
return agents temp_files = []
def main(): # Create Claude Code format files
"""Main execution function""" for filename, content in agent_files.items():
temp_file = os.path.join(tempfile.gettempdir(), filename)
with open(temp_file, 'w', encoding='utf-8') as f:
f.write(content)
temp_files.append(temp_file)
# Create agents return temp_files
agents = create_agents_from_configs()
# Create sequential workflow def main():
"""Main execution function demonstrating AgentLoader with Claude Code format"""
print("AgentLoader Demo - Claude Code YAML Frontmatter Format")
print("=" * 60)
# Create markdown files demonstrating both formats
print("\n1. Creating markdown files...")
temp_files = create_markdown_agent_files()
try:
# Load agents using AgentLoader
print("\n2. Loading agents using AgentLoader...")
agents = load_agents_from_markdown(temp_files)
print(f" Successfully loaded {len(agents)} agents:")
for agent in agents:
temp_attr = getattr(agent, 'temperature', 'default')
max_loops = getattr(agent, 'max_loops', 1)
print(f" - {agent.agent_name} (temp: {temp_attr}, loops: {max_loops})")
# Demonstrate individual agent configuration
print("\n3. Agent Configuration Details:")
for i, agent in enumerate(agents, 1):
print(f" Agent {i}: {agent.agent_name}")
print(f" Model: {getattr(agent, 'model_name', 'default')}")
print(f" System prompt preview: {agent.system_prompt[:100]}...")
print()
# Create sequential workflow with loaded agents
print("4. Creating sequential workflow...")
research_workflow = SequentialWorkflow( research_workflow = SequentialWorkflow(
agents=agents, agents=agents,
max_loops=1, max_loops=1,
@ -122,19 +190,44 @@ def main():
2. Competitive landscape and major players 2. Competitive landscape and major players
3. Financial viability and investment attractiveness 3. Financial viability and investment attractiveness
4. Industry dynamics and regulatory considerations 4. Industry dynamics and regulatory considerations
5. Risk assessment and mitigation strategies
Provide strategic recommendations for market entry. Provide comprehensive strategic recommendations for market entry.
""" """
print("Executing research workflow...") print("5. Executing research workflow...")
print("=" * 50) print("=" * 50)
# Execute workflow # Note: In a real scenario, this would execute the workflow
result = research_workflow.run(task) # For demo purposes, we'll show the task distribution
print(f"Task distributed to {len(agents)} specialized agents:")
for i, agent in enumerate(agents, 1):
print(f" Agent {i} ({agent.agent_name}): Ready to process")
print(f"\nTask preview: {task[:150]}...")
print("\n[Demo mode - actual workflow execution would call LLM APIs]")
print("\nResearch Analysis Complete:") print("\nDemo Summary:")
print("-" * 50) print("-" * 50)
print(result) print("✓ Successfully loaded agents using Claude Code YAML frontmatter format")
print("✓ Agents configured with different temperatures and max_loops from YAML")
print("✓ Multi-agent workflow created with specialized investment analysis agents")
print("✓ Workflow ready for comprehensive market analysis execution")
except Exception as e:
print(f"Error during demo: {e}")
import traceback
traceback.print_exc()
finally:
# Cleanup temporary files
print("\n6. Cleaning up temporary files...")
for temp_file in temp_files:
try:
os.remove(temp_file)
print(f" Removed: {os.path.basename(temp_file)}")
except OSError:
pass
if __name__ == "__main__": if __name__ == "__main__":
main() main()

@ -1,5 +1,7 @@
import os import os
import re import re
import random
import yaml
from pathlib import Path from pathlib import Path
from typing import Any, Dict, List, Optional, Union from typing import Any, Dict, List, Optional, Union
from pydantic import BaseModel, Field, field_validator from pydantic import BaseModel, Field, field_validator
@ -9,14 +11,13 @@ from swarms.structs.agent import Agent
class MarkdownAgentConfig(BaseModel): class MarkdownAgentConfig(BaseModel):
"""Configuration model for agents loaded from markdown files.""" """Configuration model for agents loaded from Claude Code markdown files."""
name: str name: str
description: str description: str
model_name: Optional[str] = "gpt-4" model_name: Optional[str] = "gpt-4"
temperature: Optional[float] = Field(default=0.1, ge=0.0, le=2.0)
mcp_url: Optional[str] = None
system_prompt: str system_prompt: str
focus_areas: Optional[List[str]] = []
approach: Optional[List[str]] = []
output: Optional[List[str]] = []
max_loops: int = Field(default=1, ge=1) max_loops: int = Field(default=1, ge=1)
autosave: bool = False autosave: bool = False
dashboard: bool = False dashboard: bool = False
@ -43,16 +44,16 @@ class MarkdownAgentConfig(BaseModel):
class AgentLoader: class AgentLoader:
""" """
Loader for creating agents from markdown files. Loader for creating agents from markdown files using Claude Code sub-agent format.
Supports both single markdown file and multiple markdown files. Supports both single markdown file and multiple markdown files.
Maintains backwards compatibility with claude code sub agents markdown format. Uses YAML frontmatter format for agent configuration.
Features: Features:
- Single markdown file loading - Single markdown file loading
- Multiple markdown files loading (batch processing) - Multiple markdown files loading (batch processing)
- Flexible markdown parsing - YAML frontmatter parsing
- Agent configuration extraction from markdown structure - Agent configuration extraction from YAML metadata
- Error handling and validation - Error handling and validation
""" """
@ -62,124 +63,51 @@ class AgentLoader:
""" """
pass pass
def parse_markdown_table(self, content: str) -> Dict[str, str]: def parse_yaml_frontmatter(self, content: str) -> Dict[str, Any]:
""" """
Parse markdown table to extract agent metadata. Parse YAML frontmatter from markdown content.
Args: Args:
content: Markdown content containing a table content: Markdown content with potential YAML frontmatter
Returns: Returns:
Dictionary with parsed table data Dictionary with parsed YAML data and remaining content
""" """
table_data = {}
# Find markdown table pattern
table_pattern = r'\|([^|]+)\|([^|]+)\|([^|]+)\|'
lines = content.split('\n') lines = content.split('\n')
header_found = False # Check if content starts with YAML frontmatter
for line in lines: if not lines[0].strip() == '---':
if '|' in line and not header_found: return {"frontmatter": {}, "content": content}
# Skip header separator line
if '---' in line:
header_found = True
continue
# Parse header
if 'name' in line.lower() and 'description' in line.lower():
continue
elif header_found and '|' in line: # Find end of frontmatter
# Parse data row end_marker = -1
match = re.match(table_pattern, line) for i, line in enumerate(lines[1:], 1):
if match: if line.strip() == '---':
table_data['name'] = match.group(1).strip() end_marker = i
table_data['description'] = match.group(2).strip()
table_data['model_name'] = match.group(3).strip()
break break
return table_data if end_marker == -1:
return {"frontmatter": {}, "content": content}
def extract_sections(self, content: str) -> Dict[str, List[str]]:
"""
Extract structured sections from markdown content.
Args:
content: Markdown content
Returns: # Extract frontmatter and content
Dictionary with section names as keys and content lists as values frontmatter_text = '\n'.join(lines[1:end_marker])
""" remaining_content = '\n'.join(lines[end_marker + 1:]).strip()
sections = {}
current_section = None
current_content = []
lines = content.split('\n') try:
for line in lines: frontmatter_data = yaml.safe_load(frontmatter_text) or {}
# Check for headers (## Section Name) except yaml.YAMLError as e:
if line.startswith('## '): logger.warning(f"Failed to parse YAML frontmatter: {e}")
# Save previous section return {"frontmatter": {}, "content": content}
if current_section:
sections[current_section.lower()] = current_content
# Start new section
current_section = line[3:].strip()
current_content = []
elif current_section and line.strip():
# Add content to current section
# Remove markdown list markers
clean_line = re.sub(r'^[-*+]\s*', '', line.strip())
clean_line = re.sub(r'^\d+\.\s*', '', clean_line)
if clean_line:
current_content.append(clean_line)
# Save last section
if current_section:
sections[current_section.lower()] = current_content
return sections
def build_system_prompt(self, config_data: Dict[str, Any]) -> str:
"""
Build comprehensive system prompt from parsed markdown data.
Args:
config_data: Dictionary containing parsed agent configuration
Returns:
Complete system prompt string
"""
prompt_parts = []
# Add description
if config_data.get('description'):
prompt_parts.append(f"Role: {config_data['description']}")
# Add focus areas return {"frontmatter": frontmatter_data, "content": remaining_content}
if config_data.get('focus_areas'):
prompt_parts.append("\nFocus Areas:")
for area in config_data['focus_areas']:
prompt_parts.append(f"- {area}")
# Add approach
if config_data.get('approach'):
prompt_parts.append("\nApproach:")
for i, step in enumerate(config_data['approach'], 1):
prompt_parts.append(f"{i}. {step}")
# Add expected output
if config_data.get('output'):
prompt_parts.append("\nExpected Output:")
for output in config_data['output']:
prompt_parts.append(f"- {output}")
return '\n'.join(prompt_parts)
def parse_markdown_file(self, file_path: str) -> MarkdownAgentConfig: def parse_markdown_file(self, file_path: str) -> MarkdownAgentConfig:
""" """
Parse a single markdown file to extract agent configuration. Parse a single markdown file to extract agent configuration.
Uses Claude Code sub-agent YAML frontmatter format.
Args: Args:
file_path: Path to markdown file file_path: Path to markdown file
@ -189,7 +117,7 @@ class AgentLoader:
Raises: Raises:
FileNotFoundError: If file doesn't exist FileNotFoundError: If file doesn't exist
ValueError: If parsing fails ValueError: If parsing fails or no YAML frontmatter found
""" """
if not os.path.exists(file_path): if not os.path.exists(file_path):
raise FileNotFoundError(f"Markdown file {file_path} not found.") raise FileNotFoundError(f"Markdown file {file_path} not found.")
@ -198,25 +126,29 @@ class AgentLoader:
with open(file_path, 'r', encoding='utf-8') as file: with open(file_path, 'r', encoding='utf-8') as file:
content = file.read() content = file.read()
# Parse table for basic metadata # Parse YAML frontmatter (Claude Code sub-agent format)
table_data = self.parse_markdown_table(content) yaml_result = self.parse_yaml_frontmatter(content)
frontmatter = yaml_result["frontmatter"]
remaining_content = yaml_result["content"]
# Extract sections if not frontmatter:
sections = self.extract_sections(content) raise ValueError(f"No YAML frontmatter found in {file_path}. File must use Claude Code sub-agent format with YAML frontmatter.")
# Build configuration # Use YAML frontmatter data
config_data = { config_data = {
'name': table_data.get('name', Path(file_path).stem), 'name': frontmatter.get('name', Path(file_path).stem),
'description': table_data.get('description', 'Agent loaded from markdown'), 'description': frontmatter.get('description', 'Agent loaded from markdown'),
'model_name': table_data.get('model_name', 'gpt-4'), 'model_name': frontmatter.get('model_name') or frontmatter.get('model', 'gpt-4'),
'focus_areas': sections.get('focus areas', []), 'temperature': frontmatter.get('temperature', 0.1),
'approach': sections.get('approach', []), 'max_loops': frontmatter.get('max_loops', 1),
'output': sections.get('output', []), 'mcp_url': frontmatter.get('mcp_url'),
'system_prompt': remaining_content.strip(),
} }
# Build system prompt # Generate random model if not specified
system_prompt = self.build_system_prompt(config_data) if not config_data['model_name'] or config_data['model_name'] == 'random':
config_data['system_prompt'] = system_prompt models = ['gpt-4', 'gpt-4-turbo', 'claude-3-sonnet', 'claude-3-haiku']
config_data['model_name'] = random.choice(models)
logger.info(f"Successfully parsed markdown file: {file_path}") logger.info(f"Successfully parsed markdown file: {file_path}")
return MarkdownAgentConfig(**config_data) return MarkdownAgentConfig(**config_data)
@ -247,7 +179,7 @@ class AgentLoader:
'agent_name': config_dict['name'], 'agent_name': config_dict['name'],
'system_prompt': config_dict['system_prompt'], 'system_prompt': config_dict['system_prompt'],
'model_name': config_dict.get('model_name', 'gpt-4'), 'model_name': config_dict.get('model_name', 'gpt-4'),
# Don't pass llm explicitly - let Agent handle it internally 'temperature': config_dict.get('temperature', 0.1),
'max_loops': config_dict['max_loops'], 'max_loops': config_dict['max_loops'],
'autosave': config_dict['autosave'], 'autosave': config_dict['autosave'],
'dashboard': config_dict['dashboard'], 'dashboard': config_dict['dashboard'],
@ -321,10 +253,10 @@ class AgentLoader:
def load_single_agent(self, file_path: str, **kwargs) -> Agent: def load_single_agent(self, file_path: str, **kwargs) -> Agent:
""" """
Convenience method for loading a single agent. Convenience method for loading a single agent.
Backwards compatible with claude code sub agents markdown. Uses Claude Code sub-agent YAML frontmatter format.
Args: Args:
file_path: Path to markdown file file_path: Path to markdown file with YAML frontmatter
**kwargs: Additional configuration overrides **kwargs: Additional configuration overrides
Returns: Returns:
@ -335,10 +267,10 @@ class AgentLoader:
def load_multiple_agents(self, file_paths: Union[str, List[str]], **kwargs) -> List[Agent]: def load_multiple_agents(self, file_paths: Union[str, List[str]], **kwargs) -> List[Agent]:
""" """
Convenience method for loading multiple agents. Convenience method for loading multiple agents.
Backwards compatible with claude code sub agents markdown. Uses Claude Code sub-agent YAML frontmatter format.
Args: Args:
file_paths: Directory path or list of file paths file_paths: Directory path or list of file paths with YAML frontmatter
**kwargs: Additional configuration overrides **kwargs: Additional configuration overrides
Returns: Returns:
@ -347,13 +279,13 @@ class AgentLoader:
return self.load_agents_from_markdown(file_paths, **kwargs) return self.load_agents_from_markdown(file_paths, **kwargs)
# Convenience functions for backwards compatibility # Convenience functions
def load_agent_from_markdown(file_path: str, **kwargs) -> Agent: def load_agent_from_markdown(file_path: str, **kwargs) -> Agent:
""" """
Load a single agent from a markdown file. Load a single agent from a markdown file with Claude Code YAML frontmatter format.
Args: Args:
file_path: Path to markdown file file_path: Path to markdown file with YAML frontmatter
**kwargs: Additional configuration overrides **kwargs: Additional configuration overrides
Returns: Returns:
@ -365,10 +297,10 @@ def load_agent_from_markdown(file_path: str, **kwargs) -> Agent:
def load_agents_from_markdown(file_paths: Union[str, List[str]], **kwargs) -> List[Agent]: def load_agents_from_markdown(file_paths: Union[str, List[str]], **kwargs) -> List[Agent]:
""" """
Load multiple agents from markdown files. Load multiple agents from markdown files with Claude Code YAML frontmatter format.
Args: Args:
file_paths: Directory path or list of file paths file_paths: Directory path or list of file paths with YAML frontmatter
**kwargs: Additional configuration overrides **kwargs: Additional configuration overrides
Returns: Returns:

@ -1,244 +0,0 @@
"""
Test script for the AgentLoader functionality.
This tests the core functionality without requiring external models.
"""
import os
import tempfile
from pathlib import Path
import sys
# Add swarms to path for local testing
sys.path.insert(0, os.path.join(os.path.dirname(__file__)))
from swarms.utils.agent_loader import AgentLoader, MarkdownAgentConfig
def test_markdown_parsing():
"""Test markdown parsing functionality."""
print("Testing markdown parsing...")
# Create a sample markdown content
sample_content = """| name | description | model |
|------|-------------|-------|
| test-agent | A test agent for validation | gpt-4 |
## Focus Areas
- Testing functionality
- Validating implementation
- Ensuring compatibility
## Approach
1. Parse markdown structure
2. Extract configuration data
3. Validate parsed results
4. Create agent instance
## Output
- Test results
- Validation reports
- Configuration summary
"""
# Test parsing functionality
loader = AgentLoader()
# Test table parsing
table_data = loader.parse_markdown_table(sample_content)
assert table_data['name'] == 'test-agent'
assert table_data['description'] == 'A test agent for validation'
assert table_data['model_name'] == 'gpt-4'
print("[OK] Table parsing successful")
# Test section extraction
sections = loader.extract_sections(sample_content)
assert 'focus areas' in sections
assert len(sections['focus areas']) == 3
assert 'approach' in sections
assert len(sections['approach']) == 4
print("[OK] Section extraction successful")
# Test system prompt building
config_data = {
'description': table_data['description'],
'focus_areas': sections['focus areas'],
'approach': sections['approach'],
'output': sections.get('output', [])
}
system_prompt = loader.build_system_prompt(config_data)
assert 'Role:' in system_prompt
assert 'Focus Areas:' in system_prompt
assert 'Approach:' in system_prompt
print("[OK] System prompt building successful")
print("Markdown parsing tests passed!")
return True
def test_file_operations():
"""Test file loading operations."""
print("\\nTesting file operations...")
# Create temporary markdown file
sample_content = """| name | description | model |
|------|-------------|-------|
| file-test-agent | Agent created from file | gpt-4 |
## Focus Areas
- File processing
- Configuration validation
## Approach
1. Load from file
2. Parse content
3. Create configuration
## Output
- Loaded agent
- Configuration object
"""
with tempfile.NamedTemporaryFile(mode='w', suffix='.md', delete=False) as f:
f.write(sample_content)
temp_file = f.name
try:
loader = AgentLoader()
# Test file parsing
config = loader.parse_markdown_file(temp_file)
assert isinstance(config, MarkdownAgentConfig)
assert config.name == 'file-test-agent'
assert config.description == 'Agent created from file'
print("[OK] File parsing successful")
# Test configuration validation
assert len(config.focus_areas) == 2
assert len(config.approach) == 3
assert config.system_prompt is not None
print("[OK] Configuration validation successful")
finally:
# Cleanup
if os.path.exists(temp_file):
os.remove(temp_file)
print("File operations tests passed!")
return True
def test_multiple_files():
"""Test loading multiple files."""
print("\\nTesting multiple file loading...")
# Create multiple temporary files
files = []
for i in range(3):
content = f"""| name | description | model |
|------|-------------|-------|
| agent-{i} | Test agent number {i} | gpt-4 |
## Focus Areas
- Multi-agent testing
- Batch processing
## Approach
1. Process multiple files
2. Create agent configurations
3. Return agent list
## Output
- Multiple agents
- Batch results
"""
temp_file = tempfile.NamedTemporaryFile(mode='w', suffix='.md', delete=False)
temp_file.write(content)
temp_file.close()
files.append(temp_file.name)
try:
loader = AgentLoader()
# Test parsing multiple files
configs = []
for file_path in files:
config = loader.parse_markdown_file(file_path)
configs.append(config)
assert len(configs) == 3
for i, config in enumerate(configs):
assert config.name == f'agent-{i}'
print("[OK] Multiple file parsing successful")
finally:
# Cleanup
for file_path in files:
if os.path.exists(file_path):
os.remove(file_path)
print("Multiple file tests passed!")
return True
def test_error_handling():
"""Test error handling scenarios."""
print("\\nTesting error handling...")
loader = AgentLoader()
# Test non-existent file
try:
loader.parse_markdown_file("nonexistent.md")
assert False, "Should have raised FileNotFoundError"
except FileNotFoundError:
print("[OK] FileNotFoundError handling successful")
# Test invalid markdown
with tempfile.NamedTemporaryFile(mode='w', suffix='.md', delete=False) as f:
f.write("Invalid markdown content without proper structure")
invalid_file = f.name
try:
# This should not raise an error, but should handle gracefully
config = loader.parse_markdown_file(invalid_file)
# Should have defaults
assert config.name is not None
print("[OK] Invalid markdown handling successful")
finally:
if os.path.exists(invalid_file):
os.remove(invalid_file)
print("Error handling tests passed!")
return True
def main():
"""Run all tests."""
print("=== AgentLoader Test Suite ===")
tests = [
test_markdown_parsing,
test_file_operations,
test_multiple_files,
test_error_handling
]
passed = 0
total = len(tests)
for test in tests:
try:
if test():
passed += 1
except Exception as e:
print(f"[FAIL] Test {test.__name__} failed: {e}")
print(f"\\n=== Results: {passed}/{total} tests passed ===")
if passed == total:
print("All tests passed!")
return True
else:
print("Some tests failed!")
return False
if __name__ == "__main__":
success = main()
exit(0 if success else 1)
Loading…
Cancel
Save