Update app.py
Browse files
app.py
CHANGED
@@ -8,8 +8,12 @@ from langchain.vectorstores import FAISS
|
|
8 |
from langchain.schema import Document
|
9 |
from duckduckgo_search import DDGS
|
10 |
|
|
|
|
|
|
|
11 |
# Environment variables and configurations
|
12 |
huggingface_token = os.environ.get("HUGGINGFACE_TOKEN")
|
|
|
13 |
|
14 |
MODELS = [
|
15 |
"mistralai/Mistral-7B-Instruct-v0.3",
|
@@ -18,20 +22,31 @@ MODELS = [
|
|
18 |
"meta-llama/Meta-Llama-3.1-8B-Instruct",
|
19 |
"meta-llama/Meta-Llama-3.1-70B-Instruct"
|
20 |
]
|
|
|
21 |
|
22 |
def get_embeddings():
|
|
|
23 |
return HuggingFaceEmbeddings(model_name="sentence-transformers/stsb-roberta-large")
|
24 |
|
25 |
def duckduckgo_search(query):
|
26 |
-
|
27 |
-
|
28 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
|
30 |
async def rephrase_query(query, history, model):
|
31 |
-
|
|
|
|
|
|
|
32 |
|
33 |
-
If the query is unique, rephrase it to
|
34 |
-
If the query is related to the previous conversation, incorporate relevant context from the
|
35 |
|
36 |
Provide your analysis in the following format:
|
37 |
<analysis>Your reasoning about whether the query is unique or related</analysis>
|
@@ -47,12 +62,14 @@ async def rephrase_query(query, history, model):
|
|
47 |
client = InferenceClient(model, token=huggingface_token)
|
48 |
|
49 |
try:
|
|
|
50 |
response = await asyncio.to_thread(
|
51 |
client.text_generation,
|
52 |
prompt=f"{system_message}\n\n{user_message}",
|
53 |
max_new_tokens=150,
|
54 |
temperature=0.2,
|
55 |
)
|
|
|
56 |
|
57 |
# Extract the rephrased query from the response
|
58 |
analysis_start = response.find("<analysis>")
|
@@ -63,36 +80,43 @@ async def rephrase_query(query, history, model):
|
|
63 |
if analysis_start != -1 and analysis_end != -1 and rephrased_start != -1 and rephrased_end != -1:
|
64 |
analysis = response[analysis_start + 10:analysis_end].strip()
|
65 |
rephrased_query = response[rephrased_start + 17:rephrased_end].strip()
|
|
|
66 |
return analysis, rephrased_query
|
67 |
else:
|
68 |
-
logging.error("Failed to parse the rephrase response")
|
69 |
return None, query
|
70 |
except Exception as e:
|
71 |
logging.error(f"Error in rephrase_query: {str(e)}")
|
72 |
return None, query
|
73 |
|
74 |
def create_web_search_vectors(search_results):
|
|
|
75 |
embed = get_embeddings()
|
76 |
documents = []
|
77 |
for result in search_results:
|
78 |
if 'body' in result:
|
79 |
content = f"{result['title']}\n{result['body']}\nSource: {result['href']}"
|
80 |
documents.append(Document(page_content=content, metadata={"source": result['href']}))
|
|
|
81 |
return FAISS.from_documents(documents, embed)
|
82 |
|
83 |
async def get_response_with_search(query, model, use_embeddings, num_calls=3, temperature=0.2):
|
|
|
84 |
search_results = duckduckgo_search(query)
|
85 |
|
86 |
if not search_results:
|
|
|
87 |
yield "No web search results available. Please try again.", ""
|
88 |
return
|
89 |
|
90 |
if use_embeddings:
|
|
|
91 |
web_search_database = create_web_search_vectors(search_results)
|
92 |
retriever = web_search_database.as_retriever(search_kwargs={"k": 5})
|
93 |
relevant_docs = retriever.get_relevant_documents(query)
|
94 |
context = "\n".join([doc.page_content for doc in relevant_docs])
|
95 |
else:
|
|
|
96 |
context = "\n".join([f"{result['title']}\n{result['body']}\nSource: {result['href']}" for result in search_results])
|
97 |
|
98 |
system_message = """ You are a world-class AI system, capable of complex reasoning and reflection.
|
@@ -108,12 +132,12 @@ async def get_response_with_search(query, model, use_embeddings, num_calls=3, te
|
|
108 |
Write a detailed and complete research document that fulfills the following user request: '{query}'
|
109 |
After writing the document, please provide a list of sources used in your response."""
|
110 |
|
111 |
-
# Use Hugging Face API
|
112 |
client = InferenceClient(model, token=huggingface_token)
|
113 |
full_response = ""
|
114 |
|
115 |
try:
|
116 |
for _ in range(num_calls):
|
|
|
117 |
for response in client.chat_completion(
|
118 |
messages=[
|
119 |
{"role": "system", "content": system_message},
|
@@ -138,7 +162,7 @@ After writing the document, please provide a list of sources used in your respon
|
|
138 |
yield f"An error occurred while processing your request: {str(e)}", ""
|
139 |
|
140 |
if not full_response:
|
141 |
-
logging.warning("No response generated from the model")
|
142 |
yield "No response generated from the model.", ""
|
143 |
|
144 |
async def respond(message, history, model, temperature, num_calls, use_embeddings):
|
@@ -159,6 +183,7 @@ async def respond(message, history, model, temperature, num_calls, use_embedding
|
|
159 |
response = f"{main_content}\n\n{sources}"
|
160 |
yield response
|
161 |
except asyncio.CancelledError:
|
|
|
162 |
yield "The operation was cancelled. Please try again."
|
163 |
except Exception as e:
|
164 |
logging.error(f"Error in respond function: {str(e)}")
|
@@ -178,6 +203,7 @@ css = """
|
|
178 |
|
179 |
# Gradio interface setup
|
180 |
def create_gradio_interface():
|
|
|
181 |
custom_placeholder = "Enter your question here for web search."
|
182 |
|
183 |
demo = gr.ChatInterface(
|
@@ -220,8 +246,10 @@ def create_gradio_interface():
|
|
220 |
7. Use the provided examples or ask your own questions.
|
221 |
""")
|
222 |
|
|
|
223 |
return demo
|
224 |
|
225 |
if __name__ == "__main__":
|
|
|
226 |
demo = create_gradio_interface()
|
227 |
demo.launch(share=True)
|
|
|
8 |
from langchain.schema import Document
|
9 |
from duckduckgo_search import DDGS
|
10 |
|
11 |
+
# Configure logging
|
12 |
+
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
|
13 |
+
|
14 |
# Environment variables and configurations
|
15 |
huggingface_token = os.environ.get("HUGGINGFACE_TOKEN")
|
16 |
+
logging.info("Environment variable for HuggingFace token retrieved.")
|
17 |
|
18 |
MODELS = [
|
19 |
"mistralai/Mistral-7B-Instruct-v0.3",
|
|
|
22 |
"meta-llama/Meta-Llama-3.1-8B-Instruct",
|
23 |
"meta-llama/Meta-Llama-3.1-70B-Instruct"
|
24 |
]
|
25 |
+
logging.info(f"Models list initialized with {len(MODELS)} models.")
|
26 |
|
27 |
def get_embeddings():
|
28 |
+
logging.info("Loading HuggingFace embeddings model.")
|
29 |
return HuggingFaceEmbeddings(model_name="sentence-transformers/stsb-roberta-large")
|
30 |
|
31 |
def duckduckgo_search(query):
|
32 |
+
logging.info(f"Initiating DuckDuckGo search for query: {query}")
|
33 |
+
try:
|
34 |
+
with DDGS() as ddgs:
|
35 |
+
results = ddgs.text(query, max_results=10)
|
36 |
+
logging.info(f"Search completed, found {len(results)} results.")
|
37 |
+
return results
|
38 |
+
except Exception as e:
|
39 |
+
logging.error(f"Error during DuckDuckGo search: {str(e)}")
|
40 |
+
return []
|
41 |
|
42 |
async def rephrase_query(query, history, model):
|
43 |
+
logging.info("Rephrasing query based on history and model.")
|
44 |
+
system_message = """You are an AI assistant tasked with analyzing and rephrasing user queries.
|
45 |
+
Your goal is to determine whether the query is unique or related to the previous conversation, and then rephrase it appropriately for web search.
|
46 |
+
The rephrased query should be succinct and optimized for search engines.
|
47 |
|
48 |
+
If the query is unique (i.e., unrelated to the conversation), rephrase it to make it more specific and searchable.
|
49 |
+
If the query is related to the previous conversation, incorporate relevant context from the conversation to enhance search relevance.
|
50 |
|
51 |
Provide your analysis in the following format:
|
52 |
<analysis>Your reasoning about whether the query is unique or related</analysis>
|
|
|
62 |
client = InferenceClient(model, token=huggingface_token)
|
63 |
|
64 |
try:
|
65 |
+
logging.info(f"Sending rephrase request to model {model}.")
|
66 |
response = await asyncio.to_thread(
|
67 |
client.text_generation,
|
68 |
prompt=f"{system_message}\n\n{user_message}",
|
69 |
max_new_tokens=150,
|
70 |
temperature=0.2,
|
71 |
)
|
72 |
+
logging.info("Rephrase response received.")
|
73 |
|
74 |
# Extract the rephrased query from the response
|
75 |
analysis_start = response.find("<analysis>")
|
|
|
80 |
if analysis_start != -1 and analysis_end != -1 and rephrased_start != -1 and rephrased_end != -1:
|
81 |
analysis = response[analysis_start + 10:analysis_end].strip()
|
82 |
rephrased_query = response[rephrased_start + 17:rephrased_end].strip()
|
83 |
+
logging.info(f"Rephrased query: {rephrased_query}")
|
84 |
return analysis, rephrased_query
|
85 |
else:
|
86 |
+
logging.error("Failed to parse the rephrase response.")
|
87 |
return None, query
|
88 |
except Exception as e:
|
89 |
logging.error(f"Error in rephrase_query: {str(e)}")
|
90 |
return None, query
|
91 |
|
92 |
def create_web_search_vectors(search_results):
|
93 |
+
logging.info(f"Creating web search vectors from {len(search_results)} search results.")
|
94 |
embed = get_embeddings()
|
95 |
documents = []
|
96 |
for result in search_results:
|
97 |
if 'body' in result:
|
98 |
content = f"{result['title']}\n{result['body']}\nSource: {result['href']}"
|
99 |
documents.append(Document(page_content=content, metadata={"source": result['href']}))
|
100 |
+
logging.info(f"{len(documents)} documents created for FAISS vectorization.")
|
101 |
return FAISS.from_documents(documents, embed)
|
102 |
|
103 |
async def get_response_with_search(query, model, use_embeddings, num_calls=3, temperature=0.2):
|
104 |
+
logging.info(f"Performing web search for query: {query}")
|
105 |
search_results = duckduckgo_search(query)
|
106 |
|
107 |
if not search_results:
|
108 |
+
logging.warning("No web search results found.")
|
109 |
yield "No web search results available. Please try again.", ""
|
110 |
return
|
111 |
|
112 |
if use_embeddings:
|
113 |
+
logging.info("Using embeddings to retrieve relevant documents.")
|
114 |
web_search_database = create_web_search_vectors(search_results)
|
115 |
retriever = web_search_database.as_retriever(search_kwargs={"k": 5})
|
116 |
relevant_docs = retriever.get_relevant_documents(query)
|
117 |
context = "\n".join([doc.page_content for doc in relevant_docs])
|
118 |
else:
|
119 |
+
logging.info("Using raw search results for context.")
|
120 |
context = "\n".join([f"{result['title']}\n{result['body']}\nSource: {result['href']}" for result in search_results])
|
121 |
|
122 |
system_message = """ You are a world-class AI system, capable of complex reasoning and reflection.
|
|
|
132 |
Write a detailed and complete research document that fulfills the following user request: '{query}'
|
133 |
After writing the document, please provide a list of sources used in your response."""
|
134 |
|
|
|
135 |
client = InferenceClient(model, token=huggingface_token)
|
136 |
full_response = ""
|
137 |
|
138 |
try:
|
139 |
for _ in range(num_calls):
|
140 |
+
logging.info(f"Sending request to model with {num_calls} API calls and temperature {temperature}.")
|
141 |
for response in client.chat_completion(
|
142 |
messages=[
|
143 |
{"role": "system", "content": system_message},
|
|
|
162 |
yield f"An error occurred while processing your request: {str(e)}", ""
|
163 |
|
164 |
if not full_response:
|
165 |
+
logging.warning("No response generated from the model.")
|
166 |
yield "No response generated from the model.", ""
|
167 |
|
168 |
async def respond(message, history, model, temperature, num_calls, use_embeddings):
|
|
|
183 |
response = f"{main_content}\n\n{sources}"
|
184 |
yield response
|
185 |
except asyncio.CancelledError:
|
186 |
+
logging.warning("Operation cancelled by user.")
|
187 |
yield "The operation was cancelled. Please try again."
|
188 |
except Exception as e:
|
189 |
logging.error(f"Error in respond function: {str(e)}")
|
|
|
203 |
|
204 |
# Gradio interface setup
|
205 |
def create_gradio_interface():
|
206 |
+
logging.info("Setting up Gradio interface.")
|
207 |
custom_placeholder = "Enter your question here for web search."
|
208 |
|
209 |
demo = gr.ChatInterface(
|
|
|
246 |
7. Use the provided examples or ask your own questions.
|
247 |
""")
|
248 |
|
249 |
+
logging.info("Gradio interface ready.")
|
250 |
return demo
|
251 |
|
252 |
if __name__ == "__main__":
|
253 |
+
logging.info("Launching Gradio application.")
|
254 |
demo = create_gradio_interface()
|
255 |
demo.launch(share=True)
|