azettl commited on
Commit
710a0f7
Β·
1 Parent(s): e6769b1
Files changed (1) hide show
  1. app.py +124 -37
app.py CHANGED
@@ -337,6 +337,47 @@ class VisualConsensusEngine:
337
  pass
338
  return 5.0
339
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
340
  def run_visual_consensus_session(self, question: str, discussion_rounds: int = 3,
341
  decision_protocol: str = "consensus", role_assignment: str = "balanced",
342
  topology: str = "full_mesh", moderator_model: str = "mistral",
@@ -357,7 +398,7 @@ class VisualConsensusEngine:
357
 
358
  # Log the start
359
  log_event('phase', content=f"πŸš€ Starting Discussion: {question}")
360
- log_event('phase', content=f"πŸ“Š Configuration: {len(available_models)} models, {decision_protocol} protocol, {role_assignment} roles")
361
 
362
  # Initialize visual state
363
  self.update_visual_state({
@@ -469,20 +510,23 @@ Your response should include:
469
  if not enable_step_by_step:
470
  time.sleep(1)
471
 
472
- # Create context of other responses
473
- other_responses = ""
474
- for other_model in available_models:
475
- if other_model != model:
476
- other_responses += f"\n**{self.models[other_model]['name']}**: [Previous response]\n"
477
 
478
- discussion_prompt = f"""CONTINUING DISCUSSION FOR: {question}
 
 
 
 
 
479
 
480
- Round {round_num + 1} of {discussion_rounds}
481
 
482
- Other models' current responses:
483
- {other_responses}
 
 
484
 
485
- Please provide your updated analysis considering the discussion so far.
486
  END WITH: "Confidence: X/10" """
487
 
488
  log_event('speaking', speaker=self.models[model]['name'])
@@ -531,7 +575,7 @@ END WITH: "Confidence: X/10" """
531
  else:
532
  time.sleep(1)
533
 
534
- # Phase 3: Final consensus
535
  log_event('phase', content=f"🎯 Phase 3: Final Consensus ({decision_protocol})")
536
  log_event('thinking', speaker="All participants", content="Building consensus...")
537
 
@@ -545,45 +589,69 @@ END WITH: "Confidence: X/10" """
545
  if not enable_step_by_step:
546
  time.sleep(2)
547
 
548
- # Generate consensus
549
  moderator = self.moderator_model if self.models[self.moderator_model]['available'] else available_models[0]
550
 
551
- # Collect responses from session log
552
- session = get_or_create_session_state(self.session_id)
553
- all_responses = ""
554
  confidence_scores = []
555
- for entry in session["discussion_log"]:
556
- if entry['type'] == 'message' and entry['speaker'] != 'Consilium':
557
- all_responses += f"\n**{entry['speaker']}**: {entry['content']}\n"
558
- if 'confidence' in entry:
559
- confidence_scores.append(entry['confidence'])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
560
 
561
  avg_confidence = sum(confidence_scores) / len(confidence_scores) if confidence_scores else 5.0
562
- consensus_threshold = 7.0
563
 
564
- consensus_prompt = f"""You are synthesizing the final result from this AI discussion.
565
-
566
- ORIGINAL QUESTION: {question}
567
 
568
- ALL PARTICIPANT RESPONSES:
569
  {all_responses}
570
 
 
 
 
 
 
 
571
  AVERAGE CONFIDENCE LEVEL: {avg_confidence:.1f}/10
 
572
 
573
  Your task:
574
- 1. Analyze if the participants reached genuine consensus or if there are significant disagreements
575
- 2. If there IS consensus: Provide a comprehensive final answer incorporating all insights
576
- 3. If there is NO consensus: Clearly state the disagreements and present the main conflicting positions
577
- 4. If partially aligned: Identify areas of agreement and areas of disagreement
578
 
579
  Be honest about the level of consensus achieved. Do not force agreement where none exists.
580
 
581
  Format your response as:
582
  **CONSENSUS STATUS:** [Reached/Partial/Not Reached]
583
 
584
- **FINAL ANSWER:** [Your synthesis]
 
 
585
 
586
- **AREAS OF DISAGREEMENT:** [If any - explain the key points of contention]"""
 
 
587
 
588
  log_event('speaking', speaker="Consilium", content="Analyzing consensus and synthesizing final answer...")
589
  self.update_visual_state({
@@ -602,7 +670,7 @@ Format your response as:
602
 
603
  **AREAS OF DISAGREEMENT:** Analysis could not be completed due to technical issues."""
604
 
605
- consensus_reached = "CONSENSUS STATUS: Reached" in consensus_result or avg_confidence >= consensus_threshold
606
 
607
  if consensus_reached:
608
  visual_summary = "βœ… Consensus reached!"
@@ -696,6 +764,7 @@ def run_consensus_discussion_session(question: str, discussion_rounds: int = 3,
696
  ### πŸ“Š Discussion Summary
697
  - **Question:** {question}
698
  - **Protocol:** {decision_protocol.replace('_', ' ').title()}
 
699
  - **Participants:** {len(available_models)} AI models
700
  - **Roles:** {role_assignment.title()}
701
  - **Session ID:** {session_id[:8]}...
@@ -763,11 +832,11 @@ def check_model_status_session(session_id_state: str = None, request: gr.Request
763
  'DeepSeek-R1': sambanova_key,
764
  'Meta-Llama-3.1-8B': sambanova_key,
765
  'QwQ-32B': sambanova_key,
766
- 'Web Search Agent': True
767
  }
768
 
769
  for model_name, available in models.items():
770
- if model_name == 'Web Search Agent':
771
  status = "βœ… Available (Built-in)"
772
  else:
773
  if available:
@@ -827,7 +896,8 @@ with gr.Blocks(title="🎭 Consilium: Visual AI Consensus Platform", theme=gr.th
827
  topology = gr.Dropdown(
828
  choices=["full_mesh", "star", "ring"],
829
  value="full_mesh",
830
- label="🌐 Communication Pattern"
 
831
  )
832
 
833
  moderator_model = gr.Dropdown(
@@ -938,7 +1008,7 @@ with gr.Blocks(title="🎭 Consilium: Visual AI Consensus Platform", theme=gr.th
938
  outputs=[step_status]
939
  )
940
 
941
- # Auto-refresh the roundtable state every 2 seconds during discussion
942
  def refresh_roundtable(session_id_state, request: gr.Request = None):
943
  session_id = get_session_id(request) if not session_id_state else session_id_state
944
  if session_id in user_sessions:
@@ -1116,6 +1186,23 @@ with gr.Blocks(title="🎭 Consilium: Visual AI Consensus Platform", theme=gr.th
1116
  - **Ranked Choice**: Preference-based selection
1117
  - **Unanimity**: All must agree completely
1118
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1119
  ## πŸ”’ Session Isolation
1120
 
1121
  **Each user gets their own private space:**
 
337
  pass
338
  return 5.0
339
 
340
+ # FIXED: Proper conversation context building based on topology
341
+ def build_conversation_context(self, all_messages: List[Dict], current_model: str, question: str, round_num: int, topology: str = "full_mesh") -> str:
342
+ """Build proper conversation context based on topology"""
343
+
344
+ current_model_name = self.models[current_model]['name']
345
+
346
+ if topology == "full_mesh":
347
+ # Everyone sees everyone's responses (except their own)
348
+ context = f"ORIGINAL QUESTION: {question}\n\nCONVERSATION SO FAR:\n"
349
+
350
+ for msg in all_messages:
351
+ if msg["speaker"] != current_model_name: # Don't include own messages in context
352
+ context += f"\n**{msg['speaker']}** ({msg.get('role', 'standard')}):\n{msg['text']}\n"
353
+ if 'confidence' in msg:
354
+ context += f"*Confidence: {msg['confidence']}/10*\n"
355
+
356
+ elif topology == "star":
357
+ # Only see moderator and own previous responses
358
+ context = f"ORIGINAL QUESTION: {question}\n\nRELEVANT RESPONSES:\n"
359
+ moderator_name = self.models[self.moderator_model]['name']
360
+
361
+ for msg in all_messages:
362
+ if msg["speaker"] == moderator_name:
363
+ context += f"\n**{msg['speaker']} (Moderator)**:\n{msg['text']}\n"
364
+
365
+ elif topology == "ring":
366
+ # Only see previous model in the ring
367
+ context = f"ORIGINAL QUESTION: {question}\n\nPREVIOUS RESPONSE:\n"
368
+ available_models = [model for model, info in self.models.items() if info['available']]
369
+ current_idx = available_models.index(current_model)
370
+ prev_idx = (current_idx - 1) % len(available_models)
371
+ prev_model_name = self.models[available_models[prev_idx]]['name']
372
+
373
+ # Get the most recent message from the previous model
374
+ for msg in reversed(all_messages):
375
+ if msg["speaker"] == prev_model_name:
376
+ context += f"\n**{msg['speaker']}**:\n{msg['text']}\n"
377
+ break
378
+
379
+ return context
380
+
381
  def run_visual_consensus_session(self, question: str, discussion_rounds: int = 3,
382
  decision_protocol: str = "consensus", role_assignment: str = "balanced",
383
  topology: str = "full_mesh", moderator_model: str = "mistral",
 
398
 
399
  # Log the start
400
  log_event('phase', content=f"πŸš€ Starting Discussion: {question}")
401
+ log_event('phase', content=f"πŸ“Š Configuration: {len(available_models)} models, {decision_protocol} protocol, {role_assignment} roles, {topology} topology")
402
 
403
  # Initialize visual state
404
  self.update_visual_state({
 
510
  if not enable_step_by_step:
511
  time.sleep(1)
512
 
513
+ # FIXED: Build proper conversation context based on topology
514
+ conversation_context = self.build_conversation_context(all_messages, model, question, round_num + 1, topology)
 
 
 
515
 
516
+ role = model_roles[model]
517
+ role_context = self.roles[role]
518
+
519
+ discussion_prompt = f"""{role_context}
520
+
521
+ {conversation_context}
522
 
523
+ ROUND {round_num + 1} of {discussion_rounds}
524
 
525
+ Please provide your updated analysis considering the discussion so far.
526
+ - Address any points raised by other participants
527
+ - Refine or adjust your position based on new information
528
+ - Maintain your assigned role perspective
529
 
 
530
  END WITH: "Confidence: X/10" """
531
 
532
  log_event('speaking', speaker=self.models[model]['name'])
 
575
  else:
576
  time.sleep(1)
577
 
578
+ # Phase 3: Final consensus - IMPROVED WITH PROPER ANALYSIS
579
  log_event('phase', content=f"🎯 Phase 3: Final Consensus ({decision_protocol})")
580
  log_event('thinking', speaker="All participants", content="Building consensus...")
581
 
 
589
  if not enable_step_by_step:
590
  time.sleep(2)
591
 
592
+ # Generate consensus with proper conversation analysis
593
  moderator = self.moderator_model if self.models[self.moderator_model]['available'] else available_models[0]
594
 
595
+ # FIXED: Group messages by speaker for better analysis
596
+ speaker_positions = {}
 
597
  confidence_scores = []
598
+
599
+ for msg in all_messages:
600
+ speaker = msg["speaker"]
601
+ if speaker not in speaker_positions:
602
+ speaker_positions[speaker] = []
603
+ speaker_positions[speaker].append(msg)
604
+ if 'confidence' in msg:
605
+ confidence_scores.append(msg['confidence'])
606
+
607
+ # Build comprehensive context for consensus
608
+ all_responses = f"ORIGINAL QUESTION: {question}\n\nTOPOLOGY: {topology}\nDECISION PROTOCOL: {decision_protocol}\n\n"
609
+
610
+ for speaker, messages in speaker_positions.items():
611
+ if speaker != 'Consilium': # Skip previous consensus attempts
612
+ all_responses += f"\n{'='*50}\n**{speaker}** (Role: {messages[0].get('role', 'standard')}):\n\n"
613
+ for i, msg in enumerate(messages):
614
+ if i == 0:
615
+ all_responses += f"Initial Response: {msg['text']}\n\n"
616
+ else:
617
+ all_responses += f"Round {i}: {msg['text']}\n\n"
618
+
619
+ if messages[-1].get('confidence'):
620
+ all_responses += f"Final Confidence: {messages[-1]['confidence']}/10\n"
621
 
622
  avg_confidence = sum(confidence_scores) / len(confidence_scores) if confidence_scores else 5.0
 
623
 
624
+ consensus_prompt = f"""You are synthesizing the final result from this multi-AI discussion.
 
 
625
 
 
626
  {all_responses}
627
 
628
+ ANALYSIS REQUIREMENTS:
629
+ 1. Identify areas where AIs agree vs disagree
630
+ 2. Assess the quality and strength of arguments presented
631
+ 3. Note any evolution in positions across discussion rounds
632
+ 4. Determine if genuine consensus was reached based on the {decision_protocol} protocol
633
+
634
  AVERAGE CONFIDENCE LEVEL: {avg_confidence:.1f}/10
635
+ CONSENSUS THRESHOLD: 7.0/10
636
 
637
  Your task:
638
+ - Analyze if the participants reached genuine consensus or if there are significant disagreements
639
+ - If there IS consensus: Provide a comprehensive final answer incorporating all insights
640
+ - If there is NO consensus: Clearly state the disagreements and present the main conflicting positions
641
+ - If partially aligned: Identify areas of agreement and areas of disagreement
642
 
643
  Be honest about the level of consensus achieved. Do not force agreement where none exists.
644
 
645
  Format your response as:
646
  **CONSENSUS STATUS:** [Reached/Partial/Not Reached]
647
 
648
+ **FINAL ANSWER:** [Your comprehensive synthesis]
649
+
650
+ **AREAS OF AGREEMENT:** [Points where participants aligned]
651
 
652
+ **REMAINING DISAGREEMENTS:** [If any - explain the key points of contention]
653
+
654
+ **CONFIDENCE ASSESSMENT:** [Analysis of certainty levels and reliability]"""
655
 
656
  log_event('speaking', speaker="Consilium", content="Analyzing consensus and synthesizing final answer...")
657
  self.update_visual_state({
 
670
 
671
  **AREAS OF DISAGREEMENT:** Analysis could not be completed due to technical issues."""
672
 
673
+ consensus_reached = "CONSENSUS STATUS:** Reached" in consensus_result or avg_confidence >= 7.0
674
 
675
  if consensus_reached:
676
  visual_summary = "βœ… Consensus reached!"
 
764
  ### πŸ“Š Discussion Summary
765
  - **Question:** {question}
766
  - **Protocol:** {decision_protocol.replace('_', ' ').title()}
767
+ - **Topology:** {topology.replace('_', ' ').title()}
768
  - **Participants:** {len(available_models)} AI models
769
  - **Roles:** {role_assignment.title()}
770
  - **Session ID:** {session_id[:8]}...
 
832
  'DeepSeek-R1': sambanova_key,
833
  'Meta-Llama-3.1-8B': sambanova_key,
834
  'QwQ-32B': sambanova_key,
835
+ 'Search': True
836
  }
837
 
838
  for model_name, available in models.items():
839
+ if model_name == 'Search':
840
  status = "βœ… Available (Built-in)"
841
  else:
842
  if available:
 
896
  topology = gr.Dropdown(
897
  choices=["full_mesh", "star", "ring"],
898
  value="full_mesh",
899
+ label="🌐 Communication Pattern",
900
+ info="Full mesh: all see all, Star: only moderator, Ring: chain communication"
901
  )
902
 
903
  moderator_model = gr.Dropdown(
 
1008
  outputs=[step_status]
1009
  )
1010
 
1011
+ # Auto-refresh the roundtable state every 0.5 seconds during discussion
1012
  def refresh_roundtable(session_id_state, request: gr.Request = None):
1013
  session_id = get_session_id(request) if not session_id_state else session_id_state
1014
  if session_id in user_sessions:
 
1186
  - **Ranked Choice**: Preference-based selection
1187
  - **Unanimity**: All must agree completely
1188
 
1189
+ ## 🌐 Communication Topologies (NOW IMPLEMENTED!)
1190
+
1191
+ ### πŸ•ΈοΈ **Full Mesh** (Default)
1192
+ - Every AI sees responses from ALL other AIs
1193
+ - Maximum information sharing
1194
+ - Best for comprehensive consensus
1195
+
1196
+ ### ⭐ **Star**
1197
+ - AIs only see the moderator's responses
1198
+ - Centralized communication pattern
1199
+ - Good for controlled discussions
1200
+
1201
+ ### πŸ”„ **Ring**
1202
+ - Each AI only sees the previous AI's response
1203
+ - Sequential information flow
1204
+ - Interesting for building on ideas
1205
+
1206
  ## πŸ”’ Session Isolation
1207
 
1208
  **Each user gets their own private space:**