Leonydis137 commited on
Commit
a90b38f
Β·
verified Β·
1 Parent(s): b8991fc

Rename app.pyv1 to app.py

Browse files
Files changed (1) hide show
  1. app.pyv1 β†’ app.py +494 -119
app.pyv1 β†’ app.py RENAMED
@@ -1,4 +1,4 @@
1
- # app.py - Advanced Discussion Simulator with Hexa-Agent System
2
  import gradio as gr
3
  import openai
4
  import threading
@@ -9,6 +9,14 @@ import os
9
  import pickle
10
  from datetime import datetime
11
  import re
 
 
 
 
 
 
 
 
12
 
13
  # === CONFIG ===
14
  EMBEDDING_MODEL = "text-embedding-3-small"
@@ -18,7 +26,9 @@ INDEX_FILE = "memory.index"
18
  openai.api_key = os.environ.get("OPENAI_API_KEY")
19
 
20
  # === EMBEDDING UTILS ===
 
21
  def get_embedding(text, model=EMBEDDING_MODEL):
 
22
  text = text.replace("\n", " ")
23
  try:
24
  response = openai.embeddings.create(input=[text], model=model)
@@ -41,7 +51,7 @@ try:
41
  except:
42
  memory_index = faiss.IndexFlatL2(1536)
43
 
44
- # === AGENT SYSTEM PROMPTS ===
45
  AGENT_A_PROMPT = """You are the Discussion Initiator. Your role:
46
  1. Introduce complex topics requiring multidisciplinary perspectives
47
  2. Frame debates exploring tensions between values, ethics, and progress
@@ -97,31 +107,47 @@ turn_count = 0
97
  auto_mode = False
98
  current_topic = ""
99
  last_ruling_turn = 0
 
 
 
 
 
 
 
 
100
 
101
- # === CHAT COMPLETION ===
102
- def chat_completion(system, messages, model=CHAT_MODEL):
103
- try:
104
- full_messages = [{"role": "system", "content": system}]
105
- full_messages.extend(messages)
106
-
107
  try:
108
- response = openai.chat.completions.create(
109
- model=model,
110
- messages=full_messages,
111
- temperature=0.75,
112
- max_tokens=300
113
- )
114
- return response.choices[0].message.content.strip()
115
- except AttributeError:
116
- response = openai.ChatCompletion.create(
117
- model=model,
118
- messages=full_messages,
119
- temperature=0.75,
120
- max_tokens=300
121
- )
122
- return response['choices'][0]['message']['content'].strip()
123
- except Exception as e:
124
- return f"[API Error: {str(e)}]"
 
 
 
 
 
 
 
 
 
 
125
 
126
  # === MEMORY MANAGEMENT ===
127
  def embed_and_store(text, agent=None):
@@ -131,7 +157,8 @@ def embed_and_store(text, agent=None):
131
  memory_data.append({
132
  "text": text,
133
  "timestamp": datetime.now().isoformat(),
134
- "agent": agent or "system"
 
135
  })
136
  if len(memory_data) % 5 == 0:
137
  with open(MEMORY_FILE, "wb") as f:
@@ -140,6 +167,26 @@ def embed_and_store(text, agent=None):
140
  except Exception as e:
141
  print(f"Memory Error: {str(e)}")
142
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
143
  # === CONVERSATION UTILITIES ===
144
  def format_convo():
145
  return "\n".join([f"**{m['agent']}**: {m['text']}" for m in conversation])
@@ -182,6 +229,13 @@ def detect_superficiality():
182
 
183
  return superficial_count > depth_count * 2
184
 
 
 
 
 
 
 
 
185
  def detect_repetition():
186
  """Check if recent messages are conceptually similar"""
187
  if len(conversation) < 4:
@@ -189,8 +243,12 @@ def detect_repetition():
189
 
190
  recent = [m['text'] for m in conversation[-4:]]
191
  embeddings = [get_embedding(text) for text in recent]
192
- similarity = cosine_similarity(embeddings[-1], embeddings[-3])
193
- return similarity > 0.82
 
 
 
 
194
 
195
  def detect_cultural_relevance():
196
  """Check if cultural perspectives are needed"""
@@ -231,7 +289,7 @@ def detect_judgment_opportunity():
231
  # === AGENT FUNCTIONS ===
232
  def generate_topic():
233
  """Generate a complex discussion topic"""
234
- topic = chat_completion(
235
  "Generate a complex discussion topic requiring multidisciplinary and multicultural analysis",
236
  [{"role": "user", "content": "Create a topic addressing tensions between technological progress, ethics, and cultural values"}]
237
  )
@@ -241,13 +299,31 @@ def outsider_comment():
241
  """Generate outsider perspective"""
242
  context = "\n".join([f"{m['agent']}: {m['text']}" for m in conversation[-4:]])
243
  prompt = f"Conversation Context:\n{context}\n\nProvide your cross-disciplinary perspective:"
244
- return chat_completion(OUTSIDER_PROMPT, [{"role": "user", "content": prompt}])
 
 
 
 
 
 
 
 
 
245
 
246
  def cultural_perspective():
247
  """Generate cultural diversity perspective"""
248
  context = "\n".join([f"{m['agent']}: {m['text']}" for m in conversation[-4:]])
249
  prompt = f"Conversation Context:\n{context}\n\nProvide diverse cultural perspectives on this topic:"
250
- return chat_completion(CULTURAL_LENS_PROMPT, [{"role": "user", "content": prompt}])
 
 
 
 
 
 
 
 
 
251
 
252
  def judge_ruling():
253
  """Generate final judgment or ruling"""
@@ -271,7 +347,15 @@ Your ruling should:
271
  5. Consider ethical and practical implications
272
  6. Provide constructive guidance for next steps"""
