Spaces:
Running
Running
Commit
Β·
fcc601a
1
Parent(s):
7323f55
fix: repair Gradio accordion bug and cleanup env vars
Browse files- Unwrapped ChatInterface from gr.Blocks to fix settings accordion state (fixes P1_GRADIO_SETTINGS_CLEANUP).
- Updated .env.example with missing variables and removed dead ones.
- Updated documentation for the fix.
- .env.example +11 -7
- docs/brainstorming/01_PUBMED_IMPROVEMENTS.md +125 -0
- docs/bugs/P1_GRADIO_SETTINGS_CLEANUP.md +46 -98
- src/app.py +51 -63
.env.example
CHANGED
|
@@ -8,8 +8,16 @@ OPENAI_API_KEY=sk-your-key-here
|
|
| 8 |
ANTHROPIC_API_KEY=sk-ant-your-key-here
|
| 9 |
|
| 10 |
# Model names (optional - sensible defaults)
|
| 11 |
-
OPENAI_MODEL=gpt-
|
| 12 |
-
ANTHROPIC_MODEL=claude-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
|
| 14 |
# ============== HUGGINGFACE (FREE TIER) ==============
|
| 15 |
|
|
@@ -20,7 +28,7 @@ ANTHROPIC_MODEL=claude-sonnet-4-5-20250929
|
|
| 20 |
# WITH HF_TOKEN: Uses Llama 3.1 8B Instruct (requires accepting license)
|
| 21 |
#
|
| 22 |
# For HuggingFace Spaces deployment:
|
| 23 |
-
# Set this as a "Secret" in Space Settings
|
| 24 |
# Users/judges don't need their own token - the Space secret is used
|
| 25 |
#
|
| 26 |
HF_TOKEN=hf_your-token-here
|
|
@@ -36,9 +44,5 @@ LOG_LEVEL=INFO
|
|
| 36 |
# PubMed (optional - higher rate limits)
|
| 37 |
NCBI_API_KEY=your-ncbi-key-here
|
| 38 |
|
| 39 |
-
# Modal Sandbox (optional - for secure code execution)
|
| 40 |
-
MODAL_TOKEN_ID=ak-your-modal-token-id-here
|
| 41 |
-
MODAL_TOKEN_SECRET=your-modal-token-secret-here
|
| 42 |
-
|
| 43 |
# Vector Database (optional - for LlamaIndex RAG)
|
| 44 |
CHROMA_DB_PATH=./chroma_db
|
|
|
|
| 8 |
ANTHROPIC_API_KEY=sk-ant-your-key-here
|
| 9 |
|
| 10 |
# Model names (optional - sensible defaults)
|
| 11 |
+
OPENAI_MODEL=gpt-4-turbo
|
| 12 |
+
ANTHROPIC_MODEL=claude-3-5-sonnet-20240620
|
| 13 |
+
|
| 14 |
+
# ============== EMBEDDINGS ==============
|
| 15 |
+
|
| 16 |
+
# OpenAI Embedding Model (used if LLM_PROVIDER is openai and performing RAG/Embeddings)
|
| 17 |
+
OPENAI_EMBEDDING_MODEL=text-embedding-3-small
|
| 18 |
+
|
| 19 |
+
# Local Embedding Model (used for local/offline embeddings)
|
| 20 |
+
LOCAL_EMBEDDING_MODEL=sentence-transformers/all-MiniLM-L6-v2
|
| 21 |
|
| 22 |
# ============== HUGGINGFACE (FREE TIER) ==============
|
| 23 |
|
|
|
|
| 28 |
# WITH HF_TOKEN: Uses Llama 3.1 8B Instruct (requires accepting license)
|
| 29 |
#
|
| 30 |
# For HuggingFace Spaces deployment:
|
| 31 |
+
# Set this as a "Secret" in Space Settings -> Variables and secrets
|
| 32 |
# Users/judges don't need their own token - the Space secret is used
|
| 33 |
#
|
| 34 |
HF_TOKEN=hf_your-token-here
|
|
|
|
| 44 |
# PubMed (optional - higher rate limits)
|
| 45 |
NCBI_API_KEY=your-ncbi-key-here
|
| 46 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 47 |
# Vector Database (optional - for LlamaIndex RAG)
|
| 48 |
CHROMA_DB_PATH=./chroma_db
|
docs/brainstorming/01_PUBMED_IMPROVEMENTS.md
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# PubMed Tool: Current State & Future Improvements
|
| 2 |
+
|
| 3 |
+
**Status**: Currently Implemented
|
| 4 |
+
**Priority**: High (Core Data Source)
|
| 5 |
+
|
| 6 |
+
---
|
| 7 |
+
|
| 8 |
+
## Current Implementation
|
| 9 |
+
|
| 10 |
+
### What We Have (`src/tools/pubmed.py`)
|
| 11 |
+
|
| 12 |
+
- Basic E-utilities search via `esearch.fcgi` and `efetch.fcgi`
|
| 13 |
+
- Query preprocessing (strips question words, expands synonyms)
|
| 14 |
+
- Returns: title, abstract, authors, journal, PMID
|
| 15 |
+
- Rate limiting: None implemented (relying on NCBI defaults)
|
| 16 |
+
|
| 17 |
+
### Current Limitations
|
| 18 |
+
|
| 19 |
+
1. **No Full-Text Access**: Only retrieves abstracts, not full paper text
|
| 20 |
+
2. **No Rate Limiting**: Risk of being blocked by NCBI
|
| 21 |
+
3. **No BioC Format**: Missing structured full-text extraction
|
| 22 |
+
4. **No Figure Retrieval**: No supplementary materials access
|
| 23 |
+
5. **No PMC Integration**: Missing open-access full-text via PMC
|
| 24 |
+
|
| 25 |
+
---
|
| 26 |
+
|
| 27 |
+
## Reference Implementation (DeepCritical Reference Repo)
|
| 28 |
+
|
| 29 |
+
The reference repo at `reference_repos/DeepCritical/DeepResearch/src/tools/bioinformatics_tools.py` has a more sophisticated implementation:
|
| 30 |
+
|
| 31 |
+
### Features We're Missing
|
| 32 |
+
|
| 33 |
+
```python
|
| 34 |
+
# Rate limiting (lines 47-50)
|
| 35 |
+
from limits import parse
|
| 36 |
+
from limits.storage import MemoryStorage
|
| 37 |
+
from limits.strategies import MovingWindowRateLimiter
|
| 38 |
+
|
| 39 |
+
storage = MemoryStorage()
|
| 40 |
+
limiter = MovingWindowRateLimiter(storage)
|
| 41 |
+
rate_limit = parse("3/second") # NCBI allows 3/sec without API key, 10/sec with
|
| 42 |
+
|
| 43 |
+
# Full-text via BioC format (lines 108-120)
|
| 44 |
+
def _get_fulltext(pmid: int) -> dict[str, Any] | None:
|
| 45 |
+
pmid_url = f"https://www.ncbi.nlm.nih.gov/research/bionlp/RESTful/pmcoa.cgi/BioC_json/{pmid}/unicode"
|
| 46 |
+
# Returns structured JSON with full text for open-access papers
|
| 47 |
+
|
| 48 |
+
# Figure retrieval via Europe PMC (lines 123-149)
|
| 49 |
+
def _get_figures(pmcid: str) -> dict[str, str]:
|
| 50 |
+
suppl_url = f"https://www.ebi.ac.uk/europepmc/webservices/rest/{pmcid}/supplementaryFiles"
|
| 51 |
+
# Returns base64-encoded images from supplementary materials
|
| 52 |
+
```
|
| 53 |
+
|
| 54 |
+
---
|
| 55 |
+
|
| 56 |
+
## Recommended Improvements
|
| 57 |
+
|
| 58 |
+
### Phase 1: Rate Limiting (Critical)
|
| 59 |
+
|
| 60 |
+
```python
|
| 61 |
+
# Add to src/tools/pubmed.py
|
| 62 |
+
from limits import parse
|
| 63 |
+
from limits.storage import MemoryStorage
|
| 64 |
+
from limits.strategies import MovingWindowRateLimiter
|
| 65 |
+
|
| 66 |
+
storage = MemoryStorage()
|
| 67 |
+
limiter = MovingWindowRateLimiter(storage)
|
| 68 |
+
|
| 69 |
+
# With NCBI_API_KEY: 10/sec, without: 3/sec
|
| 70 |
+
def get_rate_limit():
|
| 71 |
+
if settings.ncbi_api_key:
|
| 72 |
+
return parse("10/second")
|
| 73 |
+
return parse("3/second")
|
| 74 |
+
```
|
| 75 |
+
|
| 76 |
+
**Dependencies**: `pip install limits`
|
| 77 |
+
|
| 78 |
+
### Phase 2: Full-Text Retrieval
|
| 79 |
+
|
| 80 |
+
```python
|
| 81 |
+
async def get_fulltext(pmid: str) -> str | None:
|
| 82 |
+
"""Get full text for open-access papers via BioC API."""
|
| 83 |
+
url = f"https://www.ncbi.nlm.nih.gov/research/bionlp/RESTful/pmcoa.cgi/BioC_json/{pmid}/unicode"
|
| 84 |
+
# Only works for PMC papers (open access)
|
| 85 |
+
```
|
| 86 |
+
|
| 87 |
+
### Phase 3: PMC ID Resolution
|
| 88 |
+
|
| 89 |
+
```python
|
| 90 |
+
async def get_pmc_id(pmid: str) -> str | None:
|
| 91 |
+
"""Convert PMID to PMCID for full-text access."""
|
| 92 |
+
url = f"https://www.ncbi.nlm.nih.gov/pmc/utils/idconv/v1.0/?ids={pmid}&format=json"
|
| 93 |
+
```
|
| 94 |
+
|
| 95 |
+
---
|
| 96 |
+
|
| 97 |
+
## Python Libraries to Consider
|
| 98 |
+
|
| 99 |
+
| Library | Purpose | Notes |
|
| 100 |
+
|---------|---------|-------|
|
| 101 |
+
| [Biopython](https://biopython.org/) | `Bio.Entrez` module | Official, well-maintained |
|
| 102 |
+
| [PyMed](https://pypi.org/project/pymed/) | PubMed wrapper | Simpler API, less control |
|
| 103 |
+
| [metapub](https://pypi.org/project/metapub/) | Full-featured | Tested on 1/3 of PubMed |
|
| 104 |
+
| [limits](https://pypi.org/project/limits/) | Rate limiting | Used by reference repo |
|
| 105 |
+
|
| 106 |
+
---
|
| 107 |
+
|
| 108 |
+
## API Endpoints Reference
|
| 109 |
+
|
| 110 |
+
| Endpoint | Purpose | Rate Limit |
|
| 111 |
+
|----------|---------|------------|
|
| 112 |
+
| `esearch.fcgi` | Search for PMIDs | 3/sec (10 with key) |
|
| 113 |
+
| `efetch.fcgi` | Fetch metadata | 3/sec (10 with key) |
|
| 114 |
+
| `esummary.fcgi` | Quick metadata | 3/sec (10 with key) |
|
| 115 |
+
| `pmcoa.cgi/BioC_json` | Full text (PMC only) | Unknown |
|
| 116 |
+
| `idconv/v1.0` | PMID β PMCID | Unknown |
|
| 117 |
+
|
| 118 |
+
---
|
| 119 |
+
|
| 120 |
+
## Sources
|
| 121 |
+
|
| 122 |
+
- [PubMed E-utilities Documentation](https://www.ncbi.nlm.nih.gov/books/NBK25501/)
|
| 123 |
+
- [NCBI BioC API](https://www.ncbi.nlm.nih.gov/research/bionlp/APIs/)
|
| 124 |
+
- [Searching PubMed with Python](https://marcobonzanini.com/2015/01/12/searching-pubmed-with-python/)
|
| 125 |
+
- [PyMed on PyPI](https://pypi.org/project/pymed/)
|
docs/bugs/P1_GRADIO_SETTINGS_CLEANUP.md
CHANGED
|
@@ -3,131 +3,79 @@
|
|
| 3 |
**Priority**: P1 (UX Bug)
|
| 4 |
**Status**: OPEN
|
| 5 |
**Date**: 2025-11-27
|
|
|
|
| 6 |
|
| 7 |
---
|
| 8 |
|
| 9 |
-
##
|
| 10 |
|
| 11 |
-
The "Settings" accordion in the Gradio UI
|
| 12 |
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
|
| 17 |
-
|
| 18 |
|
| 19 |
-
|
| 20 |
-
> "Is there any subsequent plan to support gr.ChatInterface inheritance under gr.Block()? Currently using accordion is not working well."
|
| 21 |
|
| 22 |
-
**
|
| 23 |
-
|
| 24 |
-
with gr.Blocks(...) as demo: # <-- Using gr.Blocks wrapper
|
| 25 |
-
gr.ChatInterface(
|
| 26 |
-
...
|
| 27 |
-
additional_inputs_accordion=gr.Accordion(label="βοΈ Settings", open=False),
|
| 28 |
-
additional_inputs=[...],
|
| 29 |
-
)
|
| 30 |
-
```
|
| 31 |
|
| 32 |
-
|
| 33 |
|
| 34 |
---
|
| 35 |
|
| 36 |
-
##
|
| 37 |
|
| 38 |
-
|
| 39 |
-
- Content does NOT hide when collapsed
|
| 40 |
-
- Same behavior in local dev and HuggingFace Spaces
|
| 41 |
-
|
| 42 |
-
---
|
| 43 |
|
| 44 |
-
|
| 45 |
|
| 46 |
-
|
| 47 |
|
| 48 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
|
|
|
|
| 50 |
```python
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
additional_inputs=[...],
|
| 58 |
-
)
|
| 59 |
```
|
| 60 |
|
| 61 |
-
|
| 62 |
-
**Cons**: Less control over layout, no custom header/footer
|
| 63 |
-
|
| 64 |
-
### Option 2: Manual Accordion Outside ChatInterface
|
| 65 |
-
|
| 66 |
-
Move settings outside `ChatInterface` into a proper `gr.Accordion`:
|
| 67 |
-
|
| 68 |
```python
|
| 69 |
-
|
| 70 |
-
gr.
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
chatbot = gr.Chatbot()
|
| 78 |
-
msg = gr.Textbox(label="Ask a research question")
|
| 79 |
-
|
| 80 |
-
msg.submit(research_agent, [msg, chatbot, mode, api_key, provider], chatbot)
|
| 81 |
-
```
|
| 82 |
-
|
| 83 |
-
**Pros**: Full control, accordion works
|
| 84 |
-
**Cons**: More code, lose ChatInterface conveniences (examples, etc.)
|
| 85 |
-
|
| 86 |
-
### Option 3: Wait for Gradio Fix
|
| 87 |
-
|
| 88 |
-
Gradio added `.expand()` and `.collapse()` events in recent versions. Upgrading might help.
|
| 89 |
-
|
| 90 |
-
**Check current version**:
|
| 91 |
-
```bash
|
| 92 |
-
pip show gradio | grep Version
|
| 93 |
-
```
|
| 94 |
-
|
| 95 |
-
**Upgrade**:
|
| 96 |
-
```bash
|
| 97 |
-
pip install --upgrade gradio
|
| 98 |
```
|
| 99 |
|
| 100 |
---
|
| 101 |
|
| 102 |
-
##
|
| 103 |
-
|
| 104 |
-
**Option 1** (Remove gr.Blocks) is cleanest if we can live without custom header/footer.
|
| 105 |
-
|
| 106 |
-
If header/footer needed, **Option 2** gives working accordion at cost of more code.
|
| 107 |
-
|
| 108 |
-
---
|
| 109 |
-
|
| 110 |
-
## Files to Modify
|
| 111 |
-
|
| 112 |
-
| File | Change |
|
| 113 |
-
|------|--------|
|
| 114 |
-
| `src/app.py` | Restructure UI per chosen option |
|
| 115 |
-
| `pyproject.toml` | Possibly upgrade Gradio version |
|
| 116 |
-
|
| 117 |
-
---
|
| 118 |
-
|
| 119 |
-
## Test Plan
|
| 120 |
|
| 121 |
-
1.
|
| 122 |
-
2.
|
| 123 |
-
3.
|
| 124 |
-
|
| 125 |
-
|
|
|
|
|
|
|
| 126 |
|
| 127 |
---
|
| 128 |
|
| 129 |
-
##
|
| 130 |
|
| 131 |
-
-
|
| 132 |
-
-
|
| 133 |
-
- [Gradio Accordion Docs](https://www.gradio.app/docs/gradio/accordion)
|
|
|
|
| 3 |
**Priority**: P1 (UX Bug)
|
| 4 |
**Status**: OPEN
|
| 5 |
**Date**: 2025-11-27
|
| 6 |
+
**Target Component**: `src/app.py`
|
| 7 |
|
| 8 |
---
|
| 9 |
|
| 10 |
+
## 1. Problem Description
|
| 11 |
|
| 12 |
+
The "Settings" accordion in the Gradio UI (containing Orchestrator Mode, API Key, Provider) fails to collapse, even when configured with `open=False`. It remains permanently expanded, cluttering the interface and obscuring the chat history.
|
| 13 |
|
| 14 |
+
### Symptoms
|
| 15 |
+
- Accordion arrow toggles visually, but content remains visible.
|
| 16 |
+
- Occurs in both local development (`uv run src/app.py`) and HuggingFace Spaces.
|
| 17 |
|
| 18 |
+
---
|
| 19 |
|
| 20 |
+
## 2. Root Cause Analysis
|
|
|
|
| 21 |
|
| 22 |
+
**Definitive Cause**: Nested `Blocks` Context Bug.
|
| 23 |
+
`gr.ChatInterface` is itself a high-level abstraction that creates a `gr.Blocks` context. Wrapping `gr.ChatInterface` inside an external `with gr.Blocks():` context causes event listener conflicts, specifically breaking the JavaScript state management for `additional_inputs_accordion`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
|
| 25 |
+
**Reference**: [Gradio Issue #8861](https://github.com/gradio-app/gradio/issues/8861) confirms that `additional_inputs_accordion` malfunctions when `ChatInterface` is not the top-level block.
|
| 26 |
|
| 27 |
---
|
| 28 |
|
| 29 |
+
## 3. Solution Strategy: "The Unwrap Fix"
|
| 30 |
|
| 31 |
+
We will remove the redundant `gr.Blocks` wrapper. This restores the native behavior of `ChatInterface`, ensuring the accordion respects `open=False`.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
|
| 33 |
+
### Implementation Plan
|
| 34 |
|
| 35 |
+
**Refactor `src/app.py` / `create_demo()`**:
|
| 36 |
|
| 37 |
+
1. **Remove** the `with gr.Blocks() as demo:` context manager.
|
| 38 |
+
2. **Instantiate** `gr.ChatInterface` directly as the `demo` object.
|
| 39 |
+
3. **Migrate UI Elements**:
|
| 40 |
+
* **Header**: Move the H1/Title text into the `title` parameter of `ChatInterface`.
|
| 41 |
+
* **Footer**: Move the footer text ("MCP Server Active...") into the `description` parameter. `ChatInterface` supports Markdown in `description`, making it the ideal place for static info below the title but above the chat.
|
| 42 |
|
| 43 |
+
### Before (Buggy)
|
| 44 |
```python
|
| 45 |
+
def create_demo():
|
| 46 |
+
with gr.Blocks() as demo: # <--- CAUSE OF BUG
|
| 47 |
+
gr.Markdown("# Title")
|
| 48 |
+
gr.ChatInterface(..., additional_inputs_accordion=gr.Accordion(open=False))
|
| 49 |
+
gr.Markdown("Footer")
|
| 50 |
+
return demo
|
|
|
|
|
|
|
| 51 |
```
|
| 52 |
|
| 53 |
+
### After (Correct)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 54 |
```python
|
| 55 |
+
def create_demo():
|
| 56 |
+
return gr.ChatInterface( # <--- FIX: Top-level component
|
| 57 |
+
...,
|
| 58 |
+
title="𧬠DeepCritical",
|
| 59 |
+
description="*AI-Powered Drug Repurposing Agent...*\n\n---\n**MCP Server Active**...",
|
| 60 |
+
additional_inputs_accordion=gr.Accordion(label="βοΈ Settings", open=False)
|
| 61 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 62 |
```
|
| 63 |
|
| 64 |
---
|
| 65 |
|
| 66 |
+
## 4. Validation
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 67 |
|
| 68 |
+
1. **Run**: `uv run python src/app.py`
|
| 69 |
+
2. **Check**: Open `http://localhost:7860`
|
| 70 |
+
3. **Verify**:
|
| 71 |
+
* Settings accordion starts **COLLAPSED**.
|
| 72 |
+
* Header title ("DeepCritical") is visible.
|
| 73 |
+
* Footer text ("MCP Server Active") is visible in the description area.
|
| 74 |
+
* Chat functionality works (Magentic/Simple modes).
|
| 75 |
|
| 76 |
---
|
| 77 |
|
| 78 |
+
## 5. Constraints & Notes
|
| 79 |
|
| 80 |
+
- **Layout**: We lose the ability to place arbitrary elements *below* the chat box (footer will move to top, under title), but this is an acceptable trade-off for a working UI.
|
| 81 |
+
- **CSS**: `ChatInterface` handles its own CSS; any custom class styling from the previous footer will be standardized to the description text style.
|
|
|
src/app.py
CHANGED
|
@@ -193,71 +193,59 @@ def create_demo() -> Any:
|
|
| 193 |
Returns:
|
| 194 |
Configured Gradio Blocks interface with MCP server enabled
|
| 195 |
"""
|
| 196 |
-
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
| 201 |
-
"
|
| 202 |
-
"
|
| 203 |
-
|
| 204 |
-
|
| 205 |
-
|
| 206 |
-
|
| 207 |
-
|
| 208 |
-
|
| 209 |
-
|
| 210 |
-
|
| 211 |
-
|
| 212 |
-
|
| 213 |
-
"",
|
| 214 |
-
"openai",
|
| 215 |
-
],
|
| 216 |
-
[
|
| 217 |
-
"Is metformin effective for treating cancer?",
|
| 218 |
-
"simple",
|
| 219 |
-
"",
|
| 220 |
-
"openai",
|
| 221 |
-
],
|
| 222 |
-
[
|
| 223 |
-
"What medications show promise for Long COVID treatment?",
|
| 224 |
-
"simple",
|
| 225 |
-
"",
|
| 226 |
-
"openai",
|
| 227 |
-
],
|
| 228 |
],
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
label="Orchestrator Mode",
|
| 235 |
-
info="Simple: Linear | Magentic: Multi-Agent (OpenAI)",
|
| 236 |
-
),
|
| 237 |
-
gr.Textbox(
|
| 238 |
-
label="π API Key (Optional - BYOK)",
|
| 239 |
-
placeholder="sk-... or sk-ant-...",
|
| 240 |
-
type="password",
|
| 241 |
-
info="Enter your own API key. Never stored.",
|
| 242 |
-
),
|
| 243 |
-
gr.Radio(
|
| 244 |
-
choices=["openai", "anthropic"],
|
| 245 |
-
value="openai",
|
| 246 |
-
label="API Provider",
|
| 247 |
-
info="Select the provider for your API key",
|
| 248 |
-
),
|
| 249 |
],
|
| 250 |
-
|
| 251 |
-
|
| 252 |
-
|
| 253 |
-
|
| 254 |
-
|
| 255 |
-
|
| 256 |
-
|
| 257 |
-
|
| 258 |
-
|
| 259 |
-
|
| 260 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 261 |
|
| 262 |
return demo
|
| 263 |
|
|
|
|
| 193 |
Returns:
|
| 194 |
Configured Gradio Blocks interface with MCP server enabled
|
| 195 |
"""
|
| 196 |
+
# 1. Unwrapped ChatInterface (Fixes Accordion Bug)
|
| 197 |
+
demo = gr.ChatInterface(
|
| 198 |
+
fn=research_agent,
|
| 199 |
+
title="𧬠DeepCritical",
|
| 200 |
+
description=(
|
| 201 |
+
"*AI-Powered Drug Repurposing Agent β searches PubMed, "
|
| 202 |
+
"ClinicalTrials.gov & Europe PMC*\n\n"
|
| 203 |
+
"---\n"
|
| 204 |
+
"*Research tool only β not for medical advice.* \n"
|
| 205 |
+
"**MCP Server Active**: Connect Claude Desktop to `/gradio_api/mcp/`"
|
| 206 |
+
),
|
| 207 |
+
examples=[
|
| 208 |
+
[
|
| 209 |
+
"What drugs could be repurposed for Alzheimer's disease?",
|
| 210 |
+
"simple",
|
| 211 |
+
"",
|
| 212 |
+
"openai",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 213 |
],
|
| 214 |
+
[
|
| 215 |
+
"Is metformin effective for treating cancer?",
|
| 216 |
+
"simple",
|
| 217 |
+
"",
|
| 218 |
+
"openai",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 219 |
],
|
| 220 |
+
[
|
| 221 |
+
"What medications show promise for Long COVID treatment?",
|
| 222 |
+
"simple",
|
| 223 |
+
"",
|
| 224 |
+
"openai",
|
| 225 |
+
],
|
| 226 |
+
],
|
| 227 |
+
additional_inputs_accordion=gr.Accordion(label="βοΈ Settings", open=False),
|
| 228 |
+
additional_inputs=[
|
| 229 |
+
gr.Radio(
|
| 230 |
+
choices=["simple", "magentic"],
|
| 231 |
+
value="simple",
|
| 232 |
+
label="Orchestrator Mode",
|
| 233 |
+
info="Simple: Linear | Magentic: Multi-Agent (OpenAI)",
|
| 234 |
+
),
|
| 235 |
+
gr.Textbox(
|
| 236 |
+
label="π API Key (Optional - BYOK)",
|
| 237 |
+
placeholder="sk-... or sk-ant-...",
|
| 238 |
+
type="password",
|
| 239 |
+
info="Enter your own API key. Never stored.",
|
| 240 |
+
),
|
| 241 |
+
gr.Radio(
|
| 242 |
+
choices=["openai", "anthropic"],
|
| 243 |
+
value="openai",
|
| 244 |
+
label="API Provider",
|
| 245 |
+
info="Select the provider for your API key",
|
| 246 |
+
),
|
| 247 |
+
],
|
| 248 |
+
)
|
| 249 |
|
| 250 |
return demo
|
| 251 |
|