Spaces:
Sleeping
Sleeping
| from functools import partial | |
| import gradio as gr | |
| from src.gradio_utils import ( | |
| extract_table_from_chat, | |
| upload_file, | |
| redo, | |
| undo, | |
| edit_or_save_changes, | |
| update_llm_selection, | |
| ) | |
| from src.llm_calls import query_llm | |
| from src.data_handler import generate_excel_base64 | |
| SYSTEM_PROMPT = """You are a pharmacology assistant specialized in analyzing and structuring medical data. | |
| Inputs You Receive: | |
| A JSON dataset representing medications for Retinitis Pigmentosa | |
| A user query requesting additional details to be added to the dataset | |
| Your Task: | |
| Analyze the dataset and determine what new information is needed | |
| Research and generate new details based on the user’s request | |
| Enhance the dataset by adding the requested information | |
| Ensure completeness: The updated dataset must always include all medications | |
| Your Output: | |
| A succinct response explaining your findings and how the dataset was extended | |
| A fully updated JSON dataset, strictly following this format: | |
| json | |
| Copy | |
| Edit | |
| { | |
| "Medications": [ | |
| {"Name": "Medication Name", "key1": "value1", "key2": "value2", ...}, | |
| {"Name": "Medication Name", "key1": "value1", "key2": "value2", ...} | |
| ] | |
| } | |
| Key Requirements: | |
| - JSON output is mandatory in every response | |
| - All medications must be present in the JSON, even if unchanged | |
| - Extend the dataset with newly generated information—do not just retrieve existing data | |
| - No repetition of the example JSON—only return the updated data | |
| - Verify the JSON before responding to ensure it is well-formed and complete | |
| Always structure your response clearly: | |
| - Text Summary: Explanation of findings and dataset extensions | |
| - Updated JSON Dataset: Full dataset with all medications, including new information | |
| - References & Sources (if applicable) | |
| """ | |
| with gr.Blocks(theme=gr.themes.Glass()) as app: | |
| df_before = gr.State([]) # Undo history | |
| df_state = gr.State(None) # Current DataFrame | |
| df_after = gr.State([]) # Redo history | |
| last_response = gr.State("") # Store last LLM response | |
| edit_mode = gr.State("Edit") # Track edit mode | |
| base64data = gr.State(None) | |
| with gr.Sidebar(): | |
| gr.Markdown("### Configuration") | |
| llm_type = gr.Radio( | |
| choices=["Perplexity", "OpenAI"], label="LLM Type", value="Perplexity" | |
| ) | |
| api_key = gr.Textbox( | |
| label="OpenAI API Key", | |
| placeholder=f"Enter {llm_type.value} Key", | |
| interactive=True, | |
| type="password" | |
| ) | |
| gr.Markdown("### Upload existing data") | |
| file_upload = gr.File(label="Upload Excel File", file_types=[".xlsx"]) | |
| gr.Markdown("### Download table to Excel") | |
| excel_output = gr.State(None) | |
| excel_data = gr.Textbox(visible=False) | |
| download_button = gr.DownloadButton(label="Download dataset") | |
| download_button.click( | |
| generate_excel_base64, inputs=[df_state], outputs=[excel_data] | |
| ) | |
| excel_data.change( | |
| None, | |
| [excel_data], | |
| None, | |
| js=""" | |
| (base64Data) => { | |
| const binaryString = atob(base64Data); | |
| const len = binaryString.length; | |
| const bytes = new Uint8Array(len); | |
| for (let i = 0; i < len; i++) { | |
| bytes[i] = binaryString.charCodeAt(i); | |
| } | |
| const blob = new Blob([bytes], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }); | |
| const link = document.createElement("a"); | |
| link.href = URL.createObjectURL(blob); | |
| link.download = "dataset.xlsx"; | |
| document.body.appendChild(link); | |
| link.click(); | |
| document.body.removeChild(link); | |
| } | |
| """, | |
| ) | |
| llm_type.change(update_llm_selection, inputs=[llm_type], outputs=[api_key]) | |
| with gr.Accordion("System Prompt", open=False): | |
| system_prompt_box = gr.Textbox( | |
| value=SYSTEM_PROMPT, interactive=True, lines=10, label="System Prompt" | |
| ) | |
| gr.Markdown("## Medications Data CoPilot") | |
| # Chat Interface | |
| chat = gr.ChatInterface( | |
| fn=query_llm, | |
| type="messages", | |
| description="Chat with an LLM to create a data representation of medications.", | |
| stop_btn=False, | |
| save_history=False, | |
| additional_inputs=[df_state, llm_type, api_key, system_prompt_box], | |
| examples=[ | |
| [ | |
| "List 10 medications that are known to be effective for Retinitis Pigmentosa" | |
| ], | |
| [ | |
| "Add a column specifying if the medication passes the Retinal Blood Barrier" | |
| ], | |
| ["Add the safety profile for each medication"], | |
| ["Create four columns, each specifying each of the ADME profile factors"], | |
| [ | |
| "Categorize each column into up to five categories, for simple classification." | |
| ], | |
| ], | |
| ) | |
| with gr.Row(): | |
| gr.Markdown("### Medications Table") | |
| with gr.Row(): | |
| update_button = gr.Button( | |
| "Update table using the chat information", scale=8, interactive=True | |
| ) | |
| with gr.Row(): | |
| dataframe_display = gr.DataFrame(interactive=False) | |
| with gr.Row(): | |
| prev_button = gr.Button("<-", interactive=False, scale=1) | |
| edit_save_button = gr.Button("Edit", interactive=True, scale=2) | |
| next_button = gr.Button("->", interactive=False, scale=1) | |
| # Save user changes | |
| edit_save_button.click( | |
| edit_or_save_changes, | |
| inputs=[dataframe_display, df_before, df_state, df_after, edit_mode], | |
| outputs=[ | |
| dataframe_display, # Updated DataFrame | |
| df_before, # Undo history | |
| df_state, # Current state | |
| df_after, # Redo history | |
| prev_button, # Update prev button | |
| next_button, # Update next button | |
| dataframe_display, # Update DataFrame interactivity | |
| edit_save_button, # Update button label | |
| edit_mode, # Update edit mode | |
| ], | |
| ) | |
| # Undo button | |
| prev_button.click( | |
| undo, | |
| inputs=[df_before, df_state, df_after], | |
| outputs=[ | |
| dataframe_display, | |
| df_before, | |
| df_state, | |
| df_after, | |
| prev_button, | |
| next_button, | |
| ], | |
| ) | |
| # Redo button | |
| next_button.click( | |
| redo, | |
| inputs=[df_before, df_state, df_after], | |
| outputs=[ | |
| dataframe_display, | |
| df_before, | |
| df_state, | |
| df_after, | |
| prev_button, | |
| next_button, | |
| ], | |
| ) | |
| # File upload event | |
| file_upload.change( | |
| upload_file, | |
| inputs=[file_upload, df_before, df_state, df_after], | |
| outputs=[ | |
| dataframe_display, | |
| df_before, | |
| df_state, | |
| df_after, | |
| prev_button, | |
| next_button, | |
| ], | |
| ) | |
| # Update button copies chat history to text box | |
| update_button.click( | |
| partial(extract_table_from_chat, key="Medications"), | |
| inputs=[chat.chatbot, df_before, df_state, df_after, llm_type, api_key], | |
| outputs=[ | |
| dataframe_display, | |
| df_before, | |
| df_state, | |
| df_after, | |
| prev_button, | |
| next_button, | |
| ], | |
| ) | |
| # Launch App | |
| app.launch() | |