Skip to main content
Glama
8b-is
by 8b-is
safety.rs31.9 kB
//! Safety mechanisms for MEM8 consciousness simulation //! Implements critical protections against cognitive instability //! Based on MEM8 paper section: Safety Mechanisms and Consciousness Stability use crate::mem8::wave::MemoryWave; use std::collections::{HashMap, VecDeque}; use std::sync::{Arc, RwLock}; use std::time::{Duration, Instant}; /// The Custodian: Memory guard system preventing overload and instability pub struct Custodian { /// Safe repetition threshold pub safe_threshold: f32, /// Critical repetition threshold pub critical_threshold: f32, /// Memory pattern history pattern_history: RwLock<HashMap<u64, PatternTracker>>, /// Global resource limits resource_limits: ResourceLimits, } /// Pattern tracking for repetition detection struct PatternTracker { /// Pattern hash hash: u64, /// Repetition count count: usize, /// Last seen timestamp last_seen: Instant, /// Repetition intervals intervals: VecDeque<Duration>, } /// Resource limits to prevent overload struct ResourceLimits { /// Maximum active memories max_active_memories: usize, /// Maximum processing cycles per second max_cycles_per_second: usize, /// Maximum memory growth rate max_growth_rate: f32, } impl Default for Custodian { fn default() -> Self { Self::new() } } impl Custodian { pub fn new() -> Self { Self { safe_threshold: 5.0, critical_threshold: 10.0, pattern_history: RwLock::new(HashMap::new()), resource_limits: ResourceLimits { max_active_memories: 10_000, max_cycles_per_second: 1_000, max_growth_rate: 1.5, }, } } /// Guard memory access based on repetition score pub fn guard_memory(&self, memory: &MemoryWave) -> GuardDecision { let pattern_hash = self.calculate_pattern_hash(memory); let repetition_score = self.calculate_repetition_score(pattern_hash); if repetition_score < self.safe_threshold { GuardDecision::Allow } else if repetition_score < self.critical_threshold { GuardDecision::Throttle(self.calculate_throttle_factor(repetition_score)) } else { GuardDecision::Block(BlockReason::ExcessiveRepetition) } } /// Calculate hash for memory pattern fn calculate_pattern_hash(&self, memory: &MemoryWave) -> u64 { use std::collections::hash_map::DefaultHasher; use std::hash::{Hash, Hasher}; let mut hasher = DefaultHasher::new(); // Hash key characteristics ((memory.frequency * 100.0) as u32).hash(&mut hasher); ((memory.amplitude * 100.0) as u32).hash(&mut hasher); ((memory.valence * 100.0) as i32).hash(&mut hasher); hasher.finish() } /// Calculate repetition score for a pattern fn calculate_repetition_score(&self, pattern_hash: u64) -> f32 { let mut history = self.pattern_history.write().unwrap(); let now = Instant::now(); let tracker = history .entry(pattern_hash) .or_insert_with(|| PatternTracker { hash: pattern_hash, count: 0, last_seen: now, intervals: VecDeque::with_capacity(10), }); // Update tracker let interval = now.duration_since(tracker.last_seen); tracker.intervals.push_back(interval); if tracker.intervals.len() > 10 { tracker.intervals.pop_front(); } tracker.count += 1; tracker.last_seen = now; // Calculate score based on frequency and interval pattern let frequency_factor = tracker.count as f32 / 10.0; let interval_factor = if tracker.intervals.len() > 1 { let avg_interval = tracker .intervals .iter() .map(|d| d.as_secs_f32()) .sum::<f32>() / tracker.intervals.len() as f32; // Penalize rapid repetition (1.0 / (avg_interval + 0.1)).min(10.0) } else { 1.0 }; frequency_factor * interval_factor } /// Calculate throttle factor based on repetition score fn calculate_throttle_factor(&self, score: f32) -> f32 { let normalized = (score - self.safe_threshold) / (self.critical_threshold - self.safe_threshold); normalized.clamp(0.1, 0.9) } /// Check resource limits pub fn check_resources(&self, active_count: usize, growth_rate: f32) -> GuardDecision { if active_count > self.resource_limits.max_active_memories { GuardDecision::Block(BlockReason::MemoryOverload) } else if growth_rate > self.resource_limits.max_growth_rate { GuardDecision::Throttle(0.5) } else { GuardDecision::Allow } } } /// Guard decision types #[derive(Debug, Clone)] pub enum GuardDecision { /// Allow memory operation Allow, /// Throttle with factor (0.0 to 1.0) Throttle(f32), /// Block operation with reason Block(BlockReason), } /// Reasons for blocking memory operations #[derive(Debug, Clone)] pub enum BlockReason { ExcessiveRepetition, MemoryOverload, CognitiveLoop, ResourceExhaustion, } /// Repetition poisoning prevention system pub struct RepetitionPrevention { /// Pattern breaking threshold break_threshold: f32, /// Pattern history patterns: RwLock<Vec<PatternInstance>>, /// Noise generator for pattern breaking noise_level: f32, } #[derive(Clone)] struct PatternInstance { pattern: Vec<f32>, repeat_count: usize, last_seen: Instant, } impl Default for RepetitionPrevention { fn default() -> Self { Self::new() } } impl RepetitionPrevention { pub fn new() -> Self { Self { break_threshold: 0.8, patterns: RwLock::new(Vec::new()), noise_level: 0.1, } } /// Check if pattern breaking is needed pub fn check_pattern(&self, wave_sequence: &[f32]) -> PatternBreakDecision { let mut patterns = self.patterns.write().unwrap(); // Look for matching patterns for pattern in patterns.iter_mut() { if self.patterns_match(&pattern.pattern, wave_sequence) { pattern.repeat_count += 1; pattern.last_seen = Instant::now(); // Calculate break probability let p_break = self.calculate_break_probability(pattern.repeat_count); if p_break > self.break_threshold { return PatternBreakDecision::BreakPattern { noise_level: self.noise_level, shift_attention: true, suppress_duration: Duration::from_secs(5), }; } } } // Add new pattern patterns.push(PatternInstance { pattern: wave_sequence.to_vec(), repeat_count: 1, last_seen: Instant::now(), }); // Clean old patterns patterns.retain(|p| p.last_seen.elapsed() < Duration::from_secs(300)); PatternBreakDecision::Continue } /// Check if two patterns match fn patterns_match(&self, p1: &[f32], p2: &[f32]) -> bool { if p1.len() != p2.len() { return false; } let tolerance = 0.1; p1.iter() .zip(p2.iter()) .all(|(a, b)| (a - b).abs() < tolerance) } /// Calculate probability of breaking pattern fn calculate_break_probability(&self, repeat_count: usize) -> f32 { let threshold_count = 5.0; let lambda = 0.5; if repeat_count as f32 <= threshold_count { 0.0 } else { let excess = repeat_count as f32 - threshold_count; 1.0 - (-lambda * excess * excess).exp() } } } /// Decision on pattern breaking #[derive(Debug)] pub enum PatternBreakDecision { /// Continue normal processing Continue, /// Break the pattern BreakPattern { noise_level: f32, shift_attention: bool, suppress_duration: Duration, }, } /// High-emotional memory reintroduction system pub struct EmotionalMemoryTherapy { /// Target emotional level target_emotional_level: f32, /// Therapy time constant therapy_tau: Duration, /// Safety bounds max_amplification: f32, /// Active therapy sessions sessions: RwLock<HashMap<u64, TherapySession>>, } struct TherapySession { memory_id: u64, start_time: Instant, initial_amplitude: f32, target_amplitude: f32, current_phase: TherapyPhase, } #[derive(Debug, Clone)] enum TherapyPhase { Assessment, GradualExposure, Integration, Resolution, } impl Default for EmotionalMemoryTherapy { fn default() -> Self { Self::new() } } impl EmotionalMemoryTherapy { pub fn new() -> Self { Self { target_emotional_level: 0.7, therapy_tau: Duration::from_secs(300), max_amplification: 2.0, sessions: RwLock::new(HashMap::new()), } } /// Calculate reintroduction amplitude for therapeutic processing pub fn calculate_reintroduction(&self, memory: &MemoryWave, memory_id: u64) -> f32 { let mut sessions = self.sessions.write().unwrap(); let session = sessions.entry(memory_id).or_insert_with(|| TherapySession { memory_id, start_time: Instant::now(), initial_amplitude: memory.amplitude, target_amplitude: memory.amplitude * self.target_emotional_level, current_phase: TherapyPhase::Assessment, }); let elapsed = session.start_time.elapsed().as_secs_f32(); let tau = self.therapy_tau.as_secs_f32(); // Graduated exposure formula let base_amplitude = session.initial_amplitude; let exposure_factor = 1.0 - (-elapsed / tau).exp(); let emotion_ratio = (self.target_emotional_level / memory.arousal.max(0.1)).min(self.max_amplification); base_amplitude * exposure_factor * emotion_ratio } /// Check if memory needs therapeutic reintroduction pub fn needs_therapy(&self, memory: &MemoryWave) -> bool { // High emotional content with potential for blocking memory.arousal > 0.8 && memory.valence.abs() > 0.7 } /// Update therapy phase pub fn update_phase(&self, memory_id: u64, processing_success: bool) { let mut sessions = self.sessions.write().unwrap(); if let Some(session) = sessions.get_mut(&memory_id) { session.current_phase = match (&session.current_phase, processing_success) { (TherapyPhase::Assessment, true) => TherapyPhase::GradualExposure, (TherapyPhase::GradualExposure, true) => TherapyPhase::Integration, (TherapyPhase::Integration, true) => TherapyPhase::Resolution, (TherapyPhase::Resolution, _) => { // Therapy complete, remove session sessions.remove(&memory_id); return; } _ => session.current_phase.clone(), // No phase change on failure }; } } } /// Temporal blanket reintroduction for memory recovery pub struct TemporalBlanketRecovery { /// Suppression history suppression_history: RwLock<HashMap<u64, SuppressionRecord>>, /// Recovery parameters alpha: f32, beta: f32, } struct SuppressionRecord { memory_id: u64, suppression_time: Instant, original_blanket: f32, suppression_reason: String, } impl Default for TemporalBlanketRecovery { fn default() -> Self { Self::new() } } impl TemporalBlanketRecovery { pub fn new() -> Self { Self { suppression_history: RwLock::new(HashMap::new()), alpha: 0.1, // Decay rate for suppression beta: 0.5, // Need-based amplification } } /// Record memory suppression pub fn record_suppression(&self, memory_id: u64, original_blanket: f32, reason: String) { let mut history = self.suppression_history.write().unwrap(); history.insert( memory_id, SuppressionRecord { memory_id, suppression_time: Instant::now(), original_blanket, suppression_reason: reason, }, ); } /// Calculate restored temporal blanket value pub fn restore_blanket(&self, memory_id: u64, contextual_need: f32) -> Option<f32> { let history = self.suppression_history.read().unwrap(); if let Some(record) = history.get(&memory_id) { let elapsed = record.suppression_time.elapsed().as_secs_f32(); // Restoration formula from paper let decay_factor = (-self.alpha * elapsed).exp(); let need_factor = self.beta * contextual_need; let restored = record.original_blanket * decay_factor + need_factor; Some(restored.clamp(0.0, 1.0)) } else { None } } /// Check if memory should be restored pub fn should_restore(&self, memory_id: u64, contextual_importance: f32) -> bool { let history = self.suppression_history.read().unwrap(); if let Some(record) = history.get(&memory_id) { // Restore if sufficient time has passed and context demands it let min_suppression_time = Duration::from_secs(60); record.suppression_time.elapsed() > min_suppression_time && contextual_importance > 0.7 } else { false } } } /// Divergence tracking for anomaly detection pub struct DivergenceTracker { /// Baseline measurements baseline: RwLock<SystemBaseline>, /// Current measurements current: RwLock<SystemMeasurement>, /// Divergence thresholds thresholds: DivergenceThresholds, } #[derive(Clone)] struct SystemBaseline { relationship_values: HashMap<String, f32>, activity_levels: HashMap<String, f32>, emotional_state: EmotionalBaseline, established_at: Instant, } #[derive(Clone)] pub struct SystemMeasurement { pub relationship_values: HashMap<String, f32>, pub activity_levels: HashMap<String, f32>, pub emotional_state: EmotionalState, pub measured_at: Instant, } #[derive(Clone)] struct EmotionalBaseline { valence: f32, arousal: f32, coherence: f32, } #[derive(Clone)] pub struct EmotionalState { pub valence: f32, pub arousal: f32, pub coherence: f32, pub divergence: f32, } struct DivergenceThresholds { normal_max: f32, // 0-50 unusual_max: f32, // 51-150 high_risk_min: f32, // 151-255 } impl Default for DivergenceTracker { fn default() -> Self { Self::new() } } impl DivergenceTracker { pub fn new() -> Self { Self { baseline: RwLock::new(SystemBaseline { relationship_values: HashMap::new(), activity_levels: HashMap::new(), emotional_state: EmotionalBaseline { valence: 0.0, arousal: 0.5, coherence: 0.8, }, established_at: Instant::now(), }), current: RwLock::new(SystemMeasurement { relationship_values: HashMap::new(), activity_levels: HashMap::new(), emotional_state: EmotionalState { valence: 0.0, arousal: 0.5, coherence: 0.8, divergence: 0.0, }, measured_at: Instant::now(), }), thresholds: DivergenceThresholds { normal_max: 50.0, unusual_max: 150.0, high_risk_min: 151.0, }, } } /// Calculate divergence score (0-255) pub fn calculate_divergence(&self) -> u8 { let baseline = self.baseline.read().unwrap(); let current = self.current.read().unwrap(); let mut total_divergence = 0.0; // Relationship divergence for (key, baseline_val) in &baseline.relationship_values { if let Some(current_val) = current.relationship_values.get(key) { let r_diff = (current_val - baseline_val).abs(); total_divergence += 2.0 * r_diff; } } // Activity divergence for (key, baseline_val) in &baseline.activity_levels { if let Some(current_val) = current.activity_levels.get(key) { let a_diff = (current_val - baseline_val).abs(); total_divergence += a_diff; } } // Emotional divergence let e_diff = ((current.emotional_state.valence - baseline.emotional_state.valence).abs() + (current.emotional_state.arousal - baseline.emotional_state.arousal).abs() + (baseline.emotional_state.coherence - current.emotional_state.coherence).abs()) / 3.0; total_divergence += e_diff * 50.0; total_divergence.min(255.0) as u8 } /// Get divergence category pub fn get_divergence_category(&self) -> DivergenceCategory { let score = self.calculate_divergence(); match score { 0..=50 => DivergenceCategory::Normal, 51..=150 => DivergenceCategory::Unusual, 151..=255 => DivergenceCategory::HighRisk, } } /// Update measurement pub fn update_measurement(&self, measurement: SystemMeasurement) { let mut current = self.current.write().unwrap(); *current = measurement; } /// Reset baseline pub fn reset_baseline(&self) { let current = self.current.read().unwrap(); let mut baseline = self.baseline.write().unwrap(); baseline.relationship_values = current.relationship_values.clone(); baseline.activity_levels = current.activity_levels.clone(); baseline.emotional_state = EmotionalBaseline { valence: current.emotional_state.valence, arousal: current.emotional_state.arousal, coherence: current.emotional_state.coherence, }; baseline.established_at = Instant::now(); } } #[derive(Debug, Clone)] pub enum DivergenceCategory { Normal, // Safe variance Unusual, // Monitoring required HighRisk, // Immediate intervention } /// Collective emotional state tracker pub struct CollectiveEmotionalIntelligence { /// Individual emotional states individuals: RwLock<HashMap<String, IndividualState>>, /// Group psychological safety threshold safety_threshold: f32, /// Harmony calculator harmony_weights: HarmonyWeights, } #[derive(Clone)] struct IndividualState { id: String, emotional_state: EmotionalState, safety_level: f32, trust_coefficient: f32, last_update: Instant, } struct HarmonyWeights { emotional_resonance: f32, // 0.3 interaction_pattern: f32, // 0.25 trust_coefficient: f32, // 0.25 adaptation_rate: f32, // 0.2 } impl Default for CollectiveEmotionalIntelligence { fn default() -> Self { Self::new() } } impl CollectiveEmotionalIntelligence { pub fn new() -> Self { Self { individuals: RwLock::new(HashMap::new()), safety_threshold: 200.0 / 255.0, // From paper harmony_weights: HarmonyWeights { emotional_resonance: 0.3, interaction_pattern: 0.25, trust_coefficient: 0.25, adaptation_rate: 0.2, }, } } /// Calculate collective emotional state pub fn calculate_collective_state(&self) -> CollectiveState { let individuals = self.individuals.read().unwrap(); if individuals.is_empty() { return CollectiveState::default(); } // Calculate average emotional state let mut total_valence = 0.0; let mut total_arousal = 0.0; let mut min_safety: f32 = 1.0; for individual in individuals.values() { total_valence += individual.emotional_state.valence; total_arousal += individual.emotional_state.arousal; min_safety = min_safety.min(individual.safety_level); } let n = individuals.len() as f32; let avg_valence = total_valence / n; let avg_arousal = total_arousal / n; // Apply minimum safety as limiting factor (from paper) let collective_emotion = (avg_valence * min_safety, avg_arousal * min_safety); CollectiveState { emotional_valence: collective_emotion.0, emotional_arousal: collective_emotion.1, psychological_safety: min_safety, group_size: individuals.len(), harmony_score: self.calculate_harmony(), } } /// Calculate group harmony score fn calculate_harmony(&self) -> f32 { let individuals = self.individuals.read().unwrap(); if individuals.len() < 2 { return 1.0; // Perfect harmony with self } // Calculate components let emotional_resonance = self.calculate_emotional_resonance(&individuals); let interaction_quality = 0.8; // Placeholder - would track actual interactions let avg_trust = individuals .values() .map(|i| i.trust_coefficient) .sum::<f32>() / individuals.len() as f32; let adaptation_rate = 0.7; // Placeholder - would track learning rate // Weighted harmony score self.harmony_weights.emotional_resonance * emotional_resonance + self.harmony_weights.interaction_pattern * interaction_quality + self.harmony_weights.trust_coefficient * avg_trust + self.harmony_weights.adaptation_rate * adaptation_rate } /// Calculate emotional resonance between individuals fn calculate_emotional_resonance(&self, individuals: &HashMap<String, IndividualState>) -> f32 { let states: Vec<_> = individuals.values().collect(); let n = states.len(); if n < 2 { return 1.0; } let mut total_similarity = 0.0; let mut pairs = 0; for i in 0..n { for j in i + 1..n { let valence_diff = (states[i].emotional_state.valence - states[j].emotional_state.valence).abs(); let arousal_diff = (states[i].emotional_state.arousal - states[j].emotional_state.arousal).abs(); let similarity = 1.0 - (valence_diff + arousal_diff) / 2.0; total_similarity += similarity; pairs += 1; } } total_similarity / pairs as f32 } /// Update individual state pub fn update_individual( &self, id: String, emotional_state: EmotionalState, safety_level: f32, ) { let mut individuals = self.individuals.write().unwrap(); if let Some(individual) = individuals.get_mut(&id) { individual.emotional_state = emotional_state; individual.safety_level = safety_level; individual.last_update = Instant::now(); // Update trust coefficient based on consistency individual.trust_coefficient = (individual.trust_coefficient * 0.9 + 0.1).min(1.0); } else { individuals.insert( id.clone(), IndividualState { id, emotional_state, safety_level, trust_coefficient: 0.5, // Start at neutral trust last_update: Instant::now(), }, ); } } /// Check if psychological safety is maintained pub fn is_psychologically_safe(&self) -> bool { let collective = self.calculate_collective_state(); collective.psychological_safety >= self.safety_threshold } } #[derive(Debug, Default)] pub struct CollectiveState { pub emotional_valence: f32, pub emotional_arousal: f32, pub psychological_safety: f32, pub group_size: usize, pub harmony_score: f32, } /// Integrated safety system combining all mechanisms pub struct SafetySystem { pub custodian: Arc<Custodian>, pub repetition_prevention: Arc<RepetitionPrevention>, pub emotional_therapy: Arc<EmotionalMemoryTherapy>, pub temporal_recovery: Arc<TemporalBlanketRecovery>, pub divergence_tracker: Arc<DivergenceTracker>, pub collective_intelligence: Arc<CollectiveEmotionalIntelligence>, } impl Default for SafetySystem { fn default() -> Self { Self::new() } } impl SafetySystem { pub fn new() -> Self { Self { custodian: Arc::new(Custodian::new()), repetition_prevention: Arc::new(RepetitionPrevention::new()), emotional_therapy: Arc::new(EmotionalMemoryTherapy::new()), temporal_recovery: Arc::new(TemporalBlanketRecovery::new()), divergence_tracker: Arc::new(DivergenceTracker::new()), collective_intelligence: Arc::new(CollectiveEmotionalIntelligence::new()), } } /// Comprehensive safety check for memory operations pub fn check_memory_safety(&self, memory: &MemoryWave, memory_id: u64) -> SafetyAssessment { // Check with Custodian let guard_decision = self.custodian.guard_memory(memory); // Check divergence let divergence = self.divergence_tracker.get_divergence_category(); // Check collective safety let collectively_safe = self.collective_intelligence.is_psychologically_safe(); // Check if therapeutic intervention needed let needs_therapy = self.emotional_therapy.needs_therapy(memory); SafetyAssessment { guard_decision, divergence_category: divergence, collectively_safe, needs_therapy, recommendations: self.generate_recommendations(memory, memory_id), } } /// Generate safety recommendations fn generate_recommendations( &self, memory: &MemoryWave, memory_id: u64, ) -> Vec<SafetyRecommendation> { let mut recommendations = Vec::new(); // Check if memory was previously suppressed if self .temporal_recovery .should_restore(memory_id, memory.amplitude) { recommendations.push(SafetyRecommendation::RestoreSuppressedMemory); } // Check if pattern breaking needed let pattern_check = self .repetition_prevention .check_pattern(&[memory.frequency, memory.amplitude]); if matches!(pattern_check, PatternBreakDecision::BreakPattern { .. }) { recommendations.push(SafetyRecommendation::InjectNoiseToBreakPattern); } // Check if emotional therapy needed if memory.arousal > 0.9 && memory.valence.abs() > 0.8 { recommendations.push(SafetyRecommendation::ApplyGraduatedExposure); } recommendations } } #[derive(Debug)] pub struct SafetyAssessment { pub guard_decision: GuardDecision, pub divergence_category: DivergenceCategory, pub collectively_safe: bool, pub needs_therapy: bool, pub recommendations: Vec<SafetyRecommendation>, } #[derive(Debug, Clone)] pub enum SafetyRecommendation { RestoreSuppressedMemory, InjectNoiseToBreakPattern, ApplyGraduatedExposure, ReduceSystemLoad, IncreaseMonitoring, } #[cfg(test)] mod tests { use super::*; #[test] fn test_custodian_repetition_detection() { let custodian = Custodian::new(); let mut wave = MemoryWave::new(440.0, 0.8); wave.valence = 0.5; // First access should be allowed match custodian.guard_memory(&wave) { GuardDecision::Allow => {} _ => panic!("First access should be allowed"), } // Multiple rapid accesses should trigger throttling for _ in 0..10 { let _ = custodian.guard_memory(&wave); } match custodian.guard_memory(&wave) { GuardDecision::Throttle(_) | GuardDecision::Block(_) => {} GuardDecision::Allow => panic!("Repetitive access should be throttled or blocked"), } } #[test] fn test_pattern_breaking() { let prevention = RepetitionPrevention::new(); let pattern = vec![440.0, 0.8, 440.0, 0.8]; // Repeated patterns should trigger breaking for _ in 0..10 { let decision = prevention.check_pattern(&pattern); if matches!(decision, PatternBreakDecision::BreakPattern { .. }) { return; // Test passed } } panic!("Pattern breaking should have been triggered"); } #[test] fn test_emotional_therapy() { // Create therapy with shorter tau for testing let mut therapy = EmotionalMemoryTherapy::new(); therapy.therapy_tau = std::time::Duration::from_millis(100); // Short tau for test let mut wave = MemoryWave::new(600.0, 0.9); wave.arousal = 0.9; wave.valence = -0.8; assert!(therapy.needs_therapy(&wave)); // Wait for exposure to ramp up std::thread::sleep(std::time::Duration::from_millis(50)); let reintro = therapy.calculate_reintroduction(&wave, 123); assert!(reintro > 0.0, "reintro was {}", reintro); assert!(reintro <= wave.amplitude * therapy.max_amplification); } #[test] fn test_divergence_tracking() { let tracker = DivergenceTracker::new(); // Initial divergence should be minimal assert!(matches!( tracker.get_divergence_category(), DivergenceCategory::Normal )); // Update with divergent measurement let mut measurement = SystemMeasurement { relationship_values: HashMap::new(), activity_levels: HashMap::new(), emotional_state: EmotionalState { valence: 0.9, // High divergence from baseline arousal: 0.9, coherence: 0.2, divergence: 0.0, }, measured_at: Instant::now(), }; measurement .relationship_values .insert("test".to_string(), 0.9); measurement.activity_levels.insert("test".to_string(), 0.9); tracker.update_measurement(measurement); let divergence = tracker.calculate_divergence(); assert!(divergence > 0); } #[test] fn test_collective_emotional_intelligence() { let cei = CollectiveEmotionalIntelligence::new(); // Add individuals cei.update_individual( "user1".to_string(), EmotionalState { valence: 0.5, arousal: 0.6, coherence: 0.8, divergence: 0.0, }, 0.9, ); cei.update_individual( "user2".to_string(), EmotionalState { valence: 0.4, arousal: 0.5, coherence: 0.7, divergence: 0.0, }, 0.85, ); let collective = cei.calculate_collective_state(); assert_eq!(collective.group_size, 2); assert!(collective.psychological_safety > 0.0); assert!(collective.harmony_score > 0.0); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/8b-is/smart-tree'

If you have feedback or need assistance with the MCP directory API, please join our Discord server