273
 
274
- ruling = chat_completion(JUDGE_PROMPT, [{"role": "user", "content": prompt}])
 
 
 
 
 
 
 
 
275
  last_ruling_turn = turn_count
276
  return ruling
277
 
@@ -282,29 +366,42 @@ def step(topic_input=""):
282
  # Initialize new discussion
283
  if not conversation:
284
  current_topic = topic_input or generate_topic()
285
- msg = chat_completion(
 
 
 
 
 
 
 
 
 
 
286
  AGENT_A_PROMPT,
287
- [{"role": "user", "content": f"Initiate a deep discussion on: {current_topic}"}]
 
288
  )
289
  conversation.append({"agent": "πŸ’‘ Initiator", "text": msg})
290
  embed_and_store(msg, "Initiator")
291
  turn_count = 1
292
  last_ruling_turn = 0
293
- return format_convo(), "", "", "", "", current_topic
294
 
295
  # Critical Responder engages
296
  last_msg = conversation[-1]['text']
297
- b_msg = chat_completion(
298
  AGENT_B_PROMPT,
299
- [{"role": "user", "content": f"Topic: {current_topic}\n\nLast statement: {last_msg}"}]
 
300
  )
301
  conversation.append({"agent": "πŸ” Responder", "text": b_msg})
302
  embed_and_store(b_msg, "Responder")
303
 
304
  # Initiator counters
305
- a_msg = chat_completion(
306
  AGENT_A_PROMPT,
307
- [{"role": "user", "content": f"Topic: {current_topic}\n\nCritical response: {b_msg}"}]
 
308
  )
309
  conversation.append({"agent": "πŸ’‘ Initiator", "text": a_msg})
310
  embed_and_store(a_msg, "Initiator")
@@ -314,7 +411,11 @@ def step(topic_input=""):
314
  if turn_count % 3 == 0 or detect_repetition() or detect_superficiality():
315
  context = "\n".join([m['text'] for m in conversation[-4:]])
316
  prompt = f"Topic: {current_topic}\n\nDiscussion Context:\n{context}\n\nDeepen the analysis:"
317
- intervention = chat_completion(OVERSEER_PROMPT, [{"role": "user", "content": prompt}])
 
 
 
 
318
  conversation.append({"agent": "βš–οΈ Depth Guardian", "text": intervention})
319
  embed_and_store(intervention, "Overseer")
320
 
@@ -342,96 +443,281 @@ def step(topic_input=""):
342
  embed_and_store(judge_msg, "Judge")
343
 
344
  turn_count += 1
345
- return format_convo(), intervention, outsider_msg, cultural_msg, judge_msg, current_topic
346
 
347
- # === OVERSEER QUERY HANDLER ===
348
- def overseer_respond(query):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
349
  try:
350
- context = "\n".join([m['text'] for m in conversation[-3:]]) if conversation else "No context"
351
- messages = [{"role": "user", "content": f"Discussion Topic: {current_topic}\n\nRecent context:\n{context}\n\nQuery: {query}"}]
352
- return chat_completion(OVERSEER_PROMPT, messages)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
353
  except Exception as e:
354
- return f"[Overseer Error: {str(e)}]"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
355
 
356
- # === JUDGE RULING HANDLER ===
357
- def request_ruling():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
358
  try:
359
- ruling = judge_ruling()
360
- conversation.append({"agent": "βš–οΈ Judge", "text": ruling})
361
- embed_and_store(ruling, "Judge")
362
- return ruling
 
 
 
 
 
 
 
363
  except Exception as e:
364
- return f"[Judge Error: {str(e)}]"
365
-
366
- # === AUTO MODE HANDLER ===
367
- def auto_loop():
368
- global auto_mode
369
- while auto_mode:
370
- step()
371
- time.sleep(6)
372
-
373
- def toggle_auto():
374
- global auto_mode
375
- auto_mode = not auto_mode
376
- if auto_mode:
377
- threading.Thread(target=auto_loop, daemon=True).start()
378
- return "πŸ”΄ Auto: OFF" if not auto_mode else "🟒 Auto: ON"
379
 
380
  # === GRADIO UI ===
381
- with gr.Blocks(title="Advanced Discussion Simulator") as demo:
382
- gr.Markdown("# 🧠 Advanced Discussion Simulator")
383
- gr.Markdown("### Hexa-Agent System for Complex Discourse")
384
 
 
385
  with gr.Row():
386
- topic_display = gr.Textbox(label="Current Topic", interactive=False)
 
 
387
 
388
- with gr.Row():
389
- convo_display = gr.Markdown(
390
- value="**Discussion will appear here**",
391
- elem_id="convo-display",
392
- elem_classes="convo-scroll"
393
  )
394
 
395
- with gr.Row():
396
- step_btn = gr.Button("▢️ Next Turn", variant="primary")
397
- auto_btn = gr.Button("πŸ”΄ Auto: OFF", variant="secondary")
398
- clear_btn = gr.Button("πŸ”„ New Discussion", variant="stop")
399
- topic_btn = gr.Button("🎲 Random Topic", variant="secondary")
400
- ruling_btn = gr.Button("βš–οΈ Request Ruling", variant="primary")
401
 
