ST-x-Tony commited on
Commit
7e17d80
Β·
verified Β·
1 Parent(s): 33871a2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +21 -64
app.py CHANGED
@@ -5,15 +5,7 @@
5
 
6
  # ──────────────────────────────────────────────────────────────
7
  # REASONING‑ENFORCED AGENT CONTRACT (AGENT.md)
8
- # This file is the operating policy for the entire assistant.
9
- # For every request, the agent MUST:
10
- # - Understand the goal and requirements.
11
- # - Check constraints and missing information.
12
- # - Decompose complex tasks and track dependencies.
13
- # - Plan, execute, verify, and adapt.
14
- # Private chain‑of‑thought is NEVER exposed.
15
- # Only concise reasoning summaries are shown.
16
- # See the full policy in the multi‑line comment below.
17
  # ──────────────────────────────────────────────────────────────
18
 
19
  """
@@ -55,7 +47,7 @@ execution, verification, sources, or completion.
55
 
56
  ## 6. REASONING VISIBILITY
57
  The agent MUST reason internally but NEVER expose private chain‑of‑thought.
58
- Provide concise summaries (Approach, Key assumptions, Decision, Blocker, Verification, Result) only when useful.
59
 
60
  ## 7. FINAL CONTRACT
61
  UNDERSTAND β†’ PLAN β†’ ACT β†’ VERIFY β†’ ADAPT β†’ DELIVER
@@ -84,7 +76,7 @@ from gradio_client import Client
84
  # ============================================================
85
 
86
  APP_NAME = "X-RUDRA"
87
- VERSION = "3.7.0" # bumped version
88
 
89
  M1_REPO = os.getenv("M1_REPO", "Shrijanagain/M1")
90
  M2_REPO = os.getenv("M2_REPO", "Shrijanagain/M2")
@@ -226,15 +218,15 @@ Answer:"""
226
  title = src.get("title", "Untitled")
227
  snippet = src.get("snippet", src.get("description", ""))
228
  parts.append(f"{i}. {title}: {snippet[:200]}..." if snippet else f"{i}. {title}")
229
- return "\n\n".join(parts), ""
230
  else:
231
- return "I couldn't find specific information on that topic. Could you rephrase?", ""
232
 
233
  # If only one draft exists, use that as final
234
  if not draft_m1:
235
- return draft_m2, ""
236
  if not draft_m2:
237
- return draft_m1, ""
238
 
239
  # ----- 2. Merge both drafts using M2 -----
240
  merge_prompt = f"""Question: {question}
@@ -251,18 +243,12 @@ Final answer:"""
251
 
252
  merged = call_model(m2_client, merge_prompt, max_tokens, temperature)
253
  if not merged:
254
- # If merging fails, fallback to draft_m1 (or draft_m2)
255
  merged = draft_m1
256
 
257
- # Extract thinking from <think> tags (if any)
258
- thinking_content = ""
259
- clean_answer = merged
260
- think_match = re.search(r"<think>(.*?)</think>", merged, re.DOTALL)
261
- if think_match:
262
- thinking_content = think_match.group(1).strip()
263
- clean_answer = re.sub(r"<think>.*?</think>", "", merged, flags=re.DOTALL).strip()
264
-
265
- return clean_answer, thinking_content
266
 
267
 
268
  # ============================================================
@@ -433,7 +419,7 @@ def safe_dict(value):
433
 
434
 
435
  # ============================================================
436
- # MAIN RESEARCH FUNCTION (always returns 6 outputs)
437
  # ============================================================
438
 
439
  async def do_research(question, max_results, max_rounds, use_models, freshness):
@@ -442,10 +428,9 @@ async def do_research(question, max_results, max_rounds, use_models, freshness):
442
  empty_sources = ""
443
  empty_evidence = ""
444
  empty_verification = ""
445
- empty_thinking = ""
446
 
447
  if not question or not str(question).strip():
448
- return empty_history, empty_activity, empty_sources, empty_evidence, empty_verification, empty_thinking
449
 
450
  question = str(question).strip()
451
 
@@ -456,7 +441,7 @@ async def do_research(question, max_results, max_rounds, use_models, freshness):
456
  {"role": "user", "content": question},
457
  {"role": "assistant", "content": answer}
458
  ]
459
- return history, "⚑ Casual chat (model reply, no search).", "", "", "", ""
460
 
461
  # ---- Serious query ----
462
  started = time.perf_counter()
