|
|
import gradio as gr |
|
|
from gradio_client import Client, handle_file |
|
|
|
|
|
|
|
|
API_URL = "ellamind/sui-demo" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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; |
|
|
} |
|
|
""" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def summarize_proxy(pdf_file, language, words, custom_instruction): |
|
|
"""Calls the backend Space API and yields exactly 3 results.""" |
|
|
if not pdf_file: |
|
|
|
|
|
yield "Please upload a PDF document.", "", gr.update(visible=False) |
|
|
return |
|
|
|
|
|
try: |
|
|
client = Client(API_URL) |
|
|
|
|
|
|
|
|
job = client.submit( |
|
|
pdf_file=handle_file(pdf_file), |
|
|
language=language, |
|
|
words=words, |
|
|
custom_instruction=custom_instruction, |
|
|
api_name="/summarize" |
|
|
) |
|
|
|
|
|
for result in job: |
|
|
|
|
|
|
|
|
if len(result) == 3: |
|
|
yield result[0], result[1], result[2] |
|
|
else: |
|
|
|
|
|
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) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def create_app(): |
|
|
|
|
|
with gr.Blocks(title="sui-1-24b") as app: |
|
|
|
|
|
gr.HTML(""" |
|
|
<div class="main-header"> |
|
|
<h1>sui-1-24b</h1> |
|
|
<p>Grounded summaries with verifiable source citations</p> |
|
|
</div> |
|
|
""") |
|
|
|
|
|
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.*") |
|
|
|
|
|
|
|
|
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(""" |
|
|
<div class="footer"> |
|
|
Powered by <a href="https://huggingface.co/ellamind/sui-1-24b" target="_blank">ellamind/sui-1-24b</a> via API |
|
|
</div> |
|
|
""") |
|
|
|
|
|
return app |
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
|
|
create_app().launch(theme=THEME, css=CSS) |