402
- with gr.Row():
403
- with gr.Column(scale=1):
404
- gr.Markdown("### βš–οΈ Depth Guardian")
405
- intervention_display = gr.Textbox(label="", interactive=False)
406
- with gr.Column(scale=1):
407
- gr.Markdown("### 🌐 Cross-Disciplinary")
408
- outsider_display = gr.Textbox(label="", interactive=False)
409
- with gr.Column(scale=1):
410
- gr.Markdown("### 🌍 Cultural Lens")
411
- cultural_display = gr.Textbox(label="", interactive=False)
 
 
 
 
 
 
412
 
413
- with gr.Row():
414
- with gr.Column(scale=3):
415
- gr.Markdown("### βš–οΈ Final Judgment")
416
- judge_display = gr.Textbox(label="", interactive=False, lines=4)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
417
 
418
- with gr.Accordion("πŸ’¬ Guide the Discussion", open=False):
419
- topic_input = gr.Textbox(label="Set Custom Topic", placeholder="e.g., Ethics of AGI in cultural contexts...")
 
 
 
 
 
 
 
 
420
  with gr.Row():
421
- qbox = gr.Textbox(label="Ask the Depth Guardian", placeholder="What perspectives are missing?")
422
- ruling_qbox = gr.Textbox(label="Specific Question for Judge", placeholder="What should be our guiding principle?")
 
 
 
 
 
423
  with gr.Row():
424
- overseer_out = gr.Textbox(label="Depth Guardian Response", interactive=False)
425
- judge_out = gr.Textbox(label="Judge's Response", interactive=False)
 
 
 
 
 
 
 
 
 
426
 
427
- # Custom CSS for scrollable conversation
428
  demo.css = """
429
- .convo-scroll {
430
  max-height: 400px;
431
  overflow-y: auto;
432
- padding: 10px;
433
  border: 1px solid #e0e0e0;
434
- border-radius: 5px;
 
 
 
 
 
 
 
 
 
435
  }
436
  """
437
 
@@ -441,40 +727,129 @@ with gr.Blocks(title="Advanced Discussion Simulator") as demo:
441
  conversation = []
442
  turn_count = 0
443
  current_topic = ""
444
- return "**New discussion started**", "", "", "", "", "", ""
 
 
 
 
445
 
446
  def new_topic():
447
- clear_convo()
448
  topic = generate_topic()
449
- return "", "", "", "", "", topic, topic
450
 
451
  def ask_judge(query):
452
  try:
453
  context = "\n".join([m['text'] for m in conversation[-3:]]) if conversation else "No context"
454
  messages = [{"role": "user", "content": f"Discussion Topic: {current_topic}\n\nRecent context:\n{context}\n\nSpecific Question: {query}"}]
455
- return chat_completion(JUDGE_PROMPT, messages)
456
  except Exception as e:
457
  return f"[Judge Error: {str(e)}]"
458
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
459
  step_btn.click(
460
  step,
461
- inputs=[topic_input],
462
- outputs=[convo_display, intervention_display, outsider_display, cultural_display, judge_display, topic_display]
 
 
 
 
 
 
 
 
463
  )
464
- qbox.submit(overseer_respond, inputs=qbox, outputs=overseer_out)
465
- ruling_qbox.submit(ask_judge, inputs=ruling_qbox, outputs=judge_out)
466
- auto_btn.click(toggle_auto, outputs=auto_btn)
467
  clear_btn.click(
468
  clear_convo,
469
- outputs=[convo_display, intervention_display, outsider_display, cultural_display, judge_display, topic_display, overseer_out]
 
 
 
 
470
  )
471
  topic_btn.click(
472
  new_topic,
473
- outputs=[convo_display, intervention_display, outsider_display, cultural_display, judge_display, topic_display, overseer_out]
474
  )
