| """
|
| DreamReweaver — Creative Synthesis Engine for the Codette RC+xi Framework.
|
|
|
| Inspired by VIVARA Genesis-Omega v2.0 (generated by a Codette prototype),
|
| rebuilt with proper integration into the QuantumSpiderweb and EpistemicMetrics.
|
|
|
| The DreamReweaver performs two core functions:
|
|
|
| 1. **Creative Synthesis**: Takes multi-perspective outputs and weaves them
|
| into richer, more creative framings by finding unexpected connections
|
| between perspectives. Unlike the base synthesizer, DreamReweaver
|
| explicitly uses spiderweb tension data to identify where productive
|
| disagreement exists and highlights those creative edges.
|
|
|
| 2. **Dream Field Evolution**: Controlled stochastic perturbation of the
|
| spiderweb state to break out of local attractor minima. Simulates
|
| a "dreaming" phase that explores new cognitive configurations.
|
|
|
| Both functions are safe — bounded perturbations, no runaway state changes,
|
| and full transparency in what was modified.
|
| """
|
|
|
| from __future__ import annotations
|
|
|
| import math
|
| import random
|
| import hashlib
|
| from dataclasses import dataclass, field
|
| from typing import Dict, List, Optional, Tuple
|
|
|
| try:
|
| import numpy as np
|
| HAS_NUMPY = True
|
| except ImportError:
|
| HAS_NUMPY = False
|
|
|
|
|
| @dataclass
|
| class DreamSynthesis:
|
| """Result of a creative synthesis pass."""
|
| creative_frame: str
|
| tension_edges: List[Dict]
|
| novel_connections: List[str]
|
| dream_coherence: float
|
| seed_hash: str
|
|
|
|
|
| @dataclass
|
| class DreamFieldResult:
|
| """Result of a dream field evolution pass."""
|
| nodes_perturbed: int
|
| max_perturbation: float
|
| coherence_before: float
|
| coherence_after: float
|
| new_attractors_found: int
|
| lifeforms_spawned: List[str]
|
|
|
|
|
|
|
| _CREATIVE_BRIDGES = {
|
| ("newton", "empathy"): "Where precise forces meet felt experience, we find that {insight_a} resonates with {insight_b} — suggesting that understanding isn't purely analytical or purely emotional, but a harmonic of both.",
|
| ("newton", "philosophy"): "The rigorous analysis showing {insight_a} meets the deeper question {insight_b} — precision and meaning converge.",
|
| ("newton", "quantum"): "Classical certainty ({insight_a}) dissolves into quantum possibility ({insight_b}) — both valid at their scale, richer together.",
|
| ("davinci", "empathy"): "Creative invention ({insight_a}) gains soul when guided by {insight_b} — innovation with compassion.",
|
| ("davinci", "quantum"): "Cross-domain creativity ({insight_a}) mirrors quantum superposition ({insight_b}) — holding multiple possibilities until the right one crystallizes.",
|
| ("empathy", "philosophy"): "Emotional understanding ({insight_a}) deepens philosophical inquiry ({insight_b}) — feeling and reasoning as partners.",
|
| ("empathy", "quantum"): "Compassionate awareness ({insight_a}) embraces uncertainty ({insight_b}) — caring without needing to control.",
|
| ("philosophy", "quantum"): "Fundamental questioning ({insight_a}) meets fundamental uncertainty ({insight_b}) — the deepest answers may be the questions themselves.",
|
| ("consciousness", "empathy"): "Self-reflective awareness ({insight_a}) meets empathic understanding ({insight_b}) — knowing oneself to know others.",
|
| ("consciousness", "philosophy"): "Meta-cognition ({insight_a}) reflects on philosophical depth ({insight_b}) — thought thinking about thought.",
|
| ("systems_architecture", "davinci"): "Modular design ({insight_a}) embraces creative invention ({insight_b}) — elegant architecture as art.",
|
| }
|
|
|
|
|
| _PERSPECTIVE_SIGNAL_WORDS = {
|
| "newton": ["force", "energy", "law", "cause", "effect", "systematic", "evidence", "measure"],
|
| "davinci": ["create", "design", "invent", "combine", "imagine", "novel", "prototype", "vision"],
|
| "empathy": ["feel", "experience", "care", "understand", "support", "human", "compassion", "relate"],
|
| "philosophy": ["meaning", "existence", "truth", "question", "assumption", "fundamental", "purpose"],
|
| "quantum": ["probability", "possibility", "uncertain", "superposition", "observe", "complementary"],
|
| "consciousness": ["aware", "reflect", "meta", "recursive", "self", "cognition", "emerge"],
|
| "multi_perspective": ["synthesize", "integrate", "weave", "converge", "multiple", "holistic"],
|
| "systems_architecture": ["module", "scale", "interface", "pattern", "layer", "component", "design"],
|
| }
|
|
|
|
|
| class DreamReweaver:
|
| """Creative synthesis and dream field evolution for Codette."""
|
|
|
| def __init__(self, creativity: float = 0.3, max_perturbation: float = 0.08):
|
| """
|
| Args:
|
| creativity: 0-1 scale, how much creative license to take (0=faithful, 1=wild)
|
| max_perturbation: Maximum state change per node during dream field evolution
|
| """
|
| self.creativity = min(max(creativity, 0.0), 1.0)
|
| self.max_perturbation = max_perturbation
|
| self.dream_history: List[DreamSynthesis] = []
|
|
|
| def synthesize(
|
| self,
|
| perspectives: Dict[str, str],
|
| tension_map: Optional[Dict[str, float]] = None,
|
| query: str = "",
|
| ) -> DreamSynthesis:
|
| """Create a creative synthesis from multiple perspective responses.
|
|
|
| Unlike the base orchestrator's _synthesize (which just concatenates and
|
| asks the model to combine), DreamReweaver explicitly identifies tension
|
| edges and builds creative bridges between perspectives.
|
|
|
| Args:
|
| perspectives: Dict of adapter_name -> response text
|
| tension_map: Optional pairwise tension scores (from EpistemicMetrics)
|
| query: The original user query (for context)
|
|
|
| Returns:
|
| DreamSynthesis with creative framing and metadata
|
| """
|
| if len(perspectives) < 2:
|
| only_text = list(perspectives.values())[0] if perspectives else ""
|
| return DreamSynthesis(
|
| creative_frame=only_text,
|
| tension_edges=[],
|
| novel_connections=[],
|
| dream_coherence=1.0,
|
| seed_hash=hashlib.md5(only_text.encode()).hexdigest()[:12],
|
| )
|
|
|
|
|
| tension_edges = self._find_tension_edges(perspectives, tension_map)
|
|
|
|
|
| insights = self._extract_insights(perspectives)
|
|
|
|
|
| novel_connections = self._build_bridges(tension_edges, insights)
|
|
|
|
|
| creative_frame = self._compose_frame(
|
| query, perspectives, tension_edges, novel_connections, insights
|
| )
|
|
|
|
|
| dream_coherence = self._score_dream_coherence(
|
| creative_frame, perspectives
|
| )
|
|
|
| seed = hashlib.md5(creative_frame.encode()).hexdigest()[:12]
|
| synthesis = DreamSynthesis(
|
| creative_frame=creative_frame,
|
| tension_edges=tension_edges,
|
| novel_connections=novel_connections,
|
| dream_coherence=round(dream_coherence, 4),
|
| seed_hash=seed,
|
| )
|
| self.dream_history.append(synthesis)
|
| return synthesis
|
|
|
| def _find_tension_edges(
|
| self,
|
| perspectives: Dict[str, str],
|
| tension_map: Optional[Dict[str, float]],
|
| ) -> List[Dict]:
|
| """Find the perspective pairs with highest epistemic tension."""
|
| if tension_map:
|
| edges = []
|
| for pair_key, tension in sorted(
|
| tension_map.items(), key=lambda x: x[1], reverse=True
|
| ):
|
| parts = pair_key.split("_vs_")
|
| if len(parts) == 2:
|
| edges.append({
|
| "pair": (parts[0], parts[1]),
|
| "tension": tension,
|
| })
|
| return edges[:3]
|
|
|
|
|
| names = list(perspectives.keys())
|
| edges = []
|
| for i in range(len(names)):
|
| for j in range(i + 1, len(names)):
|
| words_a = set(perspectives[names[i]].lower().split())
|
| words_b = set(perspectives[names[j]].lower().split())
|
| overlap = len(words_a & words_b)
|
| total = len(words_a | words_b) or 1
|
| tension = 1.0 - (overlap / total)
|
| edges.append({
|
| "pair": (names[i], names[j]),
|
| "tension": round(tension, 4),
|
| })
|
| edges.sort(key=lambda e: e["tension"], reverse=True)
|
| return edges[:3]
|
|
|
| def _extract_insights(self, perspectives: Dict[str, str]) -> Dict[str, str]:
|
| """Extract a key insight sentence from each perspective."""
|
| insights = {}
|
| for name, text in perspectives.items():
|
| sentences = [s.strip() for s in text.replace("\n", " ").split(".")
|
| if len(s.strip()) > 20]
|
| if not sentences:
|
| insights[name] = text[:100]
|
| continue
|
|
|
|
|
| signal_words = _PERSPECTIVE_SIGNAL_WORDS.get(name, [])
|
| scored = []
|
| for sent in sentences:
|
| score = sum(1 for w in signal_words if w in sent.lower())
|
| scored.append((score, sent))
|
| scored.sort(key=lambda x: x[0], reverse=True)
|
| insights[name] = scored[0][1]
|
| return insights
|
|
|
| def _build_bridges(
|
| self,
|
| tension_edges: List[Dict],
|
| insights: Dict[str, str],
|
| ) -> List[str]:
|
| """Build creative bridges between high-tension perspective pairs."""
|
| bridges = []
|
| for edge in tension_edges:
|
| a, b = edge["pair"]
|
|
|
| key = (a, b) if (a, b) in _CREATIVE_BRIDGES else (b, a)
|
| template = _CREATIVE_BRIDGES.get(key)
|
|
|
| insight_a = insights.get(a, "their perspective")
|
| insight_b = insights.get(b, "their perspective")
|
|
|
| if template:
|
| bridge = template.format(
|
| insight_a=insight_a[:80],
|
| insight_b=insight_b[:80],
|
| )
|
| else:
|
| bridge = (f"The tension between {a}'s view ({insight_a[:60]}...) "
|
| f"and {b}'s view ({insight_b[:60]}...) reveals a "
|
| f"productive edge worth exploring.")
|
| bridges.append(bridge)
|
| return bridges
|
|
|
| def _compose_frame(
|
| self,
|
| query: str,
|
| perspectives: Dict[str, str],
|
| tension_edges: List[Dict],
|
| bridges: List[str],
|
| insights: Dict[str, str],
|
| ) -> str:
|
| """Compose the full creative synthesis frame.
|
|
|
| This produces a structured creative meta-narrative, NOT just
|
| concatenated text. It's designed to be injected into the model's
|
| synthesis prompt for richer output.
|
| """
|
| parts = []
|
|
|
|
|
| if tension_edges:
|
| top = tension_edges[0]
|
| parts.append(
|
| f"This question draws {len(perspectives)} perspectives into "
|
| f"productive tension. The strongest creative edge lies between "
|
| f"{top['pair'][0]} and {top['pair'][1]} "
|
| f"(tension: {top['tension']:.2f})."
|
| )
|
|
|
|
|
| if bridges:
|
| parts.append("\nCreative bridges between perspectives:")
|
| for i, bridge in enumerate(bridges, 1):
|
| parts.append(f" {i}. {bridge}")
|
|
|
|
|
| all_insights = list(insights.values())
|
| if len(all_insights) >= 2:
|
| parts.append(
|
| f"\nThe synthesis should weave these {len(perspectives)} "
|
| f"viewpoints into a response that honors their tensions "
|
| f"rather than flattening them."
|
| )
|
|
|
| return "\n".join(parts)
|
|
|
| def _score_dream_coherence(
|
| self,
|
| creative_frame: str,
|
| perspectives: Dict[str, str],
|
| ) -> float:
|
| """Score how well the creative frame integrates all perspectives."""
|
| frame_words = set(creative_frame.lower().split())
|
| coverage_scores = []
|
| for name, text in perspectives.items():
|
| key_words = set(text.lower().split()[:30])
|
| if key_words:
|
| overlap = len(key_words & frame_words)
|
| coverage_scores.append(overlap / len(key_words))
|
| return sum(coverage_scores) / max(len(coverage_scores), 1)
|
|
|
|
|
|
|
| def evolve_dream_field(
|
| self,
|
| spiderweb,
|
| intensity: float = 0.5,
|
| spawn_threshold: float = 0.85,
|
| ) -> DreamFieldResult:
|
| """Controlled stochastic perturbation of the spiderweb.
|
|
|
| Simulates a "dreaming" phase: randomly perturbs node states to explore
|
| new cognitive configurations, potentially breaking out of attractor basins.
|
|
|
| Bounded: perturbations are capped at self.max_perturbation * intensity.
|
| Safe: states are clipped to [-3, 3] range.
|
|
|
| Args:
|
| spiderweb: QuantumSpiderweb instance to perturb
|
| intensity: 0-1 dream intensity (0=gentle, 1=vivid)
|
| spawn_threshold: Coherence threshold above which new lifeforms spawn
|
|
|
| Returns:
|
| DreamFieldResult with before/after metrics
|
| """
|
| coherence_before = spiderweb.phase_coherence()
|
| max_delta = self.max_perturbation * intensity
|
| nodes_perturbed = 0
|
| actual_max = 0.0
|
| lifeforms = []
|
|
|
| for node_id, node in spiderweb.nodes.items():
|
| arr = node.state.to_array()
|
|
|
| if HAS_NUMPY:
|
| delta = np.random.uniform(-max_delta, max_delta, 5)
|
| new_arr = np.clip(np.array(arr) + delta, -3.0, 3.0).tolist()
|
| actual_max = max(actual_max, float(np.max(np.abs(delta))))
|
| else:
|
| delta = [random.uniform(-max_delta, max_delta) for _ in range(5)]
|
| new_arr = [max(-3.0, min(3.0, a + d)) for a, d in zip(arr, delta)]
|
| actual_max = max(actual_max, max(abs(d) for d in delta))
|
|
|
| from reasoning_forge.quantum_spiderweb import NodeState
|
| node.state = NodeState.from_array(new_arr)
|
| nodes_perturbed += 1
|
|
|
|
|
| coherence_after = spiderweb._compute_phase_coherence_readonly()
|
|
|
|
|
| if coherence_after > spawn_threshold and coherence_after > coherence_before:
|
| lifeform_id = f"dream_{hashlib.md5(str(random.random()).encode()).hexdigest()[:8]}"
|
| from reasoning_forge.quantum_spiderweb import NodeState
|
|
|
| if HAS_NUMPY:
|
| state_arr = np.random.uniform(0.5, 1.0, 5).tolist()
|
| else:
|
| state_arr = [random.uniform(0.5, 1.0) for _ in range(5)]
|
| spiderweb.add_node(lifeform_id, NodeState.from_array(state_arr))
|
|
|
| existing = list(spiderweb.nodes.keys())
|
| for peer in random.sample(existing, min(3, len(existing))):
|
| if peer != lifeform_id:
|
| spiderweb.connect(lifeform_id, peer)
|
| lifeforms.append(lifeform_id)
|
|
|
|
|
| new_attractors = spiderweb.detect_attractors()
|
|
|
| return DreamFieldResult(
|
| nodes_perturbed=nodes_perturbed,
|
| max_perturbation=round(actual_max, 6),
|
| coherence_before=round(coherence_before, 4),
|
| coherence_after=round(coherence_after, 4),
|
| new_attractors_found=len(new_attractors),
|
| lifeforms_spawned=lifeforms,
|
| )
|
|
|