remove-unused-params from agent.py

pull/1028/head
Kye Gomez 2 weeks ago
parent bb46bd9f94
commit 67b380dc8a

@ -30,6 +30,7 @@ try:
WikipediaPersonalityScraper, WikipediaPersonalityScraper,
MEPPersonalityProfile, MEPPersonalityProfile,
) )
WIKIPEDIA_PERSONALITY_AVAILABLE = True WIKIPEDIA_PERSONALITY_AVAILABLE = True
except ImportError: except ImportError:
WIKIPEDIA_PERSONALITY_AVAILABLE = False WIKIPEDIA_PERSONALITY_AVAILABLE = False

@ -5,23 +5,19 @@ This script demonstrates the comprehensive democratic functionality of the EuroS
including bill introduction, committee work, parliamentary debates, and democratic voting. including bill introduction, committee work, parliamentary debates, and democratic voting.
""" """
import json
import time
from datetime import datetime
# Import directly from the file # Import directly from the file
from euroswarm_parliament import ( from euroswarm_parliament import (
EuroSwarmParliament, EuroSwarmParliament,
VoteType, VoteType,
ParliamentaryRole,
ParliamentaryMember
) )
def demonstrate_parliament_initialization(): def demonstrate_parliament_initialization():
"""Demonstrate parliament initialization and basic functionality with cost optimization.""" """Demonstrate parliament initialization and basic functionality with cost optimization."""
print("\nEUROSWARM PARLIAMENT INITIALIZATION DEMONSTRATION (COST OPTIMIZED)") print(
"\nEUROSWARM PARLIAMENT INITIALIZATION DEMONSTRATION (COST OPTIMIZED)"
)
print("=" * 60) print("=" * 60)
# Initialize the parliament with cost optimization # Initialize the parliament with cost optimization
@ -35,7 +31,7 @@ def demonstrate_parliament_initialization():
enable_caching=True, # NEW: Enable response caching enable_caching=True, # NEW: Enable response caching
batch_size=25, # NEW: Batch size for concurrent execution batch_size=25, # NEW: Batch size for concurrent execution
budget_limit=100.0, # NEW: Budget limit in dollars budget_limit=100.0, # NEW: Budget limit in dollars
verbose=True verbose=True,
) )
print(f"Parliament initialized with {len(parliament.meps)} MEPs") print(f"Parliament initialized with {len(parliament.meps)} MEPs")
@ -43,26 +39,32 @@ def demonstrate_parliament_initialization():
# Show parliament composition with cost stats # Show parliament composition with cost stats
composition = parliament.get_parliament_composition() composition = parliament.get_parliament_composition()
print(f"\nPARLIAMENT COMPOSITION:") print("\nPARLIAMENT COMPOSITION:")
print(f"Total MEPs: {composition['total_meps']}") print(f"Total MEPs: {composition['total_meps']}")
print(f"Loaded MEPs: {composition['loaded_meps']} (lazy loading active)") print(
f"Loaded MEPs: {composition['loaded_meps']} (lazy loading active)"
)
print(f"\nCOST OPTIMIZATION:") print("\nCOST OPTIMIZATION:")
cost_stats = composition['cost_stats'] cost_stats = composition["cost_stats"]
print(f"Budget Limit: ${cost_stats['budget_remaining'] + cost_stats['total_cost']:.2f}") 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 Used: ${cost_stats['total_cost']:.2f}")
print(f"Budget Remaining: ${cost_stats['budget_remaining']:.2f}") print(f"Budget Remaining: ${cost_stats['budget_remaining']:.2f}")
print(f"Cache Hit Rate: {cost_stats['cache_hit_rate']:.1%}") print(f"Cache Hit Rate: {cost_stats['cache_hit_rate']:.1%}")
print(f"\nPOLITICAL GROUP DISTRIBUTION:") print("\nPOLITICAL GROUP DISTRIBUTION:")
for group, data in composition['political_groups'].items(): for group, data in composition["political_groups"].items():
count = data['count'] count = data["count"]
percentage = data['percentage'] percentage = data["percentage"]
print(f" {group}: {count} MEPs ({percentage:.1f}%)") print(f" {group}: {count} MEPs ({percentage:.1f}%)")
print(f"\nCOMMITTEE LEADERSHIP:") print("\nCOMMITTEE LEADERSHIP:")
for committee_name, committee_data in composition['committees'].items(): for committee_name, committee_data in composition[
chair = committee_data['chair'] "committees"
].items():
chair = committee_data["chair"]
if chair: if chair:
print(f" {committee_name}: {chair}") print(f" {committee_name}: {chair}")
@ -95,7 +97,11 @@ def demonstrate_individual_mep_interaction(parliament):
try: try:
response = sample_mep.agent.run(test_prompt) response = sample_mep.agent.run(test_prompt)
print(response[:500] + "..." if len(response) > 500 else response) print(
response[:500] + "..."
if len(response) > 500
else response
)
except Exception as e: except Exception as e:
print(f"Error getting MEP response: {e}") print(f"Error getting MEP response: {e}")
@ -115,7 +121,7 @@ def demonstrate_committee_work(parliament):
description="Comprehensive legislation to strengthen digital rights, enhance privacy protection, and establish clear guidelines for data handling across the European Union.", 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, bill_type=VoteType.ORDINARY_LEGISLATIVE_PROCEDURE,
committee="Legal Affairs", committee="Legal Affairs",
sponsor=sponsor sponsor=sponsor,
) )
print(f"Bill: {bill.title}") print(f"Bill: {bill.title}")
@ -123,15 +129,25 @@ def demonstrate_committee_work(parliament):
print(f"Sponsor: {bill.sponsor}") print(f"Sponsor: {bill.sponsor}")
# Conduct committee hearing # Conduct committee hearing
print(f"\nCONDUCTING COMMITTEE HEARING...") print("\nCONDUCTING COMMITTEE HEARING...")
hearing_result = parliament.conduct_committee_hearing(bill.committee, bill) hearing_result = parliament.conduct_committee_hearing(
bill.committee, bill
)
print(f"Committee: {hearing_result['committee']}") print(f"Committee: {hearing_result['committee']}")
print(f"Participants: {len(hearing_result['participants'])} MEPs") print(f"Participants: {len(hearing_result['participants'])} MEPs")
print(f"Recommendation: {hearing_result['recommendations']['recommendation']}") print(
print(f"Support: {hearing_result['recommendations']['support_percentage']:.1f}%") f"Recommendation: {hearing_result['recommendations']['recommendation']}"
print(f"Oppose: {hearing_result['recommendations']['oppose_percentage']:.1f}%") )
print(f"Amend: {hearing_result['recommendations']['amend_percentage']:.1f}%") 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): def demonstrate_parliamentary_debate(parliament):
@ -149,21 +165,31 @@ def demonstrate_parliamentary_debate(parliament):
description="Legislation to implement the European Green Deal, including carbon neutrality targets, renewable energy investments, and sustainable development measures.", 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, bill_type=VoteType.ORDINARY_LEGISLATIVE_PROCEDURE,
committee="Environment, Public Health and Food Safety", committee="Environment, Public Health and Food Safety",
sponsor=sponsor sponsor=sponsor,
) )
print(f"Bill: {bill.title}") print(f"Bill: {bill.title}")
print(f"Description: {bill.description}") print(f"Description: {bill.description}")
# Conduct parliamentary debate # Conduct parliamentary debate
print(f"\nCONDUCTING PARLIAMENTARY DEBATE...") print("\nCONDUCTING PARLIAMENTARY DEBATE...")
debate_result = parliament.conduct_parliamentary_debate(bill, max_speakers=10) debate_result = parliament.conduct_parliamentary_debate(
bill, max_speakers=10
)
print(f"Debate Participants: {len(debate_result['participants'])} MEPs") print(
print(f"Debate Analysis:") f"Debate Participants: {len(debate_result['participants'])} MEPs"
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("Debate Analysis:")
print(f" Neutral: {debate_result['analysis']['neutral_count']} speakers ({debate_result['analysis']['neutral_percentage']:.1f}%)") 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): def demonstrate_democratic_voting(parliament):
@ -181,36 +207,65 @@ def demonstrate_democratic_voting(parliament):
description="Legislation to strengthen social rights, improve labor conditions, and ensure fair treatment of workers across the European Union.", 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, bill_type=VoteType.ORDINARY_LEGISLATIVE_PROCEDURE,
committee="Employment and Social Affairs", committee="Employment and Social Affairs",
sponsor=sponsor sponsor=sponsor,
) )
print(f"Bill: {bill.title}") print(f"Bill: {bill.title}")
print(f"Sponsor: {bill.sponsor}") print(f"Sponsor: {bill.sponsor}")
# Conduct democratic vote # Conduct democratic vote
print(f"\nCONDUCTING DEMOCRATIC VOTE...") print("\nCONDUCTING DEMOCRATIC VOTE...")
vote_result = parliament.conduct_democratic_vote(bill) vote_result = parliament.conduct_democratic_vote(bill)
# Calculate percentages # Calculate percentages
total_votes = vote_result.votes_for + vote_result.votes_against + vote_result.abstentions total_votes = (
in_favor_percentage = (vote_result.votes_for / total_votes * 100) if total_votes > 0 else 0 vote_result.votes_for
against_percentage = (vote_result.votes_against / total_votes * 100) if total_votes > 0 else 0 + vote_result.votes_against
abstentions_percentage = (vote_result.abstentions / total_votes * 100) if total_votes > 0 else 0 + 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(f"Vote Results:") print("Vote Results:")
print(f" Total Votes: {total_votes}") print(f" Total Votes: {total_votes}")
print(f" In Favor: {vote_result.votes_for} ({in_favor_percentage:.1f}%)") print(
print(f" Against: {vote_result.votes_against} ({against_percentage:.1f}%)") f" In Favor: {vote_result.votes_for} ({in_favor_percentage:.1f}%)"
print(f" Abstentions: {vote_result.abstentions} ({abstentions_percentage:.1f}%)") )
print(
f" Against: {vote_result.votes_against} ({against_percentage:.1f}%)"
)
print(
f" Abstentions: {vote_result.abstentions} ({abstentions_percentage:.1f}%)"
)
print(f" Result: {vote_result.result.value}") print(f" Result: {vote_result.result.value}")
# Show political group breakdown if available # Show political group breakdown if available
if hasattr(vote_result, 'group_votes') and vote_result.group_votes: if (
print(f"\nPOLITICAL GROUP BREAKDOWN:") hasattr(vote_result, "group_votes")
and vote_result.group_votes
):
print("\nPOLITICAL GROUP BREAKDOWN:")
for group, votes in vote_result.group_votes.items(): for group, votes in vote_result.group_votes.items():
print(f" {group}: {votes['in_favor']}/{votes['total']} in favor ({votes['percentage']:.1f}%)") print(
f" {group}: {votes['in_favor']}/{votes['total']} in favor ({votes['percentage']:.1f}%)"
)
else: else:
print(f"\nIndividual votes recorded: {len(vote_result.individual_votes)} MEPs") print(
f"\nIndividual votes recorded: {len(vote_result.individual_votes)} MEPs"
)
def demonstrate_complete_democratic_session(parliament): def demonstrate_complete_democratic_session(parliament):
@ -228,15 +283,21 @@ def demonstrate_complete_democratic_session(parliament):
bill_description="Comprehensive legislation to promote innovation, support technology startups, and establish Europe as a global leader in digital transformation and technological advancement.", 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, bill_type=VoteType.ORDINARY_LEGISLATIVE_PROCEDURE,
committee="Industry, Research and Energy", committee="Industry, Research and Energy",
sponsor=sponsor sponsor=sponsor,
) )
print(f"Session Results:") print("Session Results:")
print(f" Bill: {session_result['bill'].title}") print(f" Bill: {session_result['bill'].title}")
print(f" Committee Hearing: {session_result['hearing']['recommendations']['recommendation']}") print(
print(f" Debate Participants: {len(session_result['debate']['participants'])} MEPs") 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" Final Vote: {session_result['vote']['result']}")
print(f" Vote Margin: {session_result['vote']['in_favor_percentage']:.1f}% in favor") print(
f" Vote Margin: {session_result['vote']['in_favor_percentage']:.1f}% in favor"
)
def demonstrate_political_analysis(parliament): def demonstrate_political_analysis(parliament):
@ -254,7 +315,7 @@ def demonstrate_political_analysis(parliament):
description="Comprehensive climate action legislation including carbon pricing, renewable energy targets, and sustainable development measures.", description="Comprehensive climate action legislation including carbon pricing, renewable energy targets, and sustainable development measures.",
bill_type=VoteType.ORDINARY_LEGISLATIVE_PROCEDURE, bill_type=VoteType.ORDINARY_LEGISLATIVE_PROCEDURE,
committee="Environment, Public Health and Food Safety", committee="Environment, Public Health and Food Safety",
sponsor=sponsor sponsor=sponsor,
) )
print(f"Bill: {bill.title}") print(f"Bill: {bill.title}")
@ -263,14 +324,16 @@ def demonstrate_political_analysis(parliament):
# Analyze political landscape # Analyze political landscape
analysis = parliament.analyze_political_landscape(bill) analysis = parliament.analyze_political_landscape(bill)
print(f"\nPOLITICAL LANDSCAPE ANALYSIS:") print("\nPOLITICAL LANDSCAPE ANALYSIS:")
print(f" Overall Support: {analysis['overall_support']:.1f}%") print(f" Overall Support: {analysis['overall_support']:.1f}%")
print(f" Opposition: {analysis['opposition']:.1f}%") print(f" Opposition: {analysis['opposition']:.1f}%")
print(f" Uncertainty: {analysis['uncertainty']:.1f}%") print(f" Uncertainty: {analysis['uncertainty']:.1f}%")
print(f"\nPOLITICAL GROUP ANALYSIS:") print("\nPOLITICAL GROUP ANALYSIS:")
for group, data in analysis['group_analysis'].items(): for group, data in analysis["group_analysis"].items():
print(f" {group}: {data['support']:.1f}% support, {data['opposition']:.1f}% opposition") print(
f" {group}: {data['support']:.1f}% support, {data['opposition']:.1f}% opposition"
)
def demonstrate_hierarchical_democratic_voting(parliament): def demonstrate_hierarchical_democratic_voting(parliament):
@ -288,25 +351,35 @@ def demonstrate_hierarchical_democratic_voting(parliament):
description="Comprehensive climate action legislation including carbon pricing, renewable energy targets, and sustainable development measures.", description="Comprehensive climate action legislation including carbon pricing, renewable energy targets, and sustainable development measures.",
bill_type=VoteType.ORDINARY_LEGISLATIVE_PROCEDURE, bill_type=VoteType.ORDINARY_LEGISLATIVE_PROCEDURE,
committee="Environment, Public Health and Food Safety", committee="Environment, Public Health and Food Safety",
sponsor=sponsor sponsor=sponsor,
) )
print(f"Bill: {bill.title}") print(f"Bill: {bill.title}")
print(f"Sponsor: {bill.sponsor}") print(f"Sponsor: {bill.sponsor}")
# Conduct hierarchical vote # Conduct hierarchical vote
print(f"\nCONDUCTING HIERARCHICAL DEMOCRATIC VOTE...") print("\nCONDUCTING HIERARCHICAL DEMOCRATIC VOTE...")
hierarchical_result = parliament.conduct_hierarchical_democratic_vote(bill) hierarchical_result = (
parliament.conduct_hierarchical_democratic_vote(bill)
)
print(f"Hierarchical Vote Results:") print("Hierarchical Vote Results:")
print(f" Total Votes: {hierarchical_result['total_votes']}") print(f" Total Votes: {hierarchical_result['total_votes']}")
print(f" In Favor: {hierarchical_result['in_favor']} ({hierarchical_result['in_favor_percentage']:.1f}%)") print(
print(f" Against: {hierarchical_result['against']} ({hierarchical_result['against_percentage']:.1f}%)") 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(f" Result: {hierarchical_result['result']}")
print(f"\nPOLITICAL GROUP BOARD DECISIONS:") print("\nPOLITICAL GROUP BOARD DECISIONS:")
for group, decision in hierarchical_result['group_decisions'].items(): for group, decision in hierarchical_result[
print(f" {group}: {decision['decision']} ({decision['confidence']:.1f}% confidence)") "group_decisions"
].items():
print(
f" {group}: {decision['decision']} ({decision['confidence']:.1f}% confidence)"
)
def demonstrate_complete_hierarchical_session(parliament): def demonstrate_complete_hierarchical_session(parliament):
@ -324,15 +397,21 @@ def demonstrate_complete_hierarchical_session(parliament):
bill_description="Comprehensive climate action legislation including carbon pricing, renewable energy targets, and sustainable development measures.", bill_description="Comprehensive climate action legislation including carbon pricing, renewable energy targets, and sustainable development measures.",
bill_type=VoteType.ORDINARY_LEGISLATIVE_PROCEDURE, bill_type=VoteType.ORDINARY_LEGISLATIVE_PROCEDURE,
committee="Environment, Public Health and Food Safety", committee="Environment, Public Health and Food Safety",
sponsor=sponsor sponsor=sponsor,
) )
print(f"Hierarchical Session Results:") print("Hierarchical Session Results:")
print(f" Bill: {session_result['bill'].title}") print(f" Bill: {session_result['bill'].title}")
print(f" Committee Hearing: {session_result['hearing']['recommendations']['recommendation']}") print(
print(f" Debate Participants: {len(session_result['debate']['participants'])} MEPs") 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" Final Vote: {session_result['vote']['result']}")
print(f" Vote Margin: {session_result['vote']['in_favor_percentage']:.1f}% in favor") print(
f" Vote Margin: {session_result['vote']['in_favor_percentage']:.1f}% in favor"
)
def demonstrate_wikipedia_personalities(parliament): def demonstrate_wikipedia_personalities(parliament):
@ -344,14 +423,18 @@ def demonstrate_wikipedia_personalities(parliament):
# Check if Wikipedia personalities are available # Check if Wikipedia personalities are available
if not parliament.enable_wikipedia_personalities: if not parliament.enable_wikipedia_personalities:
print("Wikipedia personality system not available") print("Wikipedia personality system not available")
print("To enable: Install required dependencies and run Wikipedia scraper") print(
"To enable: Install required dependencies and run Wikipedia scraper"
)
return return
print(f"Wikipedia personality system enabled") print("Wikipedia personality system enabled")
print(f"Loaded {len(parliament.personality_profiles)} personality profiles") print(
f"Loaded {len(parliament.personality_profiles)} personality profiles"
)
# Show sample personality profiles # Show sample personality profiles
print(f"\nSAMPLE PERSONALITY PROFILES:") print("\nSAMPLE PERSONALITY PROFILES:")
print("-" * 40) print("-" * 40)
sample_count = 0 sample_count = 0
@ -360,17 +443,35 @@ def demonstrate_wikipedia_personalities(parliament):
break break
print(f"\n{mep_name}") print(f"\n{mep_name}")
print(f" Wikipedia URL: {profile.wikipedia_url if profile.wikipedia_url else 'Not available'}") print(
print(f" Summary: {profile.summary[:200]}..." if profile.summary else "No summary available") f" Wikipedia URL: {profile.wikipedia_url if profile.wikipedia_url else 'Not 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(
print(f" Achievements: {profile.achievements[:150]}..." if profile.achievements else "Parliamentary service") 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}") print(f" Last Updated: {profile.last_updated}")
sample_count += 1 sample_count += 1
# Demonstrate personality-driven voting # Demonstrate personality-driven voting
print(f"\nPERSONALITY-DRIVEN VOTING DEMONSTRATION:") print("\nPERSONALITY-DRIVEN VOTING DEMONSTRATION:")
print("-" * 50) print("-" * 50)
# Create a test bill that would trigger different personality responses # Create a test bill that would trigger different personality responses
@ -379,14 +480,14 @@ def demonstrate_wikipedia_personalities(parliament):
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.", 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, bill_type=VoteType.ORDINARY_LEGISLATIVE_PROCEDURE,
committee="Environment", committee="Environment",
sponsor="Climate Action Leader" sponsor="Climate Action Leader",
) )
print(f"Bill: {bill.title}") print(f"Bill: {bill.title}")
print(f"Description: {bill.description}") print(f"Description: {bill.description}")
# Show how different MEPs with Wikipedia personalities would respond # Show how different MEPs with Wikipedia personalities would respond
print(f"\nPERSONALITY-BASED RESPONSES:") print("\nPERSONALITY-BASED RESPONSES:")
print("-" * 40) print("-" * 40)
sample_meps = list(parliament.personality_profiles.keys())[:3] sample_meps = list(parliament.personality_profiles.keys())[:3]
@ -400,38 +501,58 @@ def demonstrate_wikipedia_personalities(parliament):
# Show personality influence # Show personality influence
if profile.political_views: if profile.political_views:
print(f" Political Views: {profile.political_views[:100]}...") print(
f" Political Views: {profile.political_views[:100]}..."
)
if profile.policy_focus: if profile.policy_focus:
print(f" Policy Focus: {profile.policy_focus[:100]}...") print(
f" Policy Focus: {profile.policy_focus[:100]}..."
)
# Predict voting behavior based on personality # Predict voting behavior based on personality
if "environment" in profile.policy_focus.lower() or "climate" in profile.political_views.lower(): if (
"environment" in profile.policy_focus.lower()
or "climate" in profile.political_views.lower()
):
predicted_vote = "LIKELY SUPPORT" predicted_vote = "LIKELY SUPPORT"
reasoning = "Environmental policy focus and climate advocacy" reasoning = (
elif "economic" in profile.policy_focus.lower() or "business" in profile.political_views.lower(): "Environmental policy focus and climate advocacy"
)
elif (
"economic" in profile.policy_focus.lower()
or "business" in profile.political_views.lower()
):
predicted_vote = "LIKELY OPPOSE" predicted_vote = "LIKELY OPPOSE"
reasoning = "Economic concerns about investment costs" reasoning = "Economic concerns about investment costs"
else: else:
predicted_vote = "UNCERTAIN" predicted_vote = "UNCERTAIN"
reasoning = "Mixed considerations based on party alignment" reasoning = (
"Mixed considerations based on party alignment"
)
print(f" Predicted Vote: {predicted_vote}") print(f" Predicted Vote: {predicted_vote}")
print(f" Reasoning: {reasoning}") print(f" Reasoning: {reasoning}")
# Demonstrate scraping functionality # Demonstrate scraping functionality
print(f"\nWIKIPEDIA SCRAPING CAPABILITIES:") print("\nWIKIPEDIA SCRAPING CAPABILITIES:")
print("-" * 50) print("-" * 50)
print("Can scrape Wikipedia data for all 717 MEPs") print("Can scrape Wikipedia data for all 717 MEPs")
print("Extracts political views, career history, and achievements") print(
"Extracts political views, career history, and achievements"
)
print("Creates detailed personality profiles in JSON format") print("Creates detailed personality profiles in JSON format")
print("Integrates real personality data into AI agent system prompts") print(
"Integrates real personality data into AI agent system prompts"
)
print("Enables realistic, personality-driven voting behavior") print("Enables realistic, personality-driven voting behavior")
print("Respectful API usage with configurable delays") print("Respectful API usage with configurable delays")
print(f"\nTo scrape all MEP personalities:") print("\nTo scrape all MEP personalities:")
print(" parliament.scrape_wikipedia_personalities(delay=1.0)") print(" parliament.scrape_wikipedia_personalities(delay=1.0)")
print(" # This will create personality profiles for all 717 MEPs") print(
" # This will create personality profiles for all 717 MEPs"
)
print(" # Profiles are saved in 'mep_personalities/' directory") print(" # Profiles are saved in 'mep_personalities/' directory")
@ -447,23 +568,33 @@ def demonstrate_optimized_parliamentary_session(parliament):
bill_description="Comprehensive legislation to strengthen digital rights, enhance privacy protection, and establish clear guidelines for data handling across the European Union.", 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, bill_type=VoteType.ORDINARY_LEGISLATIVE_PROCEDURE,
committee="Legal Affairs", committee="Legal Affairs",
max_cost=25.0 # Max $25 for this session max_cost=25.0, # Max $25 for this session
) )
print(f"Session Results:") print("Session Results:")
print(f" Bill: {session_result['session_summary']['bill_title']}") print(
print(f" Final Outcome: {session_result['session_summary']['final_outcome']}") f" Bill: {session_result['session_summary']['bill_title']}"
print(f" Total Cost: ${session_result['session_summary']['total_cost']:.2f}") )
print(f" Budget Remaining: ${session_result['cost_stats']['budget_remaining']:.2f}") 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 # Show detailed cost statistics
cost_stats = parliament.get_cost_statistics() cost_stats = parliament.get_cost_statistics()
print(f"\nDETAILED COST STATISTICS:") print("\nDETAILED COST STATISTICS:")
print(f" Total Tokens Used: {cost_stats['total_tokens']:,}") print(f" Total Tokens Used: {cost_stats['total_tokens']:,}")
print(f" Requests Made: {cost_stats['requests_made']}") print(f" Requests Made: {cost_stats['requests_made']}")
print(f" Cache Hits: {cost_stats['cache_hits']}") print(f" Cache Hits: {cost_stats['cache_hits']}")
print(f" Cache Hit Rate: {cost_stats['cache_hit_rate']:.1%}") print(f" Cache Hit Rate: {cost_stats['cache_hit_rate']:.1%}")
print(f" Loading Efficiency: {cost_stats['loading_efficiency']:.1%}") print(
f" Loading Efficiency: {cost_stats['loading_efficiency']:.1%}"
)
print(f" Cache Size: {cost_stats['cache_size']} entries") print(f" Cache Size: {cost_stats['cache_size']} entries")
return session_result return session_result
@ -474,7 +605,9 @@ def main():
print("EUROSWARM PARLIAMENT - COST OPTIMIZED DEMONSTRATION") print("EUROSWARM PARLIAMENT - COST OPTIMIZED DEMONSTRATION")
print("=" * 60) print("=" * 60)
print("This demonstration shows the EuroSwarm Parliament with cost optimization features:") print(
"This demonstration shows the EuroSwarm Parliament with cost optimization features:"
)
print("• Lazy loading of MEP agents (only create when needed)") print("• Lazy loading of MEP agents (only create when needed)")
print("• Response caching (avoid repeated API calls)") print("• Response caching (avoid repeated API calls)")
print("• Batch processing (control memory and cost)") print("• Batch processing (control memory and cost)")
@ -504,17 +637,25 @@ def main():
# Show final cost statistics # Show final cost statistics
final_stats = parliament.get_cost_statistics() final_stats = parliament.get_cost_statistics()
print(f"\nFINAL COST STATISTICS:") print("\nFINAL COST STATISTICS:")
print(f"Total Cost: ${final_stats['total_cost']:.2f}") print(f"Total Cost: ${final_stats['total_cost']:.2f}")
print(f"Budget Remaining: ${final_stats['budget_remaining']:.2f}") print(f"Budget Remaining: ${final_stats['budget_remaining']:.2f}")
print(f"Cache Hit Rate: {final_stats['cache_hit_rate']:.1%}") print(f"Cache Hit Rate: {final_stats['cache_hit_rate']:.1%}")
print(f"Loading Efficiency: {final_stats['loading_efficiency']:.1%}") print(
f"Loading Efficiency: {final_stats['loading_efficiency']:.1%}"
)
print(f"\n✅ COST OPTIMIZATION DEMONSTRATION COMPLETED!") print("\n✅ COST OPTIMIZATION DEMONSTRATION COMPLETED!")
print(f"✅ EuroSwarm Parliament now supports cost-effective large-scale simulations") print(
print(f"✅ Lazy loading: {final_stats['loaded_meps']}/{final_stats['total_meps']} MEPs loaded") "✅ 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"✅ 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(
f"✅ Budget control: ${final_stats['total_cost']:.2f} spent of ${final_stats['budget_remaining'] + final_stats['total_cost']:.2f} budget"
)
if __name__ == "__main__": if __name__ == "__main__":

@ -17,13 +17,10 @@ Key Features:
import os import os
import random import random
import json import json
import time
import hashlib import hashlib
from typing import Dict, List, Optional, Union, Any, Set from typing import Dict, List, Optional, Any
from dataclasses import dataclass, field from dataclasses import dataclass, field
from enum import Enum from enum import Enum
from datetime import datetime
from functools import lru_cache
from swarms import Agent from swarms import Agent
from swarms.structs.multi_agent_exec import run_agents_concurrently from swarms.structs.multi_agent_exec import run_agents_concurrently
@ -31,10 +28,6 @@ from swarms.structs.board_of_directors_swarm import (
BoardOfDirectorsSwarm, BoardOfDirectorsSwarm,
BoardMember, BoardMember,
BoardMemberRole, BoardMemberRole,
BoardDecisionType,
BoardSpec,
BoardOrder,
BoardDecision,
enable_board_feature, enable_board_feature,
) )
from swarms.utils.loguru_logger import initialize_logger from swarms.utils.loguru_logger import initialize_logger
@ -136,7 +129,9 @@ class CostTracker:
def add_tokens(self, tokens: int): def add_tokens(self, tokens: int):
"""Add tokens used and calculate cost.""" """Add tokens used and calculate cost."""
self.total_tokens_used += tokens self.total_tokens_used += tokens
self.total_cost_estimate = (self.total_tokens_used / 1_000_000) * self.token_cost_per_1m self.total_cost_estimate = (
self.total_tokens_used / 1_000_000
) * self.token_cost_per_1m
self.requests_made += 1 self.requests_made += 1
def add_cache_hit(self): def add_cache_hit(self):
@ -154,8 +149,11 @@ class CostTracker:
"total_cost": self.total_cost_estimate, "total_cost": self.total_cost_estimate,
"requests_made": self.requests_made, "requests_made": self.requests_made,
"cache_hits": self.cache_hits, "cache_hits": self.cache_hits,
"cache_hit_rate": self.cache_hits / max(1, self.requests_made + self.cache_hits), "cache_hit_rate": self.cache_hits
"budget_remaining": max(0, self.budget_limit - self.total_cost_estimate) / max(1, self.requests_made + self.cache_hits),
"budget_remaining": max(
0, self.budget_limit - self.total_cost_estimate
),
} }
@ -195,7 +193,9 @@ class MassAgentTemplate:
""" """
self.data_source = data_source self.data_source = data_source
self.agent_count = agent_count self.agent_count = agent_count
self.enable_hierarchical_organization = enable_hierarchical_organization self.enable_hierarchical_organization = (
enable_hierarchical_organization
)
self.enable_group_swarms = enable_group_swarms self.enable_group_swarms = enable_group_swarms
self.enable_lazy_loading = enable_lazy_loading self.enable_lazy_loading = enable_lazy_loading
self.enable_caching = enable_caching self.enable_caching = enable_caching
@ -220,9 +220,15 @@ class MassAgentTemplate:
self._organize_agents() self._organize_agents()
if self.verbose: if self.verbose:
logger.info(f"Mass Agent Template initialized with {len(self.agents)} agent profiles") logger.info(
logger.info(f"Lazy loading: {self.enable_lazy_loading}, Caching: {self.enable_caching}") f"Mass Agent Template initialized with {len(self.agents)} agent profiles"
logger.info(f"Budget limit: ${budget_limit}, Batch size: {batch_size}") )
logger.info(
f"Lazy loading: {self.enable_lazy_loading}, Caching: {self.enable_caching}"
)
logger.info(
f"Budget limit: ${budget_limit}, Batch size: {batch_size}"
)
def _load_agent_profiles(self) -> List[Dict[str, Any]]: def _load_agent_profiles(self) -> List[Dict[str, Any]]:
""" """
@ -238,15 +244,20 @@ class MassAgentTemplate:
if self.data_source and os.path.exists(self.data_source): if self.data_source and os.path.exists(self.data_source):
# Load from file - customize based on your data format # Load from file - customize based on your data format
try: try:
if self.data_source.endswith('.json'): if self.data_source.endswith(".json"):
with open(self.data_source, 'r', encoding='utf-8') as f: with open(
self.data_source, "r", encoding="utf-8"
) as f:
agent_data = json.load(f) agent_data = json.load(f)
elif self.data_source.endswith('.csv'): elif self.data_source.endswith(".csv"):
import pandas as pd import pandas as pd
df = pd.read_csv(self.data_source) df = pd.read_csv(self.data_source)
agent_data = df.to_dict('records') agent_data = df.to_dict("records")
else: else:
logger.warning(f"Unsupported data format: {self.data_source}") logger.warning(
f"Unsupported data format: {self.data_source}"
)
except Exception as e: except Exception as e:
logger.error(f"Error loading agent data: {e}") logger.error(f"Error loading agent data: {e}")
@ -265,7 +276,7 @@ class MassAgentTemplate:
skills=data["skills"], skills=data["skills"],
experience_level=data["experience_level"], experience_level=data["experience_level"],
agent=None, # Will be created on demand agent=None, # Will be created on demand
is_loaded=False is_loaded=False,
) )
self.agents[data["name"]] = agent_profile self.agents[data["name"]] = agent_profile
@ -300,7 +311,9 @@ class MassAgentTemplate:
return profile.agent return profile.agent
def _load_agents_batch(self, agent_names: List[str]) -> List[Agent]: def _load_agents_batch(
self, agent_names: List[str]
) -> List[Agent]:
""" """
Load multiple agents in a batch. Load multiple agents in a batch.
@ -319,7 +332,9 @@ class MassAgentTemplate:
return loaded_agents return loaded_agents
def _get_cache_key(self, task: str, agent_names: List[str]) -> str: def _get_cache_key(
self, task: str, agent_names: List[str]
) -> str:
""" """
Generate a cache key for a task and agent combination. Generate a cache key for a task and agent combination.
@ -367,7 +382,9 @@ class MassAgentTemplate:
if self.enable_caching: if self.enable_caching:
self.response_cache[cache_key] = response self.response_cache[cache_key] = response
if self.verbose: if self.verbose:
logger.info(f"Cached response for key: {cache_key[:20]}...") logger.info(
f"Cached response for key: {cache_key[:20]}..."
)
def _generate_synthetic_data(self) -> List[Dict[str, Any]]: def _generate_synthetic_data(self) -> List[Dict[str, Any]]:
""" """
@ -384,47 +401,107 @@ class MassAgentTemplate:
"name": "Alex_Developer", "name": "Alex_Developer",
"role": AgentRole.SPECIALIST, "role": AgentRole.SPECIALIST,
"category": AgentCategory.TECHNICAL, "category": AgentCategory.TECHNICAL,
"specialization": ["Python", "Machine Learning", "API Development"], "specialization": [
"personality_traits": ["analytical", "detail-oriented", "problem-solver"], "Python",
"skills": ["Python", "TensorFlow", "FastAPI", "Docker"], "Machine Learning",
"experience_level": "senior" "API Development",
],
"personality_traits": [
"analytical",
"detail-oriented",
"problem-solver",
],
"skills": [
"Python",
"TensorFlow",
"FastAPI",
"Docker",
],
"experience_level": "senior",
}, },
{ {
"name": "Sarah_Designer", "name": "Sarah_Designer",
"role": AgentRole.CREATOR, "role": AgentRole.CREATOR,
"category": AgentCategory.CREATIVE, "category": AgentCategory.CREATIVE,
"specialization": ["UI/UX Design", "Visual Design", "Brand Identity"], "specialization": [
"personality_traits": ["creative", "user-focused", "aesthetic"], "UI/UX Design",
"skills": ["Figma", "Adobe Creative Suite", "User Research", "Prototyping"], "Visual Design",
"experience_level": "senior" "Brand Identity",
],
"personality_traits": [
"creative",
"user-focused",
"aesthetic",
],
"skills": [
"Figma",
"Adobe Creative Suite",
"User Research",
"Prototyping",
],
"experience_level": "senior",
}, },
{ {
"name": "Mike_Analyst", "name": "Mike_Analyst",
"role": AgentRole.ANALYST, "role": AgentRole.ANALYST,
"category": AgentCategory.ANALYTICAL, "category": AgentCategory.ANALYTICAL,
"specialization": ["Data Analysis", "Business Intelligence", "Market Research"], "specialization": [
"personality_traits": ["data-driven", "curious", "insightful"], "Data Analysis",
"Business Intelligence",
"Market Research",
],
"personality_traits": [
"data-driven",
"curious",
"insightful",
],
"skills": ["SQL", "Python", "Tableau", "Statistics"], "skills": ["SQL", "Python", "Tableau", "Statistics"],
"experience_level": "expert" "experience_level": "expert",
}, },
{ {
"name": "Lisa_Manager", "name": "Lisa_Manager",
"role": AgentRole.MANAGER, "role": AgentRole.MANAGER,
"category": AgentCategory.STRATEGIC, "category": AgentCategory.STRATEGIC,
"specialization": ["Project Management", "Team Leadership", "Strategic Planning"], "specialization": [
"personality_traits": ["organized", "leadership", "strategic"], "Project Management",
"skills": ["Agile", "Scrum", "Risk Management", "Stakeholder Communication"], "Team Leadership",
"experience_level": "senior" "Strategic Planning",
],
"personality_traits": [
"organized",
"leadership",
"strategic",
],
"skills": [
"Agile",
"Scrum",
"Risk Management",
"Stakeholder Communication",
],
"experience_level": "senior",
}, },
{ {
"name": "Tom_Coordinator", "name": "Tom_Coordinator",
"role": AgentRole.COORDINATOR, "role": AgentRole.COORDINATOR,
"category": AgentCategory.OPERATIONAL, "category": AgentCategory.OPERATIONAL,
"specialization": ["Process Optimization", "Workflow Management", "Resource Allocation"], "specialization": [
"personality_traits": ["efficient", "coordinated", "systematic"], "Process Optimization",
"skills": ["Process Mapping", "Automation", "Resource Planning", "Quality Assurance"], "Workflow Management",
"experience_level": "senior" "Resource Allocation",
} ],
"personality_traits": [
"efficient",
"coordinated",
"systematic",
],
"skills": [
"Process Mapping",
"Automation",
"Resource Planning",
"Quality Assurance",
],
"experience_level": "senior",
},
] ]
# Generate the specified number of agents # Generate the specified number of agents
@ -437,14 +514,18 @@ class MassAgentTemplate:
"role": template["role"], "role": template["role"],
"category": template["category"], "category": template["category"],
"specialization": template["specialization"].copy(), "specialization": template["specialization"].copy(),
"personality_traits": template["personality_traits"].copy(), "personality_traits": template[
"personality_traits"
].copy(),
"skills": template["skills"].copy(), "skills": template["skills"].copy(),
"experience_level": template["experience_level"] "experience_level": template["experience_level"],
} }
# Add some randomization for variety # Add some randomization for variety
if random.random() < 0.3: if random.random() < 0.3:
agent_data["experience_level"] = random.choice(["junior", "senior", "expert"]) agent_data["experience_level"] = random.choice(
["junior", "senior", "expert"]
)
synthetic_data.append(agent_data) synthetic_data.append(agent_data)
@ -470,7 +551,9 @@ class MassAgentTemplate:
verbose=self.verbose, verbose=self.verbose,
) )
def _generate_agent_system_prompt(self, profile: AgentProfile) -> str: def _generate_agent_system_prompt(
self, profile: AgentProfile
) -> str:
""" """
Generate a comprehensive system prompt for an agent. Generate a comprehensive system prompt for an agent.
@ -526,58 +609,54 @@ Remember: You are part of a large multi-agent system. Your unique combination of
- Report progress and any issues encountered - Report progress and any issues encountered
- Maintain quality standards in all work - Maintain quality standards in all work
- Collaborate with team members as needed""", - Collaborate with team members as needed""",
AgentRole.MANAGER: """ AgentRole.MANAGER: """
- Oversee team activities and coordinate efforts - Oversee team activities and coordinate efforts
- Set priorities and allocate resources - Set priorities and allocate resources
- Monitor progress and ensure deadlines are met - Monitor progress and ensure deadlines are met
- Provide guidance and support to team members - Provide guidance and support to team members
- Make strategic decisions for the team""", - Make strategic decisions for the team""",
AgentRole.SPECIALIST: """ AgentRole.SPECIALIST: """
- Provide expert knowledge in specific domains - Provide expert knowledge in specific domains
- Solve complex technical problems - Solve complex technical problems
- Mentor other agents in your area of expertise - Mentor other agents in your area of expertise
- Stay updated on latest developments in your field - Stay updated on latest developments in your field
- Contribute specialized insights to projects""", - Contribute specialized insights to projects""",
AgentRole.COORDINATOR: """ AgentRole.COORDINATOR: """
- Facilitate communication between different groups - Facilitate communication between different groups
- Ensure smooth workflow and process optimization - Ensure smooth workflow and process optimization
- Manage dependencies and resource allocation - Manage dependencies and resource allocation
- Track project timelines and milestones - Track project timelines and milestones
- Resolve conflicts and bottlenecks""", - Resolve conflicts and bottlenecks""",
AgentRole.ANALYST: """ AgentRole.ANALYST: """
- Analyze data and extract meaningful insights - Analyze data and extract meaningful insights
- Identify patterns and trends - Identify patterns and trends
- Provide evidence-based recommendations - Provide evidence-based recommendations
- Create reports and visualizations - Create reports and visualizations
- Support decision-making with data""", - Support decision-making with data""",
AgentRole.CREATOR: """ AgentRole.CREATOR: """
- Generate innovative ideas and solutions - Generate innovative ideas and solutions
- Design and develop new content or products - Design and develop new content or products
- Think creatively and outside the box - Think creatively and outside the box
- Prototype and iterate on concepts - Prototype and iterate on concepts
- Inspire and motivate other team members""", - Inspire and motivate other team members""",
AgentRole.VALIDATOR: """ AgentRole.VALIDATOR: """
- Review and validate work quality - Review and validate work quality
- Ensure compliance with standards and requirements - Ensure compliance with standards and requirements
- Provide constructive feedback - Provide constructive feedback
- Identify potential issues and risks - Identify potential issues and risks
- Maintain quality assurance processes""", - Maintain quality assurance processes""",
AgentRole.EXECUTOR: """ AgentRole.EXECUTOR: """
- Implement plans and strategies - Implement plans and strategies
- Execute tasks with precision and efficiency - Execute tasks with precision and efficiency
- Adapt to changing circumstances - Adapt to changing circumstances
- Ensure successful completion of objectives - Ensure successful completion of objectives
- Maintain focus on results and outcomes""" - Maintain focus on results and outcomes""",
} }
return responsibilities.get(role, "Execute tasks according to your role and expertise.") return responsibilities.get(
role,
"Execute tasks according to your role and expertise.",
)
def _organize_agents(self): def _organize_agents(self):
"""Organize agents into groups and categories.""" """Organize agents into groups and categories."""
@ -601,13 +680,15 @@ Remember: You are part of a large multi-agent system. Your unique combination of
category=category, category=category,
agents=agent_names, agents=agent_names,
leader=leader, leader=leader,
total_agents=len(agent_names) total_agents=len(agent_names),
) )
self.groups[group_name] = group self.groups[group_name] = group
if self.verbose: if self.verbose:
logger.info(f"Organized agents into {len(self.groups)} groups") logger.info(
f"Organized agents into {len(self.groups)} groups"
)
def _create_group_swarms(self): def _create_group_swarms(self):
"""Create Board of Directors swarms for each group.""" """Create Board of Directors swarms for each group."""
@ -623,28 +704,41 @@ Remember: You are part of a large multi-agent system. Your unique combination of
if group.leader and group.leader in self.agents: if group.leader and group.leader in self.agents:
leader_profile = self.agents[group.leader] leader_profile = self.agents[group.leader]
if leader_profile.agent: if leader_profile.agent:
board_members.append(BoardMember( board_members.append(
agent=leader_profile.agent, BoardMember(
role=BoardMemberRole.CHAIRMAN, agent=leader_profile.agent,
voting_weight=1.0, role=BoardMemberRole.CHAIRMAN,
expertise_areas=leader_profile.specialization voting_weight=1.0,
)) expertise_areas=leader_profile.specialization,
)
)
# Add other agents as board members # Add other agents as board members
for agent_name in group.agents[:5]: # Limit to 5 board members for agent_name in group.agents[
if agent_name != group.leader and agent_name in self.agents: :5
]: # Limit to 5 board members
if (
agent_name != group.leader
and agent_name in self.agents
):
profile = self.agents[agent_name] profile = self.agents[agent_name]
if profile.agent: if profile.agent:
board_members.append(BoardMember( board_members.append(
agent=profile.agent, BoardMember(
role=BoardMemberRole.EXECUTIVE_DIRECTOR, agent=profile.agent,
voting_weight=0.8, role=BoardMemberRole.EXECUTIVE_DIRECTOR,
expertise_areas=profile.specialization voting_weight=0.8,
)) expertise_areas=profile.specialization,
)
)
# Create Board of Directors swarm # Create Board of Directors swarm
if board_members: if board_members:
agents = [member.agent for member in board_members if member.agent is not None] agents = [
member.agent
for member in board_members
if member.agent is not None
]
group.group_swarm = BoardOfDirectorsSwarm( group.group_swarm = BoardOfDirectorsSwarm(
name=group_name, name=group_name,
@ -655,11 +749,13 @@ Remember: You are part of a large multi-agent system. Your unique combination of
verbose=self.verbose, verbose=self.verbose,
decision_threshold=0.6, decision_threshold=0.6,
enable_voting=True, enable_voting=True,
enable_consensus=True enable_consensus=True,
) )
if self.verbose: if self.verbose:
logger.info(f"Created {len([g for g in self.groups.values() if g.group_swarm])} group swarms") logger.info(
f"Created {len([g for g in self.groups.values() if g.group_swarm])} group swarms"
)
def get_agent(self, agent_name: str) -> Optional[AgentProfile]: def get_agent(self, agent_name: str) -> Optional[AgentProfile]:
""" """
@ -685,7 +781,9 @@ Remember: You are part of a large multi-agent system. Your unique combination of
""" """
return self.groups.get(group_name) return self.groups.get(group_name)
def get_agents_by_category(self, category: AgentCategory) -> List[str]: def get_agents_by_category(
self, category: AgentCategory
) -> List[str]:
""" """
Get all agents in a specific category. Get all agents in a specific category.
@ -707,9 +805,15 @@ Remember: You are part of a large multi-agent system. Your unique combination of
Returns: Returns:
List[str]: List of agent names with the role List[str]: List of agent names with the role
""" """
return [name for name, profile in self.agents.items() if profile.role == role] return [
name
for name, profile in self.agents.items()
if profile.role == role
]
def run_mass_task(self, task: str, agent_count: int = 10) -> Dict[str, Any]: def run_mass_task(
self, task: str, agent_count: int = 10
) -> Dict[str, Any]:
""" """
Run a task with multiple agents working in parallel with cost optimization. Run a task with multiple agents working in parallel with cost optimization.
@ -722,10 +826,16 @@ Remember: You are part of a large multi-agent system. Your unique combination of
""" """
# Check budget before starting # Check budget before starting
if not self.cost_tracker.check_budget(): if not self.cost_tracker.check_budget():
return {"error": "Budget exceeded", "cost_stats": self.cost_tracker.get_stats()} return {
"error": "Budget exceeded",
"cost_stats": self.cost_tracker.get_stats(),
}
# Select random agents # Select random agents
selected_agent_names = random.sample(list(self.agents.keys()), min(agent_count, len(self.agents))) selected_agent_names = random.sample(
list(self.agents.keys()),
min(agent_count, len(self.agents)),
)
# Check cache first # Check cache first
cache_key = self._get_cache_key(task, selected_agent_names) cache_key = self._get_cache_key(task, selected_agent_names)
@ -737,7 +847,7 @@ Remember: You are part of a large multi-agent system. Your unique combination of
"results": cached_result, "results": cached_result,
"total_agents": len(selected_agent_names), "total_agents": len(selected_agent_names),
"cached": True, "cached": True,
"cost_stats": self.cost_tracker.get_stats() "cost_stats": self.cost_tracker.get_stats(),
} }
# Process in batches to control memory and cost # Process in batches to control memory and cost
@ -745,12 +855,18 @@ Remember: You are part of a large multi-agent system. Your unique combination of
total_processed = 0 total_processed = 0
for i in range(0, len(selected_agent_names), self.batch_size): for i in range(0, len(selected_agent_names), self.batch_size):
batch_names = selected_agent_names[i:i + self.batch_size] batch_names = selected_agent_names[
i : i + self.batch_size
]
# Check budget for this batch # Check budget for this batch
if not self.cost_tracker.check_budget(): if not self.cost_tracker.check_budget():
logger.warning(f"Budget exceeded after processing {total_processed} agents") logger.warning(
logger.warning(f"Current cost: ${self.cost_tracker.total_cost_estimate:.4f}, Budget: ${self.cost_tracker.budget_limit:.2f}") f"Budget exceeded after processing {total_processed} agents"
)
logger.warning(
f"Current cost: ${self.cost_tracker.total_cost_estimate:.4f}, Budget: ${self.cost_tracker.budget_limit:.2f}"
)
break break
# Load agents for this batch # Load agents for this batch
@ -761,20 +877,30 @@ Remember: You are part of a large multi-agent system. Your unique combination of
# Run batch # Run batch
try: try:
batch_results = run_agents_concurrently(batch_agents, task) batch_results = run_agents_concurrently(
batch_agents, task
)
all_results.extend(batch_results) all_results.extend(batch_results)
total_processed += len(batch_agents) total_processed += len(batch_agents)
# Estimate tokens used (more realistic approximation) # Estimate tokens used (more realistic approximation)
# Include both input tokens (task) and output tokens (response) # Include both input tokens (task) and output tokens (response)
task_tokens = len(task.split()) * 1.3 # ~1.3 tokens per word task_tokens = (
response_tokens = len(batch_agents) * 200 # ~200 tokens per response len(task.split()) * 1.3
) # ~1.3 tokens per word
response_tokens = (
len(batch_agents) * 200
) # ~200 tokens per response
total_tokens = int(task_tokens + response_tokens) total_tokens = int(task_tokens + response_tokens)
self.cost_tracker.add_tokens(total_tokens) self.cost_tracker.add_tokens(total_tokens)
if self.verbose: if self.verbose:
logger.info(f"Processed batch {i//self.batch_size + 1}: {len(batch_agents)} agents") logger.info(
logger.info(f"Current cost: ${self.cost_tracker.total_cost_estimate:.4f}, Budget remaining: ${self.cost_tracker.budget_limit - self.cost_tracker.total_cost_estimate:.2f}") f"Processed batch {i//self.batch_size + 1}: {len(batch_agents)} agents"
)
logger.info(
f"Current cost: ${self.cost_tracker.total_cost_estimate:.4f}, Budget remaining: ${self.cost_tracker.budget_limit - self.cost_tracker.total_cost_estimate:.2f}"
)
except Exception as e: except Exception as e:
logger.error(f"Error processing batch: {e}") logger.error(f"Error processing batch: {e}")
@ -790,11 +916,15 @@ Remember: You are part of a large multi-agent system. Your unique combination of
"results": all_results, "results": all_results,
"total_agents": total_processed, "total_agents": total_processed,
"cached": False, "cached": False,
"cost_stats": self.cost_tracker.get_stats() "cost_stats": self.cost_tracker.get_stats(),
} }
def run_mass_task_optimized(self, task: str, agent_count: int = 1000, def run_mass_task_optimized(
max_cost: float = 10.0) -> Dict[str, Any]: self,
task: str,
agent_count: int = 1000,
max_cost: float = 10.0,
) -> Dict[str, Any]:
""" """
Run a task with cost-optimized mass execution for large-scale operations. Run a task with cost-optimized mass execution for large-scale operations.
@ -816,7 +946,9 @@ Remember: You are part of a large multi-agent system. Your unique combination of
self.cost_tracker.budget_limit = max_cost self.cost_tracker.budget_limit = max_cost
# Use smaller batches for better cost control # Use smaller batches for better cost control
self.batch_size = min(25, self.batch_size) # Smaller batches for cost control self.batch_size = min(
25, self.batch_size
) # Smaller batches for cost control
result = self.run_mass_task(task, agent_count) result = self.run_mass_task(task, agent_count)
@ -827,7 +959,9 @@ Remember: You are part of a large multi-agent system. Your unique combination of
self.cost_tracker.budget_limit = original_budget self.cost_tracker.budget_limit = original_budget
self.batch_size = original_batch_size self.batch_size = original_batch_size
def run_group_task(self, group_name: str, task: str) -> Dict[str, Any]: def run_group_task(
self, group_name: str, task: str
) -> Dict[str, Any]:
""" """
Run a task with a specific group using their Board of Directors swarm. Run a task with a specific group using their Board of Directors swarm.
@ -840,7 +974,9 @@ Remember: You are part of a large multi-agent system. Your unique combination of
""" """
group = self.groups.get(group_name) group = self.groups.get(group_name)
if not group or not group.group_swarm: if not group or not group.group_swarm:
return {"error": f"Group {group_name} not found or no swarm available"} return {
"error": f"Group {group_name} not found or no swarm available"
}
# Run task with group swarm # Run task with group swarm
result = group.group_swarm.run(task) result = group.group_swarm.run(task)
@ -849,7 +985,7 @@ Remember: You are part of a large multi-agent system. Your unique combination of
"group": group_name, "group": group_name,
"task": task, "task": task,
"result": result, "result": result,
"agents_involved": group.agents "agents_involved": group.agents,
} }
def get_system_stats(self) -> Dict[str, Any]: def get_system_stats(self) -> Dict[str, Any]:
@ -862,7 +998,9 @@ Remember: You are part of a large multi-agent system. Your unique combination of
stats = { stats = {
"total_agents": len(self.agents), "total_agents": len(self.agents),
"total_groups": len(self.groups), "total_groups": len(self.groups),
"loaded_agents": len([a for a in self.agents.values() if a.is_loaded]), "loaded_agents": len(
[a for a in self.agents.values() if a.is_loaded]
),
"categories": {}, "categories": {},
"roles": {}, "roles": {},
"experience_levels": {}, "experience_levels": {},
@ -871,23 +1009,29 @@ Remember: You are part of a large multi-agent system. Your unique combination of
"lazy_loading": self.enable_lazy_loading, "lazy_loading": self.enable_lazy_loading,
"caching": self.enable_caching, "caching": self.enable_caching,
"batch_size": self.batch_size, "batch_size": self.batch_size,
"budget_limit": self.cost_tracker.budget_limit "budget_limit": self.cost_tracker.budget_limit,
} },
} }
# Category breakdown # Category breakdown
for category in AgentCategory: for category in AgentCategory:
stats["categories"][category.value] = len(self.get_agents_by_category(category)) stats["categories"][category.value] = len(
self.get_agents_by_category(category)
)
# Role breakdown # Role breakdown
for role in AgentRole: for role in AgentRole:
stats["roles"][role.value] = len(self.get_agents_by_role(role)) stats["roles"][role.value] = len(
self.get_agents_by_role(role)
)
# Experience level breakdown # Experience level breakdown
experience_counts = {} experience_counts = {}
for profile in self.agents.values(): for profile in self.agents.values():
level = profile.experience_level level = profile.experience_level
experience_counts[level] = experience_counts.get(level, 0) + 1 experience_counts[level] = (
experience_counts.get(level, 0) + 1
)
stats["experience_levels"] = experience_counts stats["experience_levels"] = experience_counts
return stats return stats
@ -909,89 +1053,113 @@ def demonstrate_mass_agent_template():
enable_caching=True, enable_caching=True,
batch_size=25, batch_size=25,
budget_limit=50.0, # $50 budget limit budget_limit=50.0, # $50 budget limit
verbose=True verbose=True,
) )
# Show system statistics # Show system statistics
stats = template.get_system_stats() stats = template.get_system_stats()
print(f"\nSYSTEM STATISTICS:") print("\nSYSTEM STATISTICS:")
print(f"Total Agents: {stats['total_agents']}") print(f"Total Agents: {stats['total_agents']}")
print(f"Loaded Agents: {stats['loaded_agents']} (lazy loading active)") print(
f"Loaded Agents: {stats['loaded_agents']} (lazy loading active)"
)
print(f"Total Groups: {stats['total_groups']}") print(f"Total Groups: {stats['total_groups']}")
print(f"\nCOST OPTIMIZATION:") print("\nCOST OPTIMIZATION:")
cost_stats = stats['cost_stats'] cost_stats = stats["cost_stats"]
print(f"Budget Limit: ${cost_stats['budget_remaining'] + cost_stats['total_cost']:.2f}") 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 Used: ${cost_stats['total_cost']:.2f}")
print(f"Budget Remaining: ${cost_stats['budget_remaining']:.2f}") print(f"Budget Remaining: ${cost_stats['budget_remaining']:.2f}")
print(f"Cache Hit Rate: {cost_stats['cache_hit_rate']:.1%}") print(f"Cache Hit Rate: {cost_stats['cache_hit_rate']:.1%}")
print(f"\nCATEGORY BREAKDOWN:") print("\nCATEGORY BREAKDOWN:")
for category, count in stats['categories'].items(): for category, count in stats["categories"].items():
print(f" {category}: {count} agents") print(f" {category}: {count} agents")
print(f"\nROLE BREAKDOWN:") print("\nROLE BREAKDOWN:")
for role, count in stats['roles'].items(): for role, count in stats["roles"].items():
print(f" {role}: {count} agents") print(f" {role}: {count} agents")
print(f"\nEXPERIENCE LEVEL BREAKDOWN:") print("\nEXPERIENCE LEVEL BREAKDOWN:")
for level, count in stats['experience_levels'].items(): for level, count in stats["experience_levels"].items():
print(f" {level}: {count} agents") print(f" {level}: {count} agents")
# Demonstrate cost-optimized mass task execution # Demonstrate cost-optimized mass task execution
print(f"\nCOST-OPTIMIZED MASS TASK DEMONSTRATION:") print("\nCOST-OPTIMIZED MASS TASK DEMONSTRATION:")
print("-" * 40) print("-" * 40)
# Small task first (low cost) # Small task first (low cost)
small_result = template.run_mass_task( small_result = template.run_mass_task(
"What is the most important skill for a software developer?", "What is the most important skill for a software developer?",
agent_count=5 agent_count=5,
) )
print(f"Small Task Results:") print("Small Task Results:")
print(f" Agents Used: {len(small_result['agents_used'])}") print(f" Agents Used: {len(small_result['agents_used'])}")
print(f" Cached: {small_result.get('cached', False)}") print(f" Cached: {small_result.get('cached', False)}")
print(f" Cost: ${small_result['cost_stats']['total_cost']:.2f}") print(f" Cost: ${small_result['cost_stats']['total_cost']:.2f}")
# Large task to demonstrate full capability # Large task to demonstrate full capability
print(f"\nLarge Task Demonstration (Full Capability):") print("\nLarge Task Demonstration (Full Capability):")
large_result = template.run_mass_task( large_result = template.run_mass_task(
"Analyze the benefits of cloud computing for small businesses", "Analyze the benefits of cloud computing for small businesses",
agent_count=200 # Use more agents to show capability agent_count=200, # Use more agents to show capability
) )
print(f" Agents Used: {len(large_result['agents_used'])}") print(f" Agents Used: {len(large_result['agents_used'])}")
print(f" Cached: {large_result.get('cached', False)}") print(f" Cached: {large_result.get('cached', False)}")
print(f" Cost: ${large_result['cost_stats']['total_cost']:.2f}") print(f" Cost: ${large_result['cost_stats']['total_cost']:.2f}")
print(f" Budget Remaining: ${large_result['cost_stats']['budget_remaining']:.2f}") print(
f" Budget Remaining: ${large_result['cost_stats']['budget_remaining']:.2f}"
)
# Show what happens with cost limits # Show what happens with cost limits
print(f"\nCost-Limited Task Demonstration:") print("\nCost-Limited Task Demonstration:")
cost_limited_result = template.run_mass_task_optimized( cost_limited_result = template.run_mass_task_optimized(
"What are the key principles of agile development?", "What are the key principles of agile development?",
agent_count=100, agent_count=100,
max_cost=2.0 # Show cost limiting in action max_cost=2.0, # Show cost limiting in action
) )
print(f" Agents Used: {len(cost_limited_result['agents_used'])}") print(f" Agents Used: {len(cost_limited_result['agents_used'])}")
print(f" Cached: {cost_limited_result.get('cached', False)}") print(f" Cached: {cost_limited_result.get('cached', False)}")
print(f" Cost: ${cost_limited_result['cost_stats']['total_cost']:.2f}") print(
print(f" Budget Remaining: ${cost_limited_result['cost_stats']['budget_remaining']:.2f}") f" Cost: ${cost_limited_result['cost_stats']['total_cost']:.2f}"
)
print(
f" Budget Remaining: ${cost_limited_result['cost_stats']['budget_remaining']:.2f}"
)
# Show final cost statistics # Show final cost statistics
final_stats = template.get_system_stats() final_stats = template.get_system_stats()
print(f"\nFINAL COST STATISTICS:") print("\nFINAL COST STATISTICS:")
print(f"Total Cost: ${final_stats['cost_stats']['total_cost']:.2f}") print(
print(f"Budget Remaining: ${final_stats['cost_stats']['budget_remaining']:.2f}") f"Total Cost: ${final_stats['cost_stats']['total_cost']:.2f}"
print(f"Cache Hit Rate: {final_stats['cost_stats']['cache_hit_rate']:.1%}") )
print(f"Total Requests: {final_stats['cost_stats']['requests_made']}") print(
f"Budget Remaining: ${final_stats['cost_stats']['budget_remaining']:.2f}"
)
print(
f"Cache Hit Rate: {final_stats['cost_stats']['cache_hit_rate']:.1%}"
)
print(
f"Total Requests: {final_stats['cost_stats']['requests_made']}"
)
print(f"Cache Hits: {final_stats['cost_stats']['cache_hits']}") print(f"Cache Hits: {final_stats['cost_stats']['cache_hits']}")
print(f"\nDEMONSTRATION COMPLETED SUCCESSFULLY!") print("\nDEMONSTRATION COMPLETED SUCCESSFULLY!")
print(f"✅ Cost optimization working: ${final_stats['cost_stats']['total_cost']:.2f} spent") print(
print(f"✅ Lazy loading working: {final_stats['loaded_agents']}/{final_stats['total_agents']} agents loaded") f"✅ Cost optimization working: ${final_stats['cost_stats']['total_cost']:.2f} spent"
print(f"✅ Caching working: {final_stats['cost_stats']['cache_hit_rate']:.1%} hit rate") )
print(
f"✅ Lazy loading working: {final_stats['loaded_agents']}/{final_stats['total_agents']} agents loaded"
)
print(
f"✅ Caching working: {final_stats['cost_stats']['cache_hit_rate']:.1%} hit rate"
)
if __name__ == "__main__": if __name__ == "__main__":