475
  ruling_btn.click(
476
- request_ruling,
477
  outputs=[judge_display]
478
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
479
 
480
  demo.launch()
 
1
+ # app.py - DeepSeek Hexa-Agent Discussion Platform
2
  import gradio as gr
3
  import openai
4
  import threading
 
9
  import pickle
10
  from datetime import datetime
11
  import re
12
+ import json
13
+ import matplotlib.pyplot as plt
14
+ import networkx as nx
15
+ from reportlab.lib.pagesizes import letter
16
+ from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer
17
+ from reportlab.lib.styles import getSampleStyleSheet
18
+ from functools import lru_cache
19
+ import requests
20
 
21
  # === CONFIG ===
22
  EMBEDDING_MODEL = "text-embedding-3-small"
 
26
  openai.api_key = os.environ.get("OPENAI_API_KEY")
27
 
28
  # === EMBEDDING UTILS ===
29
+ @lru_cache(maxsize=500)
30
  def get_embedding(text, model=EMBEDDING_MODEL):
31
+ """Cached embedding function for performance"""
32
  text = text.replace("\n", " ")
33
  try:
34
  response = openai.embeddings.create(input=[text], model=model)
 
51
  except:
52
  memory_index = faiss.IndexFlatL2(1536)
53
 
54
+ # === AGENT SYSTEM PROMPTS (Configurable) ===
55
  AGENT_A_PROMPT = """You are the Discussion Initiator. Your role:
56
  1. Introduce complex topics requiring multidisciplinary perspectives
57
  2. Frame debates exploring tensions between values, ethics, and progress
 
107
  auto_mode = False
108
  current_topic = ""
109
  last_ruling_turn = 0
110
+ agent_params = {
111
+ "Initiator": {"creativity": 0.7, "criticality": 0.5},
112
+ "Responder": {"creativity": 0.5, "criticality": 0.8},
113
+ "Guardian": {"creativity": 0.6, "criticality": 0.9},
114
+ "Provocateur": {"creativity": 0.9, "criticality": 0.7},
115
+ "Cultural": {"creativity": 0.7, "criticality": 0.6},
116
+ "Judge": {"creativity": 0.4, "criticality": 0.9}
117
+ }
118
 
119
+ # === ERROR-HANDLED API CALLS ===
120
+ def safe_chat_completion(system, messages, model=CHAT_MODEL, temperature=0.7, max_retries=3):
121
+ """Robust API call with exponential backoff"""
122
+ for attempt in range(max_retries):
 
 
123
  try:
124
+ full_messages = [{"role": "system", "content": system}]
125
+ full_messages.extend(messages)
126
+
127
+ try:
128
+ response = openai.chat.completions.create(
129
+ model=model,
130
+ messages=full_messages,
131
+ temperature=temperature,
132
+ max_tokens=300
133
+ )
134
+ return response.choices[0].message.content.strip()
135
+ except AttributeError:
136
+ response = openai.ChatCompletion.create(
137
+ model=model,
138
+ messages=full_messages,
139
+ temperature=temperature,
140
+ max_tokens=300
141
+ )
142
+ return response['choices'][0]['message']['content'].strip()
143
+ except Exception as e:
144
+ if attempt < max_retries - 1:
145
+ wait_time = 2 ** attempt
146
+ print(f"API error: {e}. Retrying in {wait_time} seconds...")
147
+ time.sleep(wait_time)
148
+ else:
149
+ return f"⚠️ API Error: {str(e)}"
150
+ return "⚠️ Max retries exceeded"
151
 
152
  # === MEMORY MANAGEMENT ===
153
  def embed_and_store(text, agent=None):
 
157
  memory_data.append({
158
  "text": text,
159
  "timestamp": datetime.now().isoformat(),
160
+ "agent": agent or "system",
161
+ "topic": current_topic
162
  })
163
  if len(memory_data) % 5 == 0:
164
  with open(MEMORY_FILE, "wb") as f:
 
167
  except Exception as e:
168
  print(f"Memory Error: {str(e)}")
169
 
170
+ def retrieve_relevant_memory(query, k=3):
171
+ """Retrieve relevant past discussions"""
172
+ try:
173
+ query_embedding = get_embedding(query)
174
+ distances, indices = memory_index.search(np.array([query_embedding], dtype='float32'), k)
175
+
176
+ relevant = []
177
+ for i, idx in enumerate(indices[0]):
178
+ if idx < len(memory_data) and idx >= 0:
179
+ relevant.append({
180
+ "text": memory_data[idx]['text'][:200] + "...",
181
+ "topic": memory_data[idx].get('topic', 'Unknown'),
182
+ "agent": memory_data[idx].get('agent', 'Unknown'),
183
+ "similarity": 1 - distances[0][i] # Convert distance to similarity
184
+ })
185
+ return relevant
186
+ except Exception as e:
187
+ print(f"Memory retrieval error: {str(e)}")
188
+ return []
189
+
190
  # === CONVERSATION UTILITIES ===
191
  def format_convo():
192
  return "\n".join([f"**{m['agent']}**: {m['text']}" for m in conversation])
 
229
 
230
  return superficial_count > depth_count * 2
231
 
232
+ def batch_cosine_similarity(embeddings):
233
+ """Efficient batch similarity calculation"""
234
+ norms = np.linalg.norm(embeddings, axis=1)
235
+ dot_matrix = np.dot(embeddings, embeddings.T)
236
+ norm_matrix = np.outer(norms, norms)
237
+ return dot_matrix / norm_matrix
238
+
239
  def detect_repetition():
240
  """Check if recent messages are conceptually similar"""
241
  if len(conversation) < 4:
 
243
 
244
  recent = [m['text'] for m in conversation[-4:]]
245
  embeddings = [get_embedding(text) for text in recent]
246
+
247
+ # Use batch processing for efficiency
248
+ similarity_matrix = batch_cosine_similarity(np.array(embeddings))
249
+
250
+ # Check similarity between current and previous messages
251
+ return any(similarity_matrix[-1][i] > 0.82 for i in range(len(embeddings)-1))
252
 
253
  def detect_cultural_relevance():
254
  """Check if cultural perspectives are needed"""
 
289
  # === AGENT FUNCTIONS ===
290
  def generate_topic():
291
  """Generate a complex discussion topic"""
292
+ topic = safe_chat_completion(
293
  "Generate a complex discussion topic requiring multidisciplinary and multicultural analysis",
294
  [{"role": "user", "content": "Create a topic addressing tensions between technological progress, ethics, and cultural values"}]
295
  )
 
299
  """Generate outsider perspective"""
300
  context = "\n".join([f"{m['agent']}: {m['text']}" for m in conversation[-4:]])
301
  prompt = f"Conversation Context:\n{context}\n\nProvide your cross-disciplinary perspective:"
302
+
303
+ # Apply agent parameters
304
+ params = agent_params["Provocateur"]
305
+ temp = 0.5 + params["creativity"] * 0.5 # Map to 0.5-1.0 range
306
+
307
+ return safe_chat_completion(
308
+ OUTSIDER_PROMPT,
309
+ [{"role": "user", "content": prompt}],
310
+ temperature=temp
311
+ )
312
 
313
  def cultural_perspective():
314
  """Generate cultural diversity perspective"""
315
  context = "\n".join([f"{m['agent']}: {m['text']}" for m in conversation[-4:]])
316
  prompt = f"Conversation Context:\n{context}\n\nProvide diverse cultural perspectives on this topic:"
317
+
318
+ # Apply agent parameters
319
+ params = agent_params["Cultural"]
320
+ temp = 0.5 + params["creativity"] * 0.5
321
+
322
+ return safe_chat_completion(
323
+ CULTURAL_LENS_PROMPT,
324
+ [{"role": "user", "content": prompt}],
325
+ temperature=temp
326
+ )
327
 
328
  def judge_ruling():
329
  """Generate final judgment or ruling"""
 
347
  5. Consider ethical and practical implications
348
  6. Provide constructive guidance for next steps"""
349
 
350
+ # Apply agent parameters
351
+ params = agent_params["Judge"]
352
+ temp = 0.3 + params["criticality"] * 0.4 # More critical = lower temperature
353
+
354
+ ruling = safe_chat_completion(
355
+ JUDGE_PROMPT,
356
+ [{"role": "user", "content": prompt}],
357
+ temperature=temp
358
+ )
359
  last_ruling_turn = turn_count
360
  return ruling
361
 
 
366
  # Initialize new discussion
367
  if not conversation:
368
  current_topic = topic_input or generate_topic()
369
+
370
+ # Retrieve relevant memory
371
+ memory_context = retrieve_relevant_memory(current_topic)
372
+ context_str = ""
373
+ if memory_context:
374
+ context_str = "\n\nRelevant past discussions:\n" + "\n".join(
375
+ [f"- {item['agent']} on '{item['topic']}': {item['text']}"
376
+ for item in memory_context]
377
+ )
378
+
379
+ msg = safe_chat_completion(
380
  AGENT_A_PROMPT,
381
+ [{"role": "user", "content": f"Initiate a deep discussion on: {current_topic}{context_str}"}],
382
+ temperature=0.5 + agent_params["Initiator"]["creativity"] * 0.5
383
  )
384
  conversation.append({"agent": "πŸ’‘ Initiator", "text": msg})
385
  embed_and_store(msg, "Initiator")
386
  turn_count = 1
387
  last_ruling_turn = 0
388
+ return format_convo(), "", "", "", "", current_topic, turn_count, ""
389
 
390
  # Critical Responder engages
391
  last_msg = conversation[-1]['text']
392
+ b_msg = safe_chat_completion(
393
  AGENT_B_PROMPT,
394
+ [{"role": "user", "content": f"Topic: {current_topic}\n\nLast statement: {last_msg}"}],
395
+ temperature=0.4 + agent_params["Responder"]["criticality"] * 0.4
396
  )
397
  conversation.append({"agent": "πŸ” Responder", "text": b_msg})
398
  embed_and_store(b_msg, "Responder")
399
 
400
  # Initiator counters
401
+ a_msg = safe_chat_completion(
402
  AGENT_A_PROMPT,
403
+ [{"role": "user", "content": f"Topic: {current_topic}\n\nCritical response: {b_msg}"}],
404
+ temperature=0.5 + agent_params["Initiator"]["creativity"] * 0.5
405
  )
406
  conversation.append({"agent": "πŸ’‘ Initiator", "text": a_msg})
407
  embed_and_store(a_msg, "Initiator")
 
411
  if turn_count % 3 == 0 or detect_repetition() or detect_superficiality():
412
  context = "\n".join([m['text'] for m in conversation[-4:]])
413
  prompt = f"Topic: {current_topic}\n\nDiscussion Context:\n{context}\n\nDeepen the analysis:"
414
+ intervention = safe_chat_completion(
415
+ OVERSEER_PROMPT,
416
+ [{"role": "user", "content": prompt}],
417
+ temperature=0.5 + agent_params["Guardian"]["criticality"] * 0.4
418
+ )
419
  conversation.append({"agent": "βš–οΈ Depth Guardian", "text": intervention})
420
  embed_and_store(intervention, "Overseer")
421
 
 
443
  embed_and_store(judge_msg, "Judge")
444
 
445
  turn_count += 1
446
+ return format_convo(), intervention, outsider_msg, cultural_msg, judge_msg, current_topic, turn_count, ""
447
 
448
+ # === ANALYSIS & VISUALIZATION ===
449
+ def analyze_conversation():
450
+ """Generate insights about the discussion"""
451
+ # Count agent contributions
452
+ agent_counts = {}
453
+ for msg in conversation:
454
+ agent = msg['agent'].split()[0] # Remove emoji
455
+ agent_counts[agent] = agent_counts.get(agent, 0) + 1
456
+
457
+ # Sentiment analysis
458
+ sentiment_prompt = f"Analyze overall sentiment of this discussion:\n{format_convo()}"
459
+ sentiment = safe_chat_completion(
460
+ "You are a sentiment analysis expert. Provide a brief assessment of the discussion tone.",
461
+ [{"role": "user", "content": sentiment_prompt}]
462
+ )
463
+
464
+ # Topic extraction
465
+ topic_prompt = f"Extract key topics from this discussion:\n{format_convo()}"
466
+ topics = safe_chat_completion(
467
+ "You are a topic extraction expert. List the top 5 topics as a JSON array.",
468
+ [{"role": "user", "content": topic_prompt}]
469
+ )
470
+
471
  try:
472
+ topics = json.loads(topics)
473
+ except:
474
+ topics = ["Topic extraction failed"]
475
+
476
+ return {
477
+ "agents": list(agent_counts.keys()),
478
+ "counts": [agent_counts.get(a, 0) for a in list(agent_counts.keys())],
479
+ "topics": topics,
480
+ "sentiment": sentiment
481
+ }
482
+
483
+ def generate_knowledge_graph():
484
+ """Create a knowledge graph of discussion concepts"""
485
+ # Extract entities and relationships
486
+ extraction_prompt = f"""
487
+ Analyze this discussion and extract:
488
+ 1. Key concepts (nouns, important terms)
489
+ 2. Relationships between concepts (verb phrases)
490
+
491
+ Discussion:
492
+ {format_convo()}
493
+
494
+ Return as JSON: {{"concepts": ["list", "of", "concepts"], "relationships": [["concept1", "relationship", "concept2"]]}}
495
+ """
496
+
497
+ try:
498
+ graph_data = safe_chat_completion(
499
+ "You are a knowledge graph extraction expert.",
500
+ [{"role": "user", "content": extraction_prompt}]
501
+ )
502
+ graph_data = json.loads(graph_data)
503
+
504
+ # Create graph visualization
505
+ G = nx.DiGraph()
506
+ G.add_nodes_from(graph_data["concepts"])
507
+
508
+ for rel in graph_data["relationships"]:
509
+ if len(rel) == 3:
510
+ G.add_edge(rel[0], rel[2], label=rel[1])
511
+
512
+ plt.figure(figsize=(10, 8))
513
+ pos = nx.spring_layout(G, seed=42)
514
+ nx.draw(G, pos, with_labels=True, node_size=2000, node_color="skyblue", font_size=10)
515
+ edge_labels = nx.get_edge_attributes(G, 'label')
516
+ nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)
517
+ plt.title("Discussion Knowledge Graph")
518
+ plt.savefig("knowledge_graph.png")
519
+ return "knowledge_graph.png"
520
  except Exception as e:
