File size: 6,234 Bytes
e324277 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# P3 Bug: Progress Bar Positioning/Overlap in ChatInterface
**Severity**: P3 (Low - UX polish)
**Status**: Open
**Discovered**: 2025-12-01
**Reporter**: Internal QA
## Symptom
The `gr.Progress()` bar renders in a strange position when used inside `ChatInterface`:
- Progress bar appears to "float" in the middle of the chat output
- Text overlaps with progress bar elements
- Bar appears static/stuck at certain percentages
- Visual artifact: `Round 2/5 (~2m 15s remaining) - 48.0%` renders both above and inside bar
## Screenshot Evidence
Progress bar appears inline between chat messages rather than in a fixed position (top/bottom of component).
## Root Cause Analysis
### The Conflict
We're mixing **two different progress mechanisms**:
1. **`gr.Progress()`** - Gradio's general-purpose progress bar API
- Designed for `gr.Interface` and `gr.Blocks` functions
- Renders as an overlay on the output component
2. **`ChatInterface.show_progress`** - Built-in chat progress
- Options: `"full"`, `"minimal"`, `"hidden"`
- `"full"` = spinner + runtime display
- `"minimal"` = runtime display only (default)
When both are used together in `ChatInterface`, the `gr.Progress()` bar fights for position with the chat's streaming output, causing visual glitches.
### Current Implementation (`src/app.py`)
```python
async def research_agent(
message: str,
history: list[dict[str, Any]],
...
progress: gr.Progress = gr.Progress(), # <- ISSUE: Manual progress bar
) -> AsyncGenerator[str, None]:
...
if event.type == "started":
progress(0, desc="Starting research...") # <- Updates overlay
elif event.type == "progress":
progress(p, desc=event.message) # <- Conflicts with chat streaming
```
### Gradio Documentation
From [Gradio ChatInterface Docs](https://www.gradio.app/docs/gradio/chatinterface):
> `show_progress`: how to show the progress animation while event is running: 'full' shows a spinner which covers the output component area as well as a runtime display in the upper right corner, 'minimal' only shows the runtime display, 'hidden' shows no progress animation at all
From [GitHub Issue #5967](https://github.com/gradio-app/gradio/issues/5967):
> `gr.Progress` is "not integrated with ChatInterface or Chatbots" - known limitation.
## Impact
| Aspect | Impact |
|--------|--------|
| Functionality | None - app works correctly |
| UX | Visual confusion, looks unprofessional |
| Accessibility | May cause screen reader confusion |
## Proposed Solutions
### Option 1: Remove `gr.Progress()` - Use Chat Text Only (RECOMMENDED)
Remove the `gr.Progress()` parameter entirely and rely on our existing emoji status messages:
```python
async def research_agent(
message: str,
history: list[dict[str, Any]],
domain: str = "sexual_health",
api_key: str = "",
api_key_state: str = "",
# REMOVED: progress: gr.Progress = gr.Progress(),
) -> AsyncGenerator[str, None]:
...
# Keep emoji status updates in chat output
# ⏱️ **PROGRESS**: Round 1/5 (~3m 0s remaining)
# These are already being yielded to the chat
```
**Pros**:
- Simplest solution
- No CSS hacks
- Status is visible in chat history
- Works with ChatInterface's built-in progress
**Cons**:
- No visual progress bar (just text status)
### Option 2: Use `show_progress="full"` Parameter
Add explicit `show_progress` to ChatInterface and remove `gr.Progress()`:
```python
demo = gr.ChatInterface(
fn=research_agent,
title="🍆 DeepBoner",
show_progress="full", # Built-in spinner + runtime
...
)
```
**Pros**:
- Uses Gradio's intended mechanism
- Consistent with Gradio UX patterns
**Cons**:
- Less granular (no percentage, no custom desc)
### Option 3: Custom Progress Component with CSS (COMPLEX)
Wrap ChatInterface in `gr.Blocks` and add a separate `gr.HTML` progress bar outside the chat:
```python
with gr.Blocks() as demo:
progress_html = gr.HTML("<div id='custom-progress'></div>", visible=False)
chat = gr.ChatInterface(...)
# Update progress_html separately from chat
```
**Pros**:
- Full control over positioning
- Can match exact design requirements
**Cons**:
- Significant refactor required
- May break MCP server integration
- More moving parts = more bugs
### Option 4: Hybrid - Progress in `additional_inputs_accordion`
Place a separate `gr.Progress` component in a fixed position (e.g., accordion header):
```python
with gr.Blocks() as demo:
with gr.Row():
progress_bar = gr.Slider(0, 100, value=0, label="Progress", interactive=False)
chat = gr.ChatInterface(...)
```
**Pros**:
- Fixed position, no overlap
**Cons**:
- Requires `gr.Blocks` wrapper (breaks MCP?)
- Clunky UX
## Recommended Fix
**Option 1: Remove `gr.Progress()`, keep emoji status text**
Rationale:
1. Our emoji status updates (`⏱️ **PROGRESS**: Round 2/5`) already provide the information
2. `gr.Progress()` was never designed for ChatInterface
3. Removing it eliminates the positioning conflict entirely
4. ChatInterface's built-in `show_progress="minimal"` handles the spinner
## Implementation Plan
1. **Remove** `progress: gr.Progress = gr.Progress()` parameter from `research_agent()`
2. **Remove** all `progress(...)` calls in the function
3. **Keep** emoji status yields (`⏱️ **PROGRESS**: ...`)
4. **Optionally** add `show_progress="minimal"` to ChatInterface (already default)
5. **Test** on HuggingFace Spaces
## Testing
```bash
# Local test
uv run python -c "from src.app import create_demo; demo, _ = create_demo(); demo.launch()"
# Verify:
# 1. No floating progress bar
# 2. Emoji status updates visible in chat
# 3. ChatInterface spinner works as expected
```
## References
- [Gradio Progress Bars Guide](https://www.gradio.app/guides/progress-bars)
- [Gradio ChatInterface Docs](https://www.gradio.app/docs/gradio/chatinterface)
- [GitHub Issue #5967: Progress bar for ChatInterface](https://github.com/gradio-app/gradio/issues/5967)
- [GitHub Issue #5815: Customize the progress bar](https://github.com/gradio-app/gradio/issues/5815)
## Version Info
- Gradio: `>=6.0.0` (pyproject.toml constraint)
- ChatInterface: Streaming async generator mode
- MCP Server: Enabled
|