@ -5,8 +5,11 @@ Test script to verify mass agent template can process more than 500 agents.
from mass_agent_template import MassAgentTemplate from mass_agent_template import MassAgentTemplate
def test_mass_agents(): def test_mass_agents():
print("Testing Mass Agent Template - Processing More Than 50 Agents") print(
"Testing Mass Agent Template - Processing More Than 50 Agents"
)
print("=" * 60) print("=" * 60)
# Initialize template with 200 agents # Initialize template with 200 agents
@ -14,48 +17,57 @@ def test_mass_agents():
agent_count=200, agent_count=200,
budget_limit=50.0, budget_limit=50.0,
batch_size=25, batch_size=25,
verbose=True verbose=True,
) )
print(f"Initialized with {len(template.agents)} agents") print(f"Initialized with {len(template.agents)} agents")
print(f"Budget limit: ${template.cost_tracker.budget_limit}") print(f"Budget limit: ${template.cost_tracker.budget_limit}")
# Test processing 100 agents # Test processing 100 agents
print(f"\nTesting with 100 agents...") print("\nTesting with 100 agents...")
result = template.run_mass_task( result = template.run_mass_task(
"What is the most important skill for your role?", "What is the most important skill for your role?",
agent_count=100 agent_count=100,
) )
print(f"Results:") print("Results:")
print(f" Agents processed: {len(result['agents_used'])}") print(f" Agents processed: {len(result['agents_used'])}")
print(f" Cost: ${result['cost_stats']['total_cost']:.4f}") print(f" Cost: ${result['cost_stats']['total_cost']:.4f}")
print(f" Budget remaining: ${result['cost_stats']['budget_remaining']:.2f}") print(
f" Budget remaining: ${result['cost_stats']['budget_remaining']:.2f}"
)
print(f" Cached: {result.get('cached', False)}") print(f" Cached: {result.get('cached', False)}")
# Test processing 150 agents # Test processing 150 agents
print(f"\nTesting with 150 agents...") print("\nTesting with 150 agents...")
result2 = template.run_mass_task( result2 = template.run_mass_task(
"Describe your approach to problem-solving", "Describe your approach to problem-solving", agent_count=150
agent_count=150
) )
print(f"Results:") print("Results:")
print(f" Agents processed: {len(result2['agents_used'])}") print(f" Agents processed: {len(result2['agents_used'])}")
print(f" Cost: ${result2['cost_stats']['total_cost']:.4f}") print(f" Cost: ${result2['cost_stats']['total_cost']:.4f}")
print(f" Budget remaining: ${result2['cost_stats']['budget_remaining']:.2f}") print(
f" Budget remaining: ${result2['cost_stats']['budget_remaining']:.2f}"
)
print(f" Cached: {result2.get('cached', False)}") print(f" Cached: {result2.get('cached', False)}")
# Show final stats # Show final stats
final_stats = template.get_system_stats() final_stats = template.get_system_stats()
print(f"\nFinal Statistics:") print("\nFinal Statistics:")
print(f" Total agents: {final_stats['total_agents']}") print(f" Total agents: {final_stats['total_agents']}")
print(f" Loaded agents: {final_stats['loaded_agents']}") print(f" Loaded agents: {final_stats['loaded_agents']}")
print(f" Total cost: ${final_stats['cost_stats']['total_cost']:.4f}") print(
print(f" Budget remaining: ${final_stats['cost_stats']['budget_remaining']:.2f}") f" Total cost: ${final_stats['cost_stats']['total_cost']:.4f}"
)
print(
f" Budget remaining: ${final_stats['cost_stats']['budget_remaining']:.2f}"
)
# Success criteria # Success criteria
total_processed = len(result['agents_used']) + len(result2['agents_used']) total_processed = len(result["agents_used"]) + len(
result2["agents_used"]
)
print(f"\nTotal agents processed: {total_processed}") print(f"\nTotal agents processed: {total_processed}")
if total_processed > 50: if total_processed > 50:
@ -63,5 +75,6 @@ def test_mass_agents():
else: else:
print("❌ FAILURE: Template still limited to 50 agents") print("❌ FAILURE: Template still limited to 50 agents")
if __name__ == "__main__": if __name__ == "__main__":
test_mass_agents() test_mass_agents()

