SanketAI commited on
Commit
b2333d3
Β·
verified Β·
1 Parent(s): 546d6cd

Upload 14 files

Browse files
agents/__init__.py ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ # agents/__init__.py
2
+ from .search_agent import SearchAgent
3
+ from .qa_agent import QAAgent
4
+ from .future_works_agent import FutureWorksAgent
5
+ from .intent_agent import IntentAgent
6
+ from .summarization_agent import SummarizationAgent
7
+ __all__ = ["IntentAgent" , "SearchAgent", "QAAgent", "FutureWorksAgent" , "SummarizationAgent"]
agents/future_works_agent.py ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain.vectorstores import FAISS
2
+ from langchain_google_genai import GoogleGenerativeAIEmbeddings
3
+ import os
4
+ from agents import SearchAgent
5
+ import streamlit as st
6
+ from config.config import model
7
+
8
+ embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001")
9
+
10
+ class FutureWorksAgent:
11
+ def __init__(self):
12
+ self.model = model
13
+ self.prompt = """Analyze the research context and provide targeted insights based on the specific task type.
14
+
15
+ Previous conversation:
16
+ {chat_history}
17
+
18
+ Current research context:
19
+ {context}
20
+
21
+ Task Type Detection:
22
+ 1. Review Paper Future Work:
23
+ If the query involves generating future work for a review paper:
24
+ - Identify emerging trends and unexplored areas
25
+ - Suggest potential research questions
26
+ - Outline methodology gaps
27
+ - Propose innovative approaches
28
+
29
+ 2. Structured Review Summary:
30
+ If the query involves creating a review paper summary:
31
+ - Synthesize key findings across papers
32
+ - Identify major research themes
33
+ - Highlight methodological approaches
34
+ - Present conflicting results or debates
35
+ - Suggest future research opportunities
36
+
37
+ 3. Improvement Plan:
38
+ If the query involves generating an improvement plan:
39
+ - Analyze existing solutions and their limitations
40
+ - Identify potential enhancements
41
+ - Suggest novel technical contributions
42
+ - Propose validation approaches
43
+ - Outline implementation steps
44
+
45
+ 4. Research Direction Synthesis:
46
+ If the query involves combining multiple papers:
47
+ - Identify common themes and patterns
48
+ - Highlight complementary approaches
49
+ - Suggest novel combinations of methods
50
+ - Propose new research directions
51
+ - Outline potential experimental designs
52
+
53
+ Format Guidelines:
54
+ - Begin with identifying the specific task type
55
+ - Provide structured, section-wise response
56
+ - Include specific examples from papers
57
+ - List concrete action items or suggestions
58
+ - Acknowledge limitations and assumptions
59
+ - Suggest validation approaches
60
+
61
+ Note: Focus on providing actionable, specific suggestions rather than general statements.
62
+ Consider both theoretical advances and practical implementations.
63
+ """
64
+
65
+ self.papers = None
66
+ self.search_agent_response = ""
67
+
68
+ def solve(self, query):
69
+
70
+ # Check if search has been performed
71
+ if not os.path.exists("vector_db"):
72
+ st.warning("No papers loaded. Performing search first...")
73
+ search_agent = SearchAgent()
74
+ self.search_agent_response , self.papers = search_agent.solve(query)
75
+
76
+ # Load vector store
77
+ vector_db = FAISS.load_local("vector_db", embeddings, index_name="base_and_adjacent", allow_dangerous_deserialization=True)
78
+
79
+ # Get chat history
80
+ chat_history = st.session_state.get("chat_history", [])
81
+ chat_history_text = "".join([f"{sender}: {msg}" for sender, msg in chat_history[-5:]])
82
+
83
+ # Get relevant chunks
84
+ retrieved = vector_db.as_retriever().get_relevant_documents(query)
85
+ context = "".join([f"{doc.page_content}\n Source: {doc.metadata['source']}" for doc in retrieved])
86
+
87
+ # Generate response
88
+ full_prompt = self.prompt.format(
89
+ chat_history=chat_history_text,
90
+ context=context
91
+ )
92
+ response = self.model.generate_content(str(self.search_agent_response) + full_prompt)
93
+ return response.text , self.papers
agents/intent_agent.py ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from config.config import model
2
+
3
+ class IntentAgent:
4
+ def __init__(self):
5
+ self.model = model
6
+ self.prompt = """You are an intent classifier for a research paper assistant. Given a user query, classify it into one of these categories:
7
+
8
+ - "search": User wants to find relevant research papers on a topic
9
+ - "qa": User has questions about specific papers or content
10
+ - "future_works": User wants to:
11
+ * Generate future work ideas for a review paper
12
+ * Create a structured review paper summary
13
+ * Generate improvement plans from research works
14
+ * Combine multiple papers for new research directions
15
+ * Review paper generation
16
+ * Synthesize multiple papers
17
+ - "summarize": User wants to:
18
+ * Summarize findings from multiple papers over a given timeframe
19
+ * Extract key information from multiple papers and present it
20
+
21
+ Example queries and their intents:
22
+ "Find papers about machine learning" -> "search"
23
+ "What does the paper say about the methodology?" -> "qa"
24
+ "What future directions can I include in my review?" -> "future_works"
25
+ "Can you help me write a literature review?" -> "future_works"
26
+ "How can I combine these papers into an improvement plan?" -> "future_works"
27
+ "What are the gaps in current research?" -> "future_works"
28
+ "Summarize findings on neural networks from these papers" -> "summarize"
29
+ "Extract key points from these papers" -> "summarize"
30
+
31
+ Respond with just the intent category.
32
+
33
+ Query: {query}"""
34
+
35
+
36
+ def get_intent(self, query):
37
+ response = self.model.generate_content(self.prompt.format(query=query))
38
+ return response.text.strip().lower()
agents/qa_agent.py ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import streamlit as st
3
+ from agents import SearchAgent
4
+ from langchain.vectorstores import FAISS
5
+ from langchain_google_genai import GoogleGenerativeAIEmbeddings
6
+ from config.config import model
7
+
8
+
9
+
10
+
11
+ embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001")
12
+
13
+ class QAAgent:
14
+ def __init__(self):
15
+
16
+ self.model = model
17
+ self.prompt = """You are a research assistant answering questions about academic papers. Use the following context from papers and chat history to provide accurate, specific answers.
18
+
19
+ Previous conversation:
20
+ {chat_history}
21
+
22
+ Paper context:
23
+ {context}
24
+
25
+ Question: {question}
26
+
27
+ Guidelines:
28
+ 1. Reference specific papers when making claims
29
+ 2. Use direct quotes when relevant
30
+ 3. Acknowledge if information isn't available in the provided context
31
+ 4. Maintain academic tone and precision
32
+ """
33
+ self.papers = None
34
+ self.search_agent_response = ""
35
+
36
+ def solve(self, query):
37
+ # Check if search has been performed
38
+ if not os.path.exists("vector_db"):
39
+ st.warning("No papers loaded. Performing search first...")
40
+ search_agent = SearchAgent()
41
+ self.search_agent_response , self.papers = search_agent.solve(query)
42
+
43
+ # Load vector store
44
+ vector_db = FAISS.load_local("vector_db", embeddings, index_name="base_and_adjacent", allow_dangerous_deserialization=True)
45
+
46
+ # Get chat history
47
+ chat_history = st.session_state.get("chat_history", [])
48
+ chat_history_text = "".join([f"{sender}: {msg}" for sender, msg in chat_history[-5:]]) # Last 5 messages
49
+
50
+ # Get relevant chunks
51
+ retrieved = vector_db.as_retriever().get_relevant_documents(query)
52
+ context = "".join([f"{doc.page_content}\n Source: {doc.metadata['source']}" for doc in retrieved])
53
+
54
+ # Generate response
55
+ full_prompt = self.prompt.format(
56
+ chat_history=chat_history_text,
57
+ context=context,
58
+ question=query
59
+ )
60
+
61
+ response = self.model.generate_content(str(self.search_agent_response) + full_prompt)
62
+ return response.text , self.papers
agents/search_agent.py ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import requests
3
+ import os
4
+ from langchain.document_loaders import PDFMinerLoader
5
+ from langchain_google_genai import GoogleGenerativeAIEmbeddings
6
+ from langchain.vectorstores import FAISS
7
+ from langchain_community.document_loaders import ArxivLoader
8
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
9
+ import faiss
10
+ from langchain_community.docstore.in_memory import InMemoryDocstore
11
+ from config.config import model
12
+ import urllib.request as libreq
13
+ import xml.etree.ElementTree as ET
14
+
15
+ os.makedirs("papers", exist_ok=True)
16
+
17
+
18
+ embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001")
19
+ index = faiss.IndexFlatL2(len(embeddings.embed_query("dummy query")))
20
+
21
+ text_splitter = RecursiveCharacterTextSplitter(
22
+ chunk_size=700,
23
+ chunk_overlap=0,
24
+ length_function=len
25
+ )
26
+
27
+ class SearchAgent:
28
+ def __init__(self):
29
+
30
+ self.model = model
31
+ self.p = """You are an assistant designed to extract research topics or titles from user queries. When a user asks about a specific topic, identify the central subject of their query and provide a concise, clear title or topic related to that area of research. If the query refers to a particular research paper, include the paper's title, author(s), and publication year.
32
+ Here are the instructions you should follow:
33
+ General Topics: If the query mentions a general topic without referring to a specific paper, identify the primary research area or topic. For example, if the query is "What are the advancements in text-to-SQL models?" your response should be simply "Text-to-SQL Models."
34
+ Specific Research Papers: If the query mentions a particular paper, extract the title, author(s), and year of the paper. For example, if the query is "What did the paper by John Doe in 2022 say about AI in healthcare?" your response should be "AI in Healthcare (John Doe, 2022)."
35
+ Abstract or General Query: If the query is an abstract or general inquiry into a topic, return the main theme or title of that topic. For instance, "What are the advancements in natural language processing?" would result in "Natural Language Processing Advancements."
36
+ Examples:
37
+ User Query: "Tell me about recent advancements in text-to-SQL models." Response: "Text-to-SQL Models."
38
+ User Query: "What does the paper 'Deep Learning for Text-to-SQL by Jane Smith, 2021' cover?" Response: "'Deep Learning for Text-to-SQL' (Jane Smith, 2021)."
39
+ User Query: "Can you summarize the paper by Alice Brown on quantum computing from 2020?" Response: "'Quantum Computing: A New Frontier' (Alice Brown, 2020)." """
40
+
41
+ def solve(self, task):
42
+ print(f"Searching for information on: {task}")
43
+ response = model.generate_content(self.p+task)
44
+ query = response.text.strip()
45
+
46
+ r=query.split(" ")
47
+ query_="%20".join(r)
48
+
49
+ with libreq.urlopen(f'''http://export.arxiv.org/api/query?search_query=all:{query_}&sortBy=relevance&sortOrder=descending&start=0&max_results=5''') as url:
50
+ r = url.read()
51
+
52
+
53
+
54
+ xml_content = r
55
+ root = ET.fromstring(xml_content)
56
+ ns = {'atom': 'http://www.w3.org/2005/Atom'}
57
+ ids = [entry.find('atom:id', ns).text for entry in root.findall('atom:entry', ns)]
58
+ pdf_urls = [url.replace("abs", "pdf") for url in ids]
59
+
60
+ # Create list to store paper information
61
+ papers = []
62
+
63
+ # Extract information for each paper
64
+ for entry in root.findall('atom:entry', ns):
65
+ paper_info = {}
66
+
67
+ # Get paper title
68
+ title = entry.find('atom:title', ns).text
69
+ paper_info['title'] = title
70
+
71
+ # Get paper ID and create PDF link
72
+ paper_id = entry.find('atom:id', ns).text
73
+ pdf_link = paper_id.replace("abs", "pdf")
74
+ paper_info['link'] = pdf_link
75
+
76
+ # Get publication year from published date
77
+ published = entry.find('atom:published', ns).text
78
+ year = published[:4] # Extract year from date string
79
+ paper_info['year'] = year
80
+
81
+ papers.append(paper_info)
82
+
83
+ all_papers = []
84
+
85
+ def download_pdf_paper_from_url(url):
86
+ paper_number = os.path.basename(url).strip(".pdf")
87
+ res = requests.get(url)
88
+ pdf_path = f"papers/{paper_number}.pdf"
89
+ with open(pdf_path, 'wb') as f:
90
+ f.write(res.content)
91
+ return paper_number
92
+
93
+ for paper in papers:
94
+ paper_number = download_pdf_paper_from_url(paper['link'])
95
+ all_papers.append(paper_number)
96
+ # Add paper number to paper info
97
+ paper['paper_number'] = paper_number
98
+
99
+ vector_db = FAISS(
100
+ embedding_function=embeddings,
101
+ index=index,
102
+ docstore=InMemoryDocstore(),
103
+ index_to_docstore_id={}
104
+ )
105
+
106
+ for pdf_number in all_papers:
107
+ docs = ArxivLoader(query=pdf_number)
108
+ docs = PDFMinerLoader(f"papers/{pdf_number}.pdf").load()
109
+ docs = text_splitter.split_documents(docs)
110
+ vector_db.add_documents(docs)
111
+
112
+ vector_db.save_local("vector_db", index_name="base_and_adjacent")
113
+
114
+ return ["Here are the papers on" + query] , papers # Return the list of paper dictionaries
115
+
agents/summarization_agent.py ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain.vectorstores import FAISS
2
+ from langchain_google_genai import GoogleGenerativeAIEmbeddings
3
+ import os
4
+ import streamlit as st
5
+ from agents import SearchAgent
6
+ from config.config import model
7
+
8
+
9
+
10
+ embeddings = GoogleGenerativeAIEmbeddings(model="models/embedding-001")
11
+
12
+ class SummarizationAgent:
13
+ def __init__(self):
14
+ self.model = model
15
+ self.prompt = """You are a research assistant tasked with synthesizing findings from multiple academic papers over time. Your goal is to create a comprehensive summary that highlights key trends, thematic developments, and methodological evolution within a given timeframe.
16
+
17
+ Given the following context, analyze the papers to produce a structured summary:
18
+
19
+ Previous conversation:
20
+ {chat_history}
21
+
22
+ Papers context:
23
+ {context}
24
+
25
+ Guidelines for timeline-based summarization:
26
+
27
+ Key Findings and Trends Over Time
28
+
29
+ Identify major discoveries and conclusions, highlighting how they have developed chronologically.
30
+ Note emerging trends, consensus, and any evolving contradictions across papers, especially in response to new technologies or shifts in the field.
31
+ Present statistical evidence and experimental results in relation to time, pointing out any measurable improvements or declines over the years.
32
+ Methodological Evolution
33
+
34
+ Compare and contrast research approaches across different time periods, emphasizing changes or advances in data collection, analysis techniques, or tools.
35
+ Identify and describe innovative methodological contributions and how these may have impacted research outcomes over time.
36
+ Theoretical Progression
37
+
38
+ Outline the theoretical foundations and highlight their chronological development.
39
+ Connect findings to existing theories, noting how interpretations or theoretical perspectives have evolved.
40
+ Identify theoretical advances, challenges, or shifts and their relationship to the timeline.
41
+ Practical Applications and Temporal Shifts
42
+
43
+ Discuss real-world applications over time, noting how findings have influenced industry practices or technology adoption.
44
+ Highlight evolving practical use cases and how implementation considerations have changed with advances in research.
45
+ Research Gaps and Future Directions
46
+
47
+ Identify limitations in studies across time periods, noting any improvement or persistent gaps.
48
+ Point out unexplored areas and suggest specific future research directions informed by chronological developments in the field.
49
+ Formatting and Style:
50
+
51
+ Organize the summary with clear sections that reflect the temporal progression.
52
+ Maintain an academic tone, using specific examples, dates, and quotes where relevant.
53
+ Clearly identify and label sections to enhance readability, and acknowledge any limitations in the available context.
54
+ """
55
+
56
+ self.papers = None
57
+ self.search_agent_response = ""
58
+
59
+ def solve(self, query):
60
+ # Check if search has been performed
61
+ if not os.path.exists("vector_db"):
62
+ st.warning("No papers loaded. Performing search first...")
63
+ search_agent = SearchAgent()
64
+ self.search_agent_response, self.papers = search_agent.solve(query)
65
+
66
+ # Load vector store
67
+ vector_db = FAISS.load_local("vector_db", embeddings, index_name="base_and_adjacent", allow_dangerous_deserialization=True)
68
+
69
+ # Get chat history
70
+ chat_history = st.session_state.get("chat_history", [])
71
+ chat_history_text = "\n".join([f"{sender}: {msg}" for sender, msg in chat_history[-5:]])
72
+
73
+ # Get relevant chunks from all papers
74
+ retrieved = vector_db.as_retriever(
75
+ search_kwargs={"k": 10} # Increase number of chunks to get broader context
76
+ ).get_relevant_documents(query)
77
+
78
+ # Organize context by paper
79
+ context = self._organize_context(retrieved)
80
+
81
+ # Generate summary
82
+ full_prompt = self.prompt.format(
83
+ chat_history=chat_history_text,
84
+ context=context
85
+ )
86
+
87
+ response = self.model.generate_content(str(self.search_agent_response) + full_prompt)
88
+ return response.text, self.papers
89
+
90
+ def _organize_context(self, documents):
91
+ """
92
+ Organizes retrieved chunks by paper and creates a structured context.
93
+ """
94
+ # Group chunks by paper
95
+ paper_chunks = {}
96
+ for doc in documents:
97
+ paper_id = doc.metadata.get('source', 'unknown')
98
+ if paper_id not in paper_chunks:
99
+ paper_chunks[paper_id] = []
100
+ paper_chunks[paper_id].append(doc.page_content)
101
+
102
+ # Create structured context
103
+ organized_context = []
104
+ for paper_id, chunks in paper_chunks.items():
105
+ paper_context = f"\nPaper: {paper_id}\n"
106
+ paper_context += "\n".join(chunks)
107
+ organized_context.append(paper_context)
108
+
109
+ return "\n\n".join(organized_context)
app.py CHANGED
@@ -1,277 +1,277 @@
1
- import streamlit as st
2
- import os
3
- import sys
4
- from typing import Tuple, List, Dict, Optional
5
- from router import Router
6
-
7
- sys.path.append(os.path.dirname(os.path.abspath(__file__)))
8
-
9
- class AcademicResearchAssistant:
10
- def __init__(self):
11
-
12
- self.router = Router()
13
- self.setup_streamlit_config()
14
- self.initialize_session_state()
15
-
16
- def setup_streamlit_config(self):
17
-
18
- st.set_page_config(
19
- page_title="Academic Research Assistant",
20
- page_icon="πŸ“š",
21
- layout="wide",
22
- initial_sidebar_state="expanded",
23
- menu_items={
24
- 'Get Help': 'https://github.com/yourusername/academic-research-assistant',
25
- 'Report a bug': "https://github.com/yourusername/academic-research-assistant/issues",
26
- 'About': "# Academic Research Assistant v1.0\nYour intelligent research companion."
27
- }
28
- )
29
-
30
- # Custom CSS to enhance the UI
31
- st.markdown("""
32
- <style>
33
- .stApp {
34
- background: linear-gradient(to bottom right, #f5f7fa, #eef2f7);
35
- }
36
- .stButton>button {
37
- background-color: #1f4287;
38
- color: white;
39
- border-radius: 5px;
40
- padding: 0.5rem 1rem;
41
- }
42
- .stProgress .st-bo {
43
- background-color: #1f4287;
44
- }
45
- .chat-message {
46
- padding: 10px;
47
- border-radius: 5px;
48
- margin: 5px 0;
49
- animation: fadeIn 0.5s ease-in;
50
- }
51
- .user-message {
52
- background-color: #e6f3ff;
53
- }
54
- .bot-message {
55
- background-color: #f0f2f6;
56
- }
57
- @keyframes fadeIn {
58
- from {opacity: 0;}
59
- to {opacity: 1;}
60
- }
61
- .paper-card {
62
- background-color: white;
63
- padding: 1.5rem;
64
- border-radius: 10px;
65
- box-shadow: 0 2px 4px rgba(0,0,0,0.1);
66
- margin-bottom: 1rem;
67
- }
68
- .paper-title {
69
- color: #1f4287;
70
- font-size: 1.1rem;
71
- font-weight: bold;
72
- margin-bottom: 0.5rem;
73
- }
74
- .paper-metadata {
75
- font-size: 0.9rem;
76
- color: #666;
77
- margin-bottom: 0.5rem;
78
- }
79
- .paper-abstract {
80
- font-size: 0.95rem;
81
- line-height: 1.5;
82
- margin-top: 1rem;
83
- padding-left: 1rem;
84
- border-left: 3px solid #1f4287;
85
- }
86
- .download-button {
87
- background-color: #4CAF50;
88
- color: white;
89
- padding: 0.5rem 1rem;
90
- border-radius: 5px;
91
- text-decoration: none;
92
- display: inline-block;
93
- margin-top: 1rem;
94
- }
95
- .metric-card {
96
- background-color: white;
97
- padding: 1rem;
98
- border-radius: 8px;
99
- box-shadow: 0 2px 4px rgba(0,0,0,0.05);
100
- text-align: center;
101
- }
102
- </style>
103
- """, unsafe_allow_html=True)
104
-
105
- def initialize_session_state(self):
106
-
107
- if "chat_history" not in st.session_state:
108
- st.session_state.chat_history = []
109
- if "fetched_papers" not in st.session_state:
110
- st.session_state.fetched_papers = []
111
- if "search_count" not in st.session_state:
112
- st.session_state.search_count = 0
113
- if "total_searches" not in st.session_state:
114
- st.session_state.total_searches = 0
115
-
116
- def display_welcome_message(self):
117
-
118
- st.title("πŸ“š Academic Research Paper Assistant")
119
-
120
- # Create three columns for metrics
121
- col1, col2, col3, col4 = st.columns([2, 1, 1, 1])
122
-
123
- with col1:
124
- st.markdown("""
125
- Welcome to your intelligent research companion! This tool helps you:
126
- - πŸ” Find relevant academic papers
127
- - πŸ“Š Analyze research trends
128
- - πŸ“– Access paper summaries
129
- - πŸ“₯ Download full papers
130
- """)
131
-
132
- # Display metrics in cards
133
- with col3:
134
- st.markdown("""
135
- <div class="metric-card">
136
- <h3>Papers Found</h3>
137
- <h2>{}</h2>
138
- </div>
139
- """.format(len(st.session_state.fetched_papers)), unsafe_allow_html=True)
140
-
141
- with col4:
142
- st.markdown("""
143
- <div class="metric-card">
144
- <h3>Total Searches</h3>
145
- <h2>{}</h2>
146
- </div>
147
- """.format(st.session_state.total_searches), unsafe_allow_html=True)
148
-
149
-
150
-
151
- def create_chat_interface(self) -> Tuple[str, bool]:
152
-
153
- with st.container():
154
- st.write("### πŸ’¬ Research Query Interface")
155
-
156
- # Create columns for better layout
157
- col1, col2 = st.columns([4, 1])
158
-
159
- with col1:
160
- user_input = st.text_input(
161
- "Enter your research query (e.g., 'Recent advances in quantum computing')",
162
- key="user_input",
163
- placeholder="Type your research question here...",
164
- max_chars=500
165
- )
166
-
167
- col3, col4, col5 = st.columns([2, 1, 1])
168
- with col3:
169
- send_button = st.button("πŸ” Search ", use_container_width=True)
170
- with col4:
171
- clear_button = st.button("πŸ—‘οΈ Clear History", use_container_width=True)
172
-
173
- if clear_button:
174
- st.session_state.chat_history = []
175
- st.session_state.fetched_papers = []
176
- st.session_state.search_count = 0
177
- st.session_state.total_searches = 0
178
- st.rerun()
179
-
180
- return user_input, send_button
181
-
182
- def process_user_input(self, user_input: str):
183
-
184
- with st.spinner('πŸ” Working on response...'):
185
- # Update search metrics
186
- st.session_state.search_count = len(st.session_state.fetched_papers)
187
- st.session_state.total_searches += 1
188
-
189
- try:
190
- # Get response from router
191
- response, papers = self.router.route_query(user_input)
192
-
193
- # Update papers in session state
194
- if papers:
195
- unique_papers = {paper['paper_number']: paper for paper in papers}
196
- st.session_state.fetched_papers = list(unique_papers.values())
197
-
198
- # Add bot response and use message to chat history
199
- if response:
200
- st.session_state.chat_history.append(("Bot", response))
201
- st.session_state.chat_history.append(("User", user_input))
202
- else:
203
- st.session_state.chat_history.append(
204
- ("Bot", "I couldn't find relevant papers for your query. Please try rephrasing or use more specific terms.")
205
- )
206
- except Exception as e:
207
- st.session_state.chat_history.append(
208
- ("Bot", f"An error occurred while processing your request: {str(e)}")
209
- )
210
- st.error("There was an error processing your request. Please try again.")
211
-
212
- def display_chat_history(self):
213
- """Display the chat history with user and bot messages"""
214
- for sender, message in reversed(st.session_state.chat_history):
215
- if sender == "User":
216
- st.markdown(
217
- "<div class='chat-message user-message'>"
218
- f"<strong>πŸ‘€ You:</strong> {message}"
219
- "</div>",
220
- unsafe_allow_html=True
221
- )
222
- else:
223
- st.markdown(
224
- "<div class='chat-message bot-message'>"
225
- f"<strong>πŸ€– Assistant:</strong> {message[0]}"
226
- "</div>",
227
- unsafe_allow_html=True
228
- )
229
-
230
- def display_papers(self):
231
- """Display the list of fetched papers with download links"""
232
- st.write("### πŸ“„ Retrieved Research Papers")
233
- if st.session_state.fetched_papers:
234
- for paper in st.session_state.fetched_papers:
235
- with st.expander(f"πŸ“‘ {paper.get('title', 'Untitled Paper')}"):
236
- st.markdown(
237
- "<div class='paper-card'>"
238
- f"<div class='paper-title'>{paper.get('title', '').replace('\n', ' ').strip()}</div>"
239
- f"<div class='paper-metadata'>Year: {paper.get('year', 'N/A')} | Paper ID: {paper.get('paper_number', 'N/A')}</div>"
240
- f"""{'<div class="paper-abstract">' + paper.get('abstract', '') + '</div>' if paper.get('abstract') else ''}"""
241
- "</div>",
242
- unsafe_allow_html=True
243
- )
244
-
245
- download_link = paper.get('link')
246
- if download_link:
247
- st.markdown(f"[πŸ“₯ Download PDF]({download_link})")
248
- else:
249
- st.warning("⚠️ No download link available")
250
- else:
251
- st.info("πŸ” No papers fetched yet. Start by entering a research query above!")
252
-
253
- def run(self):
254
- """Main method to run the application"""
255
- self.display_welcome_message()
256
-
257
-
258
- user_input, send_button = self.create_chat_interface()
259
-
260
- st.markdown("### πŸ’¬ Chat History")
261
- self.display_chat_history()
262
-
263
-
264
- if user_input and send_button:
265
- self.process_user_input(user_input)
266
- st.rerun()
267
-
268
- st.markdown("---")
269
- self.display_papers()
270
-
271
- def main():
272
-
273
- app = AcademicResearchAssistant()
274
- app.run()
275
-
276
- if __name__ == "__main__":
277
  main()
 