521
+ print(f"Graph error: {str(e)}")
522
+ return None
523
+
524
+ # === EXPORT FUNCTIONS ===
525
+ def export_pdf_report():
526
+ """Generate PDF report of discussion"""
527
+ filename = f"discussion_report_{datetime.now().strftime('%Y%m%d_%H%M%S')}.pdf"
528
+ doc = SimpleDocTemplate(filename, pagesize=letter)
529
+ styles = getSampleStyleSheet()
530
+ story = []
531
+
532
+ # Title
533
+ story.append(Paragraph(f"Discussion Report: {current_topic}", styles['Title']))
534
+ story.append(Spacer(1, 12))
535
+
536
+ # Summary
537
+ analysis = analyze_conversation()
538
+ story.append(Paragraph("Discussion Summary", styles['Heading2']))
539
+ story.append(Paragraph(f"<b>Turn Count:</b> {turn_count}", styles['BodyText']))
540
+ story.append(Paragraph(f"<b>Sentiment:</b> {analysis['sentiment']}", styles['BodyText']))
541
+ story.append(Spacer(1, 12))
542
+
543
+ # Key Topics
544
+ story.append(Paragraph("Key Topics", styles['Heading2']))
545
+ for topic in analysis['topics']:
546
+ story.append(Paragraph(f"- {topic}", styles['BodyText']))
547
+ story.append(Spacer(1, 12))
548
+
549
+ # Full Conversation
550
+ story.append(Paragraph("Full Discussion", styles['Heading2']))
551
+ for msg in conversation:
552
+ story.append(Paragraph(f"<b>{msg['agent']}:</b> {msg['text']}", styles['BodyText']))
553
+ story.append(Spacer(1, 6))
554
+
555
+ doc.build(story)
556
+ return filename
557
+
558
+ def export_json_data():
559
+ """Export conversation as JSON"""
560
+ filename = f"discussion_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
561
+ with open(filename, 'w') as f:
562
+ json.dump({
563
+ "topic": current_topic,
564
+ "turns": turn_count,
565
+ "conversation": conversation,
566
+ "analysis": analyze_conversation()
567
+ }, f, indent=2)
568
+ return filename
569
 
