| """ |
| Synthesis Engine - Combines all agent perspectives into a unified multi-perspective response. |
| |
| Takes the concept, all agent analyses, and critic feedback, then produces |
| a synthesized explanation that highlights how different perspectives complement |
| each other. Includes a Final Integrated Understanding section. |
| """ |
|
|
| import random |
| import re |
|
|
|
|
| class SynthesisEngine: |
| """Combines multi-agent analyses into coherent synthesized responses.""" |
|
|
| |
| _opening_templates = [ |
| ( |
| "To understand '{concept}' with genuine depth, we must examine it through " |
| "multiple lenses, each revealing structure that the others miss." |
| ), |
| ( |
| "'{concept}' resists single-framework analysis. Its full meaning emerges " |
| "only at the intersection of several distinct modes of reasoning." |
| ), |
| ( |
| "A comprehensive understanding of '{concept}' requires weaving together " |
| "insights from fundamentally different ways of thinking." |
| ), |
| ( |
| "No single perspective captures '{concept}' adequately. What follows is " |
| "an integrated analysis drawing on physics, philosophy, ethics, creativity, " |
| "and human experience." |
| ), |
| ( |
| "The richness of '{concept}' becomes apparent only when we hold multiple " |
| "analytical frameworks simultaneously and let them inform each other." |
| ), |
| ] |
|
|
| |
| _bridge_templates = [ |
| "Where {agent_a} reveals {insight_a}, {agent_b} adds the crucial dimension of {insight_b}.", |
| "The {agent_a} analysis and the {agent_b} analysis converge on a shared insight: {shared}.", |
| "What appears as {aspect_a} from the {agent_a} perspective is revealed as {aspect_b} when viewed through {agent_b}.", |
| "The tension between {agent_a}'s emphasis on {focus_a} and {agent_b}'s emphasis on {focus_b} is productive, not contradictory.", |
| "{agent_a} identifies the mechanism; {agent_b} identifies the meaning.", |
| "Combining {agent_a}'s structural analysis with {agent_b}'s human-centered analysis yields a fuller picture.", |
| ] |
|
|
| |
| _closing_templates = [ |
| ( |
| "**Final Integrated Understanding:** {concept} is simultaneously a " |
| "{physical_desc}, a {philosophical_desc}, a {ethical_desc}, a " |
| "{creative_desc}, and a {human_desc}. These are not competing descriptions " |
| "but complementary facets of a single complex reality. The most robust " |
| "understanding holds all five in view, using each to compensate for the " |
| "blind spots of the others." |
| ), |
| ( |
| "**Final Integrated Understanding:** The multi-perspective analysis reveals " |
| "that {concept} cannot be reduced to any single framework without distortion. " |
| "The physical analysis provides causal grounding, the philosophical analysis " |
| "excavates hidden assumptions, the ethical analysis maps the stakes, the " |
| "creative analysis opens new solution spaces, and the empathic analysis " |
| "anchors everything in lived human experience. Together they constitute " |
| "not a list of separate views but an integrated understanding richer than " |
| "any view alone." |
| ), |
| ( |
| "**Final Integrated Understanding:** What emerges from this multi-lens " |
| "examination of {concept} is not a single 'correct' interpretation but a " |
| "structured understanding of how different valid interpretations relate to " |
| "each other. The causal structure identified by physics, the meaning " |
| "structure identified by philosophy, the value structure identified by " |
| "ethics, the possibility structure identified by creative reasoning, and " |
| "the experience structure identified by empathy are all real and all " |
| "essential. Wisdom lies in knowing which lens to apply in which context " |
| "and how to translate insights between them." |
| ), |
| ] |
|
|
| def synthesize( |
| self, |
| concept: str, |
| analyses: dict[str, str], |
| critique: dict, |
| ) -> str: |
| """Produce a synthesized multi-perspective response. |
| |
| Args: |
| concept: The original concept. |
| analyses: Dict mapping agent_name -> analysis_text. |
| critique: Output from CriticAgent.evaluate_ensemble(). |
| |
| Returns: |
| A synthesized text of 200-400 words. |
| """ |
| sections = [] |
|
|
| |
| opening = random.choice(self._opening_templates).replace("{concept}", concept) |
| sections.append(opening) |
|
|
| |
| perspective_summaries = self._extract_perspective_summaries(analyses) |
| for agent_name, summary in perspective_summaries.items(): |
| sections.append(f"**{agent_name} perspective:** {summary}") |
|
|
| |
| bridges = self._generate_bridges(analyses, perspective_summaries) |
| if bridges: |
| sections.append("") |
| for bridge in bridges[:2]: |
| sections.append(bridge) |
|
|
| |
| critic_section = self._incorporate_critique(critique) |
| if critic_section: |
| sections.append("") |
| sections.append(critic_section) |
|
|
| |
| closing = self._generate_closing(concept, perspective_summaries) |
| sections.append("") |
| sections.append(closing) |
|
|
| raw_synthesis = "\n\n".join(sections) |
|
|
| |
| return self._trim_to_target(raw_synthesis, min_words=200, max_words=400) |
|
|
| def _extract_perspective_summaries( |
| self, analyses: dict[str, str] |
| ) -> dict[str, str]: |
| """Extract a 1-2 sentence summary from each agent's analysis.""" |
| summaries = {} |
| for agent_name, text in analyses.items(): |
| sentences = [s.strip() for s in re.split(r'(?<=[.!?])\s+', text) if s.strip()] |
| if len(sentences) >= 3: |
| |
| summary = " ".join(sentences[1:3]) |
| elif len(sentences) >= 1: |
| summary = sentences[0] |
| else: |
| summary = text[:200] |
|
|
| |
| words = summary.split() |
| if len(words) > 45: |
| summary = " ".join(words[:40]) + "..." |
| summaries[agent_name] = summary |
| return summaries |
|
|
| def _generate_bridges( |
| self, |
| analyses: dict[str, str], |
| summaries: dict[str, str], |
| ) -> list[str]: |
| """Generate cross-perspective bridge statements.""" |
| bridges = [] |
| agent_names = list(analyses.keys()) |
|
|
| |
| focus_map = { |
| "Newton": "causal mechanisms and measurable dynamics", |
| "Quantum": "uncertainty, probability, and the limits of definite knowledge", |
| "Ethics": "moral stakes, fairness, and human impact", |
| "Philosophy": "foundational assumptions and the structure of meaning", |
| "DaVinci": "creative possibilities and cross-domain innovation", |
| "Empathy": "emotional reality and lived human experience", |
| } |
|
|
| |
| if len(agent_names) >= 2: |
| pairs = [] |
| for i in range(len(agent_names)): |
| for j in range(i + 1, len(agent_names)): |
| pairs.append((agent_names[i], agent_names[j])) |
| random.shuffle(pairs) |
|
|
| for name_a, name_b in pairs[:3]: |
| focus_a = focus_map.get(name_a, "its analytical focus") |
| focus_b = focus_map.get(name_b, "its analytical focus") |
| template = random.choice(self._bridge_templates) |
|
|
| bridge = template.format( |
| agent_a=name_a, |
| agent_b=name_b, |
| insight_a=focus_a, |
| insight_b=focus_b, |
| shared="the importance of understanding the full system rather than isolated parts", |
| aspect_a="a structural feature", |
| aspect_b="a deeply human concern", |
| focus_a=focus_a, |
| focus_b=focus_b, |
| ) |
| bridges.append(bridge) |
|
|
| return bridges |
|
|
| def _incorporate_critique(self, critique: dict) -> str: |
| """Turn critic feedback into a synthesis-relevant observation.""" |
| parts = [] |
|
|
| if critique.get("missing_perspectives"): |
| gap = critique["missing_perspectives"][0] |
| |
| parts.append( |
| f"A notable gap in the analysis is the limited attention to " |
| f"{gap.split('lacks a ')[1].split(' perspective')[0] if 'lacks a ' in gap else 'additional'} " |
| f"dimensions, which future analysis should address." |
| ) |
|
|
| if critique.get("improvement_suggestions"): |
| suggestion = critique["improvement_suggestions"][0] |
| |
| words = suggestion.split() |
| if len(words) > 25: |
| suggestion = " ".join(words[:25]) + "..." |
| parts.append(f"The critic notes: {suggestion}") |
|
|
| overall = critique.get("overall_quality", 0) |
| if overall >= 0.75: |
| parts.append( |
| "Overall, the multi-perspective ensemble achieves strong analytical " |
| "coverage with good complementarity between viewpoints." |
| ) |
| elif overall >= 0.5: |
| parts.append( |
| "The ensemble provides reasonable coverage but would benefit from " |
| "deeper engagement between perspectives." |
| ) |
|
|
| return " ".join(parts) if parts else "" |
|
|
| def _generate_closing( |
| self, concept: str, summaries: dict[str, str] |
| ) -> str: |
| """Generate the Final Integrated Understanding section.""" |
| template = random.choice(self._closing_templates) |
|
|
| |
| descriptors = { |
| "physical_desc": "system governed by causal dynamics and conservation principles", |
| "philosophical_desc": "concept whose meaning depends on the framework from which it is examined", |
| "ethical_desc": "domain of genuine moral stakes affecting real people", |
| "creative_desc": "space of untapped possibilities waiting for cross-domain insight", |
| "human_desc": "lived experience with emotional texture that abstract analysis alone cannot capture", |
| } |
|
|
| result = template |
| result = result.replace("{concept}", concept) |
| for key, value in descriptors.items(): |
| result = result.replace("{" + key + "}", value) |
|
|
| return result |
|
|
| def _trim_to_target( |
| self, text: str, min_words: int = 200, max_words: int = 400 |
| ) -> str: |
| """Trim or pad text to fall within the target word range.""" |
| words = text.split() |
|
|
| if len(words) > max_words: |
| |
| lines = text.split("\n\n") |
| while len(" ".join(lines).split()) > max_words and len(lines) > 3: |
| |
| middle_indices = list(range(1, len(lines) - 1)) |
| if not middle_indices: |
| break |
| longest_idx = max(middle_indices, key=lambda i: len(lines[i].split())) |
| lines.pop(longest_idx) |
| return "\n\n".join(lines) |
|
|
| return text |
|
|