@@ -488,22 +473,20 @@ async def do_research(question, max_results, max_rounds, use_models, freshness):
488
  })
489
  data["sources"] = sources
490
 
491
- # Generate final answer and thinking (using new dual‑draft + merge)
492
- final_answer, thinking_content = get_combined_model_answer(question, sources)
493
 
494
  sources_md = format_sources(sources)
495
  evidence_md = format_evidence(data.get("claims", []))
496
  verification_md = format_verification(data.get("contradictions", []))
497
  activity_md = build_activity(data, elapsed_ms)
498
 
499
- thinking_md = f"### 🧠 Thinking\n\n{thinking_content}" if thinking_content else ""
500
-
501
  history = [
502
  {"role": "user", "content": question},
503
  {"role": "assistant", "content": final_answer}
504
  ]
505
 
506
- return history, activity_md, sources_md, evidence_md, verification_md, thinking_md
507
 
508
  except Exception as exc:
509
  error = f"❌ **X-RUDRA Error**\n\n`{type(exc).__name__}: {exc}`"
@@ -515,7 +498,7 @@ async def do_research(question, max_results, max_rounds, use_models, freshness):
515
  {"role": "user", "content": question},
516
  {"role": "assistant", "content": error}
517
  ]
518
- return history, "❌ Research failed.", "", "", "", ""
519
 
520
 
521
  # ============================================================
@@ -542,7 +525,7 @@ def health_check():
542
 
543
 
544
  # ============================================================
545
- # CSS – includes spinner animation
546
  # ============================================================
547
 
548
  CSS = """
@@ -554,36 +537,11 @@ body { background: #f7f7f8; }
554
  #chat { border-radius: 18px; }
555
  #send { min-height: 52px; font-size: 18px; font-weight: 700; }
556
  footer { display: none !important; }
557
-
558
- @keyframes think-pulse {
559
- 0% { opacity: 0.3; transform: scale(0.95); }
560
- 50% { opacity: 1; transform: scale(1.05); }
561
- 100% { opacity: 0.3; transform: scale(0.95); }
562
- }
563
- .thinking-spinner {
564
- display: inline-block;
565
- width: 12px;
566
- height: 12px;
567
- border-radius: 50%;
568
- background: #6b7280;
569
- margin-right: 8px;
570
- animation: think-pulse 1.2s ease-in-out infinite;
571
- }
572
- .thinking-container {
573
- background: #f3f4f6;
574
- border-left: 4px solid #6366f1;
575
- padding: 12px 16px;
576
- border-radius: 8px;
577
- margin: 12px 0;
578
- font-family: monospace;
579
- white-space: pre-wrap;
580
- word-wrap: break-word;
581
- }
582
  """
583
 
584
 
585
  # ============================================================
586
- # GRADIO UI – 6 outputs
587
  # ============================================================
588
 
589
  with gr.Blocks(title=APP_NAME) as demo:
@@ -604,7 +562,6 @@ with gr.Blocks(title=APP_NAME) as demo:
604
  with gr.Column(scale=4):
605
  gr.Markdown("## πŸ”¬ Live Research")
606
  activity = gr.Markdown("βšͺ Waiting for your question.")
607
- thinking = gr.Markdown("", visible=True)
608
  gr.Markdown("---")
