Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce Social Dynamics Simulation System module with LLMs #38

Merged
merged 2 commits into from
Nov 9, 2024

Conversation

leonvanbokhorst
Copy link
Owner

@leonvanbokhorst leonvanbokhorst commented Nov 9, 2024

Summary by Sourcery

New Features:

  • Introduce a Social Dynamics Simulation System module that models complex interpersonal dynamics, emotional states, and group decision-making processes using LLMs.

leonvanbokhorst and others added 2 commits November 9, 2024 07:57
Add sophisticated group decision-making and emotional simulation components:

- Add AdvancedDeliberation class for multi-phase group discussions
- Implement EmotionalAftermath for handling post-decision effects
- Add EmotionalLearning for agent adaptation over time
- Create comprehensive deliberation prompts and templates
- Add simulation scenario runner with complex agent interactions

The implementation includes:
- Multi-phase deliberation process
- Emotional pattern recognition
- Dynamic relationship adjustments
- Consensus building mechanics
- Detailed aftermath processing
- Agent learning and adaptation

This enhancement provides a more realistic simulation of group
dynamics and emotional intelligence in social agent interactions.
feat: Implement advanced group deliberation and emotional dynamics
Copy link
Contributor

sourcery-ai bot commented Nov 9, 2024

Reviewer's Guide by Sourcery

This PR introduces a sophisticated multi-agent social simulation system that models complex interpersonal dynamics, emotional states, and group decision-making processes. The system uses LLMs to generate realistic social interactions based on personality traits, emotional states, and social status. The implementation includes detailed classes for handling social agents, emotional states, group dynamics, decision-making processes, and conflict resolution.

Class diagram for Social Dynamics Simulation System

classDiagram
    class SocialAgent {
        +String id
        +SocialStatus status
        +Dict relationships
        +InteractionMemory memory
        +LLMInterface llm
        +PersonalityTraits personality
        +decide_interaction(other_agent, context) InteractionType
        +generate_interaction_text(other_agent, strategy, context) str
        +interact(other_agent, context) InteractionOutcome
    }

    class EnhancedSocialAgent {
        +EmotionalState emotional_state
        +InteractionStyle interaction_style
        +generate_interaction_text(other_agent, strategy, context) str
        +process_interaction_outcome(outcome, other_agent)
    }
    EnhancedSocialAgent --|> SocialAgent

    class SocialStatus {
        +float formal_rank
        +float influence
        +float respect
        +Dict expertise
        +compute_effective_status(context) float
    }

    class PersonalityTraits {
        +float extraversion
        +float agreeableness
        +float dominance
        +float openness
        +float stability
        +to_dict() Dict
    }

    class EmotionalState {
        +Enum Emotion
        +Dict current_emotions
        +update_emotion(emotion, intensity)
        +get_dominant_emotion() Tuple
    }

    class InteractionMemory {
        +List interactions
        +add_interaction(other_agent_id, interaction_text, outcome, emotional_state)
        +get_recent_interactions(n) List
        +get_interactions_with(agent_id) List
    }

    class LLMInterface {
        +String model
        +List conversation_history
        +generate(prompt) str
    }

    class GroupEmotionalDynamics {
        +List agents
        +Dict emotional_network
        +Dict group_emotion
        +List subgroups
        +List emotional_history
        +process_group_interaction(interaction) Dict
    }

    class AdvancedDeliberation {
        +GroupEmotionalDynamics group
        +DeliberationPhase current_phase
        +List phase_history
        +Dict emotional_insights
        +facilitate_phase(phase, context) PhaseOutcome
    }

    class EmotionalDecisionMaking {
        +GroupEmotionalDynamics group
        +List decision_history
        +Dict current_proposals
        +make_group_decision(proposal) DecisionOutcome
    }

    class EmotionalAftermath {
        +GroupEmotionalDynamics group
        +Dict active_effects
        +Dict learning_history
        +process_aftermath(event)
    }

    class DecisionProposal {
        +String topic
        +List options
        +EnhancedSocialAgent initiator
        +String context
        +float urgency
    }

    class DecisionOutcome {
        +String decision
        +float confidence
        +float consensus_level
        +Dict emotional_impact
        +List dissenting_agents
    }

    class GroupInteraction {
        +Type interaction_type
        +EnhancedSocialAgent initiator
        +Set participants
        +String context
        +execute()
    }

    class Conflict {
        +String id
        +Set participants
        +String trigger
        +Dict emotional_states
        +float intensity
        +String context
    }

    class AftermathEffect {
        +AftermathType effect_type
        +Tuple agents
        +float intensity
        +int duration
    }

    class EmotionalLearning {
        +EnhancedSocialAgent agent
        +Dict learned_patterns
        +float adaptation_rate
    }