570
+ def export_text_transcript():
571
+ """Export as plain text"""
572
+ filename = f"transcript_{datetime.now().strftime('%Y%m%d_%H%M%S')}.txt"
573
+ with open(filename, 'w') as f:
574
+ f.write(f"Discussion Topic: {current_topic}\n\n")
575
+ f.write("Participants:\n")
576
+ agents = set(msg['agent'] for msg in conversation)
577
+ for agent in agents:
578
+ f.write(f"- {agent}\n")
579
+
580
+ f.write("\nConversation:\n")
581
+ for msg in conversation:
582
+ f.write(f"{msg['agent']}: {msg['text']}\n\n")
583
+ return filename
584
+
585
+ # === INTEGRATION FUNCTIONS ===
586
+ def send_to_webhook(url):
587
+ """Send discussion data to external webhook"""
588
  try:
589
+ payload = {
590
+ "topic": current_topic,
591
+ "turns": turn_count,
592
+ "conversation": conversation,
593
+ "timestamp": datetime.now().isoformat()
594
+ }
595
+ response = requests.post(url, json=payload, timeout=10)
596
+ if response.status_code == 200:
597
+ return "βœ… Data sent successfully!"
598
+ else:
599
+ return f"⚠️ Error {response.status_code}: {response.text}"
600
  except Exception as e:
601
+ return f"⚠️ Connection error: {str(e)}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
602
 
603
  # === GRADIO UI ===
604
+ with gr.Blocks(theme=gr.themes.Soft(), title="DeepSeek Discussion Platform") as demo:
605
+ gr.Markdown("# 🧠 DeepSeek Hexa-Agent Discussion System")
606
+ gr.Markdown("### AI-Powered Complex Discourse Analysis")
607
 
608
+ # Status panel
609
  with gr.Row():
610
+ turn_counter = gr.Number(label="Turn Count", value=0, interactive=False)
611
+ topic_display = gr.Textbox(label="Current Topic", interactive=False, lines=2)
612
+ agent_status = gr.Textbox(label="Active Agents", value="πŸ’‘ Initiator, πŸ” Responder", interactive=False)
613
 
614
+ # Tabbed interface
615
+ with gr.Tab("Live Discussion"):
616
+ convo_display = gr.HTML(
617
+ value="<div class='convo-container'>Discussion will appear here</div>",
618
+ elem_id="convo-display"
619
  )
620
 
621
+ with gr.Row():
622
+ step_btn = gr.Button("▢️ Next Turn", variant="primary")
623
+ auto_btn = gr.Button("πŸ”΄ Auto: OFF", variant="secondary")
624
+ clear_btn = gr.Button("πŸ”„ New Discussion", variant="stop")
625
+ topic_btn = gr.Button("🎲 Random Topic", variant="secondary")
626
+ ruling_btn = gr.Button("βš–οΈ Request Ruling", variant="primary")
627
 
628
+ with gr.Tab("Agent Perspectives"):
629
+ with gr.Row():
630
+ with gr.Column(scale=1):
631
+ gr.Markdown("### βš–οΈ Depth Guardian")
632
+ intervention_display = gr.Textbox(label="", interactive=False)
633
+ with gr.Column(scale=1):
634
+ gr.Markdown("### 🌐 Cross-Disciplinary")
635
+ outsider_display = gr.Textbox(label="", interactive=False)
636
+ with gr.Column(scale=1):
637
+ gr.Markdown("### 🌍 Cultural Lens")
638
+ cultural_display = gr.Textbox(label="", interactive=False)
639
+
640
+ with gr.Row():
641
+ with gr.Column(scale=3):
642
+ gr.Markdown("### βš–οΈ Final Judgment")
643
+ judge_display = gr.Textbox(label="", interactive=False, lines=4)
644
 
645
+ with gr.Tab("Analysis Dashboard"):
646
+ gr.Markdown("### Conversation Insights")
647
+ with gr.Row():
648
+ sentiment_display = gr.Textbox(label="Discussion Sentiment", interactive=False)
649
+ topics_display = gr.JSON(label="Key Topics")
650
+
651
+ with gr.Row():
652
+ agent_plot = gr.Plot(label="Agent Participation")
653
+ analysis_btn = gr.Button("Generate Insights", variant="primary")
654
+
655
+ with gr.Row():
656
+ gr.Markdown("### Knowledge Graph")
657
+ graph_btn = gr.Button("Generate Knowledge Graph", variant="secondary")
658
+ graph_display = gr.Image(label="Concept Relationships", interactive=False)
659
+
660
+ with gr.Tab("Collaboration"):
661
+ gr.Markdown("### Real-Time Collaboration")
662
+ with gr.Row():
663
+ user_input = gr.Textbox(label="Your Contribution", placeholder="Add your perspective...")
664
+ submit_btn = gr.Button("Add to Discussion")
665
+
666
+ with gr.Row():
667
+ voting_btn = gr.Button("πŸ‘ Vote for Current Direction")
668
+ flag_btn = gr.Button("🚩 Flag Issue")
669
+
670
+ with gr.Row():
671
+ user_feedback = gr.Textbox(label="Community Feedback", interactive=False)
672
 
673
+ with gr.Tab("Export & Integrate"):
674
+ with gr.Row():
675
+ format_radio = gr.Radio(
676
+ ["PDF Report", "JSON Data", "Text Transcript"],
677
+ label="Export Format",
678
+ value="PDF Report"
679
+ )
680
+ export_btn = gr.Button("Export Discussion", variant="primary")
681
+ export_result = gr.File(label="Download File")
682
+
683
  with gr.Row():
684
+ gr.Markdown("### API Integration")
685
+ webhook_url = gr.Textbox(label="Webhook URL", placeholder="https://your-platform.com/webhook")
686
+ integrate_btn = gr.Button("Connect to External Platform", variant="secondary")
687
+ integration_status = gr.Textbox(label="Status", interactive=False)
688
+
689
+ with gr.Tab("Agent Configuration"):
690
+ gr.Markdown("### Customize Agent Behavior")
691
  with gr.Row():
692
+ for agent in ["Initiator", "Responder", "Guardian", "Provocateur", "Cultural", "Judge"]:
693
+ with gr.Column():
694
+ gr.Markdown(f"#### {agent}")
695
+ agent_params[f"{agent}_creativity"] = gr.Slider(
696
+ 0.0, 1.0, value=agent_params[agent]["creativity"],
697
+ label="Creativity", interactive=True
698
+ )
699
+ agent_params[f"{agent}_critical"] = gr.Slider(
700
+ 0.0, 1.0, value=agent_params[agent]["criticality"],
701
+ label="Criticality", interactive=True
702
+ )
703
 
