VibecoderMcSwaggins commited on
Commit
998d05d
·
1 Parent(s): 2ab9dda

fix: move title/description into ChatInterface for proper HF Spaces layout

Browse files

Root cause: gr.Markdown above gr.ChatInterface with fill_height=True
causes layout competition where ChatInterface consumes all viewport
space, pushing the Markdown behind the HuggingFace banner.

Solution: Use ChatInterface's native title/description parameters
instead of a separate gr.Markdown block. This is the Gradio-intended
pattern for full-height chat layouts.

Investigation documented in docs/bugs/002_gradio_ui_investigation.md

docs/bugs/002_gradio_ui_investigation.md ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Bug Investigation: Gradio UI Header Cutoff in HuggingFace Spaces
2
+
3
+ **Date:** November 26, 2025
4
+ **Investigator:** Gemini (Supreme World Expert in Gradio/HF)
5
+ **Status:** Documented (Pending Implementation)
6
+ **Target Bug:** Top content (Title/Markdown) cut off/hidden under HF banner.
7
+
8
+ ## 1. The Problem
9
+ The Gradio application deployed on HuggingFace Spaces displays a layout issue where the top-most content (Title and Description Markdown) is obscured by the HuggingFace Spaces header/banner. Users are unable to scroll up to reveal this content.
10
+
11
+ **Context:**
12
+ - **SDK:** Gradio `6.0.1`
13
+ - **Environment:** HuggingFace Spaces (Docker/Gradio SDK)
14
+ - **Configuration:** `header: mini` in `README.md`
15
+ - **Code Structure:** `gr.Blocks(fill_height=True)` containing `gr.Markdown` followed by `gr.ChatInterface`.
16
+
17
+ ## 2. Root Cause Analysis
18
+ The issue stems from a conflict between **Gradio's `fill_height=True` layout engine**, the **HuggingFace Spaces iframe environment**, and the **placement of content outside `ChatInterface`**.
19
+
20
+ 1. **`fill_height=True` Behavior:** When `fill_height=True` is set on `gr.Blocks`, Gradio applies CSS to force the container to take up 100% of the viewport height (`100vh`) and uses a flex column layout.
21
+ 2. **Iframe & Banner Conflict:** In HuggingFace Spaces, the app runs inside an iframe. The "Mini Header" (`header: mini`) or the standard header floats over or pushes the iframe content. When Gradio forces `100vh`, it calculates based on the *window* or *iframe* size. If the top padding isn't handled correctly by the browser's flex calculation in this context, the top element (Markdown) gets pushed up or obscured because the flex container tries to fit the massive `ChatInterface` (which also wants to fill height) into the view.
22
+ 3. **Component Structure:** `ChatInterface` is designed to be a full-page component. Placing `gr.Markdown` *above* it while `fill_height=True` is active on the *parent* creates a layout competition. The parent tries to fit both, but `ChatInterface` consumes all available space, potentially causing overflow issues at the top rather than the bottom, or messing up the scroll anchor.
23
+
24
+ ## 3. Investigation Findings
25
+
26
+ ### GitHub & Web Search
27
+ - **Similar Issues:** Multiple reports exist of "header cutoff" in Spaces when using custom layouts or `fill_height`.
28
+ - **CSS Workarounds:** Common fixes involve manually adding `margin-top` or `padding-top` to `.gradio-container` or `body`.
29
+ - **Gradio 5/6 Changes:** Gradio 5.x introduced a more aggressive `fill_height` system. While it fixes many internal scrolling issues, it assumes it owns the entire viewport, which is only partially true in an embedded Space with a header.
30
+
31
+ ### Code Analysis (`src/app.py`)
32
+ ```python
33
+ with gr.Blocks(
34
+ title="DeepCritical...",
35
+ fill_height=True, # <--- THE CULPRIT
36
+ ) as demo:
37
+ gr.Markdown(...) # <--- HIDDEN CONTENT
38
+ gr.ChatInterface(...)
39
+ ```
40
+ The `fill_height=True` is applied to the *entire* app, forcing the Markdown + ChatInterface to squeeze into the viewport.
41
+
42
+ ## 4. Potential Solutions
43
+
44
+ ### Solution A: Structural Fix (Recommended)
45
+ Move the title and description *inside* the `ChatInterface` component. `ChatInterface` natively supports `title` and `description` parameters. This allows the component to handle the layout and scrolling of the header internally, ensuring it respects the `fill_height` logic correctly.
46
+
47
+ **Why:** This is the "Gradio-native" way. It prevents layout fighting between the Markdown block and the Chat block.
48
+
49
+ **Code Change:**
50
+ ```python
51
+ gr.ChatInterface(
52
+ fn=research_agent,
53
+ title="🧬 DeepCritical",
54
+ description="## AI-Powered Drug Repurposing Research Agent\n\nAsk questions about...",
55
+ # ... other params
56
+ )
57
+ # Remove the separate gr.Markdown
58
+ ```
59
+
60
+ ### Solution B: CSS Workaround (Brittle)
61
+ Force a top margin to clear the header.
62
+
63
+ **Why:** Quick fix, but depends on the exact height of the HF header (which can change).
64
+
65
+ **Code Change:**
66
+ ```css
67
+ .gradio-container {
68
+ margin-top: 40px !important; /* Adjust based on header size */
69
+ }
70
+ ```
71
+
72
+ ### Solution C: Remove `fill_height` (Safe Fallback)
73
+ Remove `fill_height=True` from `gr.Blocks`.
74
+
75
+ **Why:** This returns to standard document flow. The page will scroll normally. The downside is the chat window might not be "sticky" at the bottom of the screen, requiring full page scrolling.
76
+
77
+ ## 5. Recommended Action Plan
78
+
79
+ We will proceed with **Solution A (Structural Fix)** as it is the most robust and architecturally correct solution.
80
+
81
+ 1. **Modify `src/app.py`**:
82
+ - Extract the Markdown content.
83
+ - Pass it into `gr.ChatInterface(title=..., description=...)`.
84
+ - Remove the standalone `gr.Markdown` component.
85
+ - Keep `fill_height=True` (or let ChatInterface handle it default) to ensure the chat stays full-screen but with the header properly integrated.
86
+
87
+ 2. **Alternative**: If Solution A is not desired (e.g., complex markdown needed that `description` doesn't support well), we will apply **Solution B (CSS)** with `padding-top: 50px`.
88
+
89
+ ## 6. Next Steps
90
+ Await approval to apply Solution A to `src/app.py`.
src/app.py CHANGED
@@ -185,23 +185,15 @@ def create_demo() -> Any:
185
  title="DeepCritical - Drug Repurposing Research Agent",
186
  fill_height=True,
187
  ) as demo:
188
- gr.Markdown("""
189
- # 🧬 DeepCritical
190
- ## AI-Powered Drug Repurposing Research Agent
191
-
192
- Ask questions about potential drug repurposing opportunities.
193
- The agent searches PubMed, ClinicalTrials.gov, and bioRxiv/medRxiv preprints.
194
-
195
- **Example questions:**
196
- - "What drugs could be repurposed for Alzheimer's disease?"
197
- - "Is metformin effective for cancer treatment?"
198
- - "What existing medications show promise for Long COVID?"
199
- """)
200
-
201
- # Main chat interface
202
  gr.ChatInterface(
203
  fn=research_agent,
204
- title="",
 
 
 
 
 
205
  examples=[
206
  [
207
  "What drugs could be repurposed for Alzheimer's disease?",
 
185
  title="DeepCritical - Drug Repurposing Research Agent",
186
  fill_height=True,
187
  ) as demo:
188
+ # Main chat interface - title/description inside ChatInterface for proper layout
 
 
 
 
 
 
 
 
 
 
 
 
 
189
  gr.ChatInterface(
190
  fn=research_agent,
191
+ title="🧬 DeepCritical",
192
+ description=(
193
+ "**AI-Powered Drug Repurposing Research Agent**\n\n"
194
+ "Ask questions about potential drug repurposing opportunities. "
195
+ "The agent searches PubMed, ClinicalTrials.gov, and bioRxiv/medRxiv preprints."
196
+ ),
197
  examples=[
198
  [
199
  "What drugs could be repurposed for Alzheimer's disease?",