1
+ import streamlit as st
2
+ import os
3
+ import sys
4
+ from typing import Tuple, List, Dict, Optional
5
+ from router import Router
6
+
7
+ sys.path.append(os.path.dirname(os.path.abspath(__file__)))
8
+
9
+ class AcademicResearchAssistant:
10
+ def __init__(self):
11
+
12
+ self.router = Router()
13
+ self.setup_streamlit_config()
14
+ self.initialize_session_state()
15
+
16
+ def setup_streamlit_config(self):
17
+
18
+ st.set_page_config(
19
+ page_title="Academic Research Assistant",
20
+ page_icon="πŸ“š",
21
+ layout="wide",
22
+ initial_sidebar_state="expanded",
23
+ menu_items={
24
+ 'Get Help': 'https://github.com/yourusername/academic-research-assistant',
25
+ 'Report a bug': "https://github.com/yourusername/academic-research-assistant/issues",
26
+ 'About': "# Academic Research Assistant v1.0\nYour intelligent research companion."
27
+ }
28
+ )
29
+
30
+ # Custom CSS to enhance the UI
31
+ st.markdown("""
32
+ <style>
33
+ .stApp {
34
+ background: linear-gradient(to bottom right, #f5f7fa, #eef2f7);
35
+ }
36
+ .stButton>button {
37
+ background-color: #1f4287;
38
+ color: white;
39
+ border-radius: 5px;
40
+ padding: 0.5rem 1rem;
41
+ }
42
+ .stProgress .st-bo {
43
+ background-color: #1f4287;
44
+ }
45
+ .chat-message {
46
+ padding: 10px;
47
+ border-radius: 5px;
48
+ margin: 5px 0;
49
+ animation: fadeIn 0.5s ease-in;
50
+ }
51
+ .user-message {
52
+ background-color: #e6f3ff;
53
+ }
54
+ .bot-message {
55
+ background-color: #f0f2f6;
56
+ }
57
+ @keyframes fadeIn {
58
+ from {opacity: 0;}
59
+ to {opacity: 1;}
60
+ }
61
+ .paper-card {
62
+ background-color: white;
63
+ padding: 1.5rem;
64
+ border-radius: 10px;
65
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
66
+ margin-bottom: 1rem;
67
+ }
68
+ .paper-title {
69
+ color: #1f4287;
70
+ font-size: 1.1rem;
71
+ font-weight: bold;
72
+ margin-bottom: 0.5rem;
73
+ }
74
+ .paper-metadata {
75
+ font-size: 0.9rem;
76
+ color: #666;
77
+ margin-bottom: 0.5rem;
78
+ }
79
+ .paper-abstract {
80
+ font-size: 0.95rem;
81
+ line-height: 1.5;
82
+ margin-top: 1rem;
83
+ padding-left: 1rem;
84
+ border-left: 3px solid #1f4287;
85
+ }
86
+ .download-button {
87
+ background-color: #4CAF50;
88
+ color: white;
89
+ padding: 0.5rem 1rem;
90
+ border-radius: 5px;
91
+ text-decoration: none;
92
+ display: inline-block;
93
+ margin-top: 1rem;
94
+ }
95
+ .metric-card {
96
+ background-color: white;
97
+ padding: 1rem;
98
+ border-radius: 8px;
99
+ box-shadow: 0 2px 4px rgba(0,0,0,0.05);
100
+ text-align: center;
101
+ }
102
+ </style>
103
+ """, unsafe_allow_html=True)
104
+
105
+ def initialize_session_state(self):
106
+
107
+ if "chat_history" not in st.session_state:
108
+ st.session_state.chat_history = []
109
+ if "fetched_papers" not in st.session_state:
110
+ st.session_state.fetched_papers = []
111
+ if "search_count" not in st.session_state:
112
+ st.session_state.search_count = 0
113
+ if "total_searches" not in st.session_state:
114
+ st.session_state.total_searches = 0
115
+
116
+ def display_welcome_message(self):
117
+
118
+ st.title("πŸ“š Academic Research Paper Assistant")
119
+
120
+ # Create three columns for metrics
121
+ col1, col2, col3, col4 = st.columns([2, 1, 1, 1])
122
+
123
+ with col1:
124
+ st.markdown("""
125
+ Welcome to your intelligent research companion! This tool helps you:
126
+ - πŸ” Find relevant academic papers
127
+ - πŸ“Š Analyze research trends
128
+ - πŸ“– Access paper summaries
129
+ - πŸ“₯ Download full papers
130
+ """)
131
+
132
+ # Display metrics in cards
133
+ with col3:
134
+ st.markdown("""
135
+ <div class="metric-card">
136
+ <h3>Papers Found</h3>
137
+ <h2>{}</h2>
138
+ </div>
139
+ """.format(len(st.session_state.fetched_papers)), unsafe_allow_html=True)
140
+
141
+ with col4:
142
+ st.markdown("""
143
+ <div class="metric-card">
144
+ <h3>Total Searches</h3>
145
+ <h2>{}</h2>
146
+ </div>
147
+ """.format(st.session_state.total_searches), unsafe_allow_html=True)
148
+
149
+
150
+
151
+ def create_chat_interface(self) -> Tuple[str, bool]:
152
+
153
+ with st.container():
154
+ st.write("### πŸ’¬ Research Query Interface")
155
+
156
+ # Create columns for better layout
157
+ col1, col2 = st.columns([4, 1])
158
+
159
+ with col1:
160
+ user_input = st.text_input(
161
+ "Enter your research query (e.g., 'Recent advances in quantum computing')",
162
+ key="user_input",
163
+ placeholder="Type your research question here...",
164
+ max_chars=500
165
+ )
166
+
167
+ col3, col4, col5 = st.columns([2, 1, 1])
168
+ with col3:
169
+ send_button = st.button("πŸ” Search ", use_container_width=True)
170
+ with col4:
171
+ clear_button = st.button("πŸ—‘οΈ Clear History", use_container_width=True)
172
+
173
+ if clear_button:
174
+ st.session_state.chat_history = []
175
+ st.session_state.fetched_papers = []
176
+ st.session_state.search_count = 0
177
+ st.session_state.total_searches = 0
178
+ st.rerun()
179
+
180
+ return user_input, send_button
181
+
182
+ def process_user_input(self, user_input: str):
183
+
184
+ with st.spinner('πŸ” Working on response...'):
185
+ # Update search metrics
186
+ st.session_state.search_count = len(st.session_state.fetched_papers)
187
+ st.session_state.total_searches += 1
188
+
189
+ try:
190
+ # Get response from router
191
+ response, papers = self.router.route_query(user_input)
192
+
193
+ # Update papers in session state
194
+ if papers:
195
+ unique_papers = {paper['paper_number']: paper for paper in papers}
196
+ st.session_state.fetched_papers = list(unique_papers.values())
197
+
198
+ # Add bot response and use message to chat history
199
+ if response:
200
+ st.session_state.chat_history.append(("Bot", response))
201
+ st.session_state.chat_history.append(("User", user_input))
202
+ else:
203
+ st.session_state.chat_history.append(
204
+ ("Bot", "I couldn't find relevant papers for your query. Please try rephrasing or use more specific terms.")
205
+ )
206
+ except Exception as e:
207
+ st.session_state.chat_history.append(
208
+ ("Bot", f"An error occurred while processing your request: {str(e)}")
209
+ )
210
+ st.error("There was an error processing your request. Please try again.")
211
+
212
+ def display_chat_history(self):
213
+ """Display the chat history with user and bot messages"""
214
+ for sender, message in reversed(st.session_state.chat_history):
215
+ if sender == "User":
216
+ st.markdown(
217
+ "<div class='chat-message user-message'>"
218
+ f"<strong>πŸ‘€ You:</strong> {message}"
219
+ "</div>",
220
+ unsafe_allow_html=True
221
+ )
222
+ else:
223
+ st.markdown(
224
+ "<div class='chat-message bot-message'>"
225
+ f"<strong>πŸ€– Assistant:</strong> {message[0]}"
226
+ "</div>",
227
+ unsafe_allow_html=True
228
+ )
229
+
230
+ def display_papers(self):
231
+ """Display the list of fetched papers with download links"""
232
+ st.write("### πŸ“„ Retrieved Research Papers")
233
+ if st.session_state.fetched_papers:
234
+ for paper in st.session_state.fetched_papers:
235
+ with st.expander(f"πŸ“‘ {paper.get('title', 'Untitled Paper')}"):
236
+ st.markdown(
237
+ "<div class='paper-card'>"
238
+ f"<div class='paper-title'>{paper.get('title', '').replace('\n', ' ').strip()}</div>"
239
+ f"<div class='paper-metadata'>Year: {paper.get('year', 'N/A')} | Paper ID: {paper.get('paper_number', 'N/A')}</div>"
240
+ f"""{'<div class="paper-abstract">' + paper.get('abstract', '') + '</div>' if paper.get('abstract') else ''}"""
241
+ "</div>",
242
+ unsafe_allow_html=True
243
+ )
244
+
245
+ download_link = paper.get('link')
246
+ if download_link:
247
+ st.markdown(f"[πŸ“₯ Download PDF]({download_link})")
248
+ else:
249
+ st.warning("⚠️ No download link available")
250
+ else:
251
+ st.info("πŸ” No papers fetched yet. Start by entering a research query above!")
252
+
253
+ def run(self):
254
+ """Main method to run the application"""
255
+ self.display_welcome_message()
256
+
257
+
258
+ user_input, send_button = self.create_chat_interface()
259
+
260
+ st.markdown("### πŸ’¬ Chat History")
261
+ self.display_chat_history()
262
+
263
+
264
+ if user_input and send_button:
265
+ self.process_user_input(user_input)
266
+ st.rerun()
267
+
268
+ st.markdown("---")
269
+ self.display_papers()
270
+
271
+ def main():
272
+
273
+ app = AcademicResearchAssistant()
274
+ app.run()
275
+
276
+ if __name__ == "__main__":
277
  main()