Loading

File-Level Changes

Change Details Files
Implemented core social agent and emotional state management system
  • Created SocialStatus class to represent agent's social standing with multiple dimensions
  • Implemented PersonalityTraits class to define core personality dimensions
  • Added EmotionalState class to manage agent emotions and their intensities
  • Created InteractionMemory class to store and manage past interactions
src/esh_status_dynamics.py
Developed group decision-making and deliberation system
  • Implemented AdvancedDeliberation class for managing group decision-making phases
  • Created EmotionalDecisionMaking class for emotion-influenced group decisions
  • Added PhaseOutcome class to track deliberation results
  • Implemented decision proposal and outcome tracking
src/esh_status_dynamics.py
Added emotional aftermath and learning system
  • Created EmotionalAftermath class to handle post-decision emotional effects
  • Implemented EmotionalLearning class for tracking and applying emotional learning
  • Added aftermath effect tracking and processing
  • Implemented emotional pattern recognition and adaptation
src/esh_status_dynamics.py
Implemented simulation scenario runner and utilities
  • Created run_simulation_scenario function to execute complete simulations
  • Added utility functions for printing simulation results
  • Implemented scenario initialization with multiple agents
  • Added phase-by-phase simulation execution logic
src/esh_status_dynamics.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time. You can also use
    this command to specify where the summary should be inserted.

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@leonvanbokhorst leonvanbokhorst changed the title Update readme @sourcery-ai Nov 9, 2024
@sourcery-ai sourcery-ai bot changed the title @sourcery-ai Introduce Social Dynamics Simulation System module with LLMs Nov 9, 2024
@leonvanbokhorst leonvanbokhorst merged commit de1cf3a into main Nov 9, 2024
1 check passed
@leonvanbokhorst leonvanbokhorst deleted the update-readme branch November 9, 2024 07:06
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @leonvanbokhorst - I've reviewed your changes - here's some feedback:

Overall Comments:

  • Consider adding comprehensive test coverage to validate the emotional and social dynamics models. Unit tests for individual components and integration tests for multi-agent scenarios would help verify realistic behavior.
Here's what I looked at during the review
  • 🟡 General issues: 1 issue found
  • 🟢 Security: all looks good
  • 🟢 Testing: all looks good
  • 🟡 Complexity: 2 issues found
  • 🟢 Documentation: all looks good

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

# Normalize other emotions to maintain total intensity
self._normalize_emotions(emotion)

def _normalize_emotions(self, primary_emotion: Emotion) -> None:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: Add check for division by zero when normalizing emotions

When primary_emotion has the only non-zero value, total - self.current_emotions[primary_emotion] will be zero, causing a division by zero. Add a check to handle this case.

}


class EmotionalDecisionMaking:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (complexity): Consider extracting emotional processing logic into a dedicated EmotionalProcessor class to handle the emotional dynamics separately from decision making.

The EmotionalDecisionMaking class mixes emotional processing, agent interaction and decision logic in ways that make the code hard to follow. Consider extracting the emotional processing into a separate EmotionalProcessor class:

class EmotionalProcessor:
    def __init__(self, group: GroupEmotionalDynamics):
        self.group = group

    async def process_dynamics(
        self, 
        contributions: List[Dict[str, Any]]
    ) -> Dict[str, Dict[EmotionalState.Emotion, float]]:
        emotional_shifts = self._process_agent_emotions(contributions)
        await self._process_emotional_contagion(emotional_shifts)
        return emotional_shifts

    def _process_agent_emotions(
        self,
        contributions: List[Dict[str, Any]]
    ) -> Dict[str, Dict[EmotionalState.Emotion, float]]:
        shifts = {}
        for agent_id, agent_contribs in self._group_by_agent(contributions).items():
            shifts[agent_id] = self._calculate_agent_shift(agent_contribs)
        return shifts

Then simplify EmotionalDecisionMaking to use this processor:

class EmotionalDecisionMaking:
    def __init__(self, group: GroupEmotionalDynamics):
        self.group = group
        self.emotional_processor = EmotionalProcessor(group)

    async def _process_emotional_dynamics(
        self,
        contributions: List[Dict[str, Any]]
    ) -> Dict[str, Dict[EmotionalState.Emotion, float]]:
        return await self.emotional_processor.process_dynamics(contributions)

This separation of concerns makes the code more maintainable while preserving all functionality.

self.phase_history: List[Dict] = []
self.emotional_insights: Dict[str, List[str]] = {}

