22
33import json
44import logging
5+ import os
56from typing import List , Union
67
78import streamlit as st
89import yaml
910
1011from curategpt import BasicExtractor
11- from curategpt .agents .chat_agent import ChatAgent , ChatResponse
12+ from curategpt .agents .chat_agent import ChatAgentAlz , ChatResponse
1213from curategpt .agents .evidence_agent import EvidenceAgent
13- from curategpt .app .helper import get_applicable_examples
1414from curategpt .app .state import get_state
1515from curategpt .wrappers import BaseWrapper
1616from curategpt .wrappers .literature import WikipediaWrapper
1717from curategpt .wrappers .literature .pubmed_wrapper import PubmedWrapper
18+ from curategpt .wrappers .paperqa .paperqawrapper import PaperQAWrapper
1819
19- PUBMED = "PubMed (via API)"
20- WIKIPEDIA = "Wikipedia (via API)"
21- # Removed JGI and ESS-Dive
22- # JGI = "JGI (via API)"
23- # ESSDIVE = "ESS-DeepDive (via API)"
20+ PUBMED = "PubMed"
21+ WIKIPEDIA = "Wikipedia"
22+ PAPERQA = "Alzheimers_Papers"
2423
2524CHAT = "Chat"
2625SEARCH = "Search"
5756cart = state .cart
5857
5958
60- st .title ("Alzheimers AI assistant" )
59+ st .title ("Alzheimer's AI Assistant" )
60+
61+ # Check if PQA_HOME environment variable is set for PaperQA
62+ if PAPERQA in [PUBMED , PAPERQA , WIKIPEDIA ] and os .environ .get ("PQA_HOME" ) is None :
63+ st .warning (
64+ "PQA_HOME environment variable is not set. To use the Alzheimer's Papers collection, "
65+ "you need to set PQA_HOME to the directory containing your indexed papers. "
66+ "Use 'curategpt paperqa index /path/to/papers' to create an index."
67+ )
6168if not db .list_collection_names ():
6269 st .warning ("No collections found. Please use command line to load one." )
6370
6471# Include Chat, Search, and CiteSeek in PAGES
6572PAGES = [
6673 CHAT ,
67- CITESEEK ,
68- SEARCH
74+ CITESEEK
6975]
7076
7177
@@ -92,12 +98,13 @@ def filtered_collection_names() -> List[str]:
9298
9399collection = st .sidebar .selectbox (
94100 "Choose collection" ,
95- [PUBMED , WIKIPEDIA ] + filtered_collection_names (), # Removed JGI and ESSDIVE, put PubMed first
96- index = 0 , # Set PubMed as default
101+ [PUBMED , PAPERQA , WIKIPEDIA ] + filtered_collection_names () + [ "No collection" ],
102+ index = 0 , # Set PUBMED as default (index 0 since it's first in the list)
97103 help = """
98104 A collection is a knowledge base. It could be anything, but
99105 it's likely your instance has some bio-ontologies pre-loaded.
100- Select 'About' to see details of each collection
106+ Select 'Alzheimer's Papers (via PaperQA)' for direct access to a trusted corpus of Alzheimer's research papers.
107+ Select 'No collection' to interact with the model directly without a knowledge base.
101108 """ ,
102109)
103110
@@ -118,11 +125,12 @@ def filtered_collection_names() -> List[str]:
118125# Add background_collection for CiteSeek functionality
119126background_collection = st .sidebar .selectbox (
120127 "Background knowledge for CiteSeek" ,
121- [NO_BACKGROUND_SELECTED , PUBMED , WIKIPEDIA ],
128+ [NO_BACKGROUND_SELECTED , PUBMED , PAPERQA , WIKIPEDIA ],
122129 index = 1 , # Set PubMed as default
123130 help = """
124131 Background databases provide evidence sources for CiteSeek.
125132 PubMed is recommended for verifying medical claims.
133+ Alzheimer's Papers provides specialized knowledge from trusted Alzheimer's research papers.
126134 """ ,
127135)
128136
@@ -131,25 +139,43 @@ def filtered_collection_names() -> List[str]:
131139st .sidebar .markdown ("Developed by the Monarch Initiative" )
132140
133141
134- def get_chat_agent () -> Union [ChatAgent , BaseWrapper ]:
135- knowledge_source_collection = None
136- if collection == PUBMED :
142+ def get_chat_agent () -> Union [ChatAgentAlz , BaseWrapper ]:
143+ if collection == "No collection" :
144+ return ChatAgentAlz (extractor = extractor )
145+ elif collection == PUBMED :
137146 source = PubmedWrapper (local_store = db , extractor = extractor )
138147 elif collection == WIKIPEDIA :
139148 source = WikipediaWrapper (local_store = db , extractor = extractor )
140- # Removed JGI and ESSDIVE cases
149+ elif collection == PAPERQA :
150+ source = PaperQAWrapper (extractor = extractor )
141151 else :
142152 source = db
143- knowledge_source_collection = collection
144- return ChatAgent (
153+
154+ agent = ChatAgentAlz (
145155 knowledge_source = source ,
146- knowledge_source_collection = knowledge_source_collection ,
156+ knowledge_source_collection = collection ,
147157 extractor = extractor ,
148158 )
149159
160+ if agent .knowledge_source is None :
161+ raise ValueError (f"Knowledge source is None for collection { collection } " )
162+
163+ return agent
164+
150165
151166def ask_chatbot (query , expand = False ) -> ChatResponse :
152- return get_chat_agent ().chat (query , expand = expand )
167+ agent = get_chat_agent ()
168+ if collection == "No collection" :
169+ response = agent .extractor .model .prompt (query , system = "You are a helpful Alzheimer's disease expert." )
170+ return ChatResponse (
171+ body = response .text (),
172+ formatted_body = response .text (),
173+ prompt = query ,
174+ references = {},
175+ uncited_references = {}
176+ )
177+ else :
178+ return agent .chat (query , expand = expand )
153179
154180
155181def html_table (rows : List [dict ]) -> str :
@@ -238,34 +264,44 @@ def _flat(obj: dict, limit=40) -> dict:
238264
239265elif option == CHAT :
240266 page_state = state .get_page_state (CHAT )
241- st .subheader ("Chat with a knowledge base" )
242- query = st .text_area (
243- f"Ask me anything (within the scope of { collection } )!" ,
244- help = "You can query the current knowledge base using natural language." ,
245- )
267+ if collection == "No collection" :
268+ st .subheader ("Chat with the Alzheimer's AI assistant" )
269+ query = st .text_area (
270+ "Ask me anything about Alzheimer's disease" ,
271+ help = "Ask questions directly to the AI without using a knowledge base." ,
272+ )
273+ else :
274+ query = st .text_area (
275+ f"Ask me anything about Alzheimer's disease (within the scope of { collection } )" ,
276+ help = "You can query the current knowledge base using natural language." ,
277+ )
278+
279+ # Only show these controls if using a knowledge base
280+ if collection != "No collection" :
281+ limit = st .slider (
282+ "Detail" ,
283+ min_value = 0 ,
284+ max_value = 30 ,
285+ value = 10 ,
286+ step = 1 ,
287+ help = """
288+ Behind the scenes, N entries are fetched from the knowledge base,
289+ and these are fed to the LLM. Selecting more examples may give more
290+ complete results, but may also exceed context windows for the model.
291+ """ ,
292+ )
293+ expand = st .checkbox (
294+ "Expand query" ,
295+ help = """
296+ If checked, perform query expansion (pubmed only).
297+ """ ,
298+ )
299+ else :
300+ # Set default values when not using a knowledge base
301+ limit = 0
302+ expand = False
246303
247- limit = st .slider (
248- "Detail" ,
249- min_value = 0 ,
250- max_value = 30 ,
251- value = 10 ,
252- step = 1 ,
253- help = """
254- Behind the scenes, N entries are fetched from the knowledge base,
255- and these are fed to the LLM. Selecting more examples may give more
256- complete results, but may also exceed context windows for the model.
257- """ ,
258- )
259- expand = st .checkbox (
260- "Expand query" ,
261- help = """
262- If checked, perform query expansion (pubmed only).
263- """ ,
264- )
265304 extractor .model_name = model_name
266- examples = get_applicable_examples (collection , CHAT )
267- st .write ("Examples:" )
268- st .write (f"<details>{ html_table (examples )} </details>" , unsafe_allow_html = True )
269305
270306 if st .button (CHAT ):
271307 response = ask_chatbot (query , expand = expand )
0 commit comments