File size: 4,990 Bytes
fbec6c3
 
 
a263aa6
d6c42b6
 
 
0623585
d6c42b6
0623585
 
d6c42b6
 
 
fbec6c3
 
0623585
fbec6c3
d6c42b6
0623585
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d6c42b6
0623585
 
 
 
 
 
d6c42b6
 
 
 
0623585
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
fbec6c3
0623585
fbec6c3
0623585
fbec6c3
 
 
 
 
0623585
 
 
 
 
 
 
fbec6c3
 
 
 
a263aa6
0623585
a263aa6
fbec6c3
 
 
 
 
1220468
0623585
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a263aa6
d6c42b6
a263aa6
0623585
a263aa6
 
0623585
 
d6c42b6
0623585
 
 
d6c42b6
0623585
 
d6c42b6
0623585
1220468
0623585
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import os
import streamlit as st
import arxiv
import random
import datetime

# -------------------------------
# Groq API Client
# -------------------------------
from groq import Groq

client = Groq(
    api_key=os.environ.get("GROQ_API_KEY"),
)

# -------------------------------
# Helper Functions (Groq-based)
# -------------------------------
def groq_summarize(text: str) -> str:
    """
    Summarize the given text using Groq's chat completion API.
    """
    response = client.chat.completions.create(
        messages=[
            {
                "role": "user",
                "content": f"Summarize this paper in one sentence and provide 3 key takeaways:\n\n{text}"
            }
        ],
        model="llama-3.3-70b-versatile",
    )
    return response.choices[0].message.content.strip()


def groq_eli5(text: str) -> str:
    """
    Explain the paper like I'm 5 years old.
    """
    response = client.chat.completions.create(
        messages=[
            {
                "role": "user",
                "content": f"Explain this paper as if I were 5 years old in one sentence:\n\n{text}"
            }
        ],
        model="llama-3.3-70b-versatile",
    )
    return response.choices[0].message.content.strip()


def calculate_scores(paper):
    """
    Generate trust and relevance scores for a paper.
    """
    trust_score = random.randint(5, 10)  # Placeholder, can be improved with citations data
    relevance_score = random.randint(5, 10)  # Placeholder, can use NLP topic matching
    return trust_score, relevance_score


def retrieve_papers(query=None, max_results=10, random_mode=False):
    """
    Retrieve academic papers from arXiv, either based on search or randomly.
    """
    if random_mode:
        query = ""  # Empty query fetches random results
    
    search = arxiv.Search(query=query, max_results=max_results)
    papers = []
    
    for result in search.results():
        trust_score, relevance_score = calculate_scores(result)
        paper = {
            "title": result.title,
            "summary": result.summary,
            "url": result.pdf_url,
            "authors": [author.name for author in result.authors],
            "published": result.published.strftime('%Y-%m-%d') if isinstance(result.published, datetime.datetime) else "n.d.",
            "doi": f"https://doi.org/10.48550/arXiv.{result.entry_id.split('/')[-1]}",
            "bib_explorer": f"https://arxiv.org/abs/{result.entry_id.split('/')[-1]}",
            "litmaps": f"https://app.litmaps.com/preview/{result.entry_id.split('/')[-1]}",
            "connected_papers": f"https://www.connectedpapers.com/{result.entry_id.split('/')[-1]}",
            "trust_score": trust_score,
            "relevance_score": relevance_score
        }
        papers.append(paper)
    return papers

# -------------------------------
# Streamlit Interface
# -------------------------------
st.title("πŸ“š PaperPilot – Intelligent Academic Navigator")

with st.sidebar:
    st.header("πŸ” Search Parameters")
    query = st.text_input("Research topic or question:")
    
    col1, col2 = st.columns([4, 1])
    with col1:
        search_button = st.button("πŸš€ Find Articles")
    with col2:
        random_button = st.button("🎲 Random Papers")
    
    if search_button:
        if query.strip():
            with st.spinner("Searching arXiv..."):
                st.session_state.papers = retrieve_papers(query=query, max_results=10)
                st.success(f"Found {len(st.session_state.papers)} papers!")
        else:
            st.warning("Please enter a search query")
    
    if random_button:
        with st.spinner("Fetching random papers..."):
            st.session_state.papers = retrieve_papers(max_results=random.randint(5, 15), random_mode=True)
            st.success(f"Fetched {len(st.session_state.papers)} random papers!")

if 'papers' in st.session_state and st.session_state.papers:
    st.header("πŸ“‘ Retrieved Papers")
    for idx, paper in enumerate(st.session_state.papers, 1):
        with st.expander(f"{idx}. {paper['title']}"):
            st.markdown(f"**Authors:** {', '.join(paper['authors'])}")
            st.markdown(f"**Published:** {paper['published']}")
            st.markdown(f"**[PDF Link]({paper['url']})** | **[DOI]({paper['doi']})** | **[Bib Explorer]({paper['bib_explorer']})** | **[Litmaps]({paper['litmaps']})** | **[Connected Papers]({paper['connected_papers']})**")
            
            with st.spinner("Generating summaries..."):
                summary = groq_summarize(paper['summary'])
                eli5_summary = groq_eli5(paper['summary'])
            
            st.markdown(f"**Summary:** {summary}")
            st.markdown(f"**ELI5:** {eli5_summary}")
            
            st.markdown(f"**Trust Score:** {paper['trust_score']} / 10  ⭐ | **Relevance Score:** {paper['relevance_score']} / 10 πŸ”₯")
else:
    st.info("Enter a query or click 🎲 Random Papers to get started.")