Spaces:
Paused
Paused
Update app.py via AI Editor
Browse files
app.py
CHANGED
@@ -132,13 +132,13 @@ def save_proposal_as_docx(proposal_text, base_filename):
|
|
132 |
memf.seek(0)
|
133 |
return memf.read()
|
134 |
|
135 |
-
def process_document(action, selected_filename=None, chat_input=None
|
136 |
global shredded_document, generated_response
|
137 |
logging.info(f"Process document called with action: {action}")
|
138 |
|
139 |
doc_content = None
|
140 |
doc_fileid = None
|
141 |
-
if action in ["shred", "generate"]:
|
142 |
if selected_filename and selected_filename in uploaded_documents:
|
143 |
doc_content = uploaded_documents[selected_filename]
|
144 |
doc_fileid = uploaded_documents_fileid.get(selected_filename)
|
@@ -149,8 +149,6 @@ def process_document(action, selected_filename=None, chat_input=None, selected_p
|
|
149 |
else:
|
150 |
doc_content = None
|
151 |
doc_fileid = None
|
152 |
-
elif action == "proposal":
|
153 |
-
pass
|
154 |
|
155 |
if action == 'shred':
|
156 |
if not doc_content:
|
@@ -225,45 +223,21 @@ def process_document(action, selected_filename=None, chat_input=None, selected_p
|
|
225 |
return result_holder["text"], result_holder["docx_bytes"], result_holder["docx_name"]
|
226 |
|
227 |
elif action == 'proposal':
|
228 |
-
|
229 |
-
generated_doc_content = None
|
230 |
-
rfp_filename = selected_filename
|
231 |
-
generated_docname = selected_generated
|
232 |
-
rfp_fileid = uploaded_documents_fileid.get(selected_filename)
|
233 |
-
gen_fileid = None
|
234 |
-
if not (selected_filename and selected_filename in uploaded_documents):
|
235 |
logging.warning("No RFP/SOW/PWS/RFI document selected for proposal action.")
|
236 |
return "No RFP/SOW/PWS/RFI document selected.", None, None
|
237 |
-
|
238 |
-
|
239 |
-
return "No generated document selected.", None, None
|
240 |
-
rfp_content = uploaded_documents[selected_filename]
|
241 |
-
gen_bytes = generated_documents[selected_generated]
|
242 |
-
try:
|
243 |
-
try:
|
244 |
-
docx_stream = io.BytesIO(gen_bytes)
|
245 |
-
doc = Document(docx_stream)
|
246 |
-
generated_doc_content = "\n".join([para.text for para in doc.paragraphs])
|
247 |
-
except Exception as e:
|
248 |
-
try:
|
249 |
-
generated_doc_content = gen_bytes.decode('utf-8')
|
250 |
-
except Exception:
|
251 |
-
generated_doc_content = "<Unable to decode generated document.>"
|
252 |
-
except Exception as e:
|
253 |
-
generated_doc_content = "<Unable to read generated document.>"
|
254 |
-
logging.error(f"Failed to read generated document: {e}")
|
255 |
-
|
256 |
prompt = (
|
257 |
-
"Respond to the following RFP/SOW/PWS/RFI
|
258 |
"The response to each section and subsection will be compliant and compelling, focusing on describing the approach, and how the labor category uses a specific industry standard process in a workflow described in steps, and how technology is used. "
|
259 |
"You must show innovation in the approach. Refer to research that validates the approach and cite sources with measurable outcome. "
|
260 |
"Be sure to respond in paragraph format only, never use numbering, or bullets, only paragraph describing in detail.\n"
|
261 |
)
|
262 |
if chat_input:
|
263 |
prompt += f"User additional instructions: {chat_input}\n"
|
264 |
-
prompt += f"\n---\nRFP/SOW/PWS/RFI ({rfp_filename}):\n"
|
265 |
-
prompt
|
266 |
-
logging.info(f"Sending proposal prompt to Gemini. RFP: {rfp_filename}, Generated Doc: {generated_docname}")
|
267 |
result_holder = {"text": None, "docx_bytes": None, "docx_name": None}
|
268 |
def thread_proposal():
|
269 |
try:
|
@@ -271,7 +245,7 @@ def process_document(action, selected_filename=None, chat_input=None, selected_p
|
|
271 |
response = gemini_generate_content(prompt, file_id=rfp_fileid, chat_input=chat_input)
|
272 |
logging.info("Received proposal results from Gemini.")
|
273 |
docx_bytes = save_proposal_as_docx(response, rfp_filename)
|
274 |
-
generated_docx_name = f"{os.path.splitext(rfp_filename)[0]}
|
275 |
result_holder["text"] = response
|
276 |
result_holder["docx_bytes"] = docx_bytes
|
277 |
result_holder["docx_name"] = generated_docx_name
|
@@ -649,14 +623,11 @@ def master_callback(
|
|
649 |
|
650 |
elif triggered_id == 'proposal-action-btn':
|
651 |
rfp_doc = selected_filename
|
652 |
-
|
653 |
-
logging.info(f"Starting proposal streaming with RFP: {rfp_doc}, Generated Doc: {gen_doc}")
|
654 |
result, generated_docx_bytes, generated_docx_name = process_document(
|
655 |
'proposal',
|
656 |
rfp_doc,
|
657 |
-
chat_input
|
658 |
-
None,
|
659 |
-
gen_doc
|
660 |
)
|
661 |
if generated_docx_bytes and generated_docx_name:
|
662 |
generated_documents[generated_docx_name] = generated_docx_bytes
|
|
|
132 |
memf.seek(0)
|
133 |
return memf.read()
|
134 |
|
135 |
+
def process_document(action, selected_filename=None, chat_input=None):
|
136 |
global shredded_document, generated_response
|
137 |
logging.info(f"Process document called with action: {action}")
|
138 |
|
139 |
doc_content = None
|
140 |
doc_fileid = None
|
141 |
+
if action in ["shred", "generate", "proposal"]:
|
142 |
if selected_filename and selected_filename in uploaded_documents:
|
143 |
doc_content = uploaded_documents[selected_filename]
|
144 |
doc_fileid = uploaded_documents_fileid.get(selected_filename)
|
|
|
149 |
else:
|
150 |
doc_content = None
|
151 |
doc_fileid = None
|
|
|
|
|
152 |
|
153 |
if action == 'shred':
|
154 |
if not doc_content:
|
|
|
223 |
return result_holder["text"], result_holder["docx_bytes"], result_holder["docx_name"]
|
224 |
|
225 |
elif action == 'proposal':
|
226 |
+
if not doc_content:
|
|
|
|
|
|
|
|
|
|
|
|
|
227 |
logging.warning("No RFP/SOW/PWS/RFI document selected for proposal action.")
|
228 |
return "No RFP/SOW/PWS/RFI document selected.", None, None
|
229 |
+
rfp_filename = selected_filename
|
230 |
+
rfp_fileid = uploaded_documents_fileid.get(selected_filename)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
231 |
prompt = (
|
232 |
+
"Respond to the following RFP/SOW/PWS/RFI by creating a highly detailed proposal response that follows each section and subsection header. "
|
233 |
"The response to each section and subsection will be compliant and compelling, focusing on describing the approach, and how the labor category uses a specific industry standard process in a workflow described in steps, and how technology is used. "
|
234 |
"You must show innovation in the approach. Refer to research that validates the approach and cite sources with measurable outcome. "
|
235 |
"Be sure to respond in paragraph format only, never use numbering, or bullets, only paragraph describing in detail.\n"
|
236 |
)
|
237 |
if chat_input:
|
238 |
prompt += f"User additional instructions: {chat_input}\n"
|
239 |
+
prompt += f"\n---\nRFP/SOW/PWS/RFI ({rfp_filename}):\n{doc_content}\n"
|
240 |
+
logging.info(f"Sending proposal prompt to Gemini. RFP: {rfp_filename}")
|
|
|
241 |
result_holder = {"text": None, "docx_bytes": None, "docx_name": None}
|
242 |
def thread_proposal():
|
243 |
try:
|
|
|
245 |
response = gemini_generate_content(prompt, file_id=rfp_fileid, chat_input=chat_input)
|
246 |
logging.info("Received proposal results from Gemini.")
|
247 |
docx_bytes = save_proposal_as_docx(response, rfp_filename)
|
248 |
+
generated_docx_name = f"{os.path.splitext(rfp_filename)[0]}_proposal.docx"
|
249 |
result_holder["text"] = response
|
250 |
result_holder["docx_bytes"] = docx_bytes
|
251 |
result_holder["docx_name"] = generated_docx_name
|
|
|
623 |
|
624 |
elif triggered_id == 'proposal-action-btn':
|
625 |
rfp_doc = selected_filename
|
626 |
+
logging.info(f"Starting proposal with RFP: {rfp_doc}")
|
|
|
627 |
result, generated_docx_bytes, generated_docx_name = process_document(
|
628 |
'proposal',
|
629 |
rfp_doc,
|
630 |
+
chat_input
|
|
|
|
|
631 |
)
|
632 |
if generated_docx_bytes and generated_docx_name:
|
633 |
generated_documents[generated_docx_name] = generated_docx_bytes
|