Spaces:
Sleeping
Sleeping
File size: 9,687 Bytes
475ef85 fa8ee23 04aa1c8 fa8ee23 04aa1c8 475ef85 fa8ee23 475ef85 fa8ee23 475ef85 fa8ee23 475ef85 fa8ee23 475ef85 fa8ee23 475ef85 fa8ee23 475ef85 fa8ee23 475ef85 fa8ee23 475ef85 fa8ee23 475ef85 2024a19 | 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 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 | import gradio as gr
import pandas as pd
import logging
from langchain_core.exceptions import OutputParserException
import os
from dotenv import load_dotenv
import azure.cosmos.cosmos_client as cosmos_client
from langchain.chains import create_retrieval_chain
import datetime
import uuid
from LiteratureAgent import RoofCoverChatbot
from Refiner import RefinementPipeline
from helpers import get_article_info
load_dotenv()
refiner = RefinementPipeline()
literature_agent = RoofCoverChatbot()
ENV = os.getenv('ENV')
HOST = os.getenv('ACCOUNT_HOST')
MASTER_KEY = os.getenv('ACCOUNT_KEY')
DATABASE_ID = os.getenv('COSMOS_DATABASE')
CONTAINER_ID = os.getenv('COSMOS_CONTAINER')
HISTORY_CONTAINER_ID = os.getenv('COSMOS_HISTORY_CONTAINER')
client = cosmos_client.CosmosClient(HOST, {'masterKey': MASTER_KEY}, user_agent="CosmosDBPythonQuickstart", user_agent_overwrite=True)
database = client.get_database_client(DATABASE_ID)
container = database.get_container_client(CONTAINER_ID)
history_container = database.get_container_client(HISTORY_CONTAINER_ID)
df = pd.read_csv("articles_db.csv")
def initialize_session(session_id):
# If no session_id exists, generate a new one
if session_id is None:
session_id = str(uuid.uuid4())
return session_id
def llm_response(query, session_id):
chat = {}
titles, links, res_titles, res_links = [], [], [], []
session_id = initialize_session(session_id)
chat["id"] = str(uuid.uuid4())
chat["chat_id"] = session_id
chat["partitionKey"] = "RoofingRoadmap"
chat["user"] = query
chat["env"] = ENV
answer = None
if 'f wave' in query.lower() or 'f-wave' in query.lower() or 'fwave' in query.lower():
query = query.replace('f wave', 'f-wave shingle').replace('f-wave', 'f-wave shingle').replace('fwave',
'f-wave shingle')
try:
response = literature_agent.get_response(query)
enhanced_query = refiner.invoke(question=query, answer=response)
try:
initial_answer = response['answer']['cited_answer'][0].get("answer", "Nothing")
except Exception as e:
initial_answer = "Nothing"
if enhanced_query.get("enhanced_answer") == "Nothing" and initial_answer == "Nothing":
answer = "Your search is beyond the scope of this tool at this time. Please explore the rest of [IBHS website](https://ibhs.org) to find research on this topic."
return answer
if enhanced_query.get("enhanced_answer") != "Nothing":
answer = enhanced_query['enhanced_answer']
else:
answer = response
citations = response['answer']['cited_answer'][1].get('citations', [])
original_citations = []
if citations:
for citation in citations:
try:
# edited_item = citation['citation'][1]["source"].replace("\\", "/").replace("Articles/", "").replace("Articles\\", "")
original_citations.append(citation['citation'][1]["source"])
title, link = get_article_info(df, citation['citation'][1]["source"])
if title not in titles:
titles.append(title)
# if link not in links:
links.append(link)
except Exception as e:
continue
try:
question_search = literature_agent.get_extra_resources(query, original_citations)
except Exception as e:
question_search = []
if question_search:
for res_item in question_search:
res_title, res_link = get_article_info(df, res_item.metadata["source"])
if res_title not in res_titles and res_title not in titles:
res_titles.append(res_title)
res_links.append(res_link)
if len(res_titles) == 5:
break
except Exception as e:
answer = "Your search is beyond the scope of this tool at this time. Please explore the rest of [IBHS website](https://ibhs.org) to find research on this topic."
return answer
finally:
if answer is None:
answer = "Your search is beyond the scope of this tool at this time. Please explore the rest of [IBHS website](https://ibhs.org) to find research on this topic."
chat["ai"] = answer
chat["timestamp"] = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
container.create_item(body=chat)
# Build the answer with superscript citations
answer_with_citations = f"{answer}"
for i, (title, link) in enumerate(zip(titles, links), start=1):
answer_with_citations += f" <sup>[[{i}]({link})]</sup> "
# Build the references section with clickable links
if not links:
markdown_list = f"{answer_with_citations}"
else:
citations_section = "\n\nCitations:\n" + "\n".join(
[f"[{i}]: [{title}]({link})" for i, (title, link) in enumerate(zip(titles, links), start=1)]
)
markdown_list = f"{answer_with_citations}{citations_section}"
# Combine answer and citations for final markdown output
if not res_links and not links:
markdown_list += f"\n\n\nHere is a list of articles that can provide more information about your inquiry:\n"
markdown_list += "\n".join(["- [IBHS Website](https://ibhs.org)", "- [FORTIFIED Website](https://fortifiedhome.org/roof/)" ])
else:
markdown_list += f"\n\n\nHere is a list of articles that can provide more information about your inquiry:\n"
markdown_list += "\n".join([f"- [{res_title}]({res_link})" for res_title, res_link in zip(res_titles, res_links)])
return markdown_list
def vote(value, data: gr.LikeData, session_id: str = None):
session_id = initialize_session(session_id)
chat_vote = {}
chat_vote["id"] = str(uuid.uuid4())
chat_vote["chat_id"] = session_id
chat_vote["partitionKey"] = "RoofingRoadmapVotes"
chat_vote["response"] = data.value[0].split('<sup>', 1)[0].split('\n', 1)[0]
chat_vote["env"] = ENV
chat_vote["timestamp"] = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
if data.liked:
chat_vote["vote"] = "upvote"
else:
chat_vote["vote"] = "downvote"
history_container.create_item(body=chat_vote)
def show_feedback_column(visible):
if visible:
# If visible, hide the column
return gr.update(visible=False), gr.update(value=""), False
else:
# If not visible, show the column and clear the Textbox
return gr.update(visible=True), "", True
def user_feedback(value, session_id):
session_id = initialize_session(session_id)
chat_feedback = {}
chat_feedback["id"] = str(uuid.uuid4())
chat_feedback["chat_id"] = session_id
chat_feedback["partitionKey"] = "RoofingRoadmapFeedback"
chat_feedback["feedback"] = value
chat_feedback["env"] = ENV
chat_feedback["timestamp"] = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
history_container.create_item(body=chat_feedback)
return gr.update(visible=False), "", session_id
with gr.Blocks() as demo:
session_id = gr.State(None)
gr.Markdown("## Find literature to answer your question!")
gr.Markdown("### Ask a question about the wind and hail performance of asphalt shingle, metal, and tile roofs.")
with gr.Row():
with gr.Column():
chatbot = gr.Chatbot(type="messages", height=400)
chatbot.like(vote, [chatbot, session_id], None)
msg = gr.Textbox(label="Hit the Enter to send your question", placeholder="What's on your mind?", show_copy_button=True)
with gr.Row():
send = gr.Button("Send", variant="secondary", scale=3)
feedback = gr.Button("Feedback", variant="stop", scale=1)
with gr.Column(visible=False, elem_id="feedback_column") as feedback_column:
usr_msg = gr.Textbox(label="Submit feedback to IBHS", info="What went wrong?", placeholder="Give us as much detail as you can!", lines=3)
usr_submit = gr.Button("Submit", variant="secondary")
def user(user_message, history: list):
return "", history + [{"role": "user", "content": user_message}]
def bot(history: list, session_id_i):
if session_id_i is None:
session_id_i = initialize_session(session_id_i)
bot_message = llm_response(history[-1]['content'], session_id_i)
history.append({"role": "assistant", "content": ""})
for character in bot_message:
history[-1]['content'] += character
yield history, session_id_i
feedback_column_state = gr.State(False)
msg.submit(user, [msg, chatbot], [msg, chatbot], queue=False).then(bot, [chatbot, session_id], [chatbot,session_id])
send.click(user, [msg, chatbot], [msg, chatbot], queue=False).then(bot, [chatbot, session_id], [chatbot, session_id])
feedback.click(fn=show_feedback_column, inputs=[feedback_column_state], outputs=[feedback_column, usr_msg, feedback_column_state])
usr_submit.click(user_feedback, [usr_msg, session_id], outputs=[feedback_column, usr_msg, session_id])
gr.Markdown("*Our chatbot is constantly learning and improving to better serve you!*")
gr.Markdown("#### Additional questions? Contact IBHS Membership Manager Larry Scott at [lscott@ibhs.org]().")
if __name__ == "__main__":
demo.launch() |