bluenevus commited on
Commit
94db5a5
·
1 Parent(s): 228c612

Update app.py via AI Editor

Browse files
Files changed (1) hide show
  1. app.py +59 -19
app.py CHANGED
@@ -26,6 +26,7 @@ CLAUDE3_MAX_OUTPUT_TOKENS = 64_000
26
  uploaded_documents = {}
27
  uploaded_proposals = {}
28
  generated_documents = {}
 
29
  shredded_document = None
30
  generated_response = None
31
 
@@ -112,7 +113,7 @@ def process_document(action, selected_filename=None, chat_input=None, selected_p
112
  if chat_input:
113
  prompt += f"User additional instructions: {chat_input}\n"
114
  prompt += f"\nFile Name: {selected_filename}\n\n{doc_content}"
115
-
116
  result_holder = {"text": None, "docx_bytes": None, "docx_name": None}
117
  def thread_shred():
118
  global shredded_document
@@ -256,6 +257,28 @@ def get_uploaded_doc_list(docdict):
256
  )
257
  return dbc.ListGroup(doc_list, flush=True)
258
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
259
  def get_uploaded_proposal_list(docdict):
260
  if not docdict:
261
  return html.Div("No proposal documents uploaded.", style={"wordWrap": "break-word"})
@@ -313,7 +336,10 @@ app.layout = dbc.Container([
313
  'margin': '10px'
314
  },
315
  multiple=False
316
- )
 
 
 
317
  ])
318
  ], className="mb-3"),
319
 
