From 51b5208b9b5ac51b7e531ddeb59093c1cb381491 Mon Sep 17 00:00:00 2001
From: YurenHao0426 <blackhao0426@gmail.com>
Date: Sat, 14 Feb 2026 01:31:53 +0000
Subject: Rework debate prompts, add turn-based rounds and self-elimination
 convergence
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

- Round 1 parallel (form positions), Round 2+ sequential turn-based (each model
  sees current round's prior responses before speaking)
- Prompts treat user question as open-ended, not as a debate proposition — models
  form their own thesis in Round 1 then defend it
- Structured opposition: each model defends own unique position, not FOR/AGAINST
- Self-convergence: each model judges if convinced after each round, eliminated
  models drop out, last one standing wins and provides final summary
- Skip convergence/judge checks on Round 1 (still forming positions)
- Auto-save now triggers on councilData/debateData updates so intermediate rounds
  persist across page refresh

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---
 frontend/src/components/Sidebar.tsx | 32 ++++++++++++++++++++++----------
 1 file changed, 22 insertions(+), 10 deletions(-)

(limited to 'frontend/src/components/Sidebar.tsx')

diff --git a/frontend/src/components/Sidebar.tsx b/frontend/src/components/Sidebar.tsx
index aeb164b..8bb5fcb 100644
--- a/frontend/src/components/Sidebar.tsx
+++ b/frontend/src/components/Sidebar.tsx
@@ -810,20 +810,32 @@ const Sidebar: React.FC<SidebarProps> = ({ isOpen, onToggle, onInteract }) => {
               }
               break;
             }
-            case 'convergence_check': {
+            case 'model_eliminated': {
               const lastRound2 = debateRounds[debateRounds.length - 1];
               if (lastRound2) {
-                lastRound2.converged = evt.data.converged;
-                updateNodeData(runningNodeId, {
-                  debateData: {
-                    rounds: [...debateRounds],
-                    finalVerdict: null,
-                    config: { judgeMode, format: debateFormat, maxRounds },
-                  },
+                if (!lastRound2.eliminated) lastRound2.eliminated = [];
+                lastRound2.eliminated.push({
+                  model: evt.data.model,
+                  convincedBy: evt.data.convinced_by,
+                  reasoning: evt.data.reasoning,
                 });
               }
-              if (evt.data.converged) {
-                setDebateStage('Consensus reached!');
+              setDebateStage(`${evt.data.model} concedes to ${evt.data.convinced_by || 'another'}...`);
+              break;
+            }
+            case 'convergence_status': {
+              const remaining = evt.data.remaining as string[];
+              updateNodeData(runningNodeId, {
+                debateData: {
+                  rounds: [...debateRounds],
+                  finalVerdict: null,
+                  config: { judgeMode, format: debateFormat, maxRounds },
+                },
+              });
+              if (remaining.length <= 1) {
+                setDebateStage(`${remaining[0] || 'Winner'} is the last one standing!`);
+              } else {
+                setDebateStage(`${remaining.length} models remaining...`);
               }
               break;
             }
-- 
cgit v1.2.3

