import streamlit as st
import asyncio
import pandas as pd
from typing import List
import os
import json
from datetime import datetime
from dotenv import load_dotenv
from multi_agent_system import MultiAgentSystem, SearchResult
from paper_writer import ResearchPaperWriter
from docx import Document
from docx.shared import Pt, Inches, RGBColor
from docx.enum.text import WD_ALIGN_PARAGRAPH
import io
# Load environment variables
load_dotenv()
# Configure page settings
st.set_page_config(
page_title="Research Assistant",
page_icon="๐",
layout="wide",
initial_sidebar_state="expanded"
)
# Custom CSS for improved UI
st.markdown("""
""", unsafe_allow_html=True)
def init_session_state():
"""Initialize session state variables"""
if 'search_history' not in st.session_state:
st.session_state.search_history = []
if 'analysis_progress' not in st.session_state:
st.session_state.analysis_progress = 0
def get_score_badge(score, label):
"""Generate color-coded badge for scores"""
try:
score_val = float(score)
if score_val >= 8:
color = "#00C853" # Green
emoji = "๐ข"
elif score_val >= 6:
color = "#FFA726" # Orange
emoji = "๐ก"
else:
color = "#EF5350" # Red
emoji = "๐ด"
return f"""
{emoji} {label}: {score_val:.1f}/10
"""
except:
return f"{label}: {score}"
def parse_literature_review(review_text):
"""Parse literature review into collapsible sections"""
sections = {}
current_section = "Introduction"
current_content = []
lines = review_text.split('\n')
for line in lines:
# Detect section headers
if line.startswith('##'):
# Save previous section
if current_content:
sections[current_section] = '\n'.join(current_content)
# Start new section
current_section = line.replace('#', '').strip()
current_content = []
else:
current_content.append(line)
# Save last section
if current_content:
sections[current_section] = '\n'.join(current_content)
return sections if sections else {"Full Review": review_text}
def convert_markdown_to_docx(markdown_text: str, title: str = "Research Paper") -> bytes:
"""Convert markdown text to Word document (.docx) format"""
try:
doc = Document()
# Set document margins
sections = doc.sections
for section in sections:
section.top_margin = Inches(1)
section.bottom_margin = Inches(1)
section.left_margin = Inches(1)
section.right_margin = Inches(1)
# Split markdown into lines
lines = markdown_text.split('\n')
for line in lines:
line = line.strip()
if not line:
continue
# Handle headers
if line.startswith('# '):
# Title (H1)
p = doc.add_heading(line[2:], level=1)
p.alignment = WD_ALIGN_PARAGRAPH.CENTER
elif line.startswith('## '):
# Section (H2)
doc.add_heading(line[3:], level=2)
elif line.startswith('### '):
# Subsection (H3)
doc.add_heading(line[4:], level=3)
elif line.startswith('#### '):
# Sub-subsection (H4)
doc.add_heading(line[5:], level=4)
elif line.startswith('- ') or line.startswith('* '):
# Bullet point
doc.add_paragraph(line[2:], style='List Bullet')
elif line.startswith('> '):
# Block quote
p = doc.add_paragraph(line[2:])
p.style = 'Intense Quote'
else:
# Regular paragraph
doc.add_paragraph(line)
# Save to bytes
doc_bytes = io.BytesIO()
doc.save(doc_bytes)
doc_bytes.seek(0)
return doc_bytes.getvalue()
except Exception as e:
st.error(f"Error converting to Word: {str(e)}")
return None
async def run_async_operations(system, search_query, max_results=3):
"""Handle async complete analysis operation"""
# Always run full pipeline: Paper Collection โ Literature Review โ Gap Analysis โ Hypothesis Generation
complete_results = await system.run_complete_analysis(search_query)
return {"type": "complete", "data": complete_results}
def main():
"""Main application function"""
st.markdown("""
ResearchForge
Autonomous AI Research Assistant
Automated Literature Review โข Gap Analysis โข Hypothesis Generation
Experiment Design โข Dataset Recommendations โข AI Research Paper Writer
""", unsafe_allow_html=True)
init_session_state()
if 'system' not in st.session_state:
with st.spinner("๐ Initializing Research Assistant... Please wait..."):
st.session_state.system = MultiAgentSystem()
st.success("โ
System initialized! Models will load when needed.")
system = st.session_state.system
# Sidebar configuration
with st.sidebar:
st.markdown("""
Configuration
""", unsafe_allow_html=True)
st.markdown("### Analysis Pipeline")
st.markdown("""
What happens when you search:
1. ๐ Collect 10-15 research papers
2. ๐ Literature Review (GPT-3.5)
3. ๐ Gap Analysis (GPT-4)
4. ๐ก Hypothesis Generation (GPT-4)
""", unsafe_allow_html=True)
st.markdown("")
# API Status
st.markdown("### API Status")
if os.getenv('OPENAI_API_KEY') and os.getenv('GOOGLE_SEARCH_ENGINE_ID'):
st.markdown("""
""", unsafe_allow_html=True)
else:
st.markdown("""
โ APIs not configured. Please check .env file
""", unsafe_allow_html=True)
st.markdown("
", unsafe_allow_html=True)
st.markdown("---")
st.markdown("""
Powered by:
โข OpenAI GPT-4 & GPT-3.5
โข Sentence-BERT
""", unsafe_allow_html=True)
# Add info about model loading
st.markdown("
", unsafe_allow_html=True)
st.markdown("""
๐ก Note: Heavy AI models load on first use. Subsequent uses are instant!
""", unsafe_allow_html=True)
# Main search interface
st.markdown("")
st.markdown("")
# Show current analysis status
if st.session_state.get('complete_data'):
current_topic = st.session_state.get('search_query', 'Unknown')
st.markdown(f"""
โ Analysis completed for: {current_topic}
""", unsafe_allow_html=True)
col1, col2 = st.columns([3, 1])
with col2:
if st.button("๐ New Analysis", type="secondary", use_container_width=True):
# Clear all session state
for key in ['complete_data', 'search_query', 'selected_hypothesis', 'selected_gap',
'experiment_results', 'selected_experiment', 'generated_paper']:
if key in st.session_state:
del st.session_state[key]
st.rerun()
# Clean, minimal search input
st.markdown("""
๐ Enter Your Research Topic
""", unsafe_allow_html=True)
search_query = st.text_input(
"Research Topic",
placeholder="e.g., machine learning for drug discovery, quantum computing applications...",
label_visibility="collapsed",
key="search_input"
)
search_button = st.button("๐ Start Analysis", type="primary", use_container_width=True)
st.markdown("
", unsafe_allow_html=True)
# Handle search
if search_button and search_query:
# Create progress bar
progress_bar = st.progress(0)
status_text = st.empty()
try:
# Phase 1: Paper Collection
status_text.markdown("""
๐ Phase 1/4: Collecting research papers...
""", unsafe_allow_html=True)
progress_bar.progress(10)
system = MultiAgentSystem()
# Phase 2: Literature Review
status_text.markdown("""
๐ Phase 2/4: Analyzing literature...
""", unsafe_allow_html=True)
progress_bar.progress(30)
# Run analysis (this includes all phases)
result = asyncio.run(run_async_operations(
system,
search_query,
max_results=5
))
# Phase 3: Gap Analysis
status_text.markdown("""
๐ Phase 3/4: Identifying research gaps...
""", unsafe_allow_html=True)
progress_bar.progress(65)
# Phase 4: Hypothesis Generation
status_text.markdown("""
๐ก Phase 4/4: Generating hypotheses...
""", unsafe_allow_html=True)
progress_bar.progress(90)
# Complete
complete_data = result["data"]
st.session_state['complete_data'] = complete_data
st.session_state['search_query'] = search_query
progress_bar.progress(100)
status_text.markdown("""
""", unsafe_allow_html=True)
st.balloons()
except Exception as e:
st.error(f"An error occurred: {str(e)}")
st.error(f"Error details: {type(e).__name__}")
# Display tabs if we have complete data in session state
if st.session_state.get('complete_data'):
complete_data = st.session_state['complete_data']
search_query = st.session_state.get('search_query', '')
# Create tabs for different sections
tab1, tab2, tab3, tab4, tab5 = st.tabs([
"๐ Literature Review",
"๐ Gap Analysis",
"๐ก Hypotheses",
"๐งช Experiment Design",
"๐ AI Paper Writer"
])
with tab1:
st.header("Literature Review")
# Show papers collected
papers = complete_data.get("papers", [])
if papers:
col1, col2, col3 = st.columns(3)
with col1:
st.metric("๐ Papers Found", len(papers))
with col2:
arxiv_count = sum(1 for p in papers if hasattr(p, 'arxiv_url') and p.arxiv_url)
st.metric("๐ arXiv Papers", arxiv_count)
with col3:
google_count = len(papers) - arxiv_count
st.metric("๐ Google Scholar", google_count)
st.markdown("---")
# Show literature review with collapsible sections
if complete_data.get("literature_review"):
review_text = complete_data["literature_review"]
# Download button for literature review
col1, col2 = st.columns([3, 1])
with col2:
st.download_button(
label="๐ฅ Download as TXT",
data=review_text,
file_name=f"literature_review_{datetime.now().strftime('%Y%m%d')}.txt",
mime="text/plain",
use_container_width=True
)
# Parse into sections
sections = parse_literature_review(review_text)
if len(sections) > 1:
st.markdown("### ๐ Review Sections (Click to Expand)")
for section_name, section_content in sections.items():
with st.expander(f"๐ {section_name}", expanded=(section_name == "Introduction" or section_name == "Full Review")):
st.markdown(section_content)
else:
st.markdown(review_text)
else:
st.warning("No literature review available")
# Display collected papers with links
if papers:
st.markdown("---")
st.subheader("๐ Research Papers Analyzed")
st.info(f"๐ก {len(papers)} papers were collected and analyzed for this review")
for i, paper in enumerate(papers, 1):
with st.expander(f"๐ Paper {i}: {paper.title}", expanded=False):
if hasattr(paper, 'authors') and paper.authors:
st.markdown(f"**โ๏ธ Authors:** {', '.join(paper.authors[:3])}{'...' if len(paper.authors) > 3 else ''}")
if hasattr(paper, 'published') and paper.published:
st.markdown(f"**๐
Published:** {paper.published}")
if hasattr(paper, 'abstract') and paper.abstract:
st.markdown(f"**๐ Abstract:**")
st.markdown(paper.abstract[:500] + "..." if len(paper.abstract) > 500 else paper.abstract)
elif hasattr(paper, 'snippet') and paper.snippet:
st.markdown(f"**๐ Summary:**")
st.markdown(paper.snippet)
# Links
links = []
if hasattr(paper, 'arxiv_url') and paper.arxiv_url:
links.append(f"[๐ arXiv]({paper.arxiv_url})")
if hasattr(paper, 'pdf_url') and paper.pdf_url:
links.append(f"[๐ฅ PDF]({paper.pdf_url})")
if hasattr(paper, 'link') and paper.link:
links.append(f"[๐ Source]({paper.link})")
if links:
st.markdown("**๐ Links:** " + " | ".join(links))
else:
st.warning("No papers were collected for this analysis")
with tab2:
st.header("Research Gap Analysis")
gap_data = complete_data.get("gap_analysis", {})
# Show which model was used
gaps_dict = gap_data.get("gaps", {})
if gaps_dict.get("source"):
if "Combined" in gaps_dict["source"]:
st.success(f"๐ค Analysis by: {gaps_dict['source']}")
elif "GPT-4" in gaps_dict["source"]:
st.info(f"๐ค Analysis by: {gaps_dict['source']}")
else:
st.success(f"๐ค Analysis by: {gaps_dict['source']}")
# Show summary metrics
col1, col2, col3, col4 = st.columns(4)
with col1:
st.metric("Papers Analyzed", gap_data.get("papers_analyzed", 0))
with col2:
total_gaps = sum(len(gaps_dict.get(k, [])) for k in ["knowledge_gaps", "methodological_gaps", "dataset_gaps", "temporal_gaps"])
st.metric("Total Gaps Found", total_gaps)
with col3:
st.metric("Categories", 4)
with col4:
# Download button
gap_text = gap_data.get("formatted_output", "No gap analysis available")
st.download_button(
label="๐ฅ Download",
data=gap_text,
file_name=f"gap_analysis_{datetime.now().strftime('%Y%m%d')}.txt",
mime="text/plain",
use_container_width=True
)
# Display formatted gap analysis
st.markdown(gap_data.get("formatted_output", "No gap analysis available"))
with tab3:
st.header("Research Hypotheses")
hyp_data = complete_data.get("hypotheses", {})
if hyp_data.get("hypotheses"):
hypotheses_list = hyp_data.get("hypotheses", [])
# Show summary metrics
col1, col2, col3 = st.columns(3)
with col1:
st.metric("Hypotheses Generated", len(hypotheses_list))
with col2:
avg_score = sum(h.get("overall_score", 0) for h in hypotheses_list) / max(len(hypotheses_list), 1)
st.metric("Avg Overall Score", f"{avg_score:.2f}")
with col3:
avg_novelty = sum(h.get("novelty_score", 0) for h in hypotheses_list) / max(len(hypotheses_list), 1)
st.metric("Avg Novelty Score", f"{avg_novelty:.2f}")
st.markdown("---")
# Side-by-side comparison table
st.markdown("### ๐ Hypothesis Comparison Table")
comparison_data = []
for idx, hyp in enumerate(hypotheses_list, 1):
comparison_data.append({
"#": idx,
"Title": hyp.get('title', 'Untitled')[:50] + '...' if len(hyp.get('title', '')) > 50 else hyp.get('title', 'Untitled'),
"Overall": f"{hyp.get('overall_score', 0):.1f}",
"Novelty": f"{hyp.get('novelty_score', 0):.1f}",
"Impact": f"{hyp.get('impact_score', 0):.1f}",
"Feasibility": f"{hyp.get('feasibility_score', 0):.1f}",
"Gap": hyp.get('gap_addressed', 'N/A')[:40] + '...' if len(hyp.get('gap_addressed', '')) > 40 else hyp.get('gap_addressed', 'N/A')
})
comparison_df = pd.DataFrame(comparison_data)
st.dataframe(comparison_df, use_container_width=True, hide_index=True)
# Download CSV button
csv = comparison_df.to_csv(index=False)
st.download_button(
label="๐ฅ Download Comparison as CSV",
data=csv,
file_name=f"hypothesis_comparison_{datetime.now().strftime('%Y%m%d')}.csv",
mime="text/csv",
use_container_width=True
)
st.markdown("---")
# Display hypotheses with selection and color-coded badges
st.markdown("### ๐ก Detailed Hypotheses (Click to Expand)")
for idx, hyp in enumerate(hypotheses_list, 1):
with st.expander(f"{'๐ด' if hyp.get('priority') == 'HIGH' else '๐ก'} Hypothesis {idx}: {hyp.get('title', 'Untitled')}", expanded=(idx==1)):
# Color-coded score badges
st.markdown("**๐ Performance Scores:**", unsafe_allow_html=True)
badges_html = ""
badges_html += get_score_badge(hyp.get('overall_score', 0), 'Overall')
badges_html += get_score_badge(hyp.get('novelty_score', 0), 'Novelty')
badges_html += get_score_badge(hyp.get('impact_score', 0), 'Impact')
badges_html += get_score_badge(hyp.get('feasibility_score', 0), 'Feasibility')
st.markdown(badges_html, unsafe_allow_html=True)
st.markdown("")
if hyp.get('gap_addressed'):
st.markdown(f"**๐ฏ Gap Addressed:** {hyp['gap_addressed']}")
if hyp.get('problem_statement'):
st.markdown(f"**โ Problem Statement:** {hyp['problem_statement']}")
if hyp.get('proposed_solution'):
st.markdown(f"**๐ก Proposed Solution:** {hyp['proposed_solution']}")
if hyp.get('expected_impact'):
st.markdown(f"**๐ Expected Impact:** {hyp['expected_impact']}")
else:
st.warning("No hypotheses generated")
with tab4:
st.header("๐งช Experiment Design")
# Check if we have hypotheses to work with
if complete_data.get('hypotheses'):
hypotheses = complete_data['hypotheses'].get('hypotheses', [])
if hypotheses:
# Hypothesis selection
st.subheader("Select a Hypothesis")
hypothesis_options = [f"Hypothesis {h.get('hypothesis_id', i+1)}: {h.get('title', 'Untitled')}"
for i, h in enumerate(hypotheses)]
selected_index = st.selectbox(
"Choose a hypothesis to generate experiments for:",
range(len(hypothesis_options)),
format_func=lambda x: hypothesis_options[x],
key="hypothesis_selector"
)
selected_hypothesis = hypotheses[selected_index]
# Store selected hypothesis and its gap in session state
st.session_state['selected_hypothesis'] = selected_hypothesis
st.session_state['selected_gap'] = selected_hypothesis.get('gap_addressed', 'Not specified')
# Show selected hypothesis details
with st.expander("๐ Selected Hypothesis Details", expanded=False):
st.write(f"**Title:** {selected_hypothesis.get('title', 'N/A')}")
st.write(f"**Gap Addressed:** {selected_hypothesis.get('gap_addressed', 'N/A')}")
st.write(f"**Problem Statement:** {selected_hypothesis.get('problem_statement', 'N/A')}")
st.write(f"**Proposed Solution:** {selected_hypothesis.get('proposed_solution', 'N/A')}")
col1, col2, col3 = st.columns(3)
with col1:
st.metric("Novelty Score", f"{selected_hypothesis.get('novelty_score', 'N/A')}/10")
with col2:
st.metric("Impact Score", f"{selected_hypothesis.get('impact_score', 'N/A')}/10")
with col3:
st.metric("Feasibility Score", f"{selected_hypothesis.get('feasibility_score', 'N/A')}/10")
# Generate Experiments Button
if st.button("๐ Generate Experiments & Datasets", key="generate_experiments"):
with st.spinner("๐งช Generating experiments, datasets, and metrics..."):
try:
experiment_results = asyncio.run(
system.generate_experiments_for_hypothesis(
selected_hypothesis,
search_query
)
)
st.session_state['experiment_results'] = experiment_results
st.session_state['selected_experiment'] = None # Reset selection
st.success("โ
Experiments generated successfully!")
except Exception as e:
st.error(f"โ Error generating experiments: {str(e)}")
# Display experiment results
if st.session_state.get('experiment_results'):
st.markdown("---")
display_experiment_results(st.session_state['experiment_results'])
else:
st.warning("โ ๏ธ No hypotheses available. Please run the complete analysis first.")
else:
st.info("๐ Run a complete analysis first to generate hypotheses.")
with tab5:
st.header("๐ AI Research Paper Writer")
st.markdown("*Generate a complete, publication-ready research paper in Word format*")
# Check if all required data is selected
selected_hypothesis = st.session_state.get('selected_hypothesis')
selected_experiment = st.session_state.get('selected_experiment')
selected_gap = st.session_state.get('selected_gap', 'Not specified')
if selected_hypothesis and selected_experiment:
# Show ready status
st.success("โ
All required components selected! Ready to generate your paper.")
st.markdown("---")
# Show selected data summary in card-like layout
st.markdown("### ๐ Your Research Paper Components:")
col1, col2 = st.columns(2)
with col1:
with st.container():
st.markdown("**๐ Research Topic**")
st.info(complete_data.get('topic', 'Unknown'))
st.markdown("**๐ก Hypothesis**")
st.info(selected_hypothesis.get('title', 'Unknown'))
with col2:
with st.container():
st.markdown("**๐งช Experiment**")
st.info(f"{selected_experiment.get('title', 'Unknown')}")
st.markdown("**๐ Gap Addressed**")
st.info(selected_gap)
st.markdown("---")
# Show what will be included
with st.expander("๐ What's included in your paper?", expanded=False):
col_a, col_b = st.columns(2)
with col_a:
st.markdown("""
**Title & Abstract**
- Title: 10-12 words based on your hypothesis
- Abstract: ~200 words summarizing the paper
**Introduction** (~550 words, 4 paragraphs)
- Background on the research topic
- Problem statement from hypothesis
- Research objectives and contributions
- Paper structure overview
**Literature Review** (~700 words, 4-5 paragraphs)
- Analysis of collected research papers
- Current state of the art
- Research gaps identified
- Positioning of your work
**Methodology** (~800 words, 5-6 paragraphs)
- Complete experimental design
- Step-by-step procedures from selected experiment
- Datasets, metrics, and evaluation approach
- Implementation details
""")
with col_b:
st.markdown("""
**Expected Results** (~550 words, 4 paragraphs)
- Anticipated experimental outcomes
- Tables and figures templates
- Performance metrics
- Analysis framework
**Discussion** (~600 words, 4-5 paragraphs)
- Interpretation of expected results
- Comparison with baselines
- Implications of findings
- Limitations and strengths
**Conclusion** (~300 words, 3 paragraphs)
- Summary of contributions
- Key findings
- Future work directions
**References**
- Formatted citations (APA style)
- All collected research papers
**Total: ~3,500 words (4-5 pages)**
""")
st.markdown("---")
# Initialize paper writer
writer = ResearchPaperWriter()
# Context for generation
paper_context = {
'topic': complete_data.get('topic', ''),
'hypothesis': selected_hypothesis,
'gap': selected_gap,
'experiment': selected_experiment,
'papers': complete_data.get('papers', []),
'literature_review': complete_data.get('literature_review', ''),
'gaps': complete_data.get('gap_analysis', {}).get('gaps', {})
}
# Generate Paper Button
st.markdown("### ๐ Generate Complete Research Paper")
st.info("๐ก Click the button below to generate a full research paper template. This will take 2-3 minutes.")
if st.button("๐ Generate Research Paper Template", type="primary", use_container_width=True, key="generate_paper"):
with st.spinner("๐ค AI is writing your complete research paper... Please wait 2-3 minutes"):
try:
# Generate complete paper
complete_paper_md = writer.generate_complete_paper(paper_context)
# Store in session state
st.session_state['generated_paper'] = complete_paper_md
st.success("โ
Research paper generated successfully!")
st.rerun()
except Exception as e:
st.error(f"โ Error generating paper: {str(e)}")
# Display and download generated paper
if st.session_state.get('generated_paper'):
st.markdown("---")
st.markdown("### ๐ Your Generated Research Paper")
# Paper stats
paper_text = st.session_state['generated_paper']
word_count = len(paper_text.split())
pages = word_count // 250
col1, col2, col3, col4 = st.columns(4)
with col1:
st.metric("Total Words", f"{word_count:,}")
with col2:
st.metric("Est. Pages", f"~{pages}")
with col3:
st.metric("Sections", "8")
with col4:
st.metric("Status", "โ
Ready")
st.markdown("")
# Preview
with st.expander("๐๏ธ Preview Paper Content", expanded=False):
st.markdown(paper_text[:3000] + "..." if len(paper_text) > 3000 else paper_text)
st.markdown("---")
st.markdown("### ๐ฅ Download Your Research Paper")
st.info("๐ก Your paper will be downloaded as a Microsoft Word document (.docx) ready for editing and submission!")
# Convert to Word document
try:
paper_title = selected_hypothesis.get('title', 'Research Paper')
doc_bytes = convert_markdown_to_docx(paper_text, paper_title)
if doc_bytes:
col1, col2, col3 = st.columns([1, 2, 1])
with col2:
st.download_button(
label="๐ Download as Word Document (.docx)",
data=doc_bytes,
file_name=f"research_paper_{datetime.now().strftime('%Y%m%d_%H%M%S')}.docx",
mime="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
use_container_width=True,
type="primary"
)
else:
st.error("Error converting paper to Word format. Please try again.")
except Exception as e:
st.error(f"Error creating Word document: {str(e)}")
st.info("๐ก Tip: Make sure python-docx is installed: pip install python-docx")
st.markdown("")
with st.expander("โน๏ธ Next Steps - How to Use Your Paper"):
st.markdown("""
### ๐ Your Research Paper Template is Ready!
**What's Included:**
- โ
Title and Abstract
- โ
Introduction with background
- โ
Literature Review from collected papers
- โ
Complete Methodology from your selected experiment
- โ
Expected Results section (fill with actual results)
- โ
Discussion framework
- โ
Conclusion
- โ
Formatted References
**How to Complete Your Paper:**
1. **Download** the Markdown or Text version
2. **Open** in Word, Google Docs, or any text editor
3. **Run** your experiment and collect results
4. **Add** actual results, figures, and tables to Section 4
5. **Update** discussion based on real findings
6. **Proofread** and format for your target journal
7. **Submit** your completed paper!
**File Formats:**
- **Markdown (.md)**: Best for converting to PDF/LaTeX via Pandoc or Overleaf
- **Text (.txt)**: Universal format, open in any editor
- **JSON**: Contains paper + metadata, machine-readable
**๐ก Pro Tip:** The paper is written in academic style using GPT-4 with all your collected research context!
""")
# Clear button
st.markdown("---")
if st.button("๐๏ธ Clear and Generate New Paper", type="secondary"):
st.session_state['generated_paper'] = None
st.success("โ
Cleared! Click 'Generate' button above to create a new paper.")
st.rerun()
elif selected_hypothesis and not selected_experiment:
st.warning("""
### โ ๏ธ Please Select an Experiment
You have selected a hypothesis, but no experiment yet.
**Steps:**
1. Go to **Tab 4** (Experiment Design)
2. Click **"Generate Experiments & Datasets"** if not done
3. **Select ONE experiment** by clicking "โ
Select This Experiment"
4. Return to this tab to generate your paper
""")
else:
st.info("""
### ๐ Complete Previous Steps First
To generate a research paper template, you need to:
1. **Tab 1-2**: Run complete analysis to collect papers and identify gaps
2. **Tab 3**: Review and select a hypothesis
3. **Tab 4**: Generate experiments and **select ONE experiment**
4. **Tab 5** (Here): Generate your complete research paper!
The AI will create a professional academic paper including:
- Title, Abstract, Introduction
- Literature Review with citations
- Methodology from your experiment
- Expected Results section (for you to fill)
- Discussion and Conclusion
- Properly formatted References
""")
# Show search history
if st.session_state.search_history:
st.header("Search History")
history_df = pd.DataFrame(st.session_state.search_history)
st.dataframe(
history_df,
hide_index=True,
column_config={
"timestamp": st.column_config.DatetimeColumn(
"Time",
format="D MMM, YYYY, HH:mm"
)
}
)
def display_experiment_results(results: dict):
"""Display the experiment generation results in a structured format"""
st.header("๐งช Detailed Experiment Plans")
# Experiments Section
if results.get('experiments'):
st.subheader("๐ฌ Select an Experiment for Your Research Paper")
st.info("๐ Each experiment contains EVERYTHING you need: introduction, methodology, datasets, metrics, models, and challenges. Choose ONE to use in your paper.")
# Experiment selection
for i, exp in enumerate(results['experiments']):
with st.expander(f"โ๏ธ Experiment {exp['id']}: {exp['title']}", expanded=(i==0)):
# Header with difficulty and time
col1, col2, col3 = st.columns([2, 1, 1])
with col1:
st.markdown(f"### ๐ {exp['title']}")
with col2:
difficulty_color = {"Easy": "๐ข", "Medium": "๐ก", "Hard": "๐ด"}
diff = exp.get('difficulty', 'Medium')
st.metric("Difficulty", f"{difficulty_color.get(diff, 'โช')} {diff}")
with col3:
st.metric("Estimated Time", exp.get('estimated_time', '2-3 months'))
st.markdown("---")
# 1. Introduction
if exp.get('introduction'):
st.markdown("**๐ 1. Introduction & Background**")
st.markdown(exp['introduction'])
st.markdown("")
# 2. Description
st.markdown("**๐ฏ 2. Experiment Overview**")
st.markdown(exp['description'])
st.markdown("")
# 3. Detailed Methodology Steps
if exp.get('steps'):
st.markdown("**๐ฌ 3. Detailed Methodology (Step-by-Step)**")
for j, step in enumerate(exp['steps'], 1):
st.markdown(f"**Step {j}:** {step}")
st.markdown("")
# 4. Datasets (from results dict, not just experiment)
st.markdown("**๐ 4. Recommended Datasets**")
if results.get('datasets'):
datasets = results['datasets']
# Check if it's a list (new format) or dict (old format)
if isinstance(datasets, list):
# New format: simple list
if datasets:
for idx, dataset in enumerate(datasets[:2], 1): # Show top 2
st.markdown(f"**{idx}. {dataset['name']}**")
st.markdown(f" - ๐ฆ Size: {dataset.get('size', 'N/A')}")
# Show downloads if available
if dataset.get('downloads'):
downloads = dataset.get('downloads')
if isinstance(downloads, int):
st.markdown(f" - ๐พ Downloads: {downloads:,}")
else:
st.markdown(f" - ๐พ Downloads: {downloads}")
# Show usability if available
if dataset.get('usability'):
st.markdown(f" - โญ Usability: {dataset['usability']:.1f}/10")
# Description
desc = dataset.get('description', '')
if len(desc) > 150:
st.markdown(f" - {desc[:150]}...")
else:
st.markdown(f" - {desc}")
# Link
if dataset.get('url'):
source = dataset.get('source', 'Kaggle')
st.markdown(f" - [๐ฅ **Access Dataset**]({dataset['url']})")
st.markdown("")
else:
st.markdown("โข Custom dataset required (see methodology)")
else:
# Old format fallback: dict with kaggle/huggingface keys
kaggle_datasets = datasets.get('kaggle', [])
hf_datasets = datasets.get('huggingface', [])
all_datasets = kaggle_datasets + hf_datasets
if all_datasets:
for idx, dataset in enumerate(all_datasets[:2], 1):
st.markdown(f"**{idx}. {dataset['name']}**")
st.markdown(f" - {dataset.get('description', '')[:150]}")
if dataset.get('url'):
st.markdown(f" - [๐ฅ **Access Dataset**]({dataset['url']})")
st.markdown("")
else:
st.markdown("โข Custom dataset required (see methodology)")
else:
st.markdown("โข Dataset recommendations will be generated based on your topic")
st.markdown("")
# 5. Evaluation Metrics
if results.get('metrics'):
st.markdown("**๐ 5. Evaluation Metrics**")
for metric in results['metrics'][:4]: # Top 4 metrics
st.markdown(f"โข **{metric['name']}**: {metric['description']}")
if metric.get('range'):
st.markdown(f" - Range: {metric['range']}")
st.markdown("")
# 6. Model Architectures
if results.get('architectures'):
st.markdown("**๐๏ธ 6. Suggested Model Architectures**")
for arch in results['architectures'][:3]: # Top 3 architectures
st.markdown(f"โข **{arch['name']}**")
st.markdown(f" - {arch['description']}")
if arch.get('parameters'):
st.markdown(f" - Parameters: {arch['parameters']}")
st.markdown("")
# 7. Baseline Models
if results.get('baselines'):
st.markdown("**๐ 7. Baseline Models for Comparison**")
for baseline in results['baselines'][:3]:
st.markdown(f"โข **{baseline['name']}**: {baseline['description']}")
if baseline.get('expected_performance'):
st.markdown(f" - Expected Performance: {baseline['expected_performance']}")
st.markdown("")
# 8. Expected Outcomes
if results.get('expected_outcomes'):
st.markdown("**๐ฏ 8. Expected Outcomes**")
outcomes = results['expected_outcomes']
col1, col2, col3, col4 = st.columns(4)
with col1:
st.metric("Target Accuracy", outcomes.get('accuracy_range', '85-92%'))
with col2:
st.metric("Training Time", outcomes.get('training_time', '4-6 hours'))
with col3:
st.metric("Model Size", outcomes.get('model_size', '50-100MB'))
with col4:
st.metric("Inference Speed", outcomes.get('inference_speed', '10-20ms'))
st.markdown("")
# 9. Challenges & Solutions
if results.get('challenges'):
st.markdown("**โ ๏ธ 9. Potential Challenges & Mitigation**")
for challenge in results['challenges'][:4]:
st.markdown(f"โข {challenge}")
st.markdown("")
# 10. Required Resources
if exp.get('required_resources'):
st.markdown("**๐ป 10. Required Resources**")
for resource in exp['required_resources']:
st.markdown(f"โข {resource}")
st.markdown("")
# Selection button - prominent
st.markdown("---")
col1, col2, col3 = st.columns([1, 2, 1])
with col2:
if st.button(f"โ Select This Experiment for Paper", key=f"select_exp_{exp['id']}", use_container_width=True, type="primary"):
st.session_state['selected_experiment'] = exp
st.success(f"โ Selected: {exp['title']}")
st.info("โ Go to Tab 5 to generate your research paper!")
# Show currently selected experiment
if st.session_state.get('selected_experiment'):
selected = st.session_state['selected_experiment']
st.markdown("---")
st.success(f"๐ฏ **Currently Selected:** Experiment {selected['id']} - {selected['title']}")
st.caption("Go to Tab 5 'AI Paper Writer' to generate your complete research paper template!")
# Download complete experiment plan as JSON
st.markdown("---")
st.subheader("๐พ Export Complete Experiment Plan")
json_str = json.dumps(results, indent=2)
st.download_button(
label="๐ฅ Download All Experiments as JSON",
data=json_str,
file_name=f"experiment_plan_{results.get('metadata', {}).get('hypothesis_id', 'unknown')}.json",
mime="application/json",
help="Download all experiment details including datasets, metrics, and models"
)
def render_footer():
"""Render footer on all pages"""
st.markdown("
", unsafe_allow_html=True)
st.markdown("---")
st.markdown("""
Development Team
Made by Radia Riaz,
Amna Alvie,
Emaan Riaz,
Maheen Alvie
Gen AI Hackathon 2025
""", unsafe_allow_html=True)
if __name__ == "__main__":
main()
render_footer()