config/config.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import google.generativeai as genai
2
+ import os
3
+ GEMINI_API_KEY = "AIzaSyD6OXS89hHRqzGCY1klK9A8qNlG0sJEvAU"
4
+
5
+ genai.configure(api_key=GEMINI_API_KEY)
6
+
7
+ if "GOOGLE_API_KEY" not in os.environ:
8
+ os.environ["GOOGLE_API_KEY"] = GEMINI_API_KEY
9
+
10
+ model = genai.GenerativeModel(model_name="gemini-1.5-flash")
11
+
12
+
13
+
imgs/Frontend.png ADDED
imgs/Q1.png ADDED
imgs/Q2.png ADDED
imgs/papers.png ADDED
imgs/papers2.png ADDED
router.py ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from agents import IntentAgent, SearchAgent, QAAgent, FutureWorksAgent , SummarizationAgent
2
+ import streamlit as st
3
+ class Router:
4
+ def __init__(self):
5
+ self.intent_agent = IntentAgent()
6
+ self.agents = {
7
+ "search": SearchAgent(),
8
+ "qa": QAAgent(),
9
+ "future_works": FutureWorksAgent(),
10
+ "summarize": SummarizationAgent()
11
+ }
12
+
13
+ def route_query(self, query):
14
+
15
+ intent = self.intent_agent.get_intent(query)
16
+ agent = self.agents.get(intent)
17
+ st.write(f"Using {intent} agent...")
18
+ if agent:
19
+ if intent == "search":
20
+ ans , d = agent.solve(query)
21
+ return ans , d
22
+ return agent.solve(query) , None
23
+ else:
24
+ return "Sorry, I couldn't understand your query. Please give valid question" , None