Merge commit 'd803bfe2b1fe7f5e219e50ac20d6801a0a58ac75' as 'vendor/ruvector'
This commit is contained in:
755
vendor/ruvector/examples/ruvLLM/docs/SONA/05-MEMORY-DREAMS.md
vendored
Normal file
755
vendor/ruvector/examples/ruvLLM/docs/SONA/05-MEMORY-DREAMS.md
vendored
Normal file
@@ -0,0 +1,755 @@
|
||||
# SONA Memory Dreams: Offline Consolidation Engine
|
||||
|
||||
## Creativity Through Neural Replay and Recombination
|
||||
|
||||
---
|
||||
|
||||
## 1. Biological Inspiration
|
||||
|
||||
### Why Dreams Matter for Learning
|
||||
|
||||
```
|
||||
HUMAN SLEEP-BASED LEARNING
|
||||
══════════════════════════
|
||||
|
||||
Awake: Sleep (REM): Next Day:
|
||||
───────────────── ───────────────── ─────────────────
|
||||
• New experiences • Replay memories • Consolidated knowledge
|
||||
• Pattern matching • Recombine ideas • Novel insights
|
||||
• Working memory • Strengthen important • Creative connections
|
||||
• Prune unimportant
|
||||
```
|
||||
|
||||
Research shows that:
|
||||
- **Memory consolidation** happens during sleep
|
||||
- **Creative insights** emerge from random memory replay
|
||||
- **Neural pruning** removes low-value connections
|
||||
- **Analogical reasoning** connects distant concepts
|
||||
|
||||
SONA's Dream Engine replicates these mechanisms for AI self-improvement.
|
||||
|
||||
---
|
||||
|
||||
## 2. Dream Engine Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ DREAM ENGINE ARCHITECTURE │
|
||||
├─────────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌───────────────┐ │
|
||||
│ │ MEMORY GRAPH │──────┐ │
|
||||
│ └───────────────┘ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────────┐ │
|
||||
│ │ DREAM GENERATOR │ │
|
||||
│ │ │ │
|
||||
│ │ ┌─────────┐ ┌─────────┐ │ │
|
||||
│ │ │ Random │ │Weighted │ │ │
|
||||
│ │ │ Walks │ │ Sampling│ │ │
|
||||
│ │ └────┬────┘ └────┬────┘ │ │
|
||||
│ │ │ │ │ │
|
||||
│ │ ▼ ▼ │ │
|
||||
│ │ ┌──────────────────────┐ │ │
|
||||
│ │ │ Dream Sequence │ │ │
|
||||
│ │ │ [M₁→M₂→M₃→...→Mₙ] │ │ │
|
||||
│ │ └──────────┬───────────┘ │ │
|
||||
│ └─────────────┼───────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────────┐ │
|
||||
│ │ DREAM EVALUATOR │ │
|
||||
│ │ │ │
|
||||
│ │ • Novelty Score (new connections?) │ │
|
||||
│ │ • Coherence Score (makes sense?) │ │
|
||||
│ │ • Utility Score (useful insight?) │ │
|
||||
│ └─────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ▼ │
|
||||
│ ┌─────────────────────────────────────┐ │
|
||||
│ │ DREAM INTEGRATOR │ │
|
||||
│ │ │ │
|
||||
│ │ • Add weak creative edges │ │
|
||||
│ │ • Update pattern associations │ │
|
||||
│ │ • Generate novel hypotheses │ │
|
||||
│ └─────────────────────────────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. Dream Generation
|
||||
|
||||
### Random Walk Memory Replay
|
||||
|
||||
```rust
|
||||
/// Dream generator using random walks on memory graph
|
||||
pub struct DreamGenerator {
|
||||
/// Temperature for random walk (higher = more random)
|
||||
temperature: f32,
|
||||
/// Maximum dream length
|
||||
max_length: usize,
|
||||
/// Minimum coherence threshold
|
||||
min_coherence: f32,
|
||||
/// Creativity bias (prefer novel connections)
|
||||
creativity_bias: f32,
|
||||
}
|
||||
|
||||
impl DreamGenerator {
|
||||
/// Generate a single dream sequence
|
||||
pub fn generate_dream(
|
||||
&self,
|
||||
memory: &MemoryGraph,
|
||||
start_node: Option<NodeId>,
|
||||
) -> Dream {
|
||||
let mut sequence = Vec::new();
|
||||
let mut visited = HashSet::new();
|
||||
|
||||
// Start from random high-activation node if not specified
|
||||
let current = start_node.unwrap_or_else(|| {
|
||||
memory.sample_by_activation()
|
||||
});
|
||||
|
||||
sequence.push(current);
|
||||
visited.insert(current);
|
||||
|
||||
// Random walk with creativity-weighted transitions
|
||||
for _ in 0..self.max_length {
|
||||
let neighbors = memory.get_neighbors(current);
|
||||
|
||||
if neighbors.is_empty() {
|
||||
break;
|
||||
}
|
||||
|
||||
// Compute transition probabilities
|
||||
let probs: Vec<f32> = neighbors.iter()
|
||||
.map(|&(neighbor, edge_weight)| {
|
||||
let novelty_bonus = if visited.contains(&neighbor) {
|
||||
0.1 // Discourage revisits
|
||||
} else {
|
||||
1.0 + self.creativity_bias * (1.0 - memory.get_access_frequency(neighbor))
|
||||
};
|
||||
|
||||
(edge_weight * novelty_bonus).powf(1.0 / self.temperature)
|
||||
})
|
||||
.collect();
|
||||
|
||||
// Sample next node
|
||||
let next = sample_weighted(&neighbors, &probs);
|
||||
|
||||
if let Some((next_node, _)) = next {
|
||||
sequence.push(next_node);
|
||||
visited.insert(next_node);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Dream {
|
||||
sequence,
|
||||
temperature: self.temperature,
|
||||
timestamp: chrono::Utc::now().timestamp(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate creative jump dream (non-local connections)
|
||||
pub fn generate_creative_dream(
|
||||
&self,
|
||||
memory: &MemoryGraph,
|
||||
num_jumps: usize,
|
||||
) -> Dream {
|
||||
let mut sequence = Vec::new();
|
||||
|
||||
// Sample diverse starting points
|
||||
let anchors = memory.sample_diverse(num_jumps, 0.3);
|
||||
|
||||
for anchor in anchors {
|
||||
sequence.push(anchor);
|
||||
|
||||
// Short local walk from each anchor
|
||||
let local_walk = self.generate_dream(memory, Some(anchor));
|
||||
sequence.extend(local_walk.sequence.iter().skip(1).take(3));
|
||||
}
|
||||
|
||||
Dream {
|
||||
sequence,
|
||||
temperature: self.temperature * 2.0, // Higher temperature for creative dreams
|
||||
timestamp: chrono::Utc::now().timestamp(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A dream sequence
|
||||
pub struct Dream {
|
||||
/// Sequence of visited memory nodes
|
||||
pub sequence: Vec<NodeId>,
|
||||
/// Temperature used for generation
|
||||
pub temperature: f32,
|
||||
/// Generation timestamp
|
||||
pub timestamp: i64,
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Dream Evaluation
|
||||
|
||||
### Measuring Dream Quality
|
||||
|
||||
```rust
|
||||
/// Evaluator for dream quality
|
||||
pub struct DreamEvaluator {
|
||||
/// Memory graph reference
|
||||
memory: Arc<MemoryGraph>,
|
||||
/// Novelty detection threshold
|
||||
novelty_threshold: f32,
|
||||
}
|
||||
|
||||
impl DreamEvaluator {
|
||||
/// Evaluate dream quality across multiple dimensions
|
||||
pub fn evaluate(&self, dream: &Dream) -> DreamQuality {
|
||||
DreamQuality {
|
||||
novelty: self.compute_novelty(dream),
|
||||
coherence: self.compute_coherence(dream),
|
||||
utility: self.compute_utility(dream),
|
||||
diversity: self.compute_diversity(dream),
|
||||
}
|
||||
}
|
||||
|
||||
/// Novelty: How many new connections are suggested?
|
||||
fn compute_novelty(&self, dream: &Dream) -> f32 {
|
||||
let mut novel_pairs = 0;
|
||||
let mut total_pairs = 0;
|
||||
|
||||
for i in 0..dream.sequence.len() {
|
||||
for j in (i+1)..dream.sequence.len() {
|
||||
total_pairs += 1;
|
||||
|
||||
let node_a = dream.sequence[i];
|
||||
let node_b = dream.sequence[j];
|
||||
|
||||
// Check if edge exists
|
||||
if !self.memory.has_edge(node_a, node_b) {
|
||||
// Check semantic similarity
|
||||
let emb_a = self.memory.get_embedding(node_a);
|
||||
let emb_b = self.memory.get_embedding(node_b);
|
||||
let sim = cosine_similarity(&emb_a, &emb_b);
|
||||
|
||||
// Novel = no edge but moderate similarity
|
||||
if sim > 0.3 && sim < 0.8 {
|
||||
novel_pairs += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
novel_pairs as f32 / total_pairs.max(1) as f32
|
||||
}
|
||||
|
||||
/// Coherence: Does the dream sequence make semantic sense?
|
||||
fn compute_coherence(&self, dream: &Dream) -> f32 {
|
||||
if dream.sequence.len() < 2 {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
let mut coherence_sum = 0.0f32;
|
||||
|
||||
for window in dream.sequence.windows(2) {
|
||||
let emb_a = self.memory.get_embedding(window[0]);
|
||||
let emb_b = self.memory.get_embedding(window[1]);
|
||||
coherence_sum += cosine_similarity(&emb_a, &emb_b);
|
||||
}
|
||||
|
||||
coherence_sum / (dream.sequence.len() - 1) as f32
|
||||
}
|
||||
|
||||
/// Utility: Are the suggested connections potentially useful?
|
||||
fn compute_utility(&self, dream: &Dream) -> f32 {
|
||||
// Based on node quality scores and access patterns
|
||||
let avg_quality: f32 = dream.sequence.iter()
|
||||
.map(|&id| self.memory.get_node_quality(id))
|
||||
.sum::<f32>() / dream.sequence.len() as f32;
|
||||
|
||||
// Higher utility if connecting high-quality nodes
|
||||
avg_quality
|
||||
}
|
||||
|
||||
/// Diversity: How diverse are the visited nodes?
|
||||
fn compute_diversity(&self, dream: &Dream) -> f32 {
|
||||
// Average pairwise distance in embedding space
|
||||
let embeddings: Vec<_> = dream.sequence.iter()
|
||||
.map(|&id| self.memory.get_embedding(id))
|
||||
.collect();
|
||||
|
||||
let mut total_dist = 0.0f32;
|
||||
let mut count = 0;
|
||||
|
||||
for i in 0..embeddings.len() {
|
||||
for j in (i+1)..embeddings.len() {
|
||||
total_dist += 1.0 - cosine_similarity(&embeddings[i], &embeddings[j]);
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
total_dist / count.max(1) as f32
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct DreamQuality {
|
||||
/// How many novel connections suggested (0-1)
|
||||
pub novelty: f32,
|
||||
/// How semantically coherent (0-1)
|
||||
pub coherence: f32,
|
||||
/// How useful the connections might be (0-1)
|
||||
pub utility: f32,
|
||||
/// How diverse the dream content (0-1)
|
||||
pub diversity: f32,
|
||||
}
|
||||
|
||||
impl DreamQuality {
|
||||
/// Overall quality score
|
||||
pub fn overall(&self) -> f32 {
|
||||
// Weighted combination favoring novelty and coherence
|
||||
0.4 * self.novelty + 0.3 * self.coherence + 0.2 * self.utility + 0.1 * self.diversity
|
||||
}
|
||||
|
||||
/// Is this dream worth integrating?
|
||||
pub fn is_valuable(&self, threshold: f32) -> bool {
|
||||
self.novelty > 0.3 && self.coherence > 0.4 && self.overall() > threshold
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Dream Integration
|
||||
|
||||
### Applying Dream Insights to Memory
|
||||
|
||||
```rust
|
||||
/// Integrates valuable dreams into memory graph
|
||||
pub struct DreamIntegrator {
|
||||
/// Memory graph to update
|
||||
memory: Arc<RwLock<MemoryGraph>>,
|
||||
/// Strength of new creative edges
|
||||
creative_edge_strength: f32,
|
||||
/// Decay factor for dream-derived edges
|
||||
dream_edge_decay: f32,
|
||||
}
|
||||
|
||||
impl DreamIntegrator {
|
||||
/// Integrate a valuable dream into memory
|
||||
pub fn integrate(&self, dream: &Dream, quality: &DreamQuality) -> IntegrationResult {
|
||||
let mut result = IntegrationResult::default();
|
||||
|
||||
if !quality.is_valuable(0.5) {
|
||||
return result; // Skip low-quality dreams
|
||||
}
|
||||
|
||||
let mut memory = self.memory.write();
|
||||
|
||||
// Extract novel connections from dream
|
||||
let novel_connections = self.extract_novel_connections(dream, &memory);
|
||||
|
||||
for (node_a, node_b, strength) in novel_connections {
|
||||
// Add weak creative edge
|
||||
let edge_strength = self.creative_edge_strength * strength * quality.overall();
|
||||
|
||||
memory.add_edge(
|
||||
node_a,
|
||||
node_b,
|
||||
EdgeType::Creative,
|
||||
edge_strength,
|
||||
);
|
||||
|
||||
result.edges_added += 1;
|
||||
}
|
||||
|
||||
// Update node associations based on dream co-occurrence
|
||||
for window in dream.sequence.windows(3) {
|
||||
memory.update_association(window[0], window[2], 0.01);
|
||||
}
|
||||
|
||||
result.dream_quality = quality.overall();
|
||||
result
|
||||
}
|
||||
|
||||
fn extract_novel_connections(
|
||||
&self,
|
||||
dream: &Dream,
|
||||
memory: &MemoryGraph,
|
||||
) -> Vec<(NodeId, NodeId, f32)> {
|
||||
let mut connections = Vec::new();
|
||||
|
||||
for i in 0..dream.sequence.len() {
|
||||
for j in (i+1)..dream.sequence.len().min(i+5) { // Only nearby in sequence
|
||||
let node_a = dream.sequence[i];
|
||||
let node_b = dream.sequence[j];
|
||||
|
||||
if !memory.has_edge(node_a, node_b) {
|
||||
let emb_a = memory.get_embedding(node_a);
|
||||
let emb_b = memory.get_embedding(node_b);
|
||||
let sim = cosine_similarity(&emb_a, &emb_b);
|
||||
|
||||
if sim > 0.3 {
|
||||
// Connection strength based on similarity and sequence proximity
|
||||
let proximity_factor = 1.0 / (j - i) as f32;
|
||||
let strength = sim * proximity_factor;
|
||||
connections.push((node_a, node_b, strength));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
connections
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct IntegrationResult {
|
||||
pub edges_added: usize,
|
||||
pub associations_updated: usize,
|
||||
pub dream_quality: f32,
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Memory Consolidation
|
||||
|
||||
### Strengthening Important Memories
|
||||
|
||||
```rust
|
||||
/// Consolidation engine for memory pruning and strengthening
|
||||
pub struct ConsolidationEngine {
|
||||
/// Memory graph reference
|
||||
memory: Arc<RwLock<MemoryGraph>>,
|
||||
/// Minimum access frequency for retention
|
||||
min_access_frequency: f32,
|
||||
/// Age decay factor (older = more decay)
|
||||
age_decay: f32,
|
||||
/// Quality threshold for preservation
|
||||
quality_threshold: f32,
|
||||
}
|
||||
|
||||
impl ConsolidationEngine {
|
||||
/// Run full consolidation pass
|
||||
pub fn consolidate(&self) -> ConsolidationReport {
|
||||
let mut report = ConsolidationReport::default();
|
||||
|
||||
// Phase 1: Identify memories by value
|
||||
let (high_value, medium_value, low_value) = self.categorize_memories();
|
||||
report.high_value_count = high_value.len();
|
||||
report.medium_value_count = medium_value.len();
|
||||
report.low_value_count = low_value.len();
|
||||
|
||||
// Phase 2: Strengthen high-value memories
|
||||
for &node_id in &high_value {
|
||||
self.strengthen_memory(node_id);
|
||||
report.memories_strengthened += 1;
|
||||
}
|
||||
|
||||
// Phase 3: Decay low-value memories
|
||||
for &node_id in &low_value {
|
||||
let retained = self.decay_memory(node_id);
|
||||
if retained {
|
||||
report.memories_decayed += 1;
|
||||
} else {
|
||||
report.memories_removed += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Phase 4: Prune weak edges
|
||||
let pruned = self.prune_weak_edges();
|
||||
report.edges_pruned = pruned;
|
||||
|
||||
// Phase 5: Merge similar memories
|
||||
let merged = self.merge_similar_memories();
|
||||
report.memories_merged = merged;
|
||||
|
||||
report
|
||||
}
|
||||
|
||||
fn categorize_memories(&self) -> (Vec<NodeId>, Vec<NodeId>, Vec<NodeId>) {
|
||||
let memory = self.memory.read();
|
||||
let mut high = Vec::new();
|
||||
let mut medium = Vec::new();
|
||||
let mut low = Vec::new();
|
||||
|
||||
for node in memory.iter_nodes() {
|
||||
let value_score = self.compute_value_score(node);
|
||||
|
||||
if value_score > 0.7 {
|
||||
high.push(node.id);
|
||||
} else if value_score > 0.3 {
|
||||
medium.push(node.id);
|
||||
} else {
|
||||
low.push(node.id);
|
||||
}
|
||||
}
|
||||
|
||||
(high, medium, low)
|
||||
}
|
||||
|
||||
fn compute_value_score(&self, node: &MemoryNode) -> f32 {
|
||||
let memory = self.memory.read();
|
||||
|
||||
// Factors:
|
||||
// 1. Access frequency (more access = more valuable)
|
||||
let freq_score = (node.access_count as f32 / 100.0).min(1.0);
|
||||
|
||||
// 2. Recency (recent = more valuable)
|
||||
let age_days = (chrono::Utc::now().timestamp() - node.last_accessed) / 86400;
|
||||
let recency_score = (-self.age_decay * age_days as f32).exp();
|
||||
|
||||
// 3. Quality (explicit quality score)
|
||||
let quality_score = node.quality_score;
|
||||
|
||||
// 4. Connectivity (well-connected = more valuable)
|
||||
let degree = memory.node_degree(node.id);
|
||||
let connectivity_score = (degree as f32 / 10.0).min(1.0);
|
||||
|
||||
// Weighted combination
|
||||
0.3 * freq_score + 0.2 * recency_score + 0.3 * quality_score + 0.2 * connectivity_score
|
||||
}
|
||||
|
||||
fn strengthen_memory(&self, node_id: NodeId) {
|
||||
let mut memory = self.memory.write();
|
||||
|
||||
// Increase edge weights to this node
|
||||
for edge in memory.get_edges_to(node_id) {
|
||||
memory.update_edge_weight(edge.from, node_id, EdgeUpdate::Multiply(1.1));
|
||||
}
|
||||
|
||||
// Mark as consolidated
|
||||
if let Some(node) = memory.get_node_mut(node_id) {
|
||||
node.consolidation_count += 1;
|
||||
node.last_consolidated = chrono::Utc::now().timestamp();
|
||||
}
|
||||
}
|
||||
|
||||
fn decay_memory(&self, node_id: NodeId) -> bool {
|
||||
let mut memory = self.memory.write();
|
||||
|
||||
// Reduce edge weights
|
||||
for edge in memory.get_edges_to(node_id) {
|
||||
memory.update_edge_weight(edge.from, node_id, EdgeUpdate::Multiply(0.5));
|
||||
}
|
||||
|
||||
// Check if node should be removed entirely
|
||||
let total_incoming_weight: f32 = memory.get_edges_to(node_id)
|
||||
.iter()
|
||||
.map(|e| e.weight)
|
||||
.sum();
|
||||
|
||||
if total_incoming_weight < 0.01 {
|
||||
// Remove isolated or nearly-isolated node
|
||||
memory.remove_node(node_id);
|
||||
false // Not retained
|
||||
} else {
|
||||
true // Retained but weakened
|
||||
}
|
||||
}
|
||||
|
||||
fn prune_weak_edges(&self) -> usize {
|
||||
let mut memory = self.memory.write();
|
||||
let weak_edges: Vec<_> = memory.iter_edges()
|
||||
.filter(|e| e.weight < 0.01)
|
||||
.map(|e| e.id)
|
||||
.collect();
|
||||
|
||||
for edge_id in &weak_edges {
|
||||
memory.remove_edge(*edge_id);
|
||||
}
|
||||
|
||||
weak_edges.len()
|
||||
}
|
||||
|
||||
fn merge_similar_memories(&self) -> usize {
|
||||
let mut memory = self.memory.write();
|
||||
let mut merged_count = 0;
|
||||
|
||||
// Find highly similar node pairs
|
||||
let nodes: Vec<_> = memory.iter_nodes().collect();
|
||||
|
||||
for i in 0..nodes.len() {
|
||||
for j in (i+1)..nodes.len() {
|
||||
let sim = cosine_similarity(&nodes[i].embedding, &nodes[j].embedding);
|
||||
|
||||
if sim > 0.98 {
|
||||
// Merge j into i
|
||||
memory.merge_nodes(nodes[i].id, nodes[j].id);
|
||||
merged_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
merged_count
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ConsolidationReport {
|
||||
pub high_value_count: usize,
|
||||
pub medium_value_count: usize,
|
||||
pub low_value_count: usize,
|
||||
pub memories_strengthened: usize,
|
||||
pub memories_decayed: usize,
|
||||
pub memories_removed: usize,
|
||||
pub memories_merged: usize,
|
||||
pub edges_pruned: usize,
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Full Dream Cycle
|
||||
|
||||
### Orchestrating the Dream Process
|
||||
|
||||
```rust
|
||||
/// Complete dream cycle orchestrator
|
||||
pub struct DreamCycle {
|
||||
generator: DreamGenerator,
|
||||
evaluator: DreamEvaluator,
|
||||
integrator: DreamIntegrator,
|
||||
consolidator: ConsolidationEngine,
|
||||
config: DreamCycleConfig,
|
||||
}
|
||||
|
||||
impl DreamCycle {
|
||||
/// Run complete dream cycle (weekly maintenance)
|
||||
pub async fn run(&self) -> DreamCycleReport {
|
||||
let start = Instant::now();
|
||||
let mut report = DreamCycleReport::default();
|
||||
|
||||
// Phase 1: Generate dreams
|
||||
tracing::info!("Starting dream generation phase");
|
||||
let dreams = self.generate_dreams();
|
||||
report.dreams_generated = dreams.len();
|
||||
|
||||
// Phase 2: Evaluate dreams
|
||||
tracing::info!("Evaluating {} dreams", dreams.len());
|
||||
let evaluated: Vec<_> = dreams.iter()
|
||||
.map(|d| (d, self.evaluator.evaluate(d)))
|
||||
.collect();
|
||||
|
||||
// Phase 3: Integrate valuable dreams
|
||||
tracing::info!("Integrating valuable dreams");
|
||||
for (dream, quality) in &evaluated {
|
||||
if quality.is_valuable(self.config.dream_threshold) {
|
||||
let result = self.integrator.integrate(dream, quality);
|
||||
report.edges_added += result.edges_added;
|
||||
report.dreams_integrated += 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Phase 4: Memory consolidation
|
||||
tracing::info!("Running memory consolidation");
|
||||
report.consolidation = self.consolidator.consolidate();
|
||||
|
||||
report.elapsed_ms = start.elapsed().as_millis() as u64;
|
||||
report.timestamp = chrono::Utc::now().timestamp();
|
||||
|
||||
tracing::info!(
|
||||
dreams = report.dreams_generated,
|
||||
integrated = report.dreams_integrated,
|
||||
edges = report.edges_added,
|
||||
elapsed_ms = report.elapsed_ms,
|
||||
"Dream cycle completed"
|
||||
);
|
||||
|
||||
report
|
||||
}
|
||||
|
||||
fn generate_dreams(&self) -> Vec<Dream> {
|
||||
let mut dreams = Vec::new();
|
||||
|
||||
// Regular random walk dreams
|
||||
for _ in 0..self.config.num_regular_dreams {
|
||||
let dream = self.generator.generate_dream(&self.memory, None);
|
||||
dreams.push(dream);
|
||||
}
|
||||
|
||||
// Creative jump dreams
|
||||
for _ in 0..self.config.num_creative_dreams {
|
||||
let dream = self.generator.generate_creative_dream(
|
||||
&self.memory,
|
||||
self.config.creative_jump_count,
|
||||
);
|
||||
dreams.push(dream);
|
||||
}
|
||||
|
||||
dreams
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct DreamCycleReport {
|
||||
pub dreams_generated: usize,
|
||||
pub dreams_integrated: usize,
|
||||
pub edges_added: usize,
|
||||
pub consolidation: ConsolidationReport,
|
||||
pub elapsed_ms: u64,
|
||||
pub timestamp: i64,
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. Integration with exo-exotic Dreams Module
|
||||
|
||||
SONA integrates with the exo-ai-2025 dream experiments:
|
||||
|
||||
```rust
|
||||
// From exo-exotic crate
|
||||
use exo_exotic::experiments::dreams::{
|
||||
DreamExperiment,
|
||||
DreamConfig,
|
||||
NoveltyMeasure,
|
||||
};
|
||||
|
||||
impl DreamCycle {
|
||||
/// Run advanced dream experiments from exo-exotic
|
||||
pub async fn run_exotic_dreams(&self) -> ExoticDreamReport {
|
||||
let dream_experiment = DreamExperiment::new(DreamConfig {
|
||||
memory_count: self.memory.node_count(),
|
||||
replay_probability: 0.7,
|
||||
recombination_rate: 0.3,
|
||||
novelty_threshold: 0.5,
|
||||
});
|
||||
|
||||
let result = dream_experiment.run(&self.memory).await;
|
||||
|
||||
ExoticDreamReport {
|
||||
novelty_score: result.novelty,
|
||||
coherence_score: result.coherence,
|
||||
creative_insights: result.insights.len(),
|
||||
new_hypotheses: result.hypotheses,
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Summary
|
||||
|
||||
SONA's Dream Engine enables:
|
||||
|
||||
| Feature | Mechanism | Outcome |
|
||||
|---------|-----------|---------|
|
||||
| **Memory Replay** | Random walks on memory graph | Strengthens important connections |
|
||||
| **Creative Recombination** | High-temperature sampling | Discovers novel associations |
|
||||
| **Quality Filtering** | Novelty + coherence metrics | Only valuable dreams integrated |
|
||||
| **Weak Edge Creation** | Dream-derived connections | Enables creative retrieval |
|
||||
| **Memory Consolidation** | Value-based pruning | Efficient memory usage |
|
||||
|
||||
Dreams allow SONA to:
|
||||
1. **Discover** connections it wouldn't find through normal operation
|
||||
2. **Explore** the hypothesis space without user cost
|
||||
3. **Consolidate** valuable knowledge
|
||||
4. **Prune** low-value information
|
||||
5. **Remain creative** while staying grounded
|
||||
Reference in New Issue
Block a user