Spaces:
Running
Running
Blu3Orange
feat: Introduce argument direction handling and enhance conviction mechanics for juror interactions
373ff24
| """Juror configuration and memory models.""" | |
| from dataclasses import dataclass, field | |
| from typing import Literal | |
| class JurorConfig: | |
| """Configuration for a single juror agent.""" | |
| # Identity | |
| juror_id: str | |
| seat_number: int | |
| name: str | |
| emoji: str # For display until sprites ready | |
| # Personality (affects reasoning style) | |
| archetype: str # "rationalist", "empath", "cynic", etc. | |
| personality_prompt: str # Detailed persona prompt | |
| # Behavior modifiers | |
| stubbornness: float # 0.0-1.0, how hard to convince | |
| volatility: float # 0.0-1.0, how much conviction swings | |
| influence: float # 0.0-1.0, how persuasive to others | |
| verbosity: float = 0.5 # 0.0-1.0, how long their arguments are | |
| # Initial stance | |
| initial_lean: str = "neutral" # "prosecution", "defense", "neutral", etc. | |
| # Model configuration | |
| model_provider: str = "gemini" # "gemini", "openai", "anthropic", "local" | |
| model_id: str = "gemini-2.5-flash" # Specific model ID | |
| temperature: float = 0.7 | |
| # Tools (future expansion) | |
| tools: list[str] = field(default_factory=list) | |
| # Memory | |
| memory_window: int = 10 # How many turns to remember in detail | |
| def is_player(self) -> bool: | |
| """Check if this is the player seat.""" | |
| return self.archetype == "player" | |
| class ArgumentMemory: | |
| """Memory of a single argument heard.""" | |
| speaker_id: str | |
| content_summary: str | |
| argument_type: str | |
| persuasiveness: float # How convincing it was to this juror | |
| counter_points: list[str] = field(default_factory=list) # Thoughts against it | |
| round_heard: int = 0 | |
| class JurorMemory: | |
| """Memory state for a single juror.""" | |
| juror_id: str | |
| # Case understanding | |
| case_summary: str = "" | |
| key_evidence: list[str] = field(default_factory=list) | |
| evidence_interpretations: dict[str, str] = field(default_factory=dict) | |
| # Deliberation memory | |
| arguments_heard: list[ArgumentMemory] = field(default_factory=list) | |
| arguments_made: list[str] = field(default_factory=list) | |
| # Compressed history (replaces old arguments_heard entries) | |
| deliberation_summary: str = "" | |
| # Relationships | |
| opinions_of_others: dict[str, float] = field(default_factory=dict) | |
| # Internal state | |
| current_conviction: float = 0.5 # 0.0-1.0 | |
| conviction_history: list[float] = field(default_factory=list) | |
| reasoning_chain: list[str] = field(default_factory=list) | |
| doubts: list[str] = field(default_factory=list) | |
| def get_current_vote(self) -> Literal["guilty", "not_guilty"]: | |
| """Get vote based on current conviction with hysteresis.""" | |
| # If no history, use simple threshold | |
| if len(self.conviction_history) < 2: | |
| return "guilty" if self.current_conviction > 0.5 else "not_guilty" | |
| # Determine previous vote from previous conviction | |
| prev_conviction = self.conviction_history[-2] | |
| prev_vote_guilty = prev_conviction > 0.5 | |
| # Apply hysteresis thresholds to prevent flip-flopping | |
| if prev_vote_guilty: | |
| # Currently guilty - need to drop below 0.4 to flip | |
| return "not_guilty" if self.current_conviction < 0.4 else "guilty" | |
| else: | |
| # Currently not guilty - need to rise above 0.6 to flip | |
| return "guilty" if self.current_conviction > 0.6 else "not_guilty" | |
| def add_argument(self, argument: ArgumentMemory) -> None: | |
| """Add a heard argument to memory.""" | |
| self.arguments_heard.append(argument) | |
| def update_conviction(self, delta: float) -> None: | |
| """Update conviction score, clamping to valid range.""" | |
| self.current_conviction = max(0.0, min(1.0, self.current_conviction + delta)) | |
| self.conviction_history.append(self.current_conviction) | |
| def get_recent_arguments(self, count: int = 5) -> list[ArgumentMemory]: | |
| """Get the most recent arguments heard.""" | |
| return self.arguments_heard[-count:] if self.arguments_heard else [] | |