Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -384,23 +384,68 @@ def count_words(text: str) -> str:
|
|
| 384 |
def get_example_posts_for_writer() -> str:
|
| 385 |
"""Get example posts to guide the writer agent."""
|
| 386 |
examples = [
|
| 387 |
-
|
|
|
|
|
|
|
| 388 |
|
| 389 |
Scientists have just revealed 14 new species living miles beneath the ocean's surface—some found at depths over 6,000 meters! This discovery is part of the Ocean Species Discoveries initiative, which is changing how new marine life is identified and shared with the world. Among the surprises: a record-setting deep-sea mollusk, a carnivorous bivalve, and even a popcorn-shaped parasitic isopod. Each of these creatures shows just how much life still hides in the ocean's darkest corners.
|
| 390 |
What's even cooler? The team is using cutting-edge lab techniques to make classifying species faster, more open, and globally collaborative—helping scientists everywhere explore and protect our planet's last great frontier: the deep sea.
|
| 391 |
|
| 392 |
-
#TuesdayTrivia #RnDCell #CCA #OceanDiscovery #MarineBiology #DeepSea"""
|
| 393 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 394 |
return json.dumps(examples, indent=2)
|
| 395 |
|
|
|
|
| 396 |
@tool
|
| 397 |
def get_example_posts_for_critic() -> str:
|
| 398 |
"""Get example posts with quality scores."""
|
| 399 |
examples = [
|
| 400 |
-
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 401 |
]
|
|
|
|
| 402 |
return json.dumps(examples, indent=2)
|
| 403 |
|
|
|
|
| 404 |
# --- 6. WORKFLOW & STATE ---
|
| 405 |
|
| 406 |
class WorkflowStage(Enum):
|
|
@@ -455,7 +500,7 @@ CRITICAL TITLE FOCUS:
|
|
| 455 |
OTHER REQUIREMENTS:
|
| 456 |
1. Use search_science_breakthroughs to find recent articles
|
| 457 |
2. Use get_all_previous_posts to see existing titles
|
| 458 |
-
3. Find 10-15 RECENT breakthroughs (last
|
| 459 |
|
| 460 |
Output Format:
|
| 461 |
**Title:** [Unique, compelling title]
|
|
@@ -592,9 +637,11 @@ Paragraph 2
|
|
| 592 |
TITLE REQUIREMENTS:
|
| 593 |
- Must be unique and compelling
|
| 594 |
- Use check_topic_similarity to verify uniqueness
|
| 595 |
-
- If title is too similar (>
|
| 596 |
|
| 597 |
-
CONTENT:
|
|
|
|
|
|
|
| 598 |
HASHTAGS: Always include #TuesdayTrivia #RnDCell #CCA + 2-4 topic hashtags""")
|
| 599 |
|
| 600 |
user_msg = HumanMessage(content=f"Write Tuesday Trivia post. VERIFY TITLE UNIQUENESS:\n{story_text}\n{retry_context}")
|
|
@@ -630,27 +677,29 @@ HASHTAGS: Always include #TuesdayTrivia #RnDCell #CCA + 2-4 topic hashtags""")
|
|
| 630 |
return state
|
| 631 |
|
| 632 |
def run_critic(state: EnhancedAgentState, progress_callback=None) -> EnhancedAgentState:
|
| 633 |
-
"""Critic Agent - Uses mistral-large-latest"""
|
| 634 |
try:
|
| 635 |
print("\n" + "="*70)
|
| 636 |
print("🤖 CRITIC AGENT")
|
| 637 |
print(f"📊 Model: mistral-large-latest")
|
| 638 |
-
print(f"🎯 Purpose: Evaluate
|
| 639 |
print("="*70)
|
| 640 |
|
| 641 |
if progress_callback:
|
| 642 |
progress_callback("🔍 Critic (mistral-large) evaluating...")
|
| 643 |
|
| 644 |
draft = state.get("draft_summary", "")
|
|
|
|
|
|
|
| 645 |
|
| 646 |
system_msg = SystemMessage(content="""You are the Critic Agent for Tuesday Trivia.
|
| 647 |
|
| 648 |
EVALUATION CRITERIA:
|
| 649 |
|
| 650 |
-
1. TITLE UNIQUENESS (
|
| 651 |
- Use check_topic_similarity to verify title uniqueness
|
| 652 |
-
- Title must have <
|
| 653 |
-
-
|
| 654 |
|
| 655 |
2. FORMAT (2 points):
|
| 656 |
- Title on first line
|
|
@@ -660,20 +709,25 @@ EVALUATION CRITERIA:
|
|
| 660 |
- Hashtags include #TuesdayTrivia #RnDCell #CCA
|
| 661 |
|
| 662 |
3. CONTENT (3 points):
|
| 663 |
-
-
|
| 664 |
- Technical details + impact
|
| 665 |
- 140-180 words
|
| 666 |
- Accurate information
|
| 667 |
|
| 668 |
-
4. STYLE (
|
| 669 |
-
-
|
| 670 |
-
- Technical concepts clear
|
| 671 |
-
- Engaging and accessible
|
| 672 |
|
| 673 |
-
OUTPUT:
|
| 674 |
-
|
|
|
|
|
|
|
| 675 |
TOTAL SCORE: X/10
|
| 676 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 677 |
|
| 678 |
CRITICAL: Always check title similarity first!""")
|
| 679 |
|
|
@@ -683,7 +737,8 @@ CRITICAL: Always check title similarity first!""")
|
|
| 683 |
response = critic_llm.invoke([system_msg, user_msg])
|
| 684 |
conversation = [system_msg, user_msg, response]
|
| 685 |
|
| 686 |
-
|
|
|
|
| 687 |
for tool_call in response.tool_calls:
|
| 688 |
name = tool_call['name']
|
| 689 |
print(f"🔧 Tool: {name}")
|
|
@@ -694,9 +749,13 @@ CRITICAL: Always check title similarity first!""")
|
|
| 694 |
else:
|
| 695 |
res = "Unknown"
|
| 696 |
conversation.append(ToolMessage(content=str(res), tool_call_id=tool_call['id']))
|
|
|
|
|
|
|
| 697 |
response = critic_llm.invoke(conversation)
|
|
|
|
|
|
|
| 698 |
|
| 699 |
-
text = response.content
|
| 700 |
score = 5.0
|
| 701 |
try:
|
| 702 |
if "TOTAL SCORE:" in text:
|
|
@@ -705,11 +764,24 @@ CRITICAL: Always check title similarity first!""")
|
|
| 705 |
pass
|
| 706 |
|
| 707 |
print(f"✅ Evaluation complete - Score: {score}/10")
|
|
|
|
|
|
|
| 708 |
state["quality_score"] = score
|
| 709 |
state["critic_feedback"] = text
|
| 710 |
-
state["stage"] = WorkflowStage.CHECKPOINT_3.value
|
| 711 |
state["progress_log"].append(f"✅ Evaluation (mistral-large-latest): {score}/10")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 712 |
return state
|
|
|
|
| 713 |
except Exception as e:
|
| 714 |
state["stage"] = WorkflowStage.ERROR.value
|
| 715 |
state["error_message"] = f"Critic failed: {str(e)}"
|
|
|
|
| 384 |
def get_example_posts_for_writer() -> str:
|
| 385 |
"""Get example posts to guide the writer agent."""
|
| 386 |
examples = [
|
| 387 |
+
{
|
| 388 |
+
"title": "Scientists Found 14 Mysterious Creatures in the Ocean's Darkest Depths",
|
| 389 |
+
"content": """Scientists Found 14 Mysterious Creatures in the Ocean's Darkest Depths
|
| 390 |
|
| 391 |
Scientists have just revealed 14 new species living miles beneath the ocean's surface—some found at depths over 6,000 meters! This discovery is part of the Ocean Species Discoveries initiative, which is changing how new marine life is identified and shared with the world. Among the surprises: a record-setting deep-sea mollusk, a carnivorous bivalve, and even a popcorn-shaped parasitic isopod. Each of these creatures shows just how much life still hides in the ocean's darkest corners.
|
| 392 |
What's even cooler? The team is using cutting-edge lab techniques to make classifying species faster, more open, and globally collaborative—helping scientists everywhere explore and protect our planet's last great frontier: the deep sea.
|
| 393 |
|
| 394 |
+
#TuesdayTrivia #RnDCell #CCA #OceanDiscovery #MarineBiology #DeepSea"""
|
| 395 |
+
},
|
| 396 |
+
{
|
| 397 |
+
"title": "Researchers Have Developed Next-Generation Plant Immune System to Combat Bacterial Diseases",
|
| 398 |
+
"content": """Researchers Have Developed Next-Generation Plant Immune System to Combat Bacterial Diseases
|
| 399 |
+
|
| 400 |
+
Researchers at the University of California, Davis have used artificial intelligence to boost plant immunity, helping crops like tomatoes and potatoes resist bacterial infections. Using AlphaFold, an AI system that predicts protein structures, they redesigned the immune receptor FLS2, which identifies flagellin, a bacterial movement protein. Since bacteria mutate flagellin to escape detection, the AI-guided redesign enabled plants to recognize more bacterial variants and strengthen their defenses.
|
| 401 |
+
By altering key amino acids, the team reactivated weakened receptors, restoring the plants’ ability to detect pathogens. This innovation could provide broad-spectrum disease resistance in major crops, including protection against Ralstonia solanacearum, the bacterium that causes bacterial wilt. The researchers now plan to extend this strategy to other plants using machine learning.
|
| 402 |
+
|
| 403 |
+
#CCA_RnD #TuesdayTrivia #ArtificialIntelligence #ProteinEngineering #PlantImmunity #AgriTech #BacterialWilt #GreenTech"""
|
| 404 |
+
}
|
| 405 |
+
]
|
| 406 |
+
|
| 407 |
return json.dumps(examples, indent=2)
|
| 408 |
|
| 409 |
+
|
| 410 |
@tool
|
| 411 |
def get_example_posts_for_critic() -> str:
|
| 412 |
"""Get example posts with quality scores."""
|
| 413 |
examples = [
|
| 414 |
+
{
|
| 415 |
+
"title": "Researchers Have Developed a Cutting-Edge Silicon Photonic Chip to Enhance AI Efficiency",
|
| 416 |
+
"content": """Researchers Have Developed a Cutting-Edge Silicon Photonic Chip to Enhance AI Efficiency
|
| 417 |
+
|
| 418 |
+
Researchers at the University of Florida have developed a silicon photonic chip that uses light to perform convolution operations, the pattern-recognition tasks at the heart of artificial intelligence. By encoding data as laser light and routing it through microscopic Fresnel lenses etched onto silicon, the chip processes information optically before converting it back into digital signals.
|
| 419 |
+
In testing, the system classified handwritten digits with roughly 98% accuracy, matching traditional electronic processors while consuming significantly less energy. The chip also supports wavelength multiplexing, allowing multiple colored lasers to handle parallel data streams, marking the first on-chip optical computation applied directly to neural networks.
|
| 420 |
+
|
| 421 |
+
#TuesdayTrivia #CCA #RnDCell #ArtificialIntelligence #SiliconPhotonics #OpticalComputing #AIHardware #EnergyEfficientAI""",
|
| 422 |
+
"score": 8.5
|
| 423 |
+
},
|
| 424 |
+
{
|
| 425 |
+
"title": "Researchers Have Developed Injectable Skin That Brings Hope for Burn Victims and Scar-Free Healing",
|
| 426 |
+
"content": """Researchers Have Developed Injectable Skin That Brings Hope for Burn Victims and Scar-Free Healing
|
| 427 |
+
|
| 428 |
+
Researchers at the University of Linköping in Sweden have created an injectable gel filled with living skin cells that can be injected into wounds or 3D printed for skin transplants. Unlike conventional treatments that repair only the outer skin layer, this method rebuilds deeper dermal layers responsible for strength, elasticity, and blood vessel formation.
|
| 429 |
+
The material combines fibroblast cells with gelatin beads and a hyaluronic acid-based gel using click chemistry, allowing it to flow easily from a syringe before stabilizing in place. In animal studies, the cells survived, formed new blood vessels, and promoted healthy skin regeneration, opening new possibilities for scar-free healing and future organ repair.
|
| 430 |
+
|
| 431 |
+
#TuesdayTrivia #CCA #RnDCell #RegenerativeMedicine #TissueEngineering #SkinInASyringe #3DPrintedSkin #WoundHealing""",
|
| 432 |
+
"score": 9.0
|
| 433 |
+
},
|
| 434 |
+
{
|
| 435 |
+
"title": "Researchers Have Developed AI-Engineered Immune Cells to Target Cancer in Record Time",
|
| 436 |
+
"content": """Researchers Have Developed AI-Engineered Immune Cells to Target Cancer in Record Time
|
| 437 |
+
|
| 438 |
+
Researchers have developed an AI-driven approach that rapidly reprograms human immune cells to recognize and destroy cancer cells within weeks instead of months. By applying machine-learning models, the team designed highly specific T-cell receptors that accurately target cancer while minimizing damage to healthy tissue.
|
| 439 |
+
The AI system analyzed millions of possible receptor combinations to identify the most effective designs, enabling personalized immune therapies tailored to each patient’s cancer type. This approach could significantly accelerate treatment development and move cancer therapy beyond one-size-fits-all solutions.
|
| 440 |
+
|
| 441 |
+
#TuesdayTrivia #CCA #RnDCell #CancerResearch #Immunotherapy #ArtificialIntelligence #PrecisionMedicine #FutureOfMedicine""",
|
| 442 |
+
"score": 9.5
|
| 443 |
+
}
|
| 444 |
]
|
| 445 |
+
|
| 446 |
return json.dumps(examples, indent=2)
|
| 447 |
|
| 448 |
+
|
| 449 |
# --- 6. WORKFLOW & STATE ---
|
| 450 |
|
| 451 |
class WorkflowStage(Enum):
|
|
|
|
| 500 |
OTHER REQUIREMENTS:
|
| 501 |
1. Use search_science_breakthroughs to find recent articles
|
| 502 |
2. Use get_all_previous_posts to see existing titles
|
| 503 |
+
3. Find 10-15 RECENT breakthroughs (last 1-4 weeks)
|
| 504 |
|
| 505 |
Output Format:
|
| 506 |
**Title:** [Unique, compelling title]
|
|
|
|
| 637 |
TITLE REQUIREMENTS:
|
| 638 |
- Must be unique and compelling
|
| 639 |
- Use check_topic_similarity to verify uniqueness
|
| 640 |
+
- If title is too similar (>80% overlap), create a completely different title approach
|
| 641 |
|
| 642 |
+
CONTENT:
|
| 643 |
+
- 140-180 words, technical but accessible
|
| 644 |
+
- use get_example_posts_for_writer to get example posts and write in a similar tone
|
| 645 |
HASHTAGS: Always include #TuesdayTrivia #RnDCell #CCA + 2-4 topic hashtags""")
|
| 646 |
|
| 647 |
user_msg = HumanMessage(content=f"Write Tuesday Trivia post. VERIFY TITLE UNIQUENESS:\n{story_text}\n{retry_context}")
|
|
|
|
| 677 |
return state
|
| 678 |
|
| 679 |
def run_critic(state: EnhancedAgentState, progress_callback=None) -> EnhancedAgentState:
|
| 680 |
+
"""Critic Agent - Uses mistral-large-latest with Auto-Loop"""
|
| 681 |
try:
|
| 682 |
print("\n" + "="*70)
|
| 683 |
print("🤖 CRITIC AGENT")
|
| 684 |
print(f"📊 Model: mistral-large-latest")
|
| 685 |
+
print(f"🎯 Purpose: Evaluate and Auto-Correct")
|
| 686 |
print("="*70)
|
| 687 |
|
| 688 |
if progress_callback:
|
| 689 |
progress_callback("🔍 Critic (mistral-large) evaluating...")
|
| 690 |
|
| 691 |
draft = state.get("draft_summary", "")
|
| 692 |
+
current_retries = state.get("retry_count", 0)
|
| 693 |
+
MAX_RETRIES = 3
|
| 694 |
|
| 695 |
system_msg = SystemMessage(content="""You are the Critic Agent for Tuesday Trivia.
|
| 696 |
|
| 697 |
EVALUATION CRITERIA:
|
| 698 |
|
| 699 |
+
1. TITLE UNIQUENESS (2 points):
|
| 700 |
- Use check_topic_similarity to verify title uniqueness
|
| 701 |
+
- Title must have <90% word overlap with existing posts
|
| 702 |
+
- But title also must have some similarity to example posts , use get_example_posts_for_critic for this
|
| 703 |
|
| 704 |
2. FORMAT (2 points):
|
| 705 |
- Title on first line
|
|
|
|
| 709 |
- Hashtags include #TuesdayTrivia #RnDCell #CCA
|
| 710 |
|
| 711 |
3. CONTENT (3 points):
|
| 712 |
+
- context
|
| 713 |
- Technical details + impact
|
| 714 |
- 140-180 words
|
| 715 |
- Accurate information
|
| 716 |
|
| 717 |
+
4. STYLE (3 points):
|
| 718 |
+
- writing style must be similar to example posts, use get_example_posts_for_critic for this
|
| 719 |
+
- Technical concepts clear and accessible
|
|
|
|
| 720 |
|
| 721 |
+
OUTPUT FORMAT:
|
| 722 |
+
If Score < 7/10, you MUST provide a section called "ACTIONABLE FIXES" with specific instructions for the writer.
|
| 723 |
+
|
| 724 |
+
Structure your response exactly like this:
|
| 725 |
TOTAL SCORE: X/10
|
| 726 |
+
CRITIQUE: [General feedback]
|
| 727 |
+
ACTIONABLE FIXES:
|
| 728 |
+
- [Fix 1]
|
| 729 |
+
- [Fix 2]
|
| 730 |
+
- [Fix 3]
|
| 731 |
|
| 732 |
CRITICAL: Always check title similarity first!""")
|
| 733 |
|
|
|
|
| 737 |
response = critic_llm.invoke([system_msg, user_msg])
|
| 738 |
conversation = [system_msg, user_msg, response]
|
| 739 |
|
| 740 |
+
steps = 0
|
| 741 |
+
while hasattr(response, 'tool_calls') and response.tool_calls and steps < 5:
|
| 742 |
for tool_call in response.tool_calls:
|
| 743 |
name = tool_call['name']
|
| 744 |
print(f"🔧 Tool: {name}")
|
|
|
|
| 749 |
else:
|
| 750 |
res = "Unknown"
|
| 751 |
conversation.append(ToolMessage(content=str(res), tool_call_id=tool_call['id']))
|
| 752 |
+
|
| 753 |
+
# Get the agent's next thought/response
|
| 754 |
response = critic_llm.invoke(conversation)
|
| 755 |
+
conversation.append(response)
|
| 756 |
+
steps += 1
|
| 757 |
|
| 758 |
+
text = response.content or ""
|
| 759 |
score = 5.0
|
| 760 |
try:
|
| 761 |
if "TOTAL SCORE:" in text:
|
|
|
|
| 764 |
pass
|
| 765 |
|
| 766 |
print(f"✅ Evaluation complete - Score: {score}/10")
|
| 767 |
+
|
| 768 |
+
# Save feedback for the writer to see
|
| 769 |
state["quality_score"] = score
|
| 770 |
state["critic_feedback"] = text
|
|
|
|
| 771 |
state["progress_log"].append(f"✅ Evaluation (mistral-large-latest): {score}/10")
|
| 772 |
+
|
| 773 |
+
# --- AUTOMATIC LOOP LOGIC ---
|
| 774 |
+
# If score is low and we haven't retried too many times, send back to Writer
|
| 775 |
+
if score < 8.0 and current_retries < MAX_RETRIES:
|
| 776 |
+
print(f"🔄 Score too low ({score}). Auto-sending back to Writer with feedback...")
|
| 777 |
+
state["stage"] = WorkflowStage.WRITER.value
|
| 778 |
+
else:
|
| 779 |
+
# Score is good OR we hit max retries -> Wait for human approval
|
| 780 |
+
print("✅ Score acceptable or max retries reached. Waiting for human...")
|
| 781 |
+
state["stage"] = WorkflowStage.CHECKPOINT_3.value
|
| 782 |
+
|
| 783 |
return state
|
| 784 |
+
|
| 785 |
except Exception as e:
|
| 786 |
state["stage"] = WorkflowStage.ERROR.value
|
| 787 |
state["error_message"] = f"Critic failed: {str(e)}"
|