Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -13,7 +13,6 @@ from langchain_core.documents import Document
|
|
13 |
# Retrieve API keys from environment variables
|
14 |
google_api_key = os.getenv("GOOGLE_API_KEY")
|
15 |
tavily_api_key = os.getenv("TAVILY_API_KEY")
|
16 |
-
docusign_api_key = os.getenv("DOCUSIGN_API_KEY")
|
17 |
|
18 |
# Configure Google Generative AI
|
19 |
genai.configure(api_key=google_api_key)
|
@@ -100,17 +99,11 @@ def generate_response_with_rag(query, pdf_path, state):
|
|
100 |
embedding_model = state["embedding_model"]
|
101 |
|
102 |
# Retrieve relevant chunks based on the query
|
103 |
-
relevant_chunks = retrieve_relevant_chunks(query, chunks, embeddings, embedding_model, top_k=5)
|
104 |
|
105 |
-
# Debug: Print relevant chunks
|
106 |
-
print(f"Relevant Chunks: {relevant_chunks}")
|
107 |
-
|
108 |
# Combine the relevant chunks into a single context
|
109 |
context = "\n\n".join(relevant_chunks)
|
110 |
|
111 |
-
# Debug: Print the context
|
112 |
-
print(f"Context from PDF: {context}")
|
113 |
-
|
114 |
# Create a prompt that instructs the model to answer only from the context
|
115 |
prompt = f"""
|
116 |
You are a helpful assistant that answers questions based on the provided context.
|
@@ -125,9 +118,6 @@ def generate_response_with_rag(query, pdf_path, state):
|
|
125 |
**Answer:**
|
126 |
"""
|
127 |
|
128 |
-
# Debug: Print the prompt
|
129 |
-
print(f"Prompt for Gemini: {prompt}")
|
130 |
-
|
131 |
# Send the prompt to the Gemini model
|
132 |
try:
|
133 |
response = chat_session.send_message(prompt)
|
@@ -135,14 +125,10 @@ def generate_response_with_rag(query, pdf_path, state):
|
|
135 |
|
136 |
# Check if the initial answer is "I don't know"
|
137 |
if "I don't know" in initial_answer or "i don't know" in initial_answer:
|
138 |
-
print("Initial answer is 'I don't know'. Performing web search...")
|
139 |
docs = web_search_tool.invoke({"query": query})
|
140 |
web_results = "\n".join([d["content"] for d in docs])
|
141 |
web_results = Document(page_content=web_results)
|
142 |
|
143 |
-
# Debug: Print web search results
|
144 |
-
print(f"Web Search Results: {web_results.page_content}")
|
145 |
-
|
146 |
# Create a prompt that instructs the model to answer from the web search results
|
147 |
web_prompt = f"""
|
148 |
You are a helpful assistant that answers questions based on the provided context.
|
@@ -157,118 +143,52 @@ def generate_response_with_rag(query, pdf_path, state):
|
|
157 |
**Answer:**
|
158 |
"""
|
159 |
|
160 |
-
# Debug: Print the prompt
|
161 |
-
print(f"Prompt for Gemini (Web Search): {web_prompt}")
|
162 |
-
|
163 |
-
# Send the prompt to the Gemini model
|
164 |
web_response = chat_session.send_message(web_prompt)
|
165 |
-
# Add a note indicating the answer is based on a web search
|
166 |
return f"{web_response.text}\n\n*Note: This answer is based on a web search.*"
|
167 |
else:
|
168 |
return initial_answer
|
169 |
except Exception as e:
|
170 |
return f"Error generating response: {e}"
|
171 |
|
172 |
-
# Function to send document to DocuSign
|
173 |
-
def send_to_docusign(file_path, recipient_email, recipient_name):
|
174 |
-
account_id = "184d0409-2626-4c48-98b5-d383b9854a47"
|
175 |
-
base_url = "https://demo.docusign.net/restapi"
|
176 |
-
|
177 |
-
with open(file_path, "rb") as file:
|
178 |
-
document_base64 = base64.b64encode(file.read()).decode()
|
179 |
-
|
180 |
-
envelope_definition = {
|
181 |
-
"emailSubject": "Please sign this document",
|
182 |
-
"documents": [
|
183 |
-
{
|
184 |
-
"documentId": "1",
|
185 |
-
"name": "document.pdf",
|
186 |
-
"fileExtension": "pdf",
|
187 |
-
"documentBase64": document_base64
|
188 |
-
}
|
189 |
-
],
|
190 |
-
"recipients": {
|
191 |
-
"signers": [
|
192 |
-
{
|
193 |
-
"email": recipient_email,
|
194 |
-
"name": recipient_name,
|
195 |
-
"recipientId": "1",
|
196 |
-
"tabs": {
|
197 |
-
"signHereTabs": [
|
198 |
-
{
|
199 |
-
"documentId": "1",
|
200 |
-
"pageNumber": "1",
|
201 |
-
"xPosition": "100",
|
202 |
-
"yPosition": "100"
|
203 |
-
}
|
204 |
-
]
|
205 |
-
}
|
206 |
-
}
|
207 |
-
]
|
208 |
-
},
|
209 |
-
"status": "sent"
|
210 |
-
}
|
211 |
-
|
212 |
-
headers = {
|
213 |
-
"Authorization": f"Bearer {docusign_api_key}",
|
214 |
-
"Content-Type": "application/json"
|
215 |
-
}
|
216 |
-
try:
|
217 |
-
response = requests.post(
|
218 |
-
f"{base_url}/v2.1/accounts/{account_id}/envelopes",
|
219 |
-
headers=headers,
|
220 |
-
json=envelope_definition
|
221 |
-
)
|
222 |
-
response.raise_for_status()
|
223 |
-
return response.json()
|
224 |
-
except requests.exceptions.RequestException as e:
|
225 |
-
return {"error": str(e)}
|
226 |
-
|
227 |
# Function to process the agreement
|
228 |
-
def process_agreement(file,
|
229 |
try:
|
230 |
text = extract_text_from_pdf(file.name)
|
231 |
if text.startswith("Error"):
|
232 |
-
return text, {},
|
233 |
|
234 |
# Use Gemini for summarization
|
235 |
summary = summarize_agreement_with_gemini(text)
|
236 |
if summary.startswith("Error"):
|
237 |
-
return summary, {},
|
238 |
-
|
239 |
-
docusign_response = send_to_docusign(file.name, recipient_email, recipient_name)
|
240 |
-
if "error" in docusign_response:
|
241 |
-
return summary, {}, docusign_response, state
|
242 |
|
243 |
-
return summary, {},
|
244 |
except Exception as e:
|
245 |
-
return f"Error: {e}", {},
|
246 |
|
247 |
# Gradio interface
|
248 |
-
def main_interface(file,
|
249 |
if file is not None:
|
250 |
state["file"] = file
|
251 |
state["text"] = extract_text_from_pdf(file.name)
|
252 |
state["chat_history"] = [] # Initialize chat history
|
253 |
|
254 |
summary_output = ""
|
255 |
-
docusign_output = {}
|
256 |
chatbot_output = ""
|
257 |
|
258 |
if "file" in state:
|
259 |
-
|
260 |
-
summary_output, _, docusign_output, state = process_agreement(state["file"], recipient_email, recipient_name, state)
|
261 |
|
262 |
if question:
|
263 |
chatbot_output = generate_response_with_rag(question, state["file"].name, state)
|
264 |
-
state["chat_history"].append((question, chatbot_output))
|
265 |
|
266 |
-
return summary_output,
|
267 |
|
268 |
# CSS for styling
|
269 |
css = """
|
270 |
.gradio-container {
|
271 |
-
background-image: url('https://huggingface.co/spaces/
|
272 |
background-size: cover;
|
273 |
background-position: center;
|
274 |
background-repeat: no-repeat;
|
@@ -324,7 +244,7 @@ with gr.Blocks(css=css) as app:
|
|
324 |
"""
|
325 |
<div style="text-align: center;">
|
326 |
<h1 id="main-title">
|
327 |
-
DocWise(Agreement Analyzer with Chatbot
|
328 |
</h1>
|
329 |
</div>
|
330 |
""",
|
@@ -333,12 +253,9 @@ with gr.Blocks(css=css) as app:
|
|
333 |
state = gr.State({})
|
334 |
file_input = gr.File(label="Upload Agreement (PDF)")
|
335 |
|
336 |
-
with gr.Tab("
|
337 |
-
|
338 |
-
|
339 |
-
summary_output = gr.Textbox(label="Agreement Summary")
|
340 |
-
docusign_output = gr.JSON(label="DocuSign Response")
|
341 |
-
process_button = gr.Button("Process Agreement", elem_id="process-button")
|
342 |
|
343 |
with gr.Tab("Chatbot", elem_id="chatbot-tab"):
|
344 |
chatbot_question_input = gr.Textbox(label="Ask a Question")
|
@@ -347,13 +264,13 @@ with gr.Blocks(css=css) as app:
|
|
347 |
|
348 |
process_button.click(
|
349 |
main_interface,
|
350 |
-
inputs=[file_input,
|
351 |
-
outputs=[summary_output,
|
352 |
)
|
353 |
chatbot_button.click(
|
354 |
main_interface,
|
355 |
-
inputs=[file_input,
|
356 |
-
outputs=[summary_output,
|
357 |
)
|
358 |
|
359 |
app.launch(debug=True)
|
|
|
13 |
# Retrieve API keys from environment variables
|
14 |
google_api_key = os.getenv("GOOGLE_API_KEY")
|
15 |
tavily_api_key = os.getenv("TAVILY_API_KEY")
|
|
|
16 |
|
17 |
# Configure Google Generative AI
|
18 |
genai.configure(api_key=google_api_key)
|
|
|
99 |
embedding_model = state["embedding_model"]
|
100 |
|
101 |
# Retrieve relevant chunks based on the query
|
102 |
+
relevant_chunks = retrieve_relevant_chunks(query, chunks, embeddings, embedding_model, top_k=5)
|
103 |
|
|
|
|
|
|
|
104 |
# Combine the relevant chunks into a single context
|
105 |
context = "\n\n".join(relevant_chunks)
|
106 |
|
|
|
|
|
|
|
107 |
# Create a prompt that instructs the model to answer only from the context
|
108 |
prompt = f"""
|
109 |
You are a helpful assistant that answers questions based on the provided context.
|
|
|
118 |
**Answer:**
|
119 |
"""
|
120 |
|
|
|
|
|
|
|
121 |
# Send the prompt to the Gemini model
|
122 |
try:
|
123 |
response = chat_session.send_message(prompt)
|
|
|
125 |
|
126 |
# Check if the initial answer is "I don't know"
|
127 |
if "I don't know" in initial_answer or "i don't know" in initial_answer:
|
|
|
128 |
docs = web_search_tool.invoke({"query": query})
|
129 |
web_results = "\n".join([d["content"] for d in docs])
|
130 |
web_results = Document(page_content=web_results)
|
131 |
|
|
|
|
|
|
|
132 |
# Create a prompt that instructs the model to answer from the web search results
|
133 |
web_prompt = f"""
|
134 |
You are a helpful assistant that answers questions based on the provided context.
|
|
|
143 |
**Answer:**
|
144 |
"""
|
145 |
|
|
|
|
|
|
|
|
|
146 |
web_response = chat_session.send_message(web_prompt)
|
|
|
147 |
return f"{web_response.text}\n\n*Note: This answer is based on a web search.*"
|
148 |
else:
|
149 |
return initial_answer
|
150 |
except Exception as e:
|
151 |
return f"Error generating response: {e}"
|
152 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
153 |
# Function to process the agreement
|
154 |
+
def process_agreement(file, state):
|
155 |
try:
|
156 |
text = extract_text_from_pdf(file.name)
|
157 |
if text.startswith("Error"):
|
158 |
+
return text, {}, state
|
159 |
|
160 |
# Use Gemini for summarization
|
161 |
summary = summarize_agreement_with_gemini(text)
|
162 |
if summary.startswith("Error"):
|
163 |
+
return summary, {}, state
|
|
|
|
|
|
|
|
|
164 |
|
165 |
+
return summary, {}, state
|
166 |
except Exception as e:
|
167 |
+
return f"Error: {e}", {}, state
|
168 |
|
169 |
# Gradio interface
|
170 |
+
def main_interface(file, question, state):
|
171 |
if file is not None:
|
172 |
state["file"] = file
|
173 |
state["text"] = extract_text_from_pdf(file.name)
|
174 |
state["chat_history"] = [] # Initialize chat history
|
175 |
|
176 |
summary_output = ""
|
|
|
177 |
chatbot_output = ""
|
178 |
|
179 |
if "file" in state:
|
180 |
+
summary_output, _, state = process_agreement(state["file"], state)
|
|
|
181 |
|
182 |
if question:
|
183 |
chatbot_output = generate_response_with_rag(question, state["file"].name, state)
|
184 |
+
state["chat_history"].append((question, chatbot_output))
|
185 |
|
186 |
+
return summary_output, chatbot_output, state
|
187 |
|
188 |
# CSS for styling
|
189 |
css = """
|
190 |
.gradio-container {
|
191 |
+
background-image: url('https://huggingface.co/spaces/Nadaazakaria/DocWise/resolve/main/DALL%C2%B7E%202025-01-26%2011.43.33%20-%20A%20futuristic%20and%20sleek%20magical%20animated%20GIF-style%20icon%20design%20for%20%27DocWise%27%2C%20representing%20knowledge%2C%20documents%2C%20and%20wisdom.%20The%20design%20includes%20a%20glow.jpg');
|
192 |
background-size: cover;
|
193 |
background-position: center;
|
194 |
background-repeat: no-repeat;
|
|
|
244 |
"""
|
245 |
<div style="text-align: center;">
|
246 |
<h1 id="main-title">
|
247 |
+
DocWise (Agreement Analyzer with Chatbot)
|
248 |
</h1>
|
249 |
</div>
|
250 |
""",
|
|
|
253 |
state = gr.State({})
|
254 |
file_input = gr.File(label="Upload Agreement (PDF)")
|
255 |
|
256 |
+
with gr.Tab("Document Processing", elem_id="processing-tab"):
|
257 |
+
summary_output = gr.Textbox(label="Document Summary")
|
258 |
+
process_button = gr.Button("Process Document", elem_id="process-button")
|
|
|
|
|
|
|
259 |
|
260 |
with gr.Tab("Chatbot", elem_id="chatbot-tab"):
|
261 |
chatbot_question_input = gr.Textbox(label="Ask a Question")
|
|
|
264 |
|
265 |
process_button.click(
|
266 |
main_interface,
|
267 |
+
inputs=[file_input, gr.State(), state],
|
268 |
+
outputs=[summary_output, chatbot_answer_output, state]
|
269 |
)
|
270 |
chatbot_button.click(
|
271 |
main_interface,
|
272 |
+
inputs=[file_input, chatbot_question_input, state],
|
273 |
+
outputs=[summary_output, chatbot_answer_output, state]
|
274 |
)
|
275 |
|
276 |
app.launch(debug=True)
|