"""Test script for Phase 3: Opinion Equilibria System""" import os import sys # Add src to path sys.path.insert(0, os.path.dirname(__file__)) from src.personas.database import PersonaDatabase from src.llm.anthropic_client import AnthropicClient from src.influence.network import InfluenceNetwork from src.influence.dynamics import OpinionDynamicsEngine from src.influence.equilibrium import EquilibriumDetector def test_phase3(): """Test Phase 3 components""" print("=" * 60) print("PHASE 3 OPINION EQUILIBRIA SYSTEM TEST") print("=" * 60) # 1. Load personas print("\n1. Loading personas...") persona_db = PersonaDatabase() persona_db.load_from_directory("data/personas") all_personas = persona_db.list_personas() print(f" ✓ Loaded {len(all_personas)} personas") # 2. Select test personas test_persona_ids = [p.persona_id for p in all_personas[:3]] test_personas = [persona_db.get_persona(pid) for pid in test_persona_ids] print(f"\n2. Selected test personas:") for p in test_personas: print(f" - {p.name} ({p.role})") # 3. Build influence network (scale-free) print("\n3. Building scale-free influence network...") influence_network = InfluenceNetwork(test_personas, network_type="scale_free") print(f" ✓ Created {influence_network.network_type} network with {len(influence_network.influence_matrix)} connections") # Show influence weights print("\n Influence weights (>0.5):") for (inf_id, infd_id), weight in influence_network.influence_matrix.items(): if weight.weight > 0.5: inf_name = next(p.name for p in test_personas if p.persona_id == inf_id) infd_name = next(p.name for p in test_personas if p.persona_id == infd_id) print(f" {inf_name} → {infd_name}: {weight.weight:.2f}") # 4. Network metrics print("\n4. Network metrics:") metrics = influence_network.calculate_network_metrics() print(f" Average influence: {metrics.average_influence:.2f}") print(f" Clustering coefficient: {metrics.clustering_coefficient:.2f}") print(f"\n Centrality scores:") for persona_id, score in metrics.centrality_scores.items(): name = next(p.name for p in test_personas if p.persona_id == persona_id) print(f" {name}: {score:.2f}") # 5. Initialize LLM client print("\n5. Initializing LLM client...") try: llm_client = AnthropicClient() print(" ✓ LLM client initialized") except Exception as e: print(f" ✗ Error: {e}") print(" Skipping opinion dynamics test (requires API key)") return # 6. Run opinion dynamics (2 rounds only for quick test) print("\n6. Running opinion dynamics simulation...") print(" (Testing with 2 rounds)") question = "Should we build a new bike lane on Main Street?" print(f" Question: {question}") engine = OpinionDynamicsEngine( persona_db=persona_db, llm_client=llm_client, max_workers=2, requests_per_minute=50, ) def progress_callback(message): print(f" {message}") try: results = engine.run_dynamics( persona_ids=test_persona_ids, question=question, max_rounds=2, # Just 2 rounds for testing convergence_threshold=0.1, progress_callback=progress_callback, ) print(f"\n ✓ Completed {len(results)} rounds") # Show results print("\n Round Results:") for round_result in results: print(f"\n Round {round_result.round_number}:") print(f" - Average position: {round_result.average_position:.2f}") print(f" - Total change: {round_result.total_change:.2f}") print(f" - Convergence: {round_result.convergence_metric:.2f}") for opinion in round_result.opinions: print(f"\n {opinion.persona_name}: {opinion.position.value}") if opinion.position_change is not None: print(f" Change: {opinion.position_change:+.2f}") # 7. Analyze equilibrium print("\n7. Analyzing equilibrium state...") detector = EquilibriumDetector(convergence_threshold=0.1) equilibrium = detector.analyze_equilibrium( results, influence_network, max_rounds=2 ) print(f"\n Equilibrium Summary:") print(f" - Reached: {equilibrium.reached_equilibrium}") print(f" - Total rounds: {equilibrium.total_rounds}") print(f" - Consensus strength: {equilibrium.consensus_strength:.0%}") print(f" - Majority position: {equilibrium.majority_position.value}") print(f" - Majority %: {equilibrium.majority_percentage:.0f}%") print(f" - Opinion clusters: {len(equilibrium.opinion_clusters)}") if equilibrium.opinion_leaders: print(f"\n Top Opinion Leader:") leader = equilibrium.opinion_leaders[0] print(f" - {leader['persona_name']}") print(f" - Leadership score: {leader['leadership_score']:.2f}") print("\n" + "=" * 60) print("✅ PHASE 3 TEST COMPLETE - ALL SYSTEMS OPERATIONAL!") print("=" * 60) except Exception as e: print(f"\n ✗ Error running simulation: {e}") import traceback traceback.print_exc() if __name__ == "__main__": test_phase3()