async def facilitate_phase(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (complexity): Consider extracting emotional processing logic into a dedicated service class to improve separation of concerns.

The AdvancedDeliberation class could be simplified by extracting the emotional processing into a separate service. This would reduce coupling and make the phase facilitation flow clearer. Consider:

class EmotionalProcessingService:
    def __init__(self, group: GroupEmotionalDynamics):
        self.group = group

    async def process_contributions(
        self, 
        contributions: List[Dict[str, Any]]
    ) -> Dict[str, Dict[EmotionalState.Emotion, float]]:
        emotional_shifts = {}
        for contribution in contributions:
            shifts = await self._process_single_contribution(contribution)
            emotional_shifts[contribution["agent_id"]] = shifts
        return emotional_shifts

class AdvancedDeliberation:
    def __init__(self, group: GroupEmotionalDynamics):
        self.group = group
        self.emotional_processor = EmotionalProcessingService(group)

    async def facilitate_phase(self, phase: DeliberationPhase, context: Dict) -> PhaseOutcome:
        prompts = self._generate_phase_prompts(phase, context)
        contributions = await self._gather_phase_contributions(prompts)

        # Cleaner emotional processing through dedicated service
        emotional_shifts = await self.emotional_processor.process_contributions(contributions)

        return self._evaluate_phase_outcome(contributions, emotional_shifts)

This refactoring:

  1. Separates emotional processing concerns
  2. Reduces method complexity in facilitate_phase
  3. Makes the code flow more linear and easier to follow
  4. Improves testability of emotional processing logic

Comment on lines +590 to +591
for emotion in group_emotions:
group_emotions[emotion] /= total_influence
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (code-quality): We've found these issues:

Suggested change
for emotion in group_emotions:
group_emotions[emotion] /= total_influence
for value in group_emotions.values():
value /= total_influence

pass

async def _propagate_emotions(
self, interaction: "GroupInteraction"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (code-quality): We've found these issues:

Comment on lines +2302 to +2305
# Determine phase outcome
outcome = self._evaluate_phase_outcome(contributions, emotional_shifts)

return outcome
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (code-quality): Inline variable that is immediately returned (inline-immediately-returned-variable)

Suggested change
# Determine phase outcome
outcome = self._evaluate_phase_outcome(contributions, emotional_shifts)
return outcome
return self._evaluate_phase_outcome(contributions, emotional_shifts)

Comment on lines +2467 to +2476
contextualized_prompts = []
for prompt in base_prompts:
contextualized_prompts.append(
f"Context: {context['situation']}\n"
f"Stakes: {context['stakes']}\n"
f"Timeline: {context['timeline']}\n\n"
f"{prompt}"
)

return contextualized_prompts
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (code-quality): We've found these issues:

Suggested change
contextualized_prompts = []
for prompt in base_prompts:
contextualized_prompts.append(
f"Context: {context['situation']}\n"
f"Stakes: {context['stakes']}\n"
f"Timeline: {context['timeline']}\n\n"
f"{prompt}"
)
return contextualized_prompts
return [
f"Context: {context['situation']}\nStakes: {context['stakes']}\nTimeline: {context['timeline']}\n\n{prompt}"
for prompt in base_prompts
]

Comment on lines +2583 to +2585
emotional_similarity = self._calculate_emotional_similarity(
contributions1[-1]["emotional_state"], contributions2[-1]["emotional_state"]
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (code-quality): Inline variable that is immediately returned (inline-immediately-returned-variable)

Comment on lines +2878 to +2883
patterns = {}

# Pattern: Response to interaction types
patterns["interaction_response"] = self._calculate_interaction_response(
interaction
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (code-quality): Merge dictionary assignment with declaration (merge-dict-assign)

Suggested change
patterns = {}
# Pattern: Response to interaction types
patterns["interaction_response"] = self._calculate_interaction_response(
interaction
)
patterns = {
"interaction_response": self._calculate_interaction_response(
interaction
)
}

Comment on lines +2912 to +2922
patterns = {}

# Pattern: Decision acceptance
patterns["decision_acceptance"] = (
1.0 if self.agent.id not in decision.dissenting_agents else 0.0
)

# Pattern: Consensus alignment
patterns["consensus_alignment"] = decision.consensus_level

return patterns
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (code-quality): We've found these issues:

Suggested change
patterns = {}
# Pattern: Decision acceptance
patterns["decision_acceptance"] = (
1.0 if self.agent.id not in decision.dissenting_agents else 0.0
)
# Pattern: Consensus alignment
patterns["consensus_alignment"] = decision.consensus_level
return patterns
return {
"decision_acceptance": (
1.0 if self.agent.id not in decision.dissenting_agents else 0.0
),
"consensus_alignment": decision.consensus_level,
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant