Spaces:
Paused
Paused
Update app.py via AI Editor
Browse files
app.py
CHANGED
|
@@ -256,11 +256,48 @@ def process_document(action, selected_filename=None, chat_input=None, rfp_decode
|
|
| 256 |
elif action == 'recover':
|
| 257 |
# For recover: need compliance check or shred (selected_filename), and proposal (selected_proposal_filename)
|
| 258 |
if not selected_proposal_filename or selected_proposal_filename not in proposals:
|
|
|
|
| 259 |
return "No proposal document selected for recovery.", None, None, None, None
|
| 260 |
if not selected_filename or selected_filename not in uploaded_documents:
|
|
|
|
| 261 |
return "No compliance check or shredded requirements document selected for recovery.", None, None, None, None
|
|
|
|
| 262 |
findings_content = uploaded_documents[selected_filename]
|
| 263 |
proposal_text = proposals[selected_proposal_filename]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 264 |
logging.info(f"Recovery: fixing proposal [{selected_proposal_filename}] based on findings [{selected_filename}]")
|
| 265 |
prompt = (
|
| 266 |
"You are a proposal compliance recovery expert. Use the following findings and recommendations table, and the original proposal response. "
|
|
@@ -269,21 +306,33 @@ def process_document(action, selected_filename=None, chat_input=None, rfp_decode
|
|
| 269 |
"For each section that needs fixing, revise it in the proposal to address the recommendation for compliance or to strengthen the response. "
|
| 270 |
"Return the full proposal with only the necessary sections revised, and leave all other sections untouched. "
|
| 271 |
"Do not add any introduction, summary, or comments. Return only the revised proposal in markdown, nothing else.\n\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 272 |
"Findings and Recommendations Table or Requirements Table:\n"
|
| 273 |
f"{findings_content}\n"
|
| 274 |
"---\nOriginal Proposal:\n"
|
| 275 |
f"{proposal_text}\n"
|
| 276 |
)
|
| 277 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 278 |
if result and not result.startswith("Error"):
|
| 279 |
-
# Name for the recovered proposal: <original proposal base>_recovered.docx
|
| 280 |
base_name = os.path.splitext(selected_proposal_filename)[0]
|
| 281 |
recovered_docx_name = f"{base_name}_recovered.docx"
|
| 282 |
docx_bytes = save_proposal_as_docx(result, base_name)
|
| 283 |
proposals[recovered_docx_name] = result
|
| 284 |
proposals_fileid[recovered_docx_name] = None
|
|
|
|
| 285 |
return result, None, None, recovered_docx_name, docx_bytes
|
| 286 |
else:
|
|
|
|
| 287 |
return result, None, None, None, None
|
| 288 |
|
| 289 |
elif action == 'loe':
|
|
@@ -645,7 +694,6 @@ def master_callback(
|
|
| 645 |
output_data_upload = dcc.Markdown(result, style={"whiteSpace": "pre-wrap", "wordWrap": "break-word"})
|
| 646 |
elif triggered_id == "recover-action-btn":
|
| 647 |
action_name = "recover"
|
| 648 |
-
# For recover, use selected compliance/shred doc (doc_value) and selected proposal (proposal_value)
|
| 649 |
result, _, _, generated_filename, generated_docx_bytes = process_document(
|
| 650 |
action_name, doc_value, chat_input, None, proposal_value
|
| 651 |
)
|
|
|
|
| 256 |
elif action == 'recover':
|
| 257 |
# For recover: need compliance check or shred (selected_filename), and proposal (selected_proposal_filename)
|
| 258 |
if not selected_proposal_filename or selected_proposal_filename not in proposals:
|
| 259 |
+
logging.error("No proposal document selected for recovery.")
|
| 260 |
return "No proposal document selected for recovery.", None, None, None, None
|
| 261 |
if not selected_filename or selected_filename not in uploaded_documents:
|
| 262 |
+
logging.error("No compliance check or shredded requirements document selected for recovery.")
|
| 263 |
return "No compliance check or shredded requirements document selected for recovery.", None, None, None, None
|
| 264 |
+
|
| 265 |
findings_content = uploaded_documents[selected_filename]
|
| 266 |
proposal_text = proposals[selected_proposal_filename]
|
| 267 |
+
findings_fileid = uploaded_documents_fileid.get(selected_filename)
|
| 268 |
+
proposal_fileid = proposals_fileid.get(selected_proposal_filename)
|
| 269 |
+
|
| 270 |
+
# Upload findings doc if not already uploaded
|
| 271 |
+
if not findings_fileid:
|
| 272 |
+
if selected_filename in shredded_documents:
|
| 273 |
+
findings_bytes = shredded_documents[selected_filename]
|
| 274 |
+
elif selected_filename in uploaded_documents_bytes:
|
| 275 |
+
findings_bytes = uploaded_documents_bytes[selected_filename]
|
| 276 |
+
else:
|
| 277 |
+
findings_bytes = None
|
| 278 |
+
if findings_bytes:
|
| 279 |
+
try:
|
| 280 |
+
findings_fileid = upload_to_gemini_file(findings_bytes, selected_filename)
|
| 281 |
+
if findings_fileid:
|
| 282 |
+
uploaded_documents_fileid[selected_filename] = findings_fileid
|
| 283 |
+
logging.info(f"Findings/Compliance doc {selected_filename} uploaded to Gemini for recover.")
|
| 284 |
+
except Exception as e:
|
| 285 |
+
logging.error(f"Failed to upload findings doc {selected_filename} for recover: {e}")
|
| 286 |
+
|
| 287 |
+
# Upload proposal doc if not already uploaded
|
| 288 |
+
if not proposal_fileid:
|
| 289 |
+
proposal_bytes = None
|
| 290 |
+
if selected_proposal_filename in proposals:
|
| 291 |
+
proposal_bytes = save_proposal_as_docx(proposals[selected_proposal_filename], selected_proposal_filename)
|
| 292 |
+
if proposal_bytes:
|
| 293 |
+
try:
|
| 294 |
+
proposal_fileid = upload_to_gemini_file(proposal_bytes, selected_proposal_filename)
|
| 295 |
+
if proposal_fileid:
|
| 296 |
+
proposals_fileid[selected_proposal_filename] = proposal_fileid
|
| 297 |
+
logging.info(f"Proposal doc {selected_proposal_filename} uploaded to Gemini for recover.")
|
| 298 |
+
except Exception as e:
|
| 299 |
+
logging.error(f"Failed to upload proposal doc {selected_proposal_filename} for recover: {e}")
|
| 300 |
+
|
| 301 |
logging.info(f"Recovery: fixing proposal [{selected_proposal_filename}] based on findings [{selected_filename}]")
|
| 302 |
prompt = (
|
| 303 |
"You are a proposal compliance recovery expert. Use the following findings and recommendations table, and the original proposal response. "
|
|
|
|
| 306 |
"For each section that needs fixing, revise it in the proposal to address the recommendation for compliance or to strengthen the response. "
|
| 307 |
"Return the full proposal with only the necessary sections revised, and leave all other sections untouched. "
|
| 308 |
"Do not add any introduction, summary, or comments. Return only the revised proposal in markdown, nothing else.\n\n"
|
| 309 |
+
)
|
| 310 |
+
if chat_input:
|
| 311 |
+
prompt += f"User additional instructions: {chat_input}\n"
|
| 312 |
+
prompt += (
|
| 313 |
"Findings and Recommendations Table or Requirements Table:\n"
|
| 314 |
f"{findings_content}\n"
|
| 315 |
"---\nOriginal Proposal:\n"
|
| 316 |
f"{proposal_text}\n"
|
| 317 |
)
|
| 318 |
+
# If both are present, use both as file context for Gemini
|
| 319 |
+
used_fileid = None
|
| 320 |
+
if findings_fileid:
|
| 321 |
+
used_fileid = findings_fileid
|
| 322 |
+
elif proposal_fileid:
|
| 323 |
+
used_fileid = proposal_fileid
|
| 324 |
+
|
| 325 |
+
result = gemini_generate_content(prompt, file_id=used_fileid, chat_input=chat_input)
|
| 326 |
if result and not result.startswith("Error"):
|
|
|
|
| 327 |
base_name = os.path.splitext(selected_proposal_filename)[0]
|
| 328 |
recovered_docx_name = f"{base_name}_recovered.docx"
|
| 329 |
docx_bytes = save_proposal_as_docx(result, base_name)
|
| 330 |
proposals[recovered_docx_name] = result
|
| 331 |
proposals_fileid[recovered_docx_name] = None
|
| 332 |
+
logging.info(f"Recovered proposal generated and saved as {recovered_docx_name}.")
|
| 333 |
return result, None, None, recovered_docx_name, docx_bytes
|
| 334 |
else:
|
| 335 |
+
logging.error(f"Error in Gemini recover: {result}")
|
| 336 |
return result, None, None, None, None
|
| 337 |
|
| 338 |
elif action == 'loe':
|
|
|
|
| 694 |
output_data_upload = dcc.Markdown(result, style={"whiteSpace": "pre-wrap", "wordWrap": "break-word"})
|
| 695 |
elif triggered_id == "recover-action-btn":
|
| 696 |
action_name = "recover"
|
|
|
|
| 697 |
result, _, _, generated_filename, generated_docx_bytes = process_document(
|
| 698 |
action_name, doc_value, chat_input, None, proposal_value
|
| 699 |
)
|