@ -14,7 +14,6 @@ from typing import Dict, List, Optional, Any
from dataclasses import dataclass, asdict from dataclasses import dataclass, asdict
import requests import requests
from loguru import logger from loguru import logger
import xml.etree.ElementTree as ET
@dataclass @dataclass
@ -78,7 +77,11 @@ class WikipediaPersonalityScraper:
Scraper for gathering Wikipedia personality data for MEPs. Scraper for gathering Wikipedia personality data for MEPs.
""" """
def __init__(self, output_dir: str = "mep_personalities", verbose: bool = True): def __init__(
self,
output_dir: str = "mep_personalities",
verbose: bool = True,
):
""" """
Initialize the Wikipedia personality scraper. Initialize the Wikipedia personality scraper.
@ -89,17 +92,23 @@ class WikipediaPersonalityScraper:
self.output_dir = output_dir self.output_dir = output_dir
self.verbose = verbose self.verbose = verbose
self.session = requests.Session() self.session = requests.Session()
self.session.headers.update({ self.session.headers.update(
'User-Agent': 'EuroSwarm Parliament Personality Scraper/1.0 (https://github.com/swarms-democracy)' {
}) "User-Agent": "EuroSwarm Parliament Personality Scraper/1.0 (https://github.com/swarms-democracy)"
}
)
# Create output directory # Create output directory
os.makedirs(output_dir, exist_ok=True) os.makedirs(output_dir, exist_ok=True)
if verbose: if verbose:
logger.info(f"Wikipedia Personality Scraper initialized. Output directory: {output_dir}") logger.info(
f"Wikipedia Personality Scraper initialized. Output directory: {output_dir}"
)
def extract_mep_data_from_xml(self, xml_file: str = "EU.xml") -> List[Dict[str, str]]: def extract_mep_data_from_xml(
self, xml_file: str = "EU.xml"
) -> List[Dict[str, str]]:
""" """
Extract MEP data from EU.xml file. Extract MEP data from EU.xml file.
@ -112,31 +121,45 @@ class WikipediaPersonalityScraper:
meps = [] meps = []
try: try:
with open(xml_file, 'r', encoding='utf-8') as f: with open(xml_file, "r", encoding="utf-8") as f:
content = f.read() content = f.read()
# Use regex to extract MEP data # Use regex to extract MEP data
mep_pattern = r'<mep>\s*<fullName>(.*?)</fullName>\s*<country>(.*?)</country>\s*<politicalGroup>(.*?)</politicalGroup>\s*<id>(.*?)</id>\s*<nationalPoliticalGroup>(.*?)</nationalPoliticalGroup>\s*</mep>' mep_pattern = r"<mep>\s*<fullName>(.*?)</fullName>\s*<country>(.*?)</country>\s*<politicalGroup>(.*?)</politicalGroup>\s*<id>(.*?)</id>\s*<nationalPoliticalGroup>(.*?)</nationalPoliticalGroup>\s*</mep>"
mep_matches = re.findall(mep_pattern, content, re.DOTALL) mep_matches = re.findall(mep_pattern, content, re.DOTALL)
for full_name, country, political_group, mep_id, national_party in mep_matches: for (
meps.append({ full_name,
'full_name': full_name.strip(), country,
'country': country.strip(), political_group,
'political_group': political_group.strip(), mep_id,
'mep_id': mep_id.strip(), national_party,
'national_party': national_party.strip() ) in mep_matches:
}) meps.append(
{
"full_name": full_name.strip(),
"country": country.strip(),
"political_group": political_group.strip(),
"mep_id": mep_id.strip(),
"national_party": national_party.strip(),
}
)
if self.verbose: if self.verbose:
logger.info(f"Extracted {len(meps)} MEPs from {xml_file}") logger.info(
f"Extracted {len(meps)} MEPs from {xml_file}"
)
except Exception as e: except Exception as e:
logger.error(f"Error extracting MEP data from {xml_file}: {e}") logger.error(
f"Error extracting MEP data from {xml_file}: {e}"
)
return meps return meps
def search_wikipedia_page(self, mep_name: str, country: str) -> Optional[str]: def search_wikipedia_page(
self, mep_name: str, country: str
) -> Optional[str]:
""" """
Search for a Wikipedia page for an MEP. Search for a Wikipedia page for an MEP.
@ -151,42 +174,50 @@ class WikipediaPersonalityScraper:
# Search for the MEP on Wikipedia # Search for the MEP on Wikipedia
search_url = "https://en.wikipedia.org/w/api.php" search_url = "https://en.wikipedia.org/w/api.php"
search_params = { search_params = {
'action': 'query', "action": "query",
'format': 'json', "format": "json",
'list': 'search', "list": "search",
'srsearch': f'"{mep_name}" {country}', "srsearch": f'"{mep_name}" {country}',
'srlimit': 5, "srlimit": 5,
'srnamespace': 0 "srnamespace": 0,
} }
response = self.session.get(search_url, params=search_params) response = self.session.get(
search_url, params=search_params
)
response.raise_for_status() response.raise_for_status()
data = response.json() data = response.json()
search_results = data.get('query', {}).get('search', []) search_results = data.get("query", {}).get("search", [])
if search_results: if search_results:
# Return the first result # Return the first result
return search_results[0]['title'] return search_results[0]["title"]
# Try alternative search without quotes # Try alternative search without quotes
search_params['srsearch'] = f'{mep_name} {country}' search_params["srsearch"] = f"{mep_name} {country}"
response = self.session.get(search_url, params=search_params) response = self.session.get(
search_url, params=search_params
)
response.raise_for_status() response.raise_for_status()
data = response.json() data = response.json()
search_results = data.get('query', {}).get('search', []) search_results = data.get("query", {}).get("search", [])
if search_results: if search_results:
return search_results[0]['title'] return search_results[0]["title"]
except Exception as e: except Exception as e:
if self.verbose: if self.verbose:
logger.warning(f"Error searching Wikipedia for {mep_name}: {e}") logger.warning(
f"Error searching Wikipedia for {mep_name}: {e}"
)
return None return None
def get_wikipedia_content(self, page_title: str) -> Optional[Dict[str, Any]]: def get_wikipedia_content(
self, page_title: str
) -> Optional[Dict[str, Any]]:
""" """
Get Wikipedia content for a specific page. Get Wikipedia content for a specific page.
@ -200,42 +231,51 @@ class WikipediaPersonalityScraper:
# Get page content # Get page content
content_url = "https://en.wikipedia.org/w/api.php" content_url = "https://en.wikipedia.org/w/api.php"
content_params = { content_params = {
'action': 'query', "action": "query",
'format': 'json', "format": "json",
'titles': page_title, "titles": page_title,
'prop': 'extracts|info|categories', "prop": "extracts|info|categories",
'exintro': True, "exintro": True,
'explaintext': True, "explaintext": True,
'inprop': 'url', "inprop": "url",
'cllimit': 50 "cllimit": 50,
} }
response = self.session.get(content_url, params=content_params) response = self.session.get(
content_url, params=content_params
)
response.raise_for_status() response.raise_for_status()
data = response.json() data = response.json()
pages = data.get('query', {}).get('pages', {}) pages = data.get("query", {}).get("pages", {})
if pages: if pages:
page_id = list(pages.keys())[0] page_id = list(pages.keys())[0]
page_data = pages[page_id] page_data = pages[page_id]
return { return {
'title': page_data.get('title', ''), "title": page_data.get("title", ""),
'extract': page_data.get('extract', ''), "extract": page_data.get("extract", ""),
'url': page_data.get('fullurl', ''), "url": page_data.get("fullurl", ""),
'categories': [cat['title'] for cat in page_data.get('categories', [])], "categories": [
'pageid': page_data.get('pageid', ''), cat["title"]
'length': page_data.get('length', 0) for cat in page_data.get("categories", [])
],
"pageid": page_data.get("pageid", ""),
"length": page_data.get("length", 0),
} }
except Exception as e: except Exception as e:
if self.verbose: if self.verbose:
logger.warning(f"Error getting Wikipedia content for {page_title}: {e}") logger.warning(
f"Error getting Wikipedia content for {page_title}: {e}"
)
return None return None
def parse_wikipedia_content(self, content: str, mep_name: str) -> Dict[str, str]: def parse_wikipedia_content(
self, content: str, mep_name: str
) -> Dict[str, str]:
""" """
Parse Wikipedia content to extract structured personality information. Parse Wikipedia content to extract structured personality information.
@ -247,112 +287,136 @@ class WikipediaPersonalityScraper:
Dictionary of parsed personality information Dictionary of parsed personality information
""" """
personality_data = { personality_data = {
'summary': '', "summary": "",
'early_life': '', "early_life": "",
'political_career': '', "political_career": "",
'political_views': '', "political_views": "",
'policy_focus': '', "policy_focus": "",
'achievements': '', "achievements": "",
'controversies': '', "controversies": "",
'personal_life': '', "personal_life": "",
'education': '', "education": "",
'professional_background': '', "professional_background": "",
'party_affiliations': '', "party_affiliations": "",
'committee_experience': '', "committee_experience": "",
'voting_record': '', "voting_record": "",
'public_statements': '', "public_statements": "",
'interests': '', "interests": "",
'languages': '', "languages": "",
'awards': '', "awards": "",
'publications': '', "publications": "",
'social_media': '' "social_media": "",
} }
# Extract summary (first paragraph) # Extract summary (first paragraph)
paragraphs = content.split('\n\n') paragraphs = content.split("\n\n")
if paragraphs: if paragraphs:
personality_data['summary'] = paragraphs[0][:1000] # Limit summary length personality_data["summary"] = paragraphs[0][
:1000
] # Limit summary length
# Look for specific sections # Look for specific sections
content_lower = content.lower() content_lower = content.lower()
# Early life and education # Early life and education
early_life_patterns = [ early_life_patterns = [
r'early life[^.]*\.', r"early life[^.]*\.",
r'born[^.]*\.', r"born[^.]*\.",
r'childhood[^.]*\.', r"childhood[^.]*\.",
r'grew up[^.]*\.', r"grew up[^.]*\.",
r'education[^.]*\.' r"education[^.]*\.",
] ]
for pattern in early_life_patterns: for pattern in early_life_patterns:
matches = re.findall(pattern, content_lower, re.IGNORECASE) matches = re.findall(
pattern, content_lower, re.IGNORECASE
)
if matches: if matches:
personality_data['early_life'] = ' '.join(matches[:3]) # Take first 3 matches personality_data["early_life"] = " ".join(
matches[:3]
) # Take first 3 matches
break break
# Political career # Political career
political_patterns = [ political_patterns = [
r'political career[^.]*\.', r"political career[^.]*\.",
r'elected[^.]*\.', r"elected[^.]*\.",
r'parliament[^.]*\.', r"parliament[^.]*\.",
r'minister[^.]*\.', r"minister[^.]*\.",
r'party[^.]*\.' r"party[^.]*\.",
] ]
for pattern in political_patterns: for pattern in political_patterns:
matches = re.findall(pattern, content_lower, re.IGNORECASE) matches = re.findall(
pattern, content_lower, re.IGNORECASE
)
if matches: if matches:
personality_data['political_career'] = ' '.join(matches[:5]) # Take first 5 matches personality_data["political_career"] = " ".join(
matches[:5]
) # Take first 5 matches
break break
# Political views # Political views
views_patterns = [ views_patterns = [
r'political views[^.]*\.', r"political views[^.]*\.",
r'positions[^.]*\.', r"positions[^.]*\.",
r'advocates[^.]*\.', r"advocates[^.]*\.",
r'supports[^.]*\.', r"supports[^.]*\.",
r'opposes[^.]*\.' r"opposes[^.]*\.",
] ]
for pattern in views_patterns: for pattern in views_patterns:
matches = re.findall(pattern, content_lower, re.IGNORECASE) matches = re.findall(
pattern, content_lower, re.IGNORECASE
)
if matches: if matches:
personality_data['political_views'] = ' '.join(matches[:3]) personality_data["political_views"] = " ".join(
matches[:3]
)
break break
# Policy focus # Policy focus
policy_patterns = [ policy_patterns = [
r'policy[^.]*\.', r"policy[^.]*\.",
r'focus[^.]*\.', r"focus[^.]*\.",
r'issues[^.]*\.', r"issues[^.]*\.",
r'legislation[^.]*\.' r"legislation[^.]*\.",
] ]
for pattern in policy_patterns: for pattern in policy_patterns:
matches = re.findall(pattern, content_lower, re.IGNORECASE) matches = re.findall(
pattern, content_lower, re.IGNORECASE
)
if matches: if matches:
personality_data['policy_focus'] = ' '.join(matches[:3]) personality_data["policy_focus"] = " ".join(
matches[:3]
)
break break
# Achievements # Achievements
achievement_patterns = [ achievement_patterns = [
r'achievements[^.]*\.', r"achievements[^.]*\.",
r'accomplishments[^.]*\.', r"accomplishments[^.]*\.",
r'success[^.]*\.', r"success[^.]*\.",
r'won[^.]*\.', r"won[^.]*\.",
r'received[^.]*\.' r"received[^.]*\.",
] ]
for pattern in achievement_patterns: for pattern in achievement_patterns:
matches = re.findall(pattern, content_lower, re.IGNORECASE) matches = re.findall(
pattern, content_lower, re.IGNORECASE
)
if matches: if matches:
personality_data['achievements'] = ' '.join(matches[:3]) personality_data["achievements"] = " ".join(
matches[:3]
)
break break
return personality_data return personality_data
def create_personality_profile(self, mep_data: Dict[str, str]) -> MEPPersonalityProfile: def create_personality_profile(
self, mep_data: Dict[str, str]
) -> MEPPersonalityProfile:
""" """
Create a personality profile for an MEP. Create a personality profile for an MEP.
@ -362,8 +426,8 @@ class WikipediaPersonalityScraper:
Returns: Returns:
MEPPersonalityProfile object MEPPersonalityProfile object
""" """
mep_name = mep_data['full_name'] mep_name = mep_data["full_name"]
country = mep_data['country'] country = mep_data["country"]
# Search for Wikipedia page # Search for Wikipedia page
page_title = self.search_wikipedia_page(mep_name, country) page_title = self.search_wikipedia_page(mep_name, country)
@ -374,56 +438,76 @@ class WikipediaPersonalityScraper:
if wiki_content: if wiki_content:
# Parse content # Parse content
personality_data = self.parse_wikipedia_content(wiki_content['extract'], mep_name) personality_data = self.parse_wikipedia_content(
wiki_content["extract"], mep_name
)
# Create profile # Create profile
profile = MEPPersonalityProfile( profile = MEPPersonalityProfile(
full_name=mep_name, full_name=mep_name,
mep_id=mep_data['mep_id'], mep_id=mep_data["mep_id"],
wikipedia_url=wiki_content['url'], wikipedia_url=wiki_content["url"],
summary=personality_data['summary'], summary=personality_data["summary"],
early_life=personality_data['early_life'], early_life=personality_data["early_life"],
political_career=personality_data['political_career'], political_career=personality_data[
political_views=personality_data['political_views'], "political_career"
policy_focus=personality_data['policy_focus'], ],
achievements=personality_data['achievements'], political_views=personality_data[
controversies=personality_data['controversies'], "political_views"
personal_life=personality_data['personal_life'], ],
education=personality_data['education'], policy_focus=personality_data["policy_focus"],
professional_background=personality_data['professional_background'], achievements=personality_data["achievements"],
party_affiliations=personality_data['party_affiliations'], controversies=personality_data["controversies"],
committee_experience=personality_data['committee_experience'], personal_life=personality_data["personal_life"],
voting_record=personality_data['voting_record'], education=personality_data["education"],
public_statements=personality_data['public_statements'], professional_background=personality_data[
interests=personality_data['interests'], "professional_background"
languages=personality_data['languages'], ],
awards=personality_data['awards'], party_affiliations=personality_data[
publications=personality_data['publications'], "party_affiliations"
social_media=personality_data['social_media'], ],
last_updated=time.strftime("%Y-%m-%d %H:%M:%S") committee_experience=personality_data[
"committee_experience"
],
voting_record=personality_data["voting_record"],
public_statements=personality_data[
"public_statements"
],
interests=personality_data["interests"],
languages=personality_data["languages"],
awards=personality_data["awards"],
publications=personality_data["publications"],
social_media=personality_data["social_media"],
last_updated=time.strftime("%Y-%m-%d %H:%M:%S"),
) )
if self.verbose: if self.verbose:
logger.info(f"Created personality profile for {mep_name} from Wikipedia") logger.info(
f"Created personality profile for {mep_name} from Wikipedia"
)
return profile return profile
# Create minimal profile if no Wikipedia data found # Create minimal profile if no Wikipedia data found
profile = MEPPersonalityProfile( profile = MEPPersonalityProfile(
full_name=mep_name, full_name=mep_name,
mep_id=mep_data['mep_id'], mep_id=mep_data["mep_id"],
summary=f"{mep_name} is a Member of the European Parliament representing {country}.", summary=f"{mep_name} is a Member of the European Parliament representing {country}.",
political_career=f"Currently serving as MEP for {country}.", political_career=f"Currently serving as MEP for {country}.",
political_views=f"Member of {mep_data['political_group']} and {mep_data['national_party']}.", political_views=f"Member of {mep_data['political_group']} and {mep_data['national_party']}.",
last_updated=time.strftime("%Y-%m-%d %H:%M:%S") last_updated=time.strftime("%Y-%m-%d %H:%M:%S"),
) )
if self.verbose: if self.verbose:
logger.warning(f"No Wikipedia data found for {mep_name}, created minimal profile") logger.warning(
f"No Wikipedia data found for {mep_name}, created minimal profile"
)
return profile return profile
def save_personality_profile(self, profile: MEPPersonalityProfile) -> str: def save_personality_profile(
self, profile: MEPPersonalityProfile
) -> str:
""" """
Save personality profile to JSON file. Save personality profile to JSON file.
@ -434,15 +518,15 @@ class WikipediaPersonalityScraper:
Path to saved file Path to saved file
""" """
# Create safe filename # Create safe filename
safe_name = re.sub(r'[^\w\s-]', '', profile.full_name).strip() safe_name = re.sub(r"[^\w\s-]", "", profile.full_name).strip()
safe_name = re.sub(r'[-\s]+', '_', safe_name) safe_name = re.sub(r"[-\s]+", "_", safe_name)
filename = f"{safe_name}_{profile.mep_id}.json" filename = f"{safe_name}_{profile.mep_id}.json"
filepath = os.path.join(self.output_dir, filename) filepath = os.path.join(self.output_dir, filename)
# Convert to dictionary and save # Convert to dictionary and save
profile_dict = asdict(profile) profile_dict = asdict(profile)
with open(filepath, 'w', encoding='utf-8') as f: with open(filepath, "w", encoding="utf-8") as f:
json.dump(profile_dict, f, indent=2, ensure_ascii=False) json.dump(profile_dict, f, indent=2, ensure_ascii=False)
if self.verbose: if self.verbose:
@ -450,7 +534,9 @@ class WikipediaPersonalityScraper:
return filepath return filepath
def scrape_all_mep_personalities(self, xml_file: str = "EU.xml", delay: float = 1.0) -> Dict[str, str]: def scrape_all_mep_personalities(
self, xml_file: str = "EU.xml", delay: float = 1.0
) -> Dict[str, str]:
""" """
Scrape personality data for all MEPs. Scrape personality data for all MEPs.
@ -465,10 +551,12 @@ class WikipediaPersonalityScraper:
profile_files = {} profile_files = {}
if self.verbose: if self.verbose:
logger.info(f"Starting personality scraping for {len(meps)} MEPs") logger.info(
f"Starting personality scraping for {len(meps)} MEPs"
)
for i, mep_data in enumerate(meps, 1): for i, mep_data in enumerate(meps, 1):
mep_name = mep_data['full_name'] mep_name = mep_data["full_name"]
if self.verbose: if self.verbose:
logger.info(f"Processing {i}/{len(meps)}: {mep_name}") logger.info(f"Processing {i}/{len(meps)}: {mep_name}")
@ -489,11 +577,15 @@ class WikipediaPersonalityScraper:
continue continue
if self.verbose: if self.verbose:
logger.info(f"Completed personality scraping. {len(profile_files)} profiles created.") logger.info(
f"Completed personality scraping. {len(profile_files)} profiles created."
)
return profile_files return profile_files
def load_personality_profile(self, filepath: str) -> MEPPersonalityProfile: def load_personality_profile(
self, filepath: str
) -> MEPPersonalityProfile:
""" """
Load personality profile from JSON file. Load personality profile from JSON file.
@ -503,12 +595,14 @@ class WikipediaPersonalityScraper:
Returns: Returns:
MEPPersonalityProfile object MEPPersonalityProfile object
""" """
with open(filepath, 'r', encoding='utf-8') as f: with open(filepath, "r", encoding="utf-8") as f:
data = json.load(f) data = json.load(f)
return MEPPersonalityProfile(**data) return MEPPersonalityProfile(**data)
def get_personality_summary(self, profile: MEPPersonalityProfile) -> str: def get_personality_summary(
self, profile: MEPPersonalityProfile
) -> str:
""" """
Generate a personality summary for use in AI agent system prompts. Generate a personality summary for use in AI agent system prompts.
@ -524,22 +618,32 @@ class WikipediaPersonalityScraper:
summary_parts.append(f"Background: {profile.summary}") summary_parts.append(f"Background: {profile.summary}")
if profile.political_career: if profile.political_career:
summary_parts.append(f"Political Career: {profile.political_career}") summary_parts.append(
f"Political Career: {profile.political_career}"
)
if profile.political_views: if profile.political_views:
summary_parts.append(f"Political Views: {profile.political_views}") summary_parts.append(
f"Political Views: {profile.political_views}"
)
if profile.policy_focus: if profile.policy_focus:
summary_parts.append(f"Policy Focus: {profile.policy_focus}") summary_parts.append(
f"Policy Focus: {profile.policy_focus}"
)
if profile.achievements: if profile.achievements:
summary_parts.append(f"Notable Achievements: {profile.achievements}") summary_parts.append(
f"Notable Achievements: {profile.achievements}"
)
if profile.education: if profile.education:
summary_parts.append(f"Education: {profile.education}") summary_parts.append(f"Education: {profile.education}")
if profile.professional_background: if profile.professional_background:
summary_parts.append(f"Professional Background: {profile.professional_background}") summary_parts.append(
f"Professional Background: {profile.professional_background}"
)
return "\n".join(summary_parts) return "\n".join(summary_parts)
@ -551,12 +655,14 @@ def main():
print("=" * 70) print("=" * 70)
# Initialize scraper # Initialize scraper
scraper = WikipediaPersonalityScraper(output_dir="mep_personalities", verbose=True) scraper = WikipediaPersonalityScraper(
output_dir="mep_personalities", verbose=True
)
# Scrape all MEP personalities # Scrape all MEP personalities
profile_files = scraper.scrape_all_mep_personalities(delay=1.0) profile_files = scraper.scrape_all_mep_personalities(delay=1.0)
print(f"\n✅ Scraping completed!") print("\n✅ Scraping completed!")
print(f"📁 Profiles saved to: {scraper.output_dir}") print(f"📁 Profiles saved to: {scraper.output_dir}")
print(f"📊 Total profiles created: {len(profile_files)}") print(f"📊 Total profiles created: {len(profile_files)}")

