Spaces:
Sleeping
Sleeping
File size: 64,744 Bytes
2e7bebc 46177b3 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d 2e7bebc cb8359d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 |
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)
@graph.node
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": []
}
@graph.node
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
@graph.node
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
}
@graph.node
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
@persist(to="memory")
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.
""") |