Spaces:
Sleeping
Add Tavily API key UI configuration and update documentation
Browse filesMajor enhancements:
- Add runtime Tavily API key configuration via UI sidebar (no restart required)
- Refactor agent creation to use factory pattern for dynamic configuration
- Add example prompts display in UI to help users get started
- Update README with current code structure and new features
- Keep data directory structure with .gitkeep
Technical changes:
- Convert MCP server configs to factory functions for dynamic instantiation
- Change agent initialization from singleton to factory pattern
- Add update_api_key() method to CustomGradioUI for runtime reconfiguration
- Increase max_steps from 6 to 10 for more complex reasoning tasks
- Use get_token() from huggingface_hub for cleaner token management
- Format code with ruff
Documentation updates:
- Update all line number references in README architecture section
- Document new Tavily UI configuration option as recommended approach
- Clarify that Tavily API key is now optional (can be set via UI or env var)
- Update CLI command from huggingface-cli to hf auth login
- Fix repository clone URL to use MCP-1st-Birthday namespace
- Update acknowledgments from DuckDuckGo to Tavily search
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- .gitignore +1 -0
- README.md +40 -17
- app.py +58 -31
- data/.gitkeep +0 -0
- my_ui.py +56 -2
|
@@ -80,3 +80,4 @@ dmypy.json
|
|
| 80 |
|
| 81 |
# Project Files
|
| 82 |
data/*
|
|
|
|
|
|
| 80 |
|
| 81 |
# Project Files
|
| 82 |
data/*
|
| 83 |
+
!data/.gitkeep
|
|
@@ -41,36 +41,44 @@ An agentic deep research application powered by [smolagents](https://huggingface
|
|
| 41 |
|
| 42 |
DeepSpaceSearch consists of two main Python files working together:
|
| 43 |
|
| 44 |
-
### MCP Integration (`app.py:
|
|
|
|
| 45 |
- **MCP Servers**: Three integrated MCP servers for extended capabilities
|
| 46 |
-
- **Gradio Upload MCP** (`
|
| 47 |
-
- **Sa2VA Image Analysis** (`
|
| 48 |
-
- **Tavily Search** (`
|
| 49 |
- **`MCPClient`**: Manages MCP server connections and provides tools to the agent
|
| 50 |
-
- **
|
|
|
|
|
|
|
| 51 |
|
| 52 |
-
|
| 53 |
-
- **`CodeAgent`**: Core reasoning engine from smolagents (line 118-133)
|
| 54 |
- Orchestrates multi-step tasks with planning intervals
|
| 55 |
-
- Configuration: max_steps=
|
| 56 |
- Loads custom instructions from `instructions.txt` for agent behavior guidance
|
| 57 |
- Additional authorized imports enabled for code execution flexibility
|
| 58 |
|
| 59 |
-
### Tool Ecosystem (`app.py:
|
|
|
|
| 60 |
- **`image_generation_tool`**: Remote tool from HF Space (black-forest-labs/FLUX.1-schnell)
|
| 61 |
- **MCP Tools**: Dynamically loaded from MCP servers (Tavily search, image analysis, file upload)
|
| 62 |
- **`FinalAnswerTool`**: Required for agent to return structured responses
|
| 63 |
- **Base Tools Disabled**: Custom tool selection for optimized performance
|
| 64 |
|
| 65 |
-
### Model Layer (`app.py:
|
|
|
|
| 66 |
- **`InferenceClientModel`**: Wrapper around Hugging Face Inference API
|
| 67 |
- Default model: `Qwen/Qwen2.5-Coder-32B-Instruct` (configurable via `HF_MODEL_ID` env var)
|
| 68 |
- Parameters: max_tokens=2096, temperature=0.5, top_p=0.95
|
|
|
|
|
|
|
|
|
|
| 69 |
|
| 70 |
-
### Custom UI (`my_ui.py:7-124`)
|
| 71 |
- **`CustomGradioUI`**: Extends smolagents' `GradioUI` with custom features
|
| 72 |
- **Sidebar Layout**: Text input, submit button, and file upload in sidebar
|
| 73 |
- **File Upload**: Supports multiple file types with custom allowed extensions
|
|
|
|
|
|
|
| 74 |
- **Ocean Theme**: Professional blue gradient interface
|
| 75 |
- **Streaming Chat**: Real-time display of agent reasoning with LaTeX support
|
| 76 |
|
|
@@ -88,7 +96,7 @@ DeepSpaceSearch consists of two main Python files working together:
|
|
| 88 |
|
| 89 |
```bash
|
| 90 |
# Clone the repository
|
| 91 |
-
git clone https://huggingface.co/spaces/
|
| 92 |
cd DeepSpaceSearch
|
| 93 |
|
| 94 |
# Create and activate virtual environment
|
|
@@ -108,7 +116,7 @@ pip install -r requirements.txt
|
|
| 108 |
The easiest and most secure way to authenticate locally is using the Hugging Face CLI:
|
| 109 |
|
| 110 |
```bash
|
| 111 |
-
|
| 112 |
```
|
| 113 |
|
| 114 |
This will prompt you to paste your HF token (get one at <https://huggingface.co/settings/tokens> with `inference-api` scope) and securely store it in `~/.cache/huggingface/token`.
|
|
@@ -121,10 +129,17 @@ If you prefer environment variables, create a `.env` file:
|
|
| 121 |
HF_TOKEN=hf_... # Your HF token with inference-api scope
|
| 122 |
```
|
| 123 |
|
| 124 |
-
**2. Tavily API Key (
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
|
| 126 |
-
|
|
|
|
|
|
|
| 127 |
|
|
|
|
| 128 |
```bash
|
| 129 |
# Add to your .env file
|
| 130 |
TAVILY_API_KEY=tvly-... # Your Tavily API key
|
|
@@ -143,6 +158,8 @@ Example `.env` with all variables:
|
|
| 143 |
```env
|
| 144 |
# Required
|
| 145 |
HF_TOKEN=hf_...
|
|
|
|
|
|
|
| 146 |
TAVILY_API_KEY=tvly-...
|
| 147 |
|
| 148 |
# Optional: Use a different model
|
|
@@ -155,7 +172,7 @@ HF_MODEL_ID=meta-llama/Llama-3.3-70B-Instruct
|
|
| 155 |
python app.py
|
| 156 |
```
|
| 157 |
|
| 158 |
-
The application will launch at http://127.0.0.1:7860
|
| 159 |
|
| 160 |
## Usage
|
| 161 |
|
|
@@ -272,6 +289,7 @@ your_tool = Tool.from_space(
|
|
| 272 |
## TODO
|
| 273 |
|
| 274 |
### MCP Server Integration
|
|
|
|
| 275 |
- [x] **Integrate MCP servers using smolagents** ✅
|
| 276 |
- Implemented three MCP servers: Tavily search, Sa2VA image analysis, and Gradio file upload
|
| 277 |
- Using both stdio and HTTP-based MCP transports
|
|
@@ -289,6 +307,7 @@ your_tool = Tool.from_space(
|
|
| 289 |
- Social media trend analysis
|
| 290 |
|
| 291 |
### Enhanced Research Capabilities
|
|
|
|
| 292 |
- [ ] **Multi-source verification**
|
| 293 |
- Cross-reference information across multiple sources
|
| 294 |
- Add confidence scoring for research findings
|
|
@@ -305,6 +324,7 @@ your_tool = Tool.from_space(
|
|
| 305 |
- Export to PDF/DOCX
|
| 306 |
|
| 307 |
### Tool Improvements
|
|
|
|
| 308 |
- [ ] **Add calculator tool** for mathematical queries
|
| 309 |
- [ ] **Add code execution tool** for running Python snippets
|
| 310 |
- [ ] **Add data visualization tool** for charts and graphs
|
|
@@ -312,6 +332,7 @@ your_tool = Tool.from_space(
|
|
| 312 |
- Implemented with support for PDF, DOCX, TXT, MD, JSON, CSV, and images
|
| 313 |
|
| 314 |
### UI/UX Enhancements
|
|
|
|
| 315 |
- [ ] **Add conversation history** persistence
|
| 316 |
- [ ] **Add export chat** functionality
|
| 317 |
- [ ] **Add model selection** dropdown for different LLMs
|
|
@@ -319,12 +340,14 @@ your_tool = Tool.from_space(
|
|
| 319 |
- [ ] **Dark mode** support
|
| 320 |
|
| 321 |
### Performance & Reliability
|
|
|
|
| 322 |
- [ ] **Add caching** for repeated searches
|
| 323 |
- [ ] **Implement retry logic** for failed API calls
|
| 324 |
- [ ] **Add rate limiting** dashboard
|
| 325 |
- [ ] **Optimize token usage** with streaming truncation
|
| 326 |
|
| 327 |
### Testing & Documentation
|
|
|
|
| 328 |
- [ ] **Add unit tests** for core functions
|
| 329 |
- [ ] **Add integration tests** for tools
|
| 330 |
- [ ] **Create video demo** of capabilities
|
|
@@ -343,4 +366,4 @@ Apache 2.0 - See LICENSE file for details
|
|
| 343 |
- Built with [smolagents](https://huggingface.co/docs/smolagents) by Hugging Face
|
| 344 |
- UI powered by [Gradio](https://gradio.app)
|
| 345 |
- Image generation by [FLUX.1-schnell](https://huggingface.co/black-forest-labs/FLUX.1-schnell)
|
| 346 |
-
- Search powered by [
|
|
|
|
| 41 |
|
| 42 |
DeepSpaceSearch consists of two main Python files working together:
|
| 43 |
|
| 44 |
+
### MCP Integration (`app.py:57-96`)
|
| 45 |
+
|
| 46 |
- **MCP Servers**: Three integrated MCP servers for extended capabilities
|
| 47 |
+
- **Gradio Upload MCP** (`get_upload_files_to_gradio_server`): Uploads files to Gradio Space for processing
|
| 48 |
+
- **Sa2VA Image Analysis** (`get_image_analysis_mcp`): Visual question answering and image segmentation
|
| 49 |
+
- **Tavily Search** (`get_tavily_search_mcp`): High-quality web search API (optional, requires API key)
|
| 50 |
- **`MCPClient`**: Manages MCP server connections and provides tools to the agent
|
| 51 |
+
- **Dynamic Agent Creation**: Agent factory function allows runtime API key configuration
|
| 52 |
+
|
| 53 |
+
### Agent System (`app.py:99-157`)
|
| 54 |
|
| 55 |
+
- **`CodeAgent`**: Core reasoning engine from smolagents (line 133-148)
|
|
|
|
| 56 |
- Orchestrates multi-step tasks with planning intervals
|
| 57 |
+
- Configuration: max_steps=10, verbosity_level=1, planning_interval=3
|
| 58 |
- Loads custom instructions from `instructions.txt` for agent behavior guidance
|
| 59 |
- Additional authorized imports enabled for code execution flexibility
|
| 60 |
|
| 61 |
+
### Tool Ecosystem (`app.py:38-42, 136-142`)
|
| 62 |
+
|
| 63 |
- **`image_generation_tool`**: Remote tool from HF Space (black-forest-labs/FLUX.1-schnell)
|
| 64 |
- **MCP Tools**: Dynamically loaded from MCP servers (Tavily search, image analysis, file upload)
|
| 65 |
- **`FinalAnswerTool`**: Required for agent to return structured responses
|
| 66 |
- **Base Tools Disabled**: Custom tool selection for optimized performance
|
| 67 |
|
| 68 |
+
### Model Layer (`app.py:118-125`)
|
| 69 |
+
|
| 70 |
- **`InferenceClientModel`**: Wrapper around Hugging Face Inference API
|
| 71 |
- Default model: `Qwen/Qwen2.5-Coder-32B-Instruct` (configurable via `HF_MODEL_ID` env var)
|
| 72 |
- Parameters: max_tokens=2096, temperature=0.5, top_p=0.95
|
| 73 |
+
- Token authentication via `get_token()` from huggingface_hub
|
| 74 |
+
|
| 75 |
+
### Custom UI (`my_ui.py:7-176`)
|
| 76 |
|
|
|
|
| 77 |
- **`CustomGradioUI`**: Extends smolagents' `GradioUI` with custom features
|
| 78 |
- **Sidebar Layout**: Text input, submit button, and file upload in sidebar
|
| 79 |
- **File Upload**: Supports multiple file types with custom allowed extensions
|
| 80 |
+
- **Tavily API Key Input**: Runtime configuration of Tavily search without environment variables
|
| 81 |
+
- **Examples Display**: Pre-configured example prompts to help users get started
|
| 82 |
- **Ocean Theme**: Professional blue gradient interface
|
| 83 |
- **Streaming Chat**: Real-time display of agent reasoning with LaTeX support
|
| 84 |
|
|
|
|
| 96 |
|
| 97 |
```bash
|
| 98 |
# Clone the repository
|
| 99 |
+
git clone https://huggingface.co/spaces/MCP-1st-Birthday/DeepSpaceSearch
|
| 100 |
cd DeepSpaceSearch
|
| 101 |
|
| 102 |
# Create and activate virtual environment
|
|
|
|
| 116 |
The easiest and most secure way to authenticate locally is using the Hugging Face CLI:
|
| 117 |
|
| 118 |
```bash
|
| 119 |
+
hf auth login
|
| 120 |
```
|
| 121 |
|
| 122 |
This will prompt you to paste your HF token (get one at <https://huggingface.co/settings/tokens> with `inference-api` scope) and securely store it in `~/.cache/huggingface/token`.
|
|
|
|
| 129 |
HF_TOKEN=hf_... # Your HF token with inference-api scope
|
| 130 |
```
|
| 131 |
|
| 132 |
+
**2. Tavily API Key (Optional for Web Search)**
|
| 133 |
+
|
| 134 |
+
DeepSpaceSearch uses Tavily for high-quality web search via MCP. Get a free API key at <https://tavily.com>.
|
| 135 |
+
|
| 136 |
+
You can configure Tavily in two ways:
|
| 137 |
|
| 138 |
+
**Option A: Via the UI (Recommended)**
|
| 139 |
+
- Simply enter your API key in the "Tavily API Key" field in the sidebar when using the application
|
| 140 |
+
- No need to set environment variables or restart the app
|
| 141 |
|
| 142 |
+
**Option B: Via Environment Variable**
|
| 143 |
```bash
|
| 144 |
# Add to your .env file
|
| 145 |
TAVILY_API_KEY=tvly-... # Your Tavily API key
|
|
|
|
| 158 |
```env
|
| 159 |
# Required
|
| 160 |
HF_TOKEN=hf_...
|
| 161 |
+
|
| 162 |
+
# Optional: Configure Tavily API key (can also be set via UI)
|
| 163 |
TAVILY_API_KEY=tvly-...
|
| 164 |
|
| 165 |
# Optional: Use a different model
|
|
|
|
| 172 |
python app.py
|
| 173 |
```
|
| 174 |
|
| 175 |
+
The application will launch at <http://127.0.0.1:7860>
|
| 176 |
|
| 177 |
## Usage
|
| 178 |
|
|
|
|
| 289 |
## TODO
|
| 290 |
|
| 291 |
### MCP Server Integration
|
| 292 |
+
|
| 293 |
- [x] **Integrate MCP servers using smolagents** ✅
|
| 294 |
- Implemented three MCP servers: Tavily search, Sa2VA image analysis, and Gradio file upload
|
| 295 |
- Using both stdio and HTTP-based MCP transports
|
|
|
|
| 307 |
- Social media trend analysis
|
| 308 |
|
| 309 |
### Enhanced Research Capabilities
|
| 310 |
+
|
| 311 |
- [ ] **Multi-source verification**
|
| 312 |
- Cross-reference information across multiple sources
|
| 313 |
- Add confidence scoring for research findings
|
|
|
|
| 324 |
- Export to PDF/DOCX
|
| 325 |
|
| 326 |
### Tool Improvements
|
| 327 |
+
|
| 328 |
- [ ] **Add calculator tool** for mathematical queries
|
| 329 |
- [ ] **Add code execution tool** for running Python snippets
|
| 330 |
- [ ] **Add data visualization tool** for charts and graphs
|
|
|
|
| 332 |
- Implemented with support for PDF, DOCX, TXT, MD, JSON, CSV, and images
|
| 333 |
|
| 334 |
### UI/UX Enhancements
|
| 335 |
+
|
| 336 |
- [ ] **Add conversation history** persistence
|
| 337 |
- [ ] **Add export chat** functionality
|
| 338 |
- [ ] **Add model selection** dropdown for different LLMs
|
|
|
|
| 340 |
- [ ] **Dark mode** support
|
| 341 |
|
| 342 |
### Performance & Reliability
|
| 343 |
+
|
| 344 |
- [ ] **Add caching** for repeated searches
|
| 345 |
- [ ] **Implement retry logic** for failed API calls
|
| 346 |
- [ ] **Add rate limiting** dashboard
|
| 347 |
- [ ] **Optimize token usage** with streaming truncation
|
| 348 |
|
| 349 |
### Testing & Documentation
|
| 350 |
+
|
| 351 |
- [ ] **Add unit tests** for core functions
|
| 352 |
- [ ] **Add integration tests** for tools
|
| 353 |
- [ ] **Create video demo** of capabilities
|
|
|
|
| 366 |
- Built with [smolagents](https://huggingface.co/docs/smolagents) by Hugging Face
|
| 367 |
- UI powered by [Gradio](https://gradio.app)
|
| 368 |
- Image generation by [FLUX.1-schnell](https://huggingface.co/black-forest-labs/FLUX.1-schnell)
|
| 369 |
+
- Search powered by [Tavily](https://app.tavily.com)
|
|
@@ -2,6 +2,7 @@ import os
|
|
| 2 |
import warnings
|
| 3 |
|
| 4 |
from dotenv import load_dotenv
|
|
|
|
| 5 |
from mcp import StdioServerParameters
|
| 6 |
from smolagents import (
|
| 7 |
CodeAgent,
|
|
@@ -52,19 +53,23 @@ image_generation_tool = Tool.from_space(
|
|
| 52 |
# api_name="/image_vision",
|
| 53 |
# )
|
| 54 |
|
|
|
|
| 55 |
# MCP Servers
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
"
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
|
|
|
|
|
|
|
|
|
| 68 |
|
| 69 |
# groq_compount_beta = StdioServerParameters(
|
| 70 |
# command="uvx", # Using uvx ensures dependencies are available
|
|
@@ -78,26 +83,40 @@ upload_files_to_gradio = StdioServerParameters(
|
|
| 78 |
# },
|
| 79 |
# )
|
| 80 |
|
| 81 |
-
image_analysis_mcp = {
|
| 82 |
-
"url": "https://fffiloni-sa2va-simple-demo.hf.space/gradio_api/mcp/",
|
| 83 |
-
"transport": "streamable-http",
|
| 84 |
-
}
|
| 85 |
|
| 86 |
-
|
| 87 |
-
"
|
| 88 |
-
|
| 89 |
-
|
|
|
|
|
|
|
| 90 |
|
| 91 |
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 96 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
|
|
|
|
|
|
|
|
|
| 101 |
|
| 102 |
# Create model with user-specified parameters
|
| 103 |
model = InferenceClientModel(
|
|
@@ -106,7 +125,7 @@ def create_agent():
|
|
| 106 |
top_p=0.95,
|
| 107 |
model_id=HF_MODEL_ID,
|
| 108 |
custom_role_conversions=None,
|
| 109 |
-
token=token
|
| 110 |
)
|
| 111 |
|
| 112 |
# Load instructions from file. This text will be appended to the system prompt.
|
|
@@ -120,14 +139,14 @@ def create_agent():
|
|
| 120 |
additional_authorized_imports=["*"],
|
| 121 |
tools=[
|
| 122 |
image_generation_tool,
|
| 123 |
-
*mcp_client.get_tools(), # Use tools from the
|
| 124 |
# web_search,
|
| 125 |
# visit_webpage,
|
| 126 |
final_answer,
|
| 127 |
],
|
| 128 |
instructions=instructions,
|
| 129 |
add_base_tools=False,
|
| 130 |
-
max_steps=
|
| 131 |
verbosity_level=1,
|
| 132 |
planning_interval=3,
|
| 133 |
)
|
|
@@ -142,8 +161,15 @@ def create_agent():
|
|
| 142 |
return agent
|
| 143 |
|
| 144 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 145 |
gradio_ui = CustomGradioUI(
|
| 146 |
-
create_agent
|
| 147 |
file_upload_folder="./data",
|
| 148 |
reset_agent_memory=True,
|
| 149 |
allowed_file_types=[
|
|
@@ -157,6 +183,7 @@ gradio_ui = CustomGradioUI(
|
|
| 157 |
".jpeg",
|
| 158 |
".jpg",
|
| 159 |
], # Customize this list!
|
|
|
|
| 160 |
)
|
| 161 |
|
| 162 |
if __name__ == "__main__":
|
|
|
|
| 2 |
import warnings
|
| 3 |
|
| 4 |
from dotenv import load_dotenv
|
| 5 |
+
from huggingface_hub import get_token
|
| 6 |
from mcp import StdioServerParameters
|
| 7 |
from smolagents import (
|
| 8 |
CodeAgent,
|
|
|
|
| 53 |
# api_name="/image_vision",
|
| 54 |
# )
|
| 55 |
|
| 56 |
+
|
| 57 |
# MCP Servers
|
| 58 |
+
def get_upload_files_to_gradio_server():
|
| 59 |
+
"""Get the upload files to Gradio MCP server configuration."""
|
| 60 |
+
return StdioServerParameters(
|
| 61 |
+
command="uvx", # Using uvx ensures dependencies are available
|
| 62 |
+
args=[
|
| 63 |
+
"--from",
|
| 64 |
+
"gradio[mcp]",
|
| 65 |
+
"gradio",
|
| 66 |
+
"upload-mcp",
|
| 67 |
+
"https://fffiloni-sa2va-simple-demo.hf.space/",
|
| 68 |
+
"./data",
|
| 69 |
+
],
|
| 70 |
+
env={"UV_PYTHON": "3.12", **os.environ},
|
| 71 |
+
)
|
| 72 |
+
|
| 73 |
|
| 74 |
# groq_compount_beta = StdioServerParameters(
|
| 75 |
# command="uvx", # Using uvx ensures dependencies are available
|
|
|
|
| 83 |
# },
|
| 84 |
# )
|
| 85 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
|
| 87 |
+
def get_image_analysis_mcp():
|
| 88 |
+
"""Get the image analysis MCP configuration."""
|
| 89 |
+
return {
|
| 90 |
+
"url": "https://fffiloni-sa2va-simple-demo.hf.space/gradio_api/mcp/",
|
| 91 |
+
"transport": "streamable-http",
|
| 92 |
+
}
|
| 93 |
|
| 94 |
|
| 95 |
+
def get_tavily_search_mcp(api_key):
|
| 96 |
+
"""Get the Tavily search MCP configuration with the provided API key."""
|
| 97 |
+
return {
|
| 98 |
+
"url": f"https://mcp.tavily.com/mcp/?tavilyApiKey={api_key}",
|
| 99 |
+
"transport": "streamable-http",
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
|
| 103 |
+
def create_agent(tavily_api_key=None):
|
| 104 |
+
"""Create an agent with the specified Tavily API key (or use environment variable)."""
|
| 105 |
+
# Use provided API key or fall back to environment variable
|
| 106 |
+
api_key = tavily_api_key or TAVILY_API_KEY
|
| 107 |
|
| 108 |
+
# Build list of MCP servers - only include Tavily if API key is provided
|
| 109 |
+
mcp_servers = [
|
| 110 |
+
get_upload_files_to_gradio_server(),
|
| 111 |
+
get_image_analysis_mcp(),
|
| 112 |
+
]
|
| 113 |
|
| 114 |
+
# Only add Tavily search if we have an API key
|
| 115 |
+
if api_key:
|
| 116 |
+
mcp_servers.append(get_tavily_search_mcp(api_key))
|
| 117 |
+
|
| 118 |
+
# Create MCP client with the appropriate servers
|
| 119 |
+
mcp_client = MCPClient(mcp_servers, structured_output=False)
|
| 120 |
|
| 121 |
# Create model with user-specified parameters
|
| 122 |
model = InferenceClientModel(
|
|
|
|
| 125 |
top_p=0.95,
|
| 126 |
model_id=HF_MODEL_ID,
|
| 127 |
custom_role_conversions=None,
|
| 128 |
+
token=get_token(), # Get token from HF login (huggingface-cli login) or environment variable (HF_TOKEN)
|
| 129 |
)
|
| 130 |
|
| 131 |
# Load instructions from file. This text will be appended to the system prompt.
|
|
|
|
| 139 |
additional_authorized_imports=["*"],
|
| 140 |
tools=[
|
| 141 |
image_generation_tool,
|
| 142 |
+
*mcp_client.get_tools(), # Use tools from the MCP client
|
| 143 |
# web_search,
|
| 144 |
# visit_webpage,
|
| 145 |
final_answer,
|
| 146 |
],
|
| 147 |
instructions=instructions,
|
| 148 |
add_base_tools=False,
|
| 149 |
+
max_steps=10,
|
| 150 |
verbosity_level=1,
|
| 151 |
planning_interval=3,
|
| 152 |
)
|
|
|
|
| 161 |
return agent
|
| 162 |
|
| 163 |
|
| 164 |
+
# Example prompts for users
|
| 165 |
+
EXAMPLES = [
|
| 166 |
+
"Search the web for the latest developments in quantum computing and summarize the key findings",
|
| 167 |
+
"Generate an image of a futuristic city with flying cars and neon lights",
|
| 168 |
+
"What are the current trends in artificial intelligence research?",
|
| 169 |
+
]
|
| 170 |
+
|
| 171 |
gradio_ui = CustomGradioUI(
|
| 172 |
+
create_agent, # Pass the factory function, not the agent instance
|
| 173 |
file_upload_folder="./data",
|
| 174 |
reset_agent_memory=True,
|
| 175 |
allowed_file_types=[
|
|
|
|
| 183 |
".jpeg",
|
| 184 |
".jpg",
|
| 185 |
], # Customize this list!
|
| 186 |
+
examples=EXAMPLES,
|
| 187 |
)
|
| 188 |
|
| 189 |
if __name__ == "__main__":
|
|
File without changes
|
|
@@ -8,10 +8,33 @@ class CustomGradioUI(GradioUI):
|
|
| 8 |
"""Custom GradioUI that allows customization of the smolagents default interface."""
|
| 9 |
|
| 10 |
def __init__(
|
| 11 |
-
self,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
):
|
| 13 |
-
|
|
|
|
|
|
|
|
|
|
| 14 |
self.allowed_file_types = allowed_file_types or [".pdf", ".docx", ".txt"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
|
| 16 |
def create_app(self):
|
| 17 |
"""Override create_app to use custom allowed_file_types."""
|
|
@@ -21,6 +44,7 @@ class CustomGradioUI(GradioUI):
|
|
| 21 |
session_state = gr.State({})
|
| 22 |
stored_messages = gr.State([])
|
| 23 |
file_uploads_log = gr.State([])
|
|
|
|
| 24 |
|
| 25 |
with gr.Sidebar():
|
| 26 |
gr.Markdown(
|
|
@@ -62,6 +86,28 @@ class CustomGradioUI(GradioUI):
|
|
| 62 |
[upload_status, file_uploads_log],
|
| 63 |
)
|
| 64 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
gr.HTML(
|
| 66 |
"<br><br><h4><center>Powered by <a target='_blank' href='https://github.com/huggingface/smolagents'><b>smolagents</b></a></center></h4>"
|
| 67 |
)
|
|
@@ -84,6 +130,14 @@ class CustomGradioUI(GradioUI):
|
|
| 84 |
],
|
| 85 |
)
|
| 86 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
# Set up event handlers
|
| 88 |
text_input.submit(
|
| 89 |
self.log_user_message,
|
|
|
|
| 8 |
"""Custom GradioUI that allows customization of the smolagents default interface."""
|
| 9 |
|
| 10 |
def __init__(
|
| 11 |
+
self,
|
| 12 |
+
agent_factory,
|
| 13 |
+
file_upload_folder=None,
|
| 14 |
+
reset_agent_memory=False,
|
| 15 |
+
allowed_file_types=None,
|
| 16 |
+
examples=None,
|
| 17 |
):
|
| 18 |
+
# Store the factory function instead of the agent directly
|
| 19 |
+
self.agent_factory = agent_factory
|
| 20 |
+
# Create initial agent with no API key (will use env var if available)
|
| 21 |
+
super().__init__(agent_factory(), file_upload_folder, reset_agent_memory)
|
| 22 |
self.allowed_file_types = allowed_file_types or [".pdf", ".docx", ".txt"]
|
| 23 |
+
self.examples = examples or []
|
| 24 |
+
|
| 25 |
+
def update_api_key(self, api_key, current_key):
|
| 26 |
+
"""Update the agent with a new API key."""
|
| 27 |
+
if api_key and api_key != current_key:
|
| 28 |
+
# Recreate the agent with the new API key
|
| 29 |
+
self.agent = self.agent_factory(tavily_api_key=api_key)
|
| 30 |
+
return api_key, gr.Markdown("✓ API key updated successfully", visible=True)
|
| 31 |
+
elif not api_key and current_key:
|
| 32 |
+
# Reset to default (env var)
|
| 33 |
+
self.agent = self.agent_factory()
|
| 34 |
+
return "", gr.Markdown(
|
| 35 |
+
"API key cleared, using environment variable if set", visible=True
|
| 36 |
+
)
|
| 37 |
+
return current_key, gr.Markdown("", visible=False)
|
| 38 |
|
| 39 |
def create_app(self):
|
| 40 |
"""Override create_app to use custom allowed_file_types."""
|
|
|
|
| 44 |
session_state = gr.State({})
|
| 45 |
stored_messages = gr.State([])
|
| 46 |
file_uploads_log = gr.State([])
|
| 47 |
+
current_api_key = gr.State("") # Store current Tavily API key
|
| 48 |
|
| 49 |
with gr.Sidebar():
|
| 50 |
gr.Markdown(
|
|
|
|
| 86 |
[upload_status, file_uploads_log],
|
| 87 |
)
|
| 88 |
|
| 89 |
+
# Tavily API Key section
|
| 90 |
+
with gr.Group():
|
| 91 |
+
gr.Markdown("**Tavily API Key**", container=True)
|
| 92 |
+
gr.Markdown(
|
| 93 |
+
"Get your free API key at [tavily.com](https://app.tavily.com/home)",
|
| 94 |
+
container=False,
|
| 95 |
+
)
|
| 96 |
+
tavily_api_key_input = gr.Textbox(
|
| 97 |
+
label="API Key (optional)",
|
| 98 |
+
type="password",
|
| 99 |
+
placeholder="Enter your Tavily API key to enable web search",
|
| 100 |
+
container=False,
|
| 101 |
+
)
|
| 102 |
+
api_key_status = gr.Markdown("", visible=False)
|
| 103 |
+
|
| 104 |
+
# Update agent when API key changes
|
| 105 |
+
tavily_api_key_input.change(
|
| 106 |
+
self.update_api_key,
|
| 107 |
+
[tavily_api_key_input, current_api_key],
|
| 108 |
+
[current_api_key, api_key_status],
|
| 109 |
+
)
|
| 110 |
+
|
| 111 |
gr.HTML(
|
| 112 |
"<br><br><h4><center>Powered by <a target='_blank' href='https://github.com/huggingface/smolagents'><b>smolagents</b></a></center></h4>"
|
| 113 |
)
|
|
|
|
| 130 |
],
|
| 131 |
)
|
| 132 |
|
| 133 |
+
# Add examples if provided
|
| 134 |
+
if self.examples:
|
| 135 |
+
gr.Examples(
|
| 136 |
+
examples=self.examples,
|
| 137 |
+
inputs=text_input,
|
| 138 |
+
cache_examples=False,
|
| 139 |
+
)
|
| 140 |
+
|
| 141 |
# Set up event handlers
|
| 142 |
text_input.submit(
|
| 143 |
self.log_user_message,
|