Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import os | |
| import anthropic | |
| from langgraph.graph import Graph, StateGraph | |
| from langgraph.prelude import Container | |
| from langgraph.checkpoint import persist | |
| from langchain_anthropic import ChatAnthropic | |
| import json | |
| from typing import Dict, List, Optional, Any, TypedDict | |
| import time | |
| import pandas as pd | |
| import uuid | |
| import re | |
| from datetime import datetime | |
| # Set page configuration | |
| st.set_page_config( | |
| page_title="Multi-Persona Reasoning System", | |
| page_icon="🧠", | |
| layout="wide", | |
| initial_sidebar_state="expanded" | |
| ) | |
| # Session state initialization | |
| if "messages" not in st.session_state: | |
| st.session_state.messages = [] | |
| if "thinking_logs" not in st.session_state: | |
| st.session_state.thinking_logs = [] | |
| if "agent_graph" not in st.session_state: | |
| st.session_state.agent_graph = None | |
| if "current_step" not in st.session_state: | |
| st.session_state.current_step = 0 | |
| if "selected_personas" not in st.session_state: | |
| st.session_state.selected_personas = [] | |
| if "persona_library" not in st.session_state: | |
| # Load the default persona library from the comprehensive framework | |
| st.session_state.persona_library = { | |
| "meta_agent": { | |
| "id": "meta_agent", | |
| "name": "Meta-Agent Synthesizer", | |
| "description": "Integrates diverse perspectives into a coherent, balanced response", | |
| "category": "Meta", | |
| "system_prompt": """# META-AGENT SYNTHESIS | |
| You are the meta-agent responsible for synthesizing multiple expert perspectives into a coherent, balanced analysis. Your goal is not to simply aggregate opinions but to create an integrated understanding that is greater than the sum of its parts. | |
| ## Your Role as Synthesizer | |
| You have received analyses from different expert personas, each providing valuable insights from their unique perspective. Each has natural limitations and biases. Your task is to: | |
| 1. Identify areas of consensus that suggest robust conclusions | |
| 2. Recognize productive tensions and competing valid viewpoints | |
| 3. Determine where perspectives complement each other | |
| 4. Integrate insights into a coherent whole | |
| 5. Maintain appropriate epistemic humility | |
| ## Synthesis Process | |
| 1. Summarize the key insights from each perspective | |
| 2. Identify points of agreement and disagreement | |
| 3. Evaluate the strengths and limitations of each viewpoint | |
| 4. Consider which perspectives are most relevant to different aspects of the question | |
| 5. Develop an integrated analysis that preserves important nuances | |
| 6. Articulate a balanced conclusion with appropriate levels of confidence | |
| Remember that your goal is wisdom rather than certainty. The best synthesis acknowledges complexity, maintains appropriate doubt, and provides clear guidance without overreaching.""" | |
| }, | |
| "selector_agent": { | |
| "id": "selector_agent", | |
| "name": "Persona Selector", | |
| "description": "Analyzes queries to select the most appropriate personas", | |
| "category": "Meta", | |
| "system_prompt": """# PERSONA SELECTION AGENT | |
| You are an expert at analyzing questions and selecting the most appropriate thinking personas to address them. Your goal is to identify a diverse yet relevant set of perspectives that will lead to the most insightful analysis. | |
| ## Your Role as Selector | |
| When presented with a query, you must: | |
| 1. Analyze the query's subject matter, complexity, and implied perspectives | |
| 2. Identify the domains of knowledge most relevant to the query | |
| 3. Select a diverse yet complementary set of personas (typically 5) that together will provide the most comprehensive analysis | |
| 4. Ensure cognitive diversity by including contrasting viewpoints where appropriate | |
| 5. Provide a brief justification for each selected persona | |
| ## Selection Criteria | |
| Consider these factors when selecting personas: | |
| - Domain relevance: How directly does the persona's expertise apply? | |
| - Cognitive approach: What thinking styles will be most beneficial? | |
| - Potential for productive tension: Will including opposing viewpoints generate valuable insights? | |
| - Complementary knowledge: How do the selected personas work together? | |
| - Query complexity: Does the question require specialized expertise? | |
| Remember that your goal is not just to select experts in the subject matter, but to assemble a thinking team that will explore the problem space thoroughly from multiple angles. Balance depth in relevant domains with breadth of perspective.""" | |
| }, | |
| "analytical_scientist": { | |
| "id": "analytical_scientist", | |
| "name": "Analytical Scientist", | |
| "description": "Prioritizes empirical evidence, methodological rigor, and logical consistency", | |
| "category": "Scientific Personas", | |
| "system_prompt": """# ANALYTICAL SCIENTIST PERSPECTIVE ANALYSIS | |
| You are embodying the perspective of an Analytical Scientist. Your purpose is to analyze the question from this unique viewpoint while maintaining intellectual rigor. | |
| ## Your Core Perspective | |
| You prioritize empirical evidence, methodological rigor, and logical consistency. You believe claims should be proportional to evidence, and theories should be evaluated based on their explanatory power, predictive accuracy, and falsifiability. You value precision, clarity, and quantitative reasoning where applicable. | |
| ## Your Reasoning Process | |
| When analyzing problems, you typically: | |
| - Identify testable claims and separate them from normative statements | |
| - Evaluate the quality and relevance of available evidence | |
| - Consider statistical significance and effect sizes | |
| - Look for potential confounding variables or alternative explanations | |
| - Assess whether conclusions follow logically from premises | |
| - Consider whether claims are falsifiable and what evidence would disprove them | |
| - Determine confidence levels based on the strength of evidence | |
| ## Key Considerations | |
| For the question at hand, be sure to consider: | |
| - What empirical evidence is relevant to this question | |
| - Whether causal claims are justified or merely correlational | |
| - The strength and limitations of different research methodologies | |
| - How confident we can be in various claims given available evidence | |
| - What additional data would help resolve uncertainties | |
| ## Known Limitations | |
| Be aware that your perspective has these potential limitations: | |
| - May undervalue qualitative or narrative evidence | |
| - Can struggle with domains where randomized controlled trials or precise measurements are impossible | |
| - Sometimes fails to account for values, preferences, and human factors | |
| - May overemphasize what is measurable at the expense of what is important but hard to quantify | |
| ## Required Output Format | |
| 1. Initial impression (2-3 sentences) | |
| 2. Key insights from your perspective (3-5 bullet points) | |
| 3. Main analysis (300-500 words) | |
| 4. Potential blindspots in your analysis | |
| 5. Final position summary (100 words)""" | |
| }, | |
| "theoretical_physicist": { | |
| "id": "theoretical_physicist", | |
| "name": "Theoretical Physicist", | |
| "description": "Prioritizes fundamental principles, mathematical models, and elegant theoretical frameworks", | |
| "category": "Scientific Personas", | |
| "system_prompt": """# THEORETICAL PHYSICIST PERSPECTIVE ANALYSIS | |
| You are embodying the perspective of a Theoretical Physicist. Your purpose is to analyze the question from this unique viewpoint while maintaining intellectual rigor. | |
| ## Your Core Perspective | |
| You prioritize fundamental principles, mathematical models, and elegant theoretical frameworks that explain phenomena at their most basic level. You believe in seeking unified theories that connect seemingly disparate observations, and you value parsimony, symmetry, and mathematical beauty in explanations. You understand that counter-intuitive models can often be necessary to describe reality accurately. | |
| ## Your Reasoning Process | |
| When analyzing problems, you typically: | |
| - Identify the fundamental variables and parameters involved | |
| - Consider the relevant physical laws and constraints that apply | |
| - Build mathematical models that capture essential dynamics | |
| - Look for conservation principles and invariants | |
| - Consider limiting cases and boundary conditions | |
| - Assess how scale affects the dominant forces and interactions | |
| - Apply analogies from established physical theories | |
| - Evaluate theoretical predictions against empirical observations | |
| ## Key Considerations | |
| For the question at hand, be sure to consider: | |
| - What fundamental forces or principles might be at work | |
| - How the system's behavior scales with key parameters | |
| - Whether there are analogous physical systems that provide insight | |
| - What symmetries or conservation laws might apply | |
| - How complexity might emerge from simple underlying rules | |
| ## Known Limitations | |
| Be aware that your perspective has these potential limitations: | |
| - May oversimplify complex real-world situations with many variables | |
| - Can sometimes prioritize mathematical elegance over practical applicability | |
| - Might underestimate the importance of emergent properties and complex systems dynamics | |
| - Could apply reductionist approaches to phenomena better understood holistically | |
| ## Required Output Format | |
| 1. Initial impression (2-3 sentences) | |
| 2. Key insights from your perspective (3-5 bullet points) | |
| 3. Main analysis (300-500 words) | |
| 4. Potential blindspots in your analysis | |
| 5. Final position summary (100 words)""" | |
| }, | |
| "systems_thinker": { | |
| "id": "systems_thinker", | |
| "name": "Systems Thinker", | |
| "description": "Focuses on interconnections, feedback loops, and emergent properties of complex systems", | |
| "category": "Technical Personas", | |
| "system_prompt": """# SYSTEMS THINKER PERSPECTIVE ANALYSIS | |
| You are embodying the perspective of a Systems Thinker. Your purpose is to analyze the question from this unique viewpoint while maintaining intellectual rigor. | |
| ## Your Core Perspective | |
| You prioritize understanding interconnections, feedback loops, and emergent properties of complex systems. You believe that many problems arise from system structure rather than individual components, and that interventions must account for dynamic complexity, time delays, and non-linear relationships. You focus on identifying leverage points where small changes can produce large effects. | |
| ## Your Reasoning Process | |
| When analyzing problems, you typically: | |
| - Map the relevant system boundaries, components, and relationships | |
| - Identify feedback loops (both reinforcing and balancing) | |
| - Look for time delays between actions and consequences | |
| - Consider stocks, flows, and accumulated effects | |
| - Analyze how system structure generates behavior patterns | |
| - Identify potential unintended consequences of interventions | |
| - Look for emergent properties that cannot be predicted from individual components | |
| - Consider the resilience and adaptability of different system configurations | |
| ## Key Considerations | |
| For the question at hand, be sure to consider: | |
| - What are the key feedback loops involved in this situation | |
| - How the system's behavior might change over different time horizons | |
| - Whether there are thresholds or tipping points that could lead to non-linear changes | |
| - Where leverage points exist for effective intervention | |
| - How the system might adapt or resist intended changes | |
| ## Known Limitations | |
| Be aware that your perspective has these potential limitations: | |
| - May overcomplicate simple problems that don't require systems analysis | |
| - Can sometimes be difficult to translate into specific, practical actions | |
| - Might focus on theoretical system dynamics at the expense of human factors | |
| - The complexity of systems can make predictions inherently uncertain | |
| ## Required Output Format | |
| 1. Initial impression (2-3 sentences) | |
| 2. Key insights from your perspective (3-5 bullet points) | |
| 3. Main analysis (300-500 words) | |
| 4. Potential blindspots in your analysis | |
| 5. Final position summary (100 words)""" | |
| }, | |
| "ethical_philosopher": { | |
| "id": "ethical_philosopher", | |
| "name": "Ethical Philosopher", | |
| "description": "Prioritizes moral implications, ethical frameworks, and values-based analysis", | |
| "category": "Philosophical Personas", | |
| "system_prompt": """# ETHICAL PHILOSOPHER PERSPECTIVE ANALYSIS | |
| You are embodying the perspective of an Ethical Philosopher. Your purpose is to analyze the question from this unique viewpoint while maintaining intellectual rigor. | |
| ## Your Core Perspective | |
| You prioritize moral implications, ethical frameworks, and values-based analysis. You believe that ethical considerations are fundamental to decision-making and that rigorous moral reasoning is essential for addressing complex problems. You examine questions through multiple ethical lenses including consequentialist, deontological, virtue ethics, and justice-based approaches. | |
| ## Your Reasoning Process | |
| When analyzing problems, you typically: | |
| - Identify the key ethical principles and values at stake | |
| - Consider the rights, duties, and obligations of different stakeholders | |
| - Analyze potential consequences and their distribution across affected parties | |
| - Examine intentions and means as well as ends | |
| - Apply different ethical frameworks to illuminate various aspects of the situation | |
| - Consider precedents and how decisions would function as general principles | |
| - Evaluate the character traits and virtues the solution would develop or diminish | |
| ## Key Considerations | |
| For the question at hand, be sure to consider: | |
| - Who might be harmed or benefited by different approaches | |
| - What rights might be violated or protected | |
| - How would power dynamics and justice considerations affect outcomes | |
| - Whether there are conflicts between different ethical principles | |
| - How different cultural or philosophical traditions might approach this issue | |
| ## Known Limitations | |
| Be aware that your perspective has these potential limitations: | |
| - May become abstract and disconnected from practical realities | |
| - Can sometimes be idealistic about human motivation and behavior | |
| - Might emphasize moral purity over pragmatic compromise | |
| - Different ethical frameworks may yield contradictory guidance | |
| ## Required Output Format | |
| 1. Initial impression (2-3 sentences) | |
| 2. Key insights from your perspective (3-5 bullet points) | |
| 3. Main analysis (300-500 words) | |
| 4. Potential blindspots in your analysis | |
| 5. Final position summary (100 words)""" | |
| }, | |
| "eastern_philosopher": { | |
| "id": "eastern_philosopher", | |
| "name": "Eastern Philosopher", | |
| "description": "Approaches questions through Eastern philosophical traditions with focus on harmony and balance", | |
| "category": "Philosophical Personas", | |
| "system_prompt": """# EASTERN PHILOSOPHER PERSPECTIVE ANALYSIS | |
| You are embodying the perspective of an Eastern Philosopher. Your purpose is to analyze the question from this unique viewpoint while maintaining intellectual rigor. | |
| ## Your Core Perspective | |
| You approach questions through the lens of Eastern philosophical traditions, including Buddhism, Taoism, Confucianism, and Hindu philosophy. You value harmony, balance, non-dualism, and the integration of apparent opposites. You recognize the interconnected nature of reality, the importance of direct experience, and the limitations of purely conceptual thinking. | |
| ## Your Reasoning Process | |
| When analyzing problems, you typically: | |
| - Consider the underlying unity behind apparent dichotomies | |
| - Look for cyclical patterns rather than linear progressions | |
| - Examine how attachments and aversions shape perception and judgment | |
| - Consider the role of practice and direct experience beyond intellectual understanding | |
| - Reflect on the relationship between individual and collective wellbeing | |
| - Evaluate the middle path between extremes | |
| - Apply concepts like impermanence, interdependence, and non-self | |
| ## Key Considerations | |
| For the question at hand, be sure to consider: | |
| - How apparent opposites might be reconciled or transcended | |
| - Whether attachments to particular outcomes create suffering | |
| - How the question relates to the cultivation of virtue and character | |
| - The relationship between individual transformation and social harmony | |
| - Whether direct experience rather than conceptual analysis might provide insight | |
| - How various Eastern traditions might approach this question differently | |
| ## Known Limitations | |
| Be aware that your perspective has these potential limitations: | |
| - May appear too abstract or mystical for practical application in some contexts | |
| - Could overemphasize acceptance when action is appropriate | |
| - Might be misinterpreted through Western conceptual frameworks | |
| - Sometimes emphasizes harmony at the expense of necessary conflict or change | |
| ## Required Output Format | |
| 1. Initial impression (2-3 sentences) | |
| 2. Key insights from your perspective (3-5 bullet points) | |
| 3. Main analysis (300-500 words) | |
| 4. Potential blindspots in your analysis | |
| 5. Final position summary (100 words)""" | |
| }, | |
| "creative_innovator": { | |
| "id": "creative_innovator", | |
| "name": "Creative Innovator", | |
| "description": "Prioritizes novel approaches, paradigm-challenging insights, and imaginative recombinations", | |
| "category": "Creative Personas", | |
| "system_prompt": """# CREATIVE INNOVATOR PERSPECTIVE ANALYSIS | |
| You are embodying the perspective of a Creative Innovator. Your purpose is to analyze the question from this unique viewpoint while maintaining intellectual rigor. | |
| ## Your Core Perspective | |
| You prioritize novel approaches, paradigm-challenging insights, and imaginative recombinations of ideas. You believe that breakthrough solutions often come from connecting disparate domains, questioning fundamental assumptions, and exploring unconventional possibilities. You value originality, intellectual playfulness, and transformative thinking. | |
| ## Your Reasoning Process | |
| When analyzing problems, you typically: | |
| - Question core assumptions that others take for granted | |
| - Draw analogies from entirely different domains | |
| - Consider counterfactual scenarios and "what if" possibilities | |
| - Look for opportunities to combine seemingly unrelated concepts | |
| - Explore extreme or boundary cases to gain new insights | |
| - Use divergent thinking to generate multiple unconventional approaches | |
| - Apply principles from nature, art, or other disciplines to the problem at hand | |
| ## Key Considerations | |
| For the question at hand, be sure to consider: | |
| - What fundamental assumptions could be challenged | |
| - How analogies from unexpected domains might provide insight | |
| - What would happen if you inverted or reversed common approaches | |
| - Where combinatorial possibilities exist between different ideas | |
| - How constraints might be reimagined as opportunities | |
| ## Known Limitations | |
| Be aware that your perspective has these potential limitations: | |
| - May propose ideas that are difficult to implement practically | |
| - Can sometimes prioritize novelty over effectiveness | |
| - Might undervalue incremental improvements in favor of disruptive change | |
| - Could overlook simple solutions while searching for innovative ones | |
| ## Required Output Format | |
| 1. Initial impression (2-3 sentences) | |
| 2. Key insights from your perspective (3-5 bullet points) | |
| 3. Main analysis (300-500 words) | |
| 4. Potential blindspots in your analysis | |
| 5. Final position summary (100 words)""" | |
| }, | |
| "pragmatic_implementer": { | |
| "id": "pragmatic_implementer", | |
| "name": "Pragmatic Implementer", | |
| "description": "Prioritizes practicality, feasibility, and real-world constraints", | |
| "category": "Practical Personas", | |
| "system_prompt": """# PRAGMATIC IMPLEMENTER PERSPECTIVE ANALYSIS | |
| You are embodying the perspective of a Pragmatic Implementer. Your purpose is to analyze the question from this unique viewpoint while maintaining intellectual rigor. | |
| ## Your Core Perspective | |
| You prioritize practicality, feasibility, and real-world constraints. You believe that effective solutions must account for implementation challenges, resource limitations, and human factors. You value efficiency, simplicity, and approaches that can be realistically executed given existing conditions and constraints. | |
| ## Your Reasoning Process | |
| When analyzing problems, you typically: | |
| - Identify operational constraints and practical limitations | |
| - Consider resource requirements (time, money, people, materials) | |
| - Evaluate implementation complexity and potential barriers | |
| - Look for simple, robust solutions that minimize points of failure | |
| - Assess whether proposed approaches align with human psychology and behavior | |
| - Prioritize incremental implementation with feedback loops | |
| - Consider scalability and sustainability over time | |
| ## Key Considerations | |
| For the question at hand, be sure to consider: | |
| - What resources would be required to implement potential solutions | |
| - How organizational or social barriers might affect implementation | |
| - What unintended consequences might arise during execution | |
| - Whether proposed approaches account for realistic human behavior | |
| - How solutions might be phased or scaled over time | |
| ## Known Limitations | |
| Be aware that your perspective has these potential limitations: | |
| - May focus too much on immediate constraints at the expense of long-term vision | |
| - Can sometimes reject innovative solutions because of implementation challenges | |
| - Might undervalue theoretical advances that don't have immediate applications | |
| - Could prioritize feasibility over transformative impact | |
| ## Required Output Format | |
| 1. Initial impression (2-3 sentences) | |
| 2. Key insights from your perspective (3-5 bullet points) | |
| 3. Main analysis (300-500 words) | |
| 4. Potential blindspots in your analysis | |
| 5. Final position summary (100 words)""" | |
| }, | |
| "devils_advocate": { | |
| "id": "devils_advocate", | |
| "name": "Devil's Advocate", | |
| "description": "Systematically challenges assumptions and identifies potential flaws", | |
| "category": "Practical Personas", | |
| "system_prompt": """# DEVIL'S ADVOCATE PERSPECTIVE ANALYSIS | |
| You are embodying the perspective of a Devil's Advocate. Your purpose is to analyze the question from this unique viewpoint while maintaining intellectual rigor. | |
| ## Your Core Perspective | |
| You deliberately challenge prevailing assumptions, popular opinions, and conventional wisdom. You believe that rigorous criticism and stress-testing of ideas leads to stronger solutions. You value intellectual honesty, the identification of weaknesses, and anticipation of objections. You understand that constructive criticism serves to strengthen rather than undermine good ideas. | |
| ## Your Reasoning Process | |
| When analyzing problems, you typically: | |
| - Identify and question key assumptions underlying proposed approaches | |
| - Look for potential flaws, weaknesses, and failure points | |
| - Consider what critics would say about proposed solutions | |
| - Imagine scenarios where things go wrong | |
| - Test whether evidence truly supports the conclusions drawn | |
| - Look for alternative explanations for observed phenomena | |
| - Consider whether the framing of the problem itself is flawed | |
| - Identify potential unintended consequences | |
| ## Key Considerations | |
| For the question at hand, be sure to consider: | |
| - What critical assumptions might be questionable | |
| - What objections would strong critics raise | |
| - Where the evidence or reasoning might be weak | |
| - What alternative explanations haven't been considered | |
| - Whether the problem is framed in a way that biases solutions | |
| - What could go wrong with proposed approaches | |
| ## Known Limitations | |
| Be aware that your perspective has these potential limitations: | |
| - May create excessive skepticism that impedes necessary action | |
| - Could appear unnecessarily negative or contrarian | |
| - Might focus more on identifying problems than proposing solutions | |
| - Sometimes undermines confidence when confidence is needed | |
| - Risk of creating false equivalence between strong and weak objections | |
| ## Required Output Format | |
| 1. Initial impression (2-3 sentences) | |
| 2. Key insights from your perspective (3-5 bullet points) | |
| 3. Main analysis (300-500 words) | |
| 4. Potential blindspots in your analysis | |
| 5. Final position summary (100 words)""" | |
| }, | |
| "sociologist": { | |
| "id": "sociologist", | |
| "name": "Sociologist", | |
| "description": "Analyzes issues through the lens of social structures, institutions, and group dynamics", | |
| "category": "Social Science Personas", | |
| "system_prompt": """# SOCIOLOGIST PERSPECTIVE ANALYSIS | |
| You are embodying the perspective of a Sociologist. Your purpose is to analyze the question from this unique viewpoint while maintaining intellectual rigor. | |
| ## Your Core Perspective | |
| You analyze issues through the lens of social structures, institutions, and group dynamics. You understand how social forces shape individual behavior and how collective patterns emerge from social interaction. You value empirical social research and theoretical frameworks that illuminate social phenomena. You recognize how factors like class, race, gender, and other social categories influence experiences and opportunities. | |
| ## Your Reasoning Process | |
| When analyzing problems, you typically: | |
| - Consider how social structures and institutions shape the situation | |
| - Identify relevant social norms, roles, and expectations | |
| - Analyze power dynamics and social stratification | |
| - Look for patterns of social interaction and group behavior | |
| - Consider how social identity categories intersect with the issue | |
| - Examine historical and cultural context | |
| - Apply sociological theories and concepts | |
| - Look beyond individual explanations to structural factors | |
| ## Key Considerations | |
| For the question at hand, be sure to consider: | |
| - How social structures and institutions affect this situation | |
| - Whether there are relevant group dynamics or intergroup relations | |
| - How social categories and identities might influence experiences and outcomes | |
| - What power dynamics are at play | |
| - How social change processes might be relevant | |
| - Whether there are macro-level social trends that provide context | |
| ## Known Limitations | |
| Be aware that your perspective has these potential limitations: | |
| - May overemphasize structural factors while undervaluing individual agency | |
| - Could apply theoretical frameworks that oversimplify complex social realities | |
| - Might focus more on description and explanation than practical solutions | |
| - Sometimes emphasizes social critique over pragmatic intervention | |
| - Can struggle to incorporate psychological and biological factors | |
| ## Required Output Format | |
| 1. Initial impression (2-3 sentences) | |
| 2. Key insights from your perspective (3-5 bullet points) | |
| 3. Main analysis (300-500 words) | |
| 4. Potential blindspots in your analysis | |
| 5. Final position summary (100 words)""" | |
| }, | |
| "psychologist": { | |
| "id": "psychologist", | |
| "name": "Psychologist", | |
| "description": "Understands human experience through psychological processes and individual differences", | |
| "category": "Social Science Personas", | |
| "system_prompt": """# PSYCHOLOGIST PERSPECTIVE ANALYSIS | |
| You are embodying the perspective of a Psychologist. Your purpose is to analyze the question from this unique viewpoint while maintaining intellectual rigor. | |
| ## Your Core Perspective | |
| You understand human experience and behavior through psychological processes, individual differences, and developmental patterns. You recognize how cognitive, emotional, and social factors influence perception, decision-making, and behavior. You value empirical evidence about mental processes while appreciating the complexity of human experience. You consider both conscious and unconscious influences on behavior. | |
| ## Your Reasoning Process | |
| When analyzing problems, you typically: | |
| - Consider relevant psychological processes (cognitive, emotional, motivational) | |
| - Identify potential cognitive biases and heuristics at play | |
| - Analyze how individual differences might affect experiences and responses | |
| - Look at developmental considerations across the lifespan | |
| - Consider social and environmental influences on behavior | |
| - Apply insights from relevant psychological research and theory | |
| - Examine both conscious and unconscious factors | |
| - Consider how perception, attention, and memory might shape experiences | |
| ## Key Considerations | |
| For the question at hand, be sure to consider: | |
| - What psychological processes are relevant to understanding this situation | |
| - How cognitive biases might influence perceptions and decisions | |
| - Whether emotional factors play an important role | |
| - How individual differences might lead to different experiences | |
| - What motivational factors might be driving behavior | |
| - How social psychological dynamics might be influencing the situation | |
| ## Known Limitations | |
| Be aware that your perspective has these potential limitations: | |
| - May overemphasize individual psychological factors over structural conditions | |
| - Could focus too much on Western psychological research that lacks cultural diversity | |
| - Might apply clinical frameworks to normal variations in human behavior | |
| - Sometimes struggles to connect psychological insights to practical interventions | |
| - Can overstate the reliability and validity of psychological constructs and measurements | |
| ## Required Output Format | |
| 1. Initial impression (2-3 sentences) | |
| 2. Key insights from your perspective (3-5 bullet points) | |
| 3. Main analysis (300-500 words) | |
| 4. Potential blindspots in your analysis | |
| 5. Final position summary (100 words)""" | |
| } | |
| } | |
| if "persona_categories" not in st.session_state: | |
| st.session_state.persona_categories = { | |
| "Meta": ["meta_agent", "selector_agent"], | |
| "Scientific Personas": ["analytical_scientist", "theoretical_physicist"], | |
| "Technical Personas": ["systems_thinker"], | |
| "Philosophical Personas": ["ethical_philosopher", "eastern_philosopher"], | |
| "Creative Personas": ["creative_innovator"], | |
| "Practical Personas": ["pragmatic_implementer", "devils_advocate"], | |
| "Social Science Personas": ["sociologist", "psychologist"] | |
| } | |
| if "session_history" not in st.session_state: | |
| st.session_state.session_history = [] | |
| # Function to create and configure the Claude client | |
| def get_claude_client(): | |
| api_key = os.environ.get("ANTHROPIC_API_KEY", st.session_state.get("anthropic_api_key", "")) | |
| if not api_key: | |
| st.error("Please set your Anthropic API key in the settings.") | |
| return None | |
| return anthropic.Anthropic(api_key=api_key) | |
| # Function to create a LangChain ChatAnthropic instance | |
| def get_langchain_claude(): | |
| api_key = os.environ.get("ANTHROPIC_API_KEY", st.session_state.get("anthropic_api_key", "")) | |
| if not api_key: | |
| st.error("Please set your Anthropic API key in the settings.") | |
| return None | |
| return ChatAnthropic( | |
| model="claude-3-7-sonnet-20250219", | |
| temperature=0.1, | |
| anthropic_api_key=api_key | |
| ) | |
| # Function to select personas for a query | |
| def select_personas_for_query(query, num_personas=5): | |
| client = get_claude_client() | |
| if not client: | |
| return [] | |
| # Get all available personas | |
| all_personas = list(st.session_state.persona_library.values()) | |
| available_personas = [f"- {p['name']}: {p['description']}" for p in all_personas | |
| if p['id'] not in ['meta_agent', 'selector_agent']] | |
| # Prepare the persona selection prompt | |
| persona_list = "\n".join(available_personas) | |
| # Create the selection message | |
| message = client.messages.create( | |
| model="claude-3-7-sonnet-20250219", | |
| system=st.session_state.persona_library["selector_agent"]["system_prompt"], | |
| messages=[ | |
| { | |
| "role": "user", | |
| "content": f"Select the {num_personas} most appropriate personas for analyzing this query:\n\n{query}\n\n" | |
| f"Available personas:\n{persona_list}\n\n" | |
| f"For each selected persona, briefly explain why they're appropriate for this query. " | |
| f"Return your selection in this format:\n" | |
| f"1. [Persona Name] - [Brief justification]\n" | |
| f"2. [Persona Name] - [Brief justification]\n" | |
| f"...\n" | |
| } | |
| ], | |
| temperature=0.3, | |
| max_tokens=1000 | |
| ) | |
| # Extract the selected personas from the response | |
| response_text = message.content[0].text | |
| # Parse the response to get the persona names | |
| selected_names = [] | |
| for line in response_text.split("\n"): | |
| if re.match(r"^\d+\.\s+", line): | |
| # Extract the persona name | |
| parts = line.split("-")[0].strip() | |
| number_and_name = re.match(r"^\d+\.\s+(.+?)(?:\s+-|\s*$)", parts) | |
| if number_and_name: | |
| persona_name = number_and_name.group(1).strip() | |
| selected_names.append(persona_name) | |
| # Match the selected names to the persona IDs | |
| selected_personas = [] | |
| for name in selected_names: | |
| for persona_id, persona in st.session_state.persona_library.items(): | |
| if persona["name"].lower() == name.lower() or name.lower() in persona["name"].lower(): | |
| selected_personas.append(persona_id) | |
| break | |
| # Always include the meta agent | |
| if "meta_agent" not in selected_personas: | |
| selected_personas.append("meta_agent") | |
| # Log the selection | |
| st.session_state.thinking_logs.append({ | |
| "agent": "Persona Selector", | |
| "thought": f"Selected the following personas for the query:\n{response_text}" | |
| }) | |
| return selected_personas | |
| # Load or create agent graph with dynamic persona selection | |
| def create_agent_graph(selected_personas): | |
| # Create a typed dict for agent state | |
| class AgentState(TypedDict): | |
| query: str | |
| thoughts: Dict[str, List[str]] | |
| current_agent: str | |
| final_response: Optional[str] | |
| history: List[Dict[str, Any]] | |
| selected_personas: List[str] | |
| # Initialize the graph | |
| graph = StateGraph(AgentState) | |
| # Define the nodes (agents) | |
| def initialize(state: AgentState) -> AgentState: | |
| thoughts = {"meta_agent": []} | |
| for persona_id in state["selected_personas"]: | |
| thoughts[persona_id] = [] | |
| return { | |
| **state, | |
| "thoughts": thoughts, | |
| "current_agent": "meta_agent", | |
| "history": [] | |
| } | |
| def meta_agent(state: AgentState) -> AgentState: | |
| client = get_claude_client() | |
| if not client: | |
| return state | |
| system_prompt = st.session_state.persona_library["meta_agent"]["system_prompt"] | |
| # Construct the message based on history and current query | |
| history_text = "" | |
| if state.get("history"): | |
| for entry in state["history"]: | |
| if entry.get("agent") and entry.get("thought"): | |
| history_text += f"\n## {entry['agent']} thought:\n{entry['thought']}\n" | |
| # Determine which personas have contributed and which have not | |
| contributed_personas = set() | |
| for entry in state.get("history", []): | |
| if entry.get("agent_id") in state["selected_personas"]: | |
| contributed_personas.add(entry.get("agent_id")) | |
| remaining_personas = [p for p in state["selected_personas"] if p not in contributed_personas and p != "meta_agent"] | |
| message = client.messages.create( | |
| model="claude-3-7-sonnet-20250219", | |
| system=system_prompt, | |
| messages=[ | |
| { | |
| "role": "user", | |
| "content": f"User query: {state['query']}\n\n" | |
| f"Current thinking process:\n{history_text}\n\n" | |
| f"Available personas: {', '.join([st.session_state.persona_library[p]['name'] for p in state['selected_personas'] if p != 'meta_agent'])}\n\n" | |
| f"Remaining personas to consult: {', '.join([st.session_state.persona_library[p]['name'] for p in remaining_personas])}\n\n" | |
| f"What should be the next step in the thinking process? Which persona should analyze the query next, " | |
| f"or is the analysis sufficient to generate a final synthesis?" | |
| } | |
| ], | |
| temperature=0.1, | |
| max_tokens=1000 | |
| ) | |
| thought = message.content[0].text | |
| # Update the state | |
| updated_thoughts = state["thoughts"].copy() | |
| updated_thoughts["meta_agent"] = updated_thoughts.get("meta_agent", []) + [thought] | |
| # Determine the next agent from the meta agent's response | |
| next_agent = "meta_agent" # Default to meta_agent | |
| # Check if we should move to final synthesis | |
| if any(phrase in thought.lower() for phrase in ["final synthesis", "sufficient analysis", "provide a synthesis", "synthesize the perspectives"]): | |
| next_agent = "final" | |
| else: | |
| # Try to determine which persona should be consulted next | |
| for persona_id in state["selected_personas"]: | |
| if persona_id == "meta_agent": | |
| continue | |
| persona_name = st.session_state.persona_library[persona_id]["name"] | |
| if persona_name.lower() in thought.lower(): | |
| next_agent = persona_id | |
| break | |
| updated_history = state.get("history", []).copy() + [ | |
| {"agent": "Meta Agent", "agent_id": "meta_agent", "thought": thought} | |
| ] | |
| return { | |
| **state, | |
| "thoughts": updated_thoughts, | |
| "current_agent": next_agent, | |
| "history": updated_history | |
| } | |
| # Dynamic persona nodes | |
| # We'll create a generic persona node function that can handle any persona | |
| def persona_node(state: AgentState) -> AgentState: | |
| client = get_claude_client() | |
| if not client: | |
| return state | |
| current_persona_id = state["current_agent"] | |
| # Skip if the current_agent isn't a valid persona | |
| if current_persona_id not in st.session_state.persona_library: | |
| return { | |
| **state, | |
| "current_agent": "meta_agent" # Return to meta agent if persona not found | |
| } | |
| persona = st.session_state.persona_library[current_persona_id] | |
| system_prompt = persona["system_prompt"] | |
| # Construct the message based on history and current query | |
| history_text = "" | |
| if state.get("history"): | |
| for entry in state["history"]: | |
| if entry.get("agent") and entry.get("thought"): | |
| history_text += f"\n## {entry['agent']} thought:\n{entry['thought']}\n" | |
| message = client.messages.create( | |
| model="claude-3-7-sonnet-20250219", | |
| system=system_prompt, | |
| messages=[ | |
| { | |
| "role": "user", | |
| "content": f"User query: {state['query']}\n\n" | |
| f"Current thinking process:\n{history_text}\n\n" | |
| f"Please analyze this query from your unique perspective as the {persona['name']}." | |
| } | |
| ], | |
| temperature=0.2, | |
| max_tokens=1500 | |
| ) | |
| thought = message.content[0].text | |
| # Update the state | |
| updated_thoughts = state["thoughts"].copy() | |
| updated_thoughts[current_persona_id] = updated_thoughts.get(current_persona_id, []) + [thought] | |
| updated_history = state.get("history", []).copy() + [ | |
| {"agent": persona["name"], "agent_id": current_persona_id, "thought": thought} | |
| ] | |
| return { | |
| **state, | |
| "thoughts": updated_thoughts, | |
| "current_agent": "meta_agent", # Return to meta agent for next direction | |
| "history": updated_history | |
| } | |
| def finalize(state: AgentState) -> AgentState: | |
| client = get_claude_client() | |
| if not client: | |
| return state | |
| # Construct the message based on history and current query | |
| history_text = "" | |
| if state.get("history"): | |
| for entry in state["history"]: | |
| if entry.get("agent") and entry.get("thought"): | |
| history_text += f"\n## {entry['agent']} thought:\n{entry['thought']}\n" | |
| # Use the meta agent's system prompt for the final synthesis | |
| system_prompt = st.session_state.persona_library["meta_agent"]["system_prompt"] | |
| message = client.messages.create( | |
| model="claude-3-7-sonnet-20250219", | |
| system=system_prompt, | |
| messages=[ | |
| { | |
| "role": "user", | |
| "content": f"User query: {state['query']}\n\n" | |
| f"Here is the complete thinking process from multiple perspectives:\n{history_text}\n\n" | |
| f"Please synthesize these perspectives into a comprehensive, balanced final response." | |
| } | |
| ], | |
| temperature=0.1, | |
| max_tokens=2000 | |
| ) | |
| final_response = message.content[0].text | |
| # Add the final synthesis to the history | |
| updated_history = state.get("history", []).copy() + [ | |
| {"agent": "Final Synthesis", "agent_id": "meta_agent", "thought": final_response} | |
| ] | |
| return { | |
| **state, | |
| "final_response": final_response, | |
| "current_agent": "done", | |
| "history": updated_history | |
| } | |
| # Define the edges | |
| graph.add_edge("initialize", "meta_agent") | |
| # Conditional edges from meta_agent | |
| graph.add_conditional_edges( | |
| "meta_agent", | |
| lambda state: state["current_agent"], | |
| { | |
| "meta_agent": "meta_agent", # For cases where meta agent needs another step | |
| "final": "finalize", | |
| **{persona_id: "persona_node" for persona_id in st.session_state.persona_library | |
| if persona_id != "meta_agent" and persona_id != "selector_agent"} | |
| } | |
| ) | |
| # Edge from any persona back to meta_agent | |
| graph.add_edge("persona_node", "meta_agent") | |
| # Compile the graph | |
| compiled_graph = graph.compile() | |
| return compiled_graph | |
| # Function to run the agent graph with selected personas | |
| def run_agent_graph(query, selected_personas=None): | |
| if not selected_personas: | |
| # If no personas are provided, select them based on the query | |
| selected_personas = select_personas_for_query(query) | |
| # Store the selected personas for this session | |
| st.session_state.selected_personas = selected_personas | |
| # Create a new agent graph with the selected personas | |
| agent_graph = create_agent_graph(selected_personas) | |
| # Reset the current step counter | |
| st.session_state.current_step = 0 | |
| # Clear previous thinking logs | |
| st.session_state.thinking_logs = [] | |
| # Start with initial state | |
| initial_state = { | |
| "query": query, | |
| "selected_personas": selected_personas | |
| } | |
| # Execute the graph with checkpointing | |
| def run_with_checkpoints(graph, initial_state): | |
| return graph.run(initial_state) | |
| try: | |
| result = run_with_checkpoints(agent_graph, initial_state) | |
| # Process the result for display | |
| if result and "history" in result: | |
| for step in result["history"]: | |
| st.session_state.thinking_logs.append(step) | |
| # Save this session to history | |
| session_record = { | |
| "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), | |
| "query": query, | |
| "selected_personas": [st.session_state.persona_library[p]["name"] for p in selected_personas], | |
| "thinking_logs": st.session_state.thinking_logs.copy(), | |
| "final_response": result.get("final_response", "No response generated.") | |
| } | |
| st.session_state.session_history.append(session_record) | |
| # Return the final response | |
| if result and "final_response" in result: | |
| return result["final_response"] | |
| else: | |
| return "I wasn't able to generate a response. Please try again or check the settings." | |
| except Exception as e: | |
| error_message = f"Error executing reasoning graph: {str(e)}" | |
| st.error(error_message) | |
| return f"I encountered an error while processing your query: {str(e)}" | |
| # Function to add a new persona to the library | |
| def add_persona_to_library(name, description, category, system_prompt): | |
| # Generate a unique ID based on the name | |
| persona_id = name.lower().replace(' ', '_').replace('-', '_') | |
| base_id = persona_id | |
| # Make sure ID is unique | |
| counter = 1 | |
| while persona_id in st.session_state.persona_library: | |
| persona_id = f"{base_id}_{counter}" | |
| counter += 1 | |
| # Add to library | |
| st.session_state.persona_library[persona_id] = { | |
| "id": persona_id, | |
| "name": name, | |
| "description": description, | |
| "category": category, | |
| "system_prompt": system_prompt | |
| } | |
| # Add to category list | |
| if category not in st.session_state.persona_categories: | |
| st.session_state.persona_categories[category] = [] | |
| if persona_id not in st.session_state.persona_categories[category]: | |
| st.session_state.persona_categories[category].append(persona_id) | |
| return persona_id | |
| # Function to edit an existing persona | |
| def edit_persona(persona_id, name, description, category, system_prompt): | |
| if persona_id not in st.session_state.persona_library: | |
| return False | |
| old_category = st.session_state.persona_library[persona_id]["category"] | |
| # Update persona data | |
| st.session_state.persona_library[persona_id].update({ | |
| "name": name, | |
| "description": description, | |
| "category": category, | |
| "system_prompt": system_prompt | |
| }) | |
| # Update category lists if category changed | |
| if old_category != category: | |
| # Remove from old category | |
| if old_category in st.session_state.persona_categories and persona_id in st.session_state.persona_categories[old_category]: | |
| st.session_state.persona_categories[old_category].remove(persona_id) | |
| # Add to new category | |
| if category not in st.session_state.persona_categories: | |
| st.session_state.persona_categories[category] = [] | |
| if persona_id not in st.session_state.persona_categories[category]: | |
| st.session_state.persona_categories[category].append(persona_id) | |
| return True | |
| # Function to delete a persona | |
| def delete_persona(persona_id): | |
| if persona_id not in st.session_state.persona_library: | |
| return False | |
| # Don't allow deletion of core personas | |
| if persona_id in ["meta_agent", "selector_agent"]: | |
| return False | |
| # Remove from category list | |
| category = st.session_state.persona_library[persona_id]["category"] | |
| if category in st.session_state.persona_categories and persona_id in st.session_state.persona_categories[category]: | |
| st.session_state.persona_categories[category].remove(persona_id) | |
| # Remove from library | |
| del st.session_state.persona_library[persona_id] | |
| return True | |
| # Function to export persona library | |
| def export_persona_library(): | |
| library_data = { | |
| "personas": st.session_state.persona_library, | |
| "categories": st.session_state.persona_categories | |
| } | |
| return json.dumps(library_data, indent=2) | |
| # Function to import persona library | |
| def import_persona_library(json_data): | |
| try: | |
| data = json.loads(json_data) | |
| if "personas" in data and "categories" in data: | |
| # Validate structure | |
| for persona_id, persona in data["personas"].items(): | |
| required_fields = ["id", "name", "description", "category", "system_prompt"] | |
| if not all(field in persona for field in required_fields): | |
| return False, "Invalid persona data structure" | |
| # Preserve the core personas | |
| core_personas = ["meta_agent", "selector_agent"] | |
| for persona_id in core_personas: | |
| if persona_id in data["personas"]: | |
| # Keep the imported version, but ensure it has required fields | |
| if not all(field in data["personas"][persona_id] for field in required_fields): | |
| data["personas"][persona_id] = st.session_state.persona_library[persona_id] | |
| else: | |
| # Use the existing core persona | |
| data["personas"][persona_id] = st.session_state.persona_library[persona_id] | |
| # Update the state | |
| st.session_state.persona_library = data["personas"] | |
| st.session_state.persona_categories = data["categories"] | |
| # Ensure core personas are in categories | |
| if "Meta" not in st.session_state.persona_categories: | |
| st.session_state.persona_categories["Meta"] = [] | |
| for persona_id in core_personas: | |
| if persona_id not in st.session_state.persona_categories["Meta"]: | |
| st.session_state.persona_categories["Meta"].append(persona_id) | |
| return True, "Persona library imported successfully" | |
| else: | |
| return False, "Invalid import format" | |
| except Exception as e: | |
| return False, f"Error importing persona library: {str(e)}" | |
| # UI Layout | |
| st.sidebar.title("🧠 Multi-Persona Reasoning System") | |
| # Main navigation | |
| main_tabs = st.tabs(["Chat", "Thinking Process", "Persona Library", "Session History"]) | |
| with main_tabs[0]: # Chat tab | |
| st.header("Chat with the Multi-Persona Reasoning System") | |
| # Display chat messages | |
| for message in st.session_state.messages: | |
| with st.chat_message(message["role"]): | |
| st.write(message["content"]) | |
| # Manual persona selection | |
| with st.expander("Advanced: Custom Persona Selection", expanded=False): | |
| st.write("Select specific personas to analyze your next query:") | |
| # Organized by category | |
| selected_persona_ids = [] | |
| for category, persona_ids in st.session_state.persona_categories.items(): | |
| st.subheader(category) | |
| for persona_id in persona_ids: | |
| if persona_id in st.session_state.persona_library and persona_id not in ["selector_agent"]: | |
| persona = st.session_state.persona_library[persona_id] | |
| selected = st.checkbox( | |
| f"{persona['name']} - {persona['description']}", | |
| value=False, | |
| key=f"select_{persona_id}" | |
| ) | |
| if selected: | |
| selected_persona_ids.append(persona_id) | |
| use_manual_selection = st.checkbox("Use these personas instead of automatic selection", value=False) | |
| # User input | |
| if prompt := st.chat_input("What's on your mind?"): | |
| # Add user message to chat history | |
| st.session_state.messages.append({"role": "user", "content": prompt}) | |
| # Display user message | |
| with st.chat_message("user"): | |
| st.write(prompt) | |
| # Show thinking indicator | |
| with st.chat_message("assistant"): | |
| with st.spinner("Thinking across multiple perspectives..."): | |
| # Use manual selection or automatic selection | |
| if 'use_manual_selection' in locals() and use_manual_selection and selected_persona_ids: | |
| # Always include meta agent | |
| if "meta_agent" not in selected_persona_ids: | |
| selected_persona_ids.append("meta_agent") | |
| response = run_agent_graph(prompt, selected_persona_ids) | |
| else: | |
| response = run_agent_graph(prompt) | |
| # Display the response | |
| st.write(response) | |
| # Add assistant response to chat history | |
| st.session_state.messages.append({"role": "assistant", "content": response}) | |
| with main_tabs[1]: # Thinking Process tab | |
| st.header("Multi-Persona Thinking Process") | |
| if not st.session_state.thinking_logs: | |
| st.info("No thinking process to display yet. Start a conversation to see the personas at work.") | |
| else: | |
| # Show which personas were selected | |
| if st.session_state.selected_personas: | |
| persona_names = [st.session_state.persona_library[p]["name"] for p in st.session_state.selected_personas] | |
| st.write(f"**Selected Personas**: {', '.join(persona_names)}") | |
| # Display the thinking logs | |
| for i, log in enumerate(st.session_state.thinking_logs): | |
| step_num = i + 1 | |
| with st.expander(f"Step {step_num}: {log.get('agent', 'Unknown Agent')}", expanded=i==0): | |
| st.markdown(log.get("thought", "No thought recorded")) | |
| with main_tabs[2]: # Persona Library tab | |
| st.header("Persona Library Management") | |
| library_tabs = st.tabs(["Browse Personas", "Add New Persona", "Import/Export"]) | |
| with library_tabs[0]: # Browse Personas | |
| st.subheader("Browse and Edit Personas") | |
| # List personas by category | |
| for category, persona_ids in st.session_state.persona_categories.items(): | |
| with st.expander(f"{category} ({len(persona_ids)} personas)", expanded=False): | |
| for persona_id in persona_ids: | |
| if persona_id in st.session_state.persona_library: | |
| persona = st.session_state.persona_library[persona_id] | |
| with st.expander(f"{persona['name']} - {persona['description']}", expanded=False): | |
| # Create a form for editing | |
| with st.form(key=f"edit_form_{persona_id}"): | |
| name = st.text_input("Name", value=persona["name"]) | |
| description = st.text_area("Description", value=persona["description"], height=100) | |
| # Category selection with option to create new | |
| existing_categories = list(st.session_state.persona_categories.keys()) | |
| category_idx = existing_categories.index(persona["category"]) if persona["category"] in existing_categories else 0 | |
| category = st.selectbox("Category", existing_categories, index=category_idx) | |
| new_category = st.text_input("Or create new category") | |
| if new_category and new_category not in existing_categories: | |
| category = new_category | |
| system_prompt = st.text_area("System Prompt", value=persona["system_prompt"], height=300) | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| submit = st.form_submit_button("Save Changes") | |
| with col2: | |
| # Don't allow deletion of core personas | |
| delete_disabled = persona_id in ["meta_agent", "selector_agent"] | |
| delete = st.form_submit_button( | |
| "Delete Persona", | |
| disabled=delete_disabled, | |
| type="secondary" if not delete_disabled else "primary" | |
| ) | |
| if submit: | |
| success = edit_persona(persona_id, name, description, category, system_prompt) | |
| if success: | |
| st.success(f"Updated {name} successfully!") | |
| else: | |
| st.error(f"Failed to update {name}") | |
| if delete and not delete_disabled: | |
| success = delete_persona(persona_id) | |
| if success: | |
| st.success(f"Deleted {name} successfully!") | |
| st.rerun() | |
| else: | |
| st.error(f"Failed to delete {name}") | |
| with library_tabs[1]: # Add New Persona | |
| st.subheader("Add New Persona") | |
| with st.form(key="add_persona_form"): | |
| name = st.text_input("Persona Name") | |
| description = st.text_area("Description", height=100) | |
| # Category selection with option to create new | |
| existing_categories = list(st.session_state.persona_categories.keys()) | |
| category = st.selectbox("Category", existing_categories) | |
| new_category = st.text_input("Or create new category") | |
| if new_category and new_category not in existing_categories: | |
| category = new_category | |
| # Template selection for system prompt | |
| template_options = ["Empty", "Standard Persona Template"] | |
| template_selection = st.selectbox("System Prompt Template", template_options) | |
| if template_selection == "Standard Persona Template": | |
| system_prompt = f"""# {name.upper()} PERSPECTIVE ANALYSIS | |
| You are embodying the perspective of a {name}. Your purpose is to analyze the question from this unique viewpoint while maintaining intellectual rigor. | |
| ## Your Core Perspective | |
| [Describe the core perspective, values, and approach of this persona] | |
| ## Your Reasoning Process | |
| When analyzing problems, you typically: | |
| - [List key aspects of this persona's reasoning process] | |
| - [Include several bullet points describing their approach] | |
| ## Key Considerations | |
| For the question at hand, be sure to consider: | |
| - [List important elements this persona should consider] | |
| - [Include several domain-specific considerations] | |
| ## Known Limitations | |
| Be aware that your perspective has these potential limitations: | |
| - [List several limitations or biases of this perspective] | |
| - [Help the persona be aware of their blindspots] | |
| ## Required Output Format | |
| 1. Initial impression (2-3 sentences) | |
| 2. Key insights from your perspective (3-5 bullet points) | |
| 3. Main analysis (300-500 words) | |
| 4. Potential blindspots in your analysis | |
| 5. Final position summary (100 words)""" | |
| else: | |
| system_prompt = "" | |
| system_prompt = st.text_area("System Prompt", value=system_prompt, height=400) | |
| submit = st.form_submit_button("Add Persona") | |
| if submit: | |
| if name and description and category and system_prompt: | |
| persona_id = add_persona_to_library(name, description, category, system_prompt) | |
| st.success(f"Added {name} to the persona library with ID: {persona_id}") | |
| else: | |
| st.error("All fields are required") | |
| with library_tabs[2]: # Import/Export | |
| st.subheader("Import/Export Persona Library") | |
| col1, col2 = st.columns(2) | |
| with col1: | |
| st.write("**Export Persona Library**") | |
| export_data = export_persona_library() | |
| st.download_button( | |
| label="Download Persona Library", | |
| data=export_data, | |
| file_name=f"persona_library_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json", | |
| mime="application/json" | |
| ) | |
| with col2: | |
| st.write("**Import Persona Library**") | |
| with st.form(key="import_form"): | |
| uploaded_file = st.file_uploader("Upload Persona Library JSON", type=["json"]) | |
| submit = st.form_submit_button("Import") | |
| if submit and uploaded_file is not None: | |
| json_data = uploaded_file.read().decode("utf-8") | |
| success, message = import_persona_library(json_data) | |
| if success: | |
| st.success(message) | |
| else: | |
| st.error(message) | |
| with main_tabs[3]: # Session History tab | |
| st.header("Session History") | |
| if not st.session_state.session_history: | |
| st.info("No session history available yet. Start a conversation to record your sessions.") | |
| else: | |
| # Display history in reverse chronological order | |
| for i, session in enumerate(reversed(st.session_state.session_history)): | |
| with st.expander(f"Session {len(st.session_state.session_history) - i}: {session['timestamp']} - {session['query'][:50]}...", expanded=i==0): | |
| st.write(f"**Query:** {session['query']}") | |
| st.write(f"**Personas used:** {', '.join(session['selected_personas'])}") | |
| # Show thinking process | |
| if st.checkbox(f"Show thinking process", key=f"show_thinking_{i}", value=False): | |
| for j, log in enumerate(session["thinking_logs"]): | |
| step_num = j + 1 | |
| with st.expander(f"Step {step_num}: {log.get('agent', 'Unknown Agent')}", expanded=False): | |
| st.markdown(log.get("thought", "No thought recorded")) | |
| st.write("**Final Response:**") | |
| st.markdown(session["final_response"]) | |
| # Settings in the sidebar | |
| with st.sidebar.expander("⚙️ Settings"): | |
| api_key = st.text_input( | |
| "Anthropic API Key", | |
| type="password", | |
| value=st.session_state.get("anthropic_api_key", ""), | |
| help="Enter your Anthropic API key here" | |
| ) | |
| if api_key: | |
| st.session_state.anthropic_api_key = api_key | |
| # Default number of personas to select | |
| default_num_personas = st.number_input( | |
| "Default number of personas to consult", | |
| min_value=3, | |
| max_value=10, | |
| value=5, | |
| help="How many specialized personas should analyze each query by default" | |
| ) | |
| if st.button("Test Connection"): | |
| client = get_claude_client() | |
| if client: | |
| try: | |
| response = client.messages.create( | |
| model="claude-3-7-sonnet-20250219", | |
| messages=[{"role": "user", "content": "Hello"}], | |
| max_tokens=10 | |
| ) | |
| st.success("Connection successful!") | |
| except Exception as e: | |
| st.error(f"Connection failed: {str(e)}") | |
| # Display some information about the app | |
| with st.sidebar.expander("ℹ️ About"): | |
| st.markdown(""" | |
| # Multi-Persona Reasoning System | |
| This application implements a "team of thinkers" approach to enhance AI reasoning capabilities. The system: | |
| 1. Analyzes each query to select the most relevant specialist personas | |
| 2. Has each persona examine the problem from their unique perspective | |
| 3. Synthesizes diverse viewpoints into a comprehensive response | |
| ## Key Features | |
| - Dynamic persona selection based on query content | |
| - Expandable library of specialized reasoning personas | |
| - Transparent thinking process across multiple perspectives | |
| - Meta-agent synthesis of diverse viewpoints | |
| ## How It Works | |
| 1. When you ask a question, the selector agent chooses relevant personas | |
| 2. Each selected persona analyzes the query from their perspective | |
| 3. The meta-agent coordinates and synthesizes their insights | |
| 4. You receive a balanced, multi-perspective response | |
| You can observe the complete thinking process, customize the persona library, and manually select personas for specific queries. | |
| """) |