@ -1,5 +1,6 @@
from swarms.structs.agent import Agent from swarms.structs.agent import Agent
from swarms.structs.agent_builder import AgentsBuilder from swarms.structs.agent_builder import AgentsBuilder
from swarms.structs.agent_rearrange import AgentRearrange, rearrange
from swarms.structs.auto_swarm_builder import AutoSwarmBuilder from swarms.structs.auto_swarm_builder import AutoSwarmBuilder
from swarms.structs.base_structure import BaseStructure from swarms.structs.base_structure import BaseStructure
from swarms.structs.base_swarm import BaseSwarm from swarms.structs.base_swarm import BaseSwarm
@ -66,7 +67,6 @@ from swarms.structs.multi_agent_exec import (
run_single_agent, run_single_agent,
) )
from swarms.structs.multi_agent_router import MultiAgentRouter from swarms.structs.multi_agent_router import MultiAgentRouter
from swarms.structs.agent_rearrange import AgentRearrange, rearrange
from swarms.structs.round_robin import RoundRobinSwarm from swarms.structs.round_robin import RoundRobinSwarm
from swarms.structs.sequential_workflow import SequentialWorkflow from swarms.structs.sequential_workflow import SequentialWorkflow
from swarms.structs.spreadsheet_swarm import SpreadSheetSwarm from swarms.structs.spreadsheet_swarm import SpreadSheetSwarm

