Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| from claims_agent import ClaimsIntakeAgent | |
| from adjuster_dashboard import AdjusterDashboard | |
| from utils import extract_claim_data | |
| from PIL import Image | |
| # Initialize Agents and Dashboard | |
| intake_agent = ClaimsIntakeAgent() | |
| dashboard = AdjusterDashboard() | |
| # --- Claims Intake View Functions --- | |
| import time | |
| # --- Claims Intake View Functions --- | |
| def intake_chat(message, image, file, progress=gr.Progress()): | |
| # Yield status updates to the output box directly | |
| yield "π **Initializing AI Agent...**" | |
| progress(0.1, desc="Initializing AI Agent...") | |
| time.sleep(0.5) # Simulate init time | |
| yield "π **Analyzing Image & Documents...**" | |
| progress(0.3, desc="Analyzing Image & Documents...") | |
| # If file is provided, it comes as a filepath | |
| response = intake_agent.process_claim(message, image, file) | |
| yield "πΎ **Syncing with Adjuster Dashboard...**" | |
| progress(0.7, desc="Syncing with Adjuster Dashboard...") | |
| # Sync with Dashboard | |
| if response and "Error" not in response: | |
| try: | |
| claim_data = extract_claim_data(response) | |
| # Update the dashboard data | |
| # Note: In a real app with concurrent users, this needs better state management. | |
| # Here we update the global dashboard object. | |
| dashboard.add_claim(claim_data) | |
| except Exception as e: | |
| print(f"Error syncing to dashboard: {e}") | |
| progress(1.0, desc="Assessment Complete!") | |
| yield response | |
| # --- Adjuster Auth Functions --- | |
| def check_password(password): | |
| if password == "password": | |
| return gr.update(visible=False), gr.update(visible=True) | |
| return gr.update(visible=True), gr.update(visible=False) | |
| # --- UI Construction --- | |
| custom_css = """ | |
| #main_container { | |
| max-width: 1000px; | |
| margin: 0 auto; | |
| padding: 20px; | |
| background-color: white; | |
| box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | |
| border-radius: 10px; | |
| margin-top: 20px; | |
| } | |
| body { | |
| background-color: #f0f2f5; | |
| } | |
| h1 { | |
| text-align: center; | |
| color: #2c3e50; | |
| font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; | |
| } | |
| """ | |
| with gr.Blocks(theme=gr.themes.Soft(primary_hue="blue", secondary_hue="slate"), title="EMA Claims MVP", css=custom_css) as demo: | |
| with gr.Column(elem_id="main_container"): | |
| gr.Markdown("# π‘οΈ EMA Claims MVP") | |
| with gr.Tabs(): | |
| # Tab 1: Customer View (Claims Intake) | |
| with gr.Tab("π Claims Intake (Customer)"): | |
| gr.Markdown("### Report an Accident") | |
| gr.Markdown("Upload a photo of the damage and any relevant documents (PDF/Doc). Our AI will assess it immediately.") | |
| with gr.Row(): | |
| with gr.Column(scale=1): | |
| image_input = gr.Image(type="pil", label="Upload Damage Photo") | |
| file_input = gr.File(label="Upload Documents (PDF/Doc)", file_types=[".pdf", ".docx", ".txt"]) | |
| msg_input = gr.Textbox(placeholder="Describe the accident...", label="Description") | |
| submit_btn = gr.Button("Submit Claim", variant="primary") | |
| with gr.Column(scale=1): | |
| chat_output = gr.Markdown(label="AI Assessment") | |
| # We need to update the claims table if it's visible, but since it's in another tab, | |
| # we can rely on the global dashboard object being updated. | |
| # However, Gradio components need an event to refresh. | |
| # For MVP, we'll just update the global list. The table in the other tab won't auto-refresh | |
| # without a trigger, but we can add a "Refresh" button or make the table update on tab select (harder in simple Blocks). | |
| # Let's add a "Refresh" button to the dashboard. | |
| submit_btn.click( | |
| fn=intake_chat, | |
| inputs=[msg_input, image_input, file_input], | |
| outputs=[chat_output], | |
| show_progress=True | |
| ) | |
| # Tab 2: Adjuster View (Dashboard) | |
| with gr.Tab("π¨βπΌ Adjuster Dashboard (Internal)"): | |
| # Login State | |
| with gr.Group(visible=True) as login_group: | |
| gr.Markdown("### Internal Access Only") | |
| password_input = gr.Textbox(label="Password", type="password") | |
| login_btn = gr.Button("Login") | |
| # Dashboard Content (Hidden by default) | |
| with gr.Group(visible=False) as dashboard_group: | |
| gr.Markdown("### Incoming Claims Queue") | |
| refresh_btn = gr.Button("Refresh List", size="sm") | |
| with gr.Row(): | |
| with gr.Column(scale=2): | |
| # Dataframe for claims list | |
| claims_df = gr.Dataframe( | |
| headers=["ID", "Submitter", "Date", "Vehicle", "Status", "Fraud Risk", "Classification"], | |
| value=dashboard.get_claims_data, # Pass method to call on load/refresh | |
| interactive=False, | |
| label="Active Claims", | |
| elem_id="claims_table" | |
| ) | |
| with gr.Column(scale=1): | |
| # Details Panel | |
| details_panel = gr.Markdown("Select a claim to view details.", label="Claim Analysis") | |
| with gr.Row(): | |
| approve_btn = gr.Button("Approve Payment", variant="primary", interactive=False) | |
| escalate_btn = gr.Button("Escalate to SIU", variant="stop", interactive=False) | |
| action_output = gr.Label(label="Action Status") | |
| # Interactions | |
| claims_df.select( | |
| fn=dashboard.get_claim_details, | |
| inputs=None, | |
| outputs=[details_panel, approve_btn, escalate_btn] | |
| ) | |
| approve_btn.click( | |
| fn=dashboard.approve_claim, | |
| inputs=[details_panel], | |
| outputs=[action_output] | |
| ) | |
| escalate_btn.click( | |
| fn=dashboard.escalate_claim, | |
| inputs=[details_panel], | |
| outputs=[action_output] | |
| ) | |
| refresh_btn.click( | |
| fn=lambda: dashboard.get_claims_data(), | |
| inputs=None, | |
| outputs=[claims_df] | |
| ) | |
| login_btn.click( | |
| fn=check_password, | |
| inputs=[password_input], | |
| outputs=[login_group, dashboard_group] | |
| ) | |
| if __name__ == "__main__": | |
| demo.queue() | |
| demo.launch(server_name="0.0.0.0", # not 127.0.0.1 | |
| server_port=7860,) | |