609
  gr.Markdown(f"""
610
  ### Model Spaces
@@ -646,7 +603,7 @@ with gr.Blocks(title=APP_NAME) as demo:
646
  )
647
 
648
  inputs = [question, max_results, max_rounds, use_models, freshness]
649
- outputs = [chatbot, activity, sources, evidence, verification, thinking]
650
 
651
  send.click(fn=run_research, inputs=inputs, outputs=outputs)
652
  question.submit(fn=run_research, inputs=inputs, outputs=outputs)
 
5
 
6
  # ──────────────────────────────────────────────────────────────
7
  # REASONING‑ENFORCED AGENT CONTRACT (AGENT.md)
8
+ # See full policy in the multi‑line comment below.
 
 
 
 
 
 
 
 
9
  # ──────────────────────────────────────────────────────────────
10
 
11
  """
 
47
 
48
  ## 6. REASONING VISIBILITY
49
  The agent MUST reason internally but NEVER expose private chain‑of‑thought.
50
+ Provide concise summaries only when useful.
51
 
52
  ## 7. FINAL CONTRACT
53
  UNDERSTAND β†’ PLAN β†’ ACT β†’ VERIFY β†’ ADAPT β†’ DELIVER
 
76
  # ============================================================
77
 
78
  APP_NAME = "X-RUDRA"
79
+ VERSION = "3.7.1" # bumped
80
 
81
  M1_REPO = os.getenv("M1_REPO", "Shrijanagain/M1")
82
  M2_REPO = os.getenv("M2_REPO", "Shrijanagain/M2")
 
218
  title = src.get("title", "Untitled")
219
  snippet = src.get("snippet", src.get("description", ""))
220
  parts.append(f"{i}. {title}: {snippet[:200]}..." if snippet else f"{i}. {title}")
221
+ return "\n\n".join(parts)
222
  else:
223
+ return "I couldn't find specific information on that topic. Could you rephrase?"
224
 
225
  # If only one draft exists, use that as final
226
  if not draft_m1:
227
+ return draft_m2
228
  if not draft_m2:
229
+ return draft_m1
230
 
231
  # ----- 2. Merge both drafts using M2 -----
232
  merge_prompt = f"""Question: {question}
 
243
 
244
  merged = call_model(m2_client, merge_prompt, max_tokens, temperature)
245
  if not merged:
246
+ # If merging fails, fallback to draft_m1
247
  merged = draft_m1
248
 
249
+ # Strip any remaining <think> tags from the final answer
250
+ clean_answer = re.sub(r"<think>.*?</think>", "", merged, flags=re.DOTALL).strip()
251
+ return clean_answer
 
 
 
 
 
 
252
 
253
 
254
  # ============================================================
 
419
 
420
 
421
  # ============================================================
422
+ # MAIN RESEARCH FUNCTION (returns 5 outputs – no thinking)
423
  # ============================================================
424
 
425
  async def do_research(question, max_results, max_rounds, use_models, freshness):
 
428
  empty_sources = ""
429
  empty_evidence = ""
430
  empty_verification = ""
 
431
 
432
  if not question or not str(question).strip():
433
+ return empty_history, empty_activity, empty_sources, empty_evidence, empty_verification
434
 
435
  question = str(question).strip()
436
 
 
441
  {"role": "user", "content": question},
442
  {"role": "assistant", "content": answer}
443
  ]
444
+ return history, "⚑ Casual chat (model reply, no search).", "", "", ""
445
 
446
  # ---- Serious query ----
447
  started = time.perf_counter()
 
473
  })
474
  data["sources"] = sources
475
 
476
+ # Generate final answer (no thinking)
477
+ final_answer = get_combined_model_answer(question, sources)
478
 
479
  sources_md = format_sources(sources)
480
  evidence_md = format_evidence(data.get("claims", []))
481
  verification_md = format_verification(data.get("contradictions", []))
482
  activity_md = build_activity(data, elapsed_ms)
483
 
 
 
484
  history = [
485
  {"role": "user", "content": question},
486
  {"role": "assistant", "content": final_answer}
487
  ]
488
 
489
+ return history, activity_md, sources_md, evidence_md, verification_md
490
 
491
  except Exception as exc:
492
  error = f"❌ **X-RUDRA Error**\n\n`{type(exc).__name__}: {exc}`"
 
498
  {"role": "user", "content": question},
499
  {"role": "assistant", "content": error}
500
  ]
501
+ return history, "❌ Research failed.", "", "", ""
502
 
503
 
504
  # ============================================================
 
525
 
526
 
527
  # ============================================================
528
+ # CSS – no thinking spinner needed
529
  # ============================================================
530
 
531
  CSS = """
 
537
  #chat { border-radius: 18px; }
538
  #send { min-height: 52px; font-size: 18px; font-weight: 700; }
539
  footer { display: none !important; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
540
  """
541
 
542
 
543
  # ============================================================
544
+ # GRADIO UI – 5 outputs (no thinking)
545
  # ============================================================
546
 
547
  with gr.Blocks(title=APP_NAME) as demo:
 
562
  with gr.Column(scale=4):
563
  gr.Markdown("## πŸ”¬ Live Research")
564
  activity = gr.Markdown("βšͺ Waiting for your question.")
 
565
  gr.Markdown("---")
566
  gr.Markdown(f"""
567
  ### Model Spaces
 
603
  )
604
 
605
  inputs = [question, max_results, max_rounds, use_models, freshness]
606
+ outputs = [chatbot, activity, sources, evidence, verification]
607
 
608
  send.click(fn=run_research, inputs=inputs, outputs=outputs)
609
  question.submit(fn=run_research, inputs=inputs, outputs=outputs)