@ -21,6 +21,13 @@ from typing import (
import toml import toml
import yaml import yaml
from litellm import model_list
from litellm.utils import (
get_max_tokens,
supports_function_calling,
supports_parallel_function_calling,
supports_vision,
)
from loguru import logger from loguru import logger
from pydantic import BaseModel from pydantic import BaseModel
@ -45,7 +52,6 @@ from swarms.schemas.base_schemas import (
ChatMessageResponse, ChatMessageResponse,
) )
from swarms.schemas.conversation_schema import ConversationSchema from swarms.schemas.conversation_schema import ConversationSchema
from swarms.schemas.llm_agent_schema import ModelConfigOrigin
from swarms.schemas.mcp_schemas import ( from swarms.schemas.mcp_schemas import (
MCPConnection, MCPConnection,
) )
@ -422,7 +428,6 @@ class Agent:
mcp_config: Optional[MCPConnection] = None, mcp_config: Optional[MCPConnection] = None,
top_p: Optional[float] = 0.90, top_p: Optional[float] = 0.90,
conversation_schema: Optional[ConversationSchema] = None, conversation_schema: Optional[ConversationSchema] = None,
aditional_llm_config: Optional[ModelConfigOrigin] = None,
llm_base_url: Optional[str] = None, llm_base_url: Optional[str] = None,
llm_api_key: Optional[str] = None, llm_api_key: Optional[str] = None,
rag_config: Optional[RAGConfig] = None, rag_config: Optional[RAGConfig] = None,
@ -430,8 +435,8 @@ class Agent:
output_raw_json_from_tool_call: bool = False, output_raw_json_from_tool_call: bool = False,
summarize_multiple_images: bool = False, summarize_multiple_images: bool = False,
tool_retry_attempts: int = 3, tool_retry_attempts: int = 3,
speed_mode: str = None,
reasoning_prompt_on: bool = True, reasoning_prompt_on: bool = True,
dynamic_context_window: bool = True,
*args, *args,
**kwargs, **kwargs,
): ):
@ -562,7 +567,6 @@ class Agent:
self.mcp_config = mcp_config self.mcp_config = mcp_config
self.top_p = top_p self.top_p = top_p
self.conversation_schema = conversation_schema self.conversation_schema = conversation_schema
self.aditional_llm_config = aditional_llm_config
self.llm_base_url = llm_base_url self.llm_base_url = llm_base_url
self.llm_api_key = llm_api_key self.llm_api_key = llm_api_key
self.rag_config = rag_config self.rag_config = rag_config
@ -572,8 +576,8 @@ class Agent:
) )
self.summarize_multiple_images = summarize_multiple_images self.summarize_multiple_images = summarize_multiple_images
self.tool_retry_attempts = tool_retry_attempts self.tool_retry_attempts = tool_retry_attempts
self.speed_mode = speed_mode
self.reasoning_prompt_on = reasoning_prompt_on self.reasoning_prompt_on = reasoning_prompt_on
self.dynamic_context_window = dynamic_context_window
# Initialize the feedback # Initialize the feedback
self.feedback = [] self.feedback = []
@ -676,17 +680,15 @@ class Agent:
# Initialize the short term memory # Initialize the short term memory
memory = Conversation( memory = Conversation(
name=f"{self.agent_name}_conversation", name=f"{self.agent_name}_conversation",
system_prompt=prompt,
user=self.user_name, user=self.user_name,
rules=self.rules, rules=self.rules,
token_count=False, token_count=False,
message_id_on=False, message_id_on=False,
time_enabled=True, time_enabled=True,
) dynamic_context_window=self.dynamic_context_window,
tokenizer_model_name=self.model_name,
# Add the system prompt to the conversation context_length=self.context_length,
memory.add(
role="system",
content=prompt,
) )
return memory return memory
@ -888,11 +890,7 @@ class Agent:
Returns: Returns:
bool: True if model supports vision and image is provided, False otherwise. bool: True if model supports vision and image is provided, False otherwise.
""" """
from litellm.utils import (
supports_function_calling,
supports_parallel_function_calling,
supports_vision,
)
# Only check vision support if an image is provided # Only check vision support if an image is provided
if img is not None: if img is not None:
@ -1294,8 +1292,6 @@ class Agent:
self._handle_run_error(error) self._handle_run_error(error)
def __handle_run_error(self, error: any): def __handle_run_error(self, error: any):
import traceback
if self.autosave is True: if self.autosave is True:
self.save() self.save()
log_agent_data(self.to_dict()) log_agent_data(self.to_dict())
@ -1539,11 +1535,6 @@ class Agent:
raise raise
def reliability_check(self): def reliability_check(self):
from litellm import model_list
from litellm.utils import (
get_max_tokens,
supports_function_calling,
)
if self.system_prompt is None: if self.system_prompt is None:
logger.warning( logger.warning(

@ -1,21 +1,21 @@
import traceback
import concurrent.futures import concurrent.futures
import datetime import datetime
import inspect
import json import json
import os import os
import traceback
import uuid import uuid
from typing import ( from typing import (
TYPE_CHECKING, TYPE_CHECKING,
Any,
Dict, Dict,
List, List,
Literal,
Optional, Optional,
Union, Union,
Literal,
Any,
) )
import yaml import yaml
import inspect
from swarms.utils.any_to_str import any_to_str from swarms.utils.any_to_str import any_to_str
from swarms.utils.litellm_tokenizer import count_tokens from swarms.utils.litellm_tokenizer import count_tokens
@ -26,6 +26,18 @@ if TYPE_CHECKING:
from loguru import logger from loguru import logger
# Define available providers
providers = Literal[
"mem0",
"in-memory",
"supabase",
"redis",
"sqlite",
"duckdb",
"pulsar",
]
def generate_conversation_id(): def generate_conversation_id():
"""Generate a unique conversation ID.""" """Generate a unique conversation ID."""
return str(uuid.uuid4()) return str(uuid.uuid4())
@ -50,18 +62,6 @@ def get_conversation_dir():
return conversation_dir return conversation_dir
# Define available providers
providers = Literal[
"mem0",
"in-memory",
"supabase",
"redis",
"sqlite",
"duckdb",
"pulsar",
]
def _create_backend_conversation(backend: str, **kwargs): def _create_backend_conversation(backend: str, **kwargs):
""" """
Create a backend conversation instance based on the specified backend type. Create a backend conversation instance based on the specified backend type.
@ -183,9 +183,9 @@ class Conversation:
name: str = "conversation-test", name: str = "conversation-test",
system_prompt: Optional[str] = None, system_prompt: Optional[str] = None,
time_enabled: bool = False, time_enabled: bool = False,
autosave: bool = False, # Changed default to False autosave: bool = False,
save_filepath: str = None, save_filepath: str = None,
load_filepath: str = None, # New parameter to specify which file to load from load_filepath: str = None,
context_length: int = 8192, context_length: int = 8192,
rules: str = None, rules: str = None,
custom_rules_prompt: str = None, custom_rules_prompt: str = None,
@ -211,6 +211,8 @@ class Conversation:
redis_data_dir: Optional[str] = None, redis_data_dir: Optional[str] = None,
conversations_dir: Optional[str] = None, conversations_dir: Optional[str] = None,
export_method: str = "json", export_method: str = "json",
dynamic_context_window: bool = True,
caching: bool = True,
*args, *args,
**kwargs, **kwargs,
): ):
@ -249,6 +251,8 @@ class Conversation:
self.auto_persist = auto_persist self.auto_persist = auto_persist
self.redis_data_dir = redis_data_dir self.redis_data_dir = redis_data_dir
self.export_method = export_method self.export_method = export_method
self.dynamic_context_window = dynamic_context_window
self.caching = caching
if self.name is None: if self.name is None:
self.name = id self.name = id
@ -933,7 +937,15 @@ class Conversation:
# Fallback to in-memory implementation # Fallback to in-memory implementation
pass pass
elif self.dynamic_context_window is True:
return self.dynamic_auto_chunking()
else:
return self._return_history_as_string_worker()
def _return_history_as_string_worker(self):
formatted_messages = [] formatted_messages = []
for message in self.conversation_history: for message in self.conversation_history:
formatted_messages.append( formatted_messages.append(
f"{message['role']}: {message['content']}" f"{message['role']}: {message['content']}"
@ -1778,20 +1790,38 @@ class Conversation:
pass pass
self.conversation_history = [] self.conversation_history = []
def dynamic_auto_chunking(self):
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
# Slice the first difference number of messages and contents from the beginning of the conversation history
new_history = all_tokens[difference:]
return new_history
# # Example usage
# # conversation = Conversation() # Example usage
# conversation = Conversation(token_count=True) # conversation = Conversation()
# conversation = Conversation(token_count=True, context_length=14)
# conversation.add("user", "Hello, how are you?") # conversation.add("user", "Hello, how are you?")
# conversation.add("assistant", "I am doing well, thanks.") # conversation.add("assistant", "I am doing well, thanks.")
# conversation.add("user", "What is the weather in Tokyo?")
# print(conversation.dynamic_auto_chunking())
# # conversation.add( # # conversation.add(
# # "assistant", {"name": "tool_1", "output": "Hello, how are you?"} # # "assistant", {"name": "tool_1", "output": "Hello, how are you?"}
# # ) # )
# # print(conversation.return_json()) # print(conversation.return_json())
# # # print(conversation.get_last_message_as_string()) # # print(conversation.get_last_message_as_string())
# print(conversation.return_json()) # print(conversation.return_json())
# # # conversation.add("assistant", "I am doing well, thanks.") # # conversation.add("assistant", "I am doing well, thanks.")
# # # # print(conversation.to_json()) # # # print(conversation.to_json())
# # print(type(conversation.to_dict())) # print(type(conversation.to_dict()))
# # print(conversation.to_yaml()) # print(conversation.to_yaml())

Loading…
Cancel
Save