import gradio as gr from gradio_client import Client, handle_file # Target Space API API_URL = "ellamind/sui-demo" # ============================================================================ # Theme & Styling # ============================================================================ THEME = gr.themes.Soft( primary_hue="slate", secondary_hue="slate", neutral_hue="slate", font=gr.themes.GoogleFont("Inter"), ).set( block_radius="0.75rem", block_shadow="0 1px 3px 0 rgb(0 0 0 / 0.1)", button_primary_background_fill="*primary_800", button_primary_background_fill_hover="*primary_700", ) CSS = """ .gradio-container { max-width: 1100px !important; margin: 0 auto !important; padding-top: 2rem !important; } .main-header { text-align: center; margin-bottom: 2rem; } .main-header h1 { font-size: 2.25rem; font-weight: 800; margin-bottom: 0.5rem; color: var(--body-text-color); } .section-title { margin-bottom: 1rem !important; border-bottom: 1px solid var(--border-color-primary); padding-bottom: 0.5rem; } .output-panel { background: var(--block-background-fill) !important; border-radius: 0.75rem !important; border: 1px solid var(--border-color-primary) !important; padding: 1.5rem !important; min-height: 400px; } .summary-text { font-size: 1.05rem !important; line-height: 1.8 !important; color: var(--body-text-color) !important; background: transparent !important; } /* 1. Base style (Light Mode) */ .thinking-section { background: rgba(0, 0, 0, 0.05) !important; /* Subtle tint instead of var */ border-left: 4px solid var(--primary-500) !important; padding: 1.25rem !important; margin-bottom: 1.5rem !important; border-radius: 0 0.75rem 0.75rem 0 !important; font-style: italic !important; } /* 2. Dark Mode Override */ .dark .thinking-section { background: rgba(255, 255, 255, 0.1) !important; /* Light tint on dark background */ border-left-color: var(--primary-400) !important; } /* 3. Force the text inside the thinking section to adapt */ .thinking-section, .thinking-section p, .thinking-section span { color: var(--body-text-color) !important; opacity: 0.9; } /* 4. Extra insurance for the summary area text in dark mode */ .dark .summary-text, .dark .prose { color: #f1f5f9 !important; /* Explicit light gray/white */ } .sources-panel { font-size: 0.9rem !important; max-height: 400px; overflow-y: auto; } .generate-btn { margin-top: 1rem; font-weight: 600 !important; } .footer { text-align: center; margin-top: 3rem; padding-bottom: 2rem; font-size: 0.85rem; opacity: 0.6; } """ # ============================================================================ # API Proxy Function # ============================================================================ def summarize_proxy(pdf_file, language, words, custom_instruction): """Calls the backend Space API and yields exactly 3 results.""" if not pdf_file: # Yielding 3 values to match the interface components yield "Please upload a PDF document.", "", gr.update(visible=False) return try: client = Client(API_URL) # We start the stream. The backend yields 3 objects: (summary, sources, accordion_update) job = client.submit( pdf_file=handle_file(pdf_file), language=language, words=words, custom_instruction=custom_instruction, api_name="/summarize" ) for result in job: # Result from the client should be a list/tuple of 3 items # But let's be safe and ensure it matches the 3 outputs if len(result) == 3: yield result[0], result[1], result[2] else: # Fallback in case backend returns unexpected shape yield result[0], result[1], gr.update(visible=True) except Exception as e: yield f"### API Error\n{str(e)}", "Ensure the backend Space is active.", gr.update(visible=False) # ============================================================================ # Interface # ============================================================================ def create_app(): # Removed theme and css from constructor for Gradio 6.0 compatibility with gr.Blocks(title="sui-1-24b") as app: gr.HTML("""

sui-1-24b

Grounded summaries with verifiable source citations

""") with gr.Row(equal_height=False): with gr.Column(scale=2): gr.Markdown("### Document", elem_classes=["section-title"]) pdf_input = gr.File(label="Upload PDF", file_types=[".pdf"], type="filepath") gr.Markdown("### Options", elem_classes=["section-title"]) language = gr.Dropdown( choices=["English", "German", "Spanish", "French", "Italian"], value="German", label="Language" ) words = gr.Slider(minimum=100, maximum=600, value=150, step=50, label="Summary Length") custom_instruction = gr.Textbox( label="Instructions (Optional)", placeholder="Focus on key findings...", lines=2 ) generate_btn = gr.Button("Generate Summary", variant="primary", elem_classes=["generate-btn"]) with gr.Column(scale=3): gr.Markdown("### Summary", elem_classes=["section-title"]) summary_output = gr.Markdown(value="*Upload a PDF to begin.*") # Note: This is output #3 with gr.Accordion("View Source Citations", open=False, visible=False) as sources_accordion: sources_output = gr.Markdown(elem_classes=["sources-panel"]) generate_btn.click( fn=summarize_proxy, inputs=[pdf_input, language, words, custom_instruction], outputs=[summary_output, sources_output, sources_accordion], ) gr.HTML(""" """) return app if __name__ == "__main__": # Theme and CSS passed here to comply with Gradio 6.0 warning create_app().launch(theme=THEME, css=CSS)