704
+ # Custom CSS
705
  demo.css = """
706
+ .convo-container {
707
  max-height: 400px;
708
  overflow-y: auto;
709
+ padding: 15px;
710
  border: 1px solid #e0e0e0;
711
+ border-radius: 8px;
712
+ background-color: #f9f9f9;
713
+ line-height: 1.6;
714
+ }
715
+ .convo-container p {
716
+ margin-bottom: 10px;
717
+ }
718
+ #topic-display {
719
+ font-weight: bold;
720
+ font-size: 1.1em;
721
  }
722
  """
723
 
 
727
  conversation = []
728
  turn_count = 0
729
  current_topic = ""
730
+ return (
731
+ "<div class='convo-container'>New discussion started</div>",
732
+ "", "", "", "", "", 0, "",
733
+ {"agents": [], "counts": []}, "", None, ""
734
+ )
735
 
736
  def new_topic():
737
+ clear_result = clear_convo()
738
  topic = generate_topic()
739
+ return clear_result[:6] + (topic,) + clear_result[7:]
740
 
741
  def ask_judge(query):
742
  try:
743
  context = "\n".join([m['text'] for m in conversation[-3:]]) if conversation else "No context"
744
  messages = [{"role": "user", "content": f"Discussion Topic: {current_topic}\n\nRecent context:\n{context}\n\nSpecific Question: {query}"}]
745
+ return safe_chat_completion(JUDGE_PROMPT, messages)
746
  except Exception as e:
747
  return f"[Judge Error: {str(e)}]"
748
 
749
+ def run_analysis():
750
+ analysis = analyze_conversation()
751
+
752
+ # Create agent participation plot
753
+ plt.figure(figsize=(8, 5))
754
+ plt.bar(analysis["agents"], analysis["counts"], color='skyblue')
755
+ plt.title("Agent Participation")
756
+ plt.ylabel("Number of Contributions")
757
+ plt.xticks(rotation=45)
758
+ plt.tight_layout()
759
+ plt.savefig("agent_participation.png")
760
+
761
+ return (
762
+ analysis["sentiment"],
763
+ analysis["topics"],
764
+ "agent_participation.png",
765
+ analysis
766
+ )
767
+
768
+ def export_handler(format):
769
+ if format == "PDF Report":
770
+ return export_pdf_report()
771
+ elif format == "JSON Data":
772
+ return export_json_data()
773
+ else:
774
+ return export_text_transcript()
775
+
776
+ def add_user_contribution(text):
777
+ if text.strip():
778
+ conversation.append({"agent": "πŸ‘€ You", "text": text})
779
+ return format_convo(), f"βœ… Added: '{text[:30]}...'"
780
+ return format_convo(), "Please enter text"
781
+
782
+ def update_agent_params(*args):
783
+ # Update global agent_params based on UI sliders
784
+ params = agent_params.copy()
785
+ for agent in params.keys():
786
+ params[agent]["creativity"] = globals()[f"{agent}_creativity"].value
787
+ params[agent]["criticality"] = globals()[f"{agent}_critical"].value
788
+ return "Agent parameters updated!"
789
+
790
+ # Connect UI components
791
  step_btn.click(
792
  step,
793
+ inputs=[topic_display],
794
+ outputs=[
795
+ convo_display, intervention_display, outsider_display,
796
+ cultural_display, judge_display, topic_display, turn_counter, agent_status
797
+ ]
798
+ )
799
+ qbox.submit(ask_judge, inputs=gr.Textbox(), outputs=gr.Textbox())
800
+ auto_btn.click(
801
+ lambda: ("🟒 Auto: ON" if not auto_mode else "πŸ”΄ Auto: OFF"),
802
+ outputs=auto_btn
803
  )
 
 
 
804
  clear_btn.click(
805
  clear_convo,
806
+ outputs=[
807
+ convo_display, intervention_display, outsider_display,
808
+ cultural_display, judge_display, topic_display, turn_counter,
809
+ agent_status, agent_plot, graph_display
810
+ ]
811
  )
812
  topic_btn.click(
813
  new_topic,
814
+ outputs=[convo_display, topic_display, turn_counter]
815
  )
816
  ruling_btn.click(
817
+ lambda: judge_ruling(),
818
  outputs=[judge_display]
819
  )
820
+ analysis_btn.click(
821
+ run_analysis,
822
+ outputs=[sentiment_display, topics_display, agent_plot, topics_display]
823
+ )
824
+ graph_btn.click(
825
+ generate_knowledge_graph,
826
+ outputs=[graph_display]
827
+ )
828
+ export_btn.click(
829
+ export_handler,
830
+ inputs=[format_radio],
831
+ outputs=[export_result]
832
+ )
833
+ integrate_btn.click(
834
+ send_to_webhook,
835
+ inputs=[webhook_url],
836
+ outputs=[integration_status]
837
+ )
838
+ submit_btn.click(
839
+ add_user_contribution,
840
+ inputs=[user_input],
841
+ outputs=[convo_display, user_feedback]
842
+ )
843
+
844
+ # Connect all agent parameter sliders
845
+ param_components = [globals()[f"{agent}_{param}"]
846
+ for agent in agent_params.keys()
847
+ for param in ["creativity", "critical"]]
848
+ for comp in param_components:
849
+ comp.change(
850
+ update_agent_params,
851
+ inputs=param_components,
852
+ outputs=[gr.Textbox(visible=False)]
853
+ )
854
 
855
  demo.launch()