@@ -401,6 +427,7 @@ app.layout = dbc.Container([
401
  Output('generated-doc-list', 'children'),
402
  Output('select-generated-dropdown', 'options'),
403
  Output('select-generated-dropdown', 'value'),
 
404
  Output('output-data-upload', 'children'),
405
  [
406
  Input('upload-document', 'contents'),
@@ -414,6 +441,8 @@ app.layout = dbc.Container([
414
  Input({'type': 'delete-generated-btn', 'index': dash.ALL, 'group': 'generated'}, 'n_clicks'),
415
  State('select-generated-dropdown', 'value'),
416
  State('select-generated-dropdown', 'options'),
 
 
417
  Input('shred-action-btn', 'n_clicks'),
418
  Input('proposal-action-btn', 'n_clicks'),
419
  Input('compliance-action-btn', 'n_clicks'),
@@ -432,6 +461,7 @@ def master_callback(
432
  rfp_content, rfp_filename, rfp_delete_clicks, selected_doc,
433
  proposal_content, proposal_filename, proposal_delete_clicks, selected_proposal,
434
  generated_delete_clicks, selected_generated, generated_options,
 
435
  shred_clicks, proposal_clicks, compliance_clicks, recover_clicks, board_clicks, loe_clicks,
436
  selected_generated_dropdown,
437
  chat_input, selected_filename, selected_proposal_dropdown, selected_generated_dropdown_state
@@ -502,12 +532,24 @@ def master_callback(
502
  upload_triggered = True
503
  break
504
 
 
 
 
 
 
 
 
 
 
 
 
505
  doc_options = [{'label': fn, 'value': fn} for fn in uploaded_documents.keys()]
506
  doc_value = selected_doc if selected_doc in uploaded_documents else (next(iter(uploaded_documents), None) if uploaded_documents else None)
507
  proposal_options = [{'label': fn, 'value': fn} for fn in uploaded_proposals.keys()]
508
  proposal_value = selected_proposal if selected_proposal in uploaded_proposals else (next(iter(uploaded_proposals), None) if uploaded_proposals else None)
509
  generated_doc_options = [{'label': fn, 'value': fn} for fn in generated_documents.keys()]
510
  generated_doc_value = selected_generated if selected_generated in generated_documents else (next(iter(generated_documents), None) if generated_documents else None)
 
511
 
512
  uploaded_doc_list = get_uploaded_doc_list(uploaded_documents)
513
  uploaded_proposal_list = get_uploaded_proposal_list(uploaded_proposals)
@@ -520,7 +562,6 @@ def master_callback(
520
  'recover-action-btn', 'board-action-btn', 'loe-action-btn'
521
  ]
522
 
523
- # Fix: When "Proposal" is clicked, trigger proposal streaming with correct dropdown doc selections
524
  if triggered_id in action_buttons:
525
  result = ""
526
  generated_docx_bytes = None
@@ -528,14 +569,14 @@ def master_callback(
528
  new_selected_generated = generated_doc_value
529
 
530
  if triggered_id == 'shred-action-btn':
531
- result, generated_docx_bytes, generated_docx_name = process_document('shred', selected_filename, chat_input)
532
- if generated_docx_bytes and generated_docx_name:
533
- generated_documents[generated_docx_name] = generated_docx_bytes
534
- logging.info(f"Generated docx saved: {generated_docx_name}")
535
- new_selected_generated = generated_docx_name
 
536
 
537
  elif triggered_id == 'proposal-action-btn':
538
- # Use the currently selected doc and generated doc from dropdowns
539
  rfp_doc = selected_filename
540
  gen_doc = selected_generated_dropdown_state
541
  logging.info(f"Starting proposal streaming with RFP: {rfp_doc}, Generated Doc: {gen_doc}")
@@ -550,28 +591,26 @@ def master_callback(
550
  generated_documents[generated_docx_name] = generated_docx_bytes
551
  logging.info(f"Generated proposal docx saved: {generated_docx_name}")
552
  new_selected_generated = generated_docx_name
 
 
 
 
553
 
554
  elif triggered_id == 'compliance-action-btn':
555
  result, _, _ = process_document('compliance', selected_filename, chat_input)
 
556
  elif triggered_id == 'recover-action-btn':
557
  result, _, _ = process_document('recover', selected_filename, chat_input)
 
558
  elif triggered_id == 'board-action-btn':
559
  result, _, _ = process_document('board', selected_filename, chat_input)
 
560
  elif triggered_id == 'loe-action-btn':
561
  result, _, _ = process_document('loe', selected_filename, chat_input)
 
562
  else:
563
  result = "Action not implemented yet."
564
-
565
- if isinstance(result, str) and result.strip().startswith("Error"):
566
- output_data_upload = html.Div(result, style={"wordWrap": "break-word"})
567
- elif isinstance(result, str) and ("not implemented" in result or "No document uploaded" in result or "Shredding in progress" in result or "Generating response" in result or "Shredded document not available" in result):
568
  output_data_upload = html.Div(result, style={"wordWrap": "break-word"})
569
- else:
570
- output_data_upload = dcc.Markdown(result, style={"whiteSpace": "pre-wrap", "wordWrap": "break-word"})
571
-
572
- generated_doc_options = [{'label': fn, 'value': fn} for fn in generated_documents.keys()]
573
- generated_doc_value = new_selected_generated if new_selected_generated in generated_documents else (next(iter(generated_documents), None) if generated_documents else None)
574
- generated_doc_list = get_generated_doc_list(generated_documents)
575
 
576
  elif triggered_id == 'select-generated-dropdown':
577
  sel_gen = selected_generated_dropdown
@@ -605,6 +644,7 @@ def master_callback(
605
  generated_doc_list,
606
  generated_doc_options,
607
  generated_doc_value,
 
608
  output_data_upload
609
  )
610
 
 
26
  uploaded_documents = {}
27
  uploaded_proposals = {}
28
  generated_documents = {}
29
+ shredded_documents = {}
30
  shredded_document = None
31
  generated_response = None
32
 
 
113
  if chat_input:
114
  prompt += f"User additional instructions: {chat_input}\n"
115
  prompt += f"\nFile Name: {selected_filename}\n\n{doc_content}"
116
+
117
  result_holder = {"text": None, "docx_bytes": None, "docx_name": None}
118
  def thread_shred():
119
  global shredded_document
 
257
  )
258
  return dbc.ListGroup(doc_list, flush=True)
259
 
260
+ def get_shredded_doc_list(shreddict):
261
+ if not shreddict:
262
+ return html.Div("No shredded requirements yet.", style={"wordWrap": "break-word"})
263
+ doc_list = []
264
+ for filename in shreddict:
265
+ b64 = base64.b64encode(shreddict[filename]).decode('utf-8')
266
+ download_link = html.A(
267
+ f"Download {filename}",
268
+ href=f"data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64,{b64}",
269
+ download=filename,
270
+ target="_blank",
271
+ style={"wordWrap": "break-word", "marginRight": "10px"}
272
+ )
273
+ doc_list.append(
274
+ dbc.ListGroupItem([
275
+ html.Span(filename, style={"wordWrap": "break-word", "marginRight": "10px"}),
276
+ download_link,
277
+ dbc.Button("Delete", id={'type': 'delete-shredded-btn', 'index': filename, 'group': 'shredded'}, size="sm", color="danger", className="float-end ms-2")
278
+ ], className="d-flex justify-content-between align-items-center")
279
+ )
280
+ return dbc.ListGroup(doc_list, flush=True)
281
+
282
  def get_uploaded_proposal_list(docdict):
283
  if not docdict:
284
  return html.Div("No proposal documents uploaded.", style={"wordWrap": "break-word"})
 
336
  'margin': '10px'
337
  },
338
  multiple=False
339
+ ),
340
+ html.Hr(),
341
+ html.H6("Shredded Requirements"),
342
+ html.Div(get_shredded_doc_list(shredded_documents), id='shredded-doc-list')
343
  ])
344
  ], className="mb-3"),
345
 
 
427
  Output('generated-doc-list', 'children'),
428
  Output('select-generated-dropdown', 'options'),
429
  Output('select-generated-dropdown', 'value'),
430
+ Output('shredded-doc-list', 'children'),
431
  Output('output-data-upload', 'children'),
432
  [
433
  Input('upload-document', 'contents'),
 
441
  Input({'type': 'delete-generated-btn', 'index': dash.ALL, 'group': 'generated'}, 'n_clicks'),
442
  State('select-generated-dropdown', 'value'),
443
  State('select-generated-dropdown', 'options'),
444
+ Input({'type': 'delete-shredded-btn', 'index': dash.ALL, 'group': 'shredded'}, 'n_clicks'),
445
+ State('shredded-doc-list', 'children'),
446
  Input('shred-action-btn', 'n_clicks'),
447
  Input('proposal-action-btn', 'n_clicks'),
448
  Input('compliance-action-btn', 'n_clicks'),
 
461
  rfp_content, rfp_filename, rfp_delete_clicks, selected_doc,
462
  proposal_content, proposal_filename, proposal_delete_clicks, selected_proposal,
463
  generated_delete_clicks, selected_generated, generated_options,
464
+ shredded_delete_clicks, shredded_doc_children,
465
  shred_clicks, proposal_clicks, compliance_clicks, recover_clicks, board_clicks, loe_clicks,
466
  selected_generated_dropdown,
467
  chat_input, selected_filename, selected_proposal_dropdown, selected_generated_dropdown_state
 
532
  upload_triggered = True
533
  break
534
 
535
+ if triggered_id and isinstance(ctx.inputs_list[12], list):
536
+ for i, n_click in enumerate(shredded_delete_clicks):
537
+ if n_click:
538
+ btn_id = ctx.inputs_list[12][i]['id']
539
+ del_filename = btn_id['index']
540
+ if del_filename in shredded_documents:
541
+ del shredded_documents[del_filename]
542
+ logging.info(f"Shredded doc deleted: {del_filename}")
543
+ upload_triggered = True
544
+ break
545
+
546
  doc_options = [{'label': fn, 'value': fn} for fn in uploaded_documents.keys()]
547
  doc_value = selected_doc if selected_doc in uploaded_documents else (next(iter(uploaded_documents), None) if uploaded_documents else None)
548
  proposal_options = [{'label': fn, 'value': fn} for fn in uploaded_proposals.keys()]
549
  proposal_value = selected_proposal if selected_proposal in uploaded_proposals else (next(iter(uploaded_proposals), None) if uploaded_proposals else None)
550
  generated_doc_options = [{'label': fn, 'value': fn} for fn in generated_documents.keys()]
551
  generated_doc_value = selected_generated if selected_generated in generated_documents else (next(iter(generated_documents), None) if generated_documents else None)
552
+ shredded_doc_list_items = get_shredded_doc_list(shredded_documents)
553
 
554
  uploaded_doc_list = get_uploaded_doc_list(uploaded_documents)
555
  uploaded_proposal_list = get_uploaded_proposal_list(uploaded_proposals)
 
562
  'recover-action-btn', 'board-action-btn', 'loe-action-btn'
563
  ]
564
 
 
565
  if triggered_id in action_buttons:
566
  result = ""
567
  generated_docx_bytes = None
 
569
  new_selected_generated = generated_doc_value
570
 
571
  if triggered_id == 'shred-action-btn':
572
+ result, shredded_docx_bytes, shredded_docx_name = process_document('shred', selected_filename, chat_input)
573
+ if shredded_docx_bytes and shredded_docx_name:
574
+ shredded_documents[shredded_docx_name] = shredded_docx_bytes
575
+ logging.info(f"Shredded docx saved: {shredded_docx_name}")
576
+ shredded_doc_list_items = get_shredded_doc_list(shredded_documents)
577
+ output_data_upload = dcc.Markdown(result, style={"whiteSpace": "pre-wrap", "wordWrap": "break-word"})
578
 
579
  elif triggered_id == 'proposal-action-btn':
 
580
  rfp_doc = selected_filename
581
  gen_doc = selected_generated_dropdown_state
582
  logging.info(f"Starting proposal streaming with RFP: {rfp_doc}, Generated Doc: {gen_doc}")
 
591
  generated_documents[generated_docx_name] = generated_docx_bytes
592
  logging.info(f"Generated proposal docx saved: {generated_docx_name}")
593
  new_selected_generated = generated_docx_name
594
+ generated_doc_options = [{'label': fn, 'value': fn} for fn in generated_documents.keys()]
595
+ generated_doc_value = new_selected_generated if new_selected_generated in generated_documents else (next(iter(generated_documents), None) if generated_documents else None)
596
+ generated_doc_list = get_generated_doc_list(generated_documents)
597
+ output_data_upload = dcc.Markdown(result, style={"whiteSpace": "pre-wrap", "wordWrap": "break-word"})
598
 
599
  elif triggered_id == 'compliance-action-btn':
600
  result, _, _ = process_document('compliance', selected_filename, chat_input)
601
+ output_data_upload = html.Div(result, style={"wordWrap": "break-word"})
602
  elif triggered_id == 'recover-action-btn':
603
  result, _, _ = process_document('recover', selected_filename, chat_input)
604
+ output_data_upload = html.Div(result, style={"wordWrap": "break-word"})
605
  elif triggered_id == 'board-action-btn':
606
  result, _, _ = process_document('board', selected_filename, chat_input)
607
+ output_data_upload = html.Div(result, style={"wordWrap": "break-word"})
608
  elif triggered_id == 'loe-action-btn':
609
  result, _, _ = process_document('loe', selected_filename, chat_input)
610
+ output_data_upload = html.Div(result, style={"wordWrap": "break-word"})
611
  else:
612
  result = "Action not implemented yet."
 
 
 
 
613
  output_data_upload = html.Div(result, style={"wordWrap": "break-word"})
 
 
 
 
 
 
614
 
615
  elif triggered_id == 'select-generated-dropdown':
616
  sel_gen = selected_generated_dropdown
 
644
  generated_doc_list,
645
  generated_doc_options,
646
  generated_doc_value,
647
+ shredded_doc_list_items,
648
  output_data_upload
649
  )
650