Spaces:
Running
Running
Update dependencies and fix compatibility issues
Browse files- Fix numpy/pandas compatibility for Python 3.10
- Update vector RAG components and test procedures
- Add comprehensive test documentation
- Modernize dependency management
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
- CLAUDE.md +64 -1
- TEST_PROCEDURE.md +285 -0
- app.py +296 -85
- requirements.txt +3 -3
- test_minimal.py +20 -0
CLAUDE.md
CHANGED
@@ -152,4 +152,67 @@ The application has two modes for web scraping:
|
|
152 |
- **Mock mode** (lines 14-18 in app.py): Returns placeholder content for testing
|
153 |
- **Production mode**: Uses Crawl4AI via scraping_service.py for actual web content extraction
|
154 |
|
155 |
-
Switch between modes by commenting/uncommenting the imports and function definitions.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
152 |
- **Mock mode** (lines 14-18 in app.py): Returns placeholder content for testing
|
153 |
- **Production mode**: Uses Crawl4AI via scraping_service.py for actual web content extraction
|
154 |
|
155 |
+
Switch between modes by commenting/uncommenting the imports and function definitions.
|
156 |
+
|
157 |
+
## Testing and Quality Assurance
|
158 |
+
|
159 |
+
### Comprehensive Test Procedure
|
160 |
+
The project includes a comprehensive test procedure documented in `TEST_PROCEDURE.md` that covers:
|
161 |
+
|
162 |
+
#### Test Categories
|
163 |
+
1. **Core Application Tests**: Startup validation and Gradio interface testing
|
164 |
+
2. **Vector RAG Component Tests**: Document processing, vector store, and RAG pipeline validation
|
165 |
+
3. **Space Generation Tests**: Template creation and file generation verification
|
166 |
+
4. **Web Scraping Tests**: Mock vs production mode validation and URL processing
|
167 |
+
5. **Security and Configuration Tests**: Environment variable handling and input validation
|
168 |
+
6. **Chat Support Tests**: OpenRouter integration and Gradio 5.x compatibility
|
169 |
+
|
170 |
+
#### Automated Testing Commands
|
171 |
+
```bash
|
172 |
+
# Quick test suite for essential validation
|
173 |
+
./quick_test.sh
|
174 |
+
|
175 |
+
# Full comprehensive test suite
|
176 |
+
./full_test.sh
|
177 |
+
|
178 |
+
# Individual component testing
|
179 |
+
python test_vector_db.py
|
180 |
+
python -c "from test_vector_db import test_document_processing; test_document_processing()"
|
181 |
+
python -c "from test_vector_db import test_vector_store; test_vector_store()"
|
182 |
+
python -c "from test_vector_db import test_rag_tool; test_rag_tool()"
|
183 |
+
```
|
184 |
+
|
185 |
+
#### Pre-Test Setup
|
186 |
+
```bash
|
187 |
+
# Environment verification
|
188 |
+
python --version # Should be 3.8+
|
189 |
+
pip install -r requirements.txt
|
190 |
+
|
191 |
+
# Test data preparation
|
192 |
+
echo "This is a test document for RAG functionality testing." > test_document.txt
|
193 |
+
mkdir -p test_outputs
|
194 |
+
```
|
195 |
+
|
196 |
+
#### Regression Testing
|
197 |
+
After each commit, verify:
|
198 |
+
- All existing functionality still works
|
199 |
+
- New features don't break existing features
|
200 |
+
- Generated spaces deploy successfully to HuggingFace
|
201 |
+
- Documentation is updated appropriately
|
202 |
+
- Dependencies are correctly specified
|
203 |
+
- Security patterns are maintained
|
204 |
+
|
205 |
+
#### Performance Benchmarking
|
206 |
+
```bash
|
207 |
+
# Startup time measurement
|
208 |
+
time python -c "import app; print('App loaded')"
|
209 |
+
|
210 |
+
# Space generation time
|
211 |
+
time python -c "import app; app.generate_zip('Benchmark', 'Test', 'Role', 'Audience', 'Tasks', '', [], '', '', 'gpt-3.5-turbo', 0.7, 4000, [], False, False, None)"
|
212 |
+
|
213 |
+
# RAG processing time
|
214 |
+
time python -c "from test_vector_db import test_rag_tool; test_rag_tool()"
|
215 |
+
```
|
216 |
+
|
217 |
+
#### Continuous Integration
|
218 |
+
The test procedure is designed to integrate with GitHub Actions for automated testing on commits and pull requests. See `TEST_PROCEDURE.md` for complete setup instructions and CI configuration.
|
TEST_PROCEDURE.md
ADDED
@@ -0,0 +1,285 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# Chat UI Helper - Comprehensive Test Procedure
|
2 |
+
|
3 |
+
This document outlines a systematic test procedure for validating the Chat UI Helper application after new commits. This procedure ensures all components function correctly and can be iterated upon as the project evolves.
|
4 |
+
|
5 |
+
## Pre-Test Setup
|
6 |
+
|
7 |
+
### Environment Verification
|
8 |
+
```bash
|
9 |
+
# Verify Python environment
|
10 |
+
python --version # Should be 3.8+
|
11 |
+
|
12 |
+
# Install/update dependencies
|
13 |
+
pip install -r requirements.txt
|
14 |
+
|
15 |
+
# Verify optional dependencies status
|
16 |
+
python -c "
|
17 |
+
try:
|
18 |
+
import sentence_transformers, faiss, fitz, docx
|
19 |
+
print('✅ All RAG dependencies available')
|
20 |
+
except ImportError as e:
|
21 |
+
print(f'⚠️ Optional RAG dependencies missing: {e}')
|
22 |
+
"
|
23 |
+
```
|
24 |
+
|
25 |
+
### Test Data Preparation
|
26 |
+
```bash
|
27 |
+
# Ensure test document exists
|
28 |
+
echo "This is a test document for RAG functionality testing." > test_document.txt
|
29 |
+
|
30 |
+
# Create test directory structure if needed
|
31 |
+
mkdir -p test_outputs
|
32 |
+
```
|
33 |
+
|
34 |
+
## Test Categories
|
35 |
+
|
36 |
+
### 1. Core Application Tests
|
37 |
+
|
38 |
+
#### 1.1 Application Startup
|
39 |
+
```bash
|
40 |
+
# Test basic application launch
|
41 |
+
python app.py &
|
42 |
+
APP_PID=$!
|
43 |
+
sleep 10
|
44 |
+
curl -f http://localhost:7860 > /dev/null && echo "✅ App started successfully" || echo "❌ App failed to start"
|
45 |
+
kill $APP_PID
|
46 |
+
```
|
47 |
+
|
48 |
+
#### 1.2 Gradio Interface Validation
|
49 |
+
- [ ] Application loads without errors
|
50 |
+
- [ ] Two tabs visible: "Spaces Configuration" and "Chat Support"
|
51 |
+
- [ ] All form fields render correctly
|
52 |
+
- [ ] Template selection works (Custom vs Research Assistant)
|
53 |
+
- [ ] File upload components appear when RAG is enabled
|
54 |
+
|
55 |
+
### 2. Vector RAG Component Tests
|
56 |
+
|
57 |
+
#### 2.1 Individual Component Testing
|
58 |
+
```bash
|
59 |
+
# Test document processing
|
60 |
+
python -c "from test_vector_db import test_document_processing; test_document_processing()"
|
61 |
+
|
62 |
+
# Test vector store functionality
|
63 |
+
python -c "from test_vector_db import test_vector_store; test_vector_store()"
|
64 |
+
|
65 |
+
# Test full RAG pipeline
|
66 |
+
python -c "from test_vector_db import test_rag_tool; test_rag_tool()"
|
67 |
+
```
|
68 |
+
|
69 |
+
#### 2.2 RAG Integration Tests
|
70 |
+
- [ ] Document upload accepts PDF, DOCX, TXT, MD files
|
71 |
+
- [ ] File size validation (10MB limit) works
|
72 |
+
- [ ] Documents are processed and chunked correctly
|
73 |
+
- [ ] Vector embeddings are generated
|
74 |
+
- [ ] Similarity search returns relevant results
|
75 |
+
- [ ] RAG data serializes/deserializes properly for templates
|
76 |
+
|
77 |
+
### 3. Space Generation Tests
|
78 |
+
|
79 |
+
#### 3.1 Basic Space Creation
|
80 |
+
- [ ] Generate space with minimal configuration
|
81 |
+
- [ ] Verify all required files are created (app.py, requirements.txt, README.md, config.json)
|
82 |
+
- [ ] Check generated app.py syntax is valid
|
83 |
+
- [ ] Verify requirements.txt has correct dependencies
|
84 |
+
- [ ] Ensure README.md contains proper deployment instructions
|
85 |
+
|
86 |
+
#### 3.2 Advanced Feature Testing
|
87 |
+
- [ ] Generate space with URL grounding enabled
|
88 |
+
- [ ] Generate space with vector RAG enabled
|
89 |
+
- [ ] Generate space with access code protection
|
90 |
+
- [ ] Test template substitution works correctly
|
91 |
+
- [ ] Verify environment variable security pattern
|
92 |
+
|
93 |
+
### 4. Web Scraping Tests
|
94 |
+
|
95 |
+
#### 4.1 Mock vs Production Mode
|
96 |
+
```bash
|
97 |
+
# Test in mock mode (lines 14-18 in app.py)
|
98 |
+
# Verify placeholder content is returned
|
99 |
+
|
100 |
+
# Test in production mode
|
101 |
+
# Verify actual web content is fetched via Crawl4AI
|
102 |
+
```
|
103 |
+
|
104 |
+
#### 4.2 URL Processing
|
105 |
+
- [ ] Valid URLs are processed correctly
|
106 |
+
- [ ] Invalid URLs are handled gracefully
|
107 |
+
- [ ] Content extraction works for different site types
|
108 |
+
- [ ] Rate limiting and error handling work
|
109 |
+
|
110 |
+
### 5. Security and Configuration Tests
|
111 |
+
|
112 |
+
#### 5.1 Environment Variable Handling
|
113 |
+
- [ ] API keys are not embedded in generated templates
|
114 |
+
- [ ] Access codes use environment variable pattern
|
115 |
+
- [ ] Sensitive data is properly excluded from version control
|
116 |
+
|
117 |
+
#### 5.2 Input Validation
|
118 |
+
- [ ] File upload validation works
|
119 |
+
- [ ] URL validation prevents malicious inputs
|
120 |
+
- [ ] Content length limits are enforced
|
121 |
+
- [ ] XSS prevention in user inputs
|
122 |
+
|
123 |
+
### 6. Chat Support Tests
|
124 |
+
|
125 |
+
#### 6.1 OpenRouter Integration
|
126 |
+
- [ ] Chat responds when API key is configured
|
127 |
+
- [ ] Proper error message when API key is missing
|
128 |
+
- [ ] Message history formatting works correctly
|
129 |
+
- [ ] URL grounding provides relevant context
|
130 |
+
|
131 |
+
#### 6.2 Gradio 5.x Compatibility
|
132 |
+
- [ ] Message format uses `type="messages"`
|
133 |
+
- [ ] ChatInterface renders correctly
|
134 |
+
- [ ] User/assistant message distinction works
|
135 |
+
- [ ] Chat history persists during session
|
136 |
+
|
137 |
+
## Automated Test Execution
|
138 |
+
|
139 |
+
### Quick Test Suite
|
140 |
+
```bash
|
141 |
+
#!/bin/bash
|
142 |
+
# quick_test.sh - Run essential tests
|
143 |
+
|
144 |
+
echo "🔍 Running Quick Test Suite..."
|
145 |
+
|
146 |
+
# 1. Syntax check
|
147 |
+
python -m py_compile app.py && echo "✅ app.py syntax valid" || echo "❌ app.py syntax error"
|
148 |
+
|
149 |
+
# 2. Import test
|
150 |
+
python -c "import app; print('✅ App imports successfully')" 2>/dev/null || echo "❌ Import failed"
|
151 |
+
|
152 |
+
# 3. RAG component test (if available)
|
153 |
+
if python -c "from rag_tool import RAGTool" 2>/dev/null; then
|
154 |
+
python test_vector_db.py && echo "✅ RAG tests passed" || echo "❌ RAG tests failed"
|
155 |
+
else
|
156 |
+
echo "⚠️ RAG components not available"
|
157 |
+
fi
|
158 |
+
|
159 |
+
# 4. Template generation test
|
160 |
+
python -c "
|
161 |
+
import app
|
162 |
+
result = app.generate_zip('Test Space', 'Test Description', 'Test Role', 'Test Audience', 'Test Tasks', '', [], '', '', 'gpt-3.5-turbo', 0.7, 4000, [], False, False, None)
|
163 |
+
assert result[0].endswith('.zip'), 'ZIP generation failed'
|
164 |
+
print('✅ Space generation works')
|
165 |
+
"
|
166 |
+
|
167 |
+
echo "🎉 Quick test suite completed!"
|
168 |
+
```
|
169 |
+
|
170 |
+
### Full Test Suite
|
171 |
+
```bash
|
172 |
+
#!/bin/bash
|
173 |
+
# full_test.sh - Comprehensive testing
|
174 |
+
|
175 |
+
echo "🔍 Running Full Test Suite..."
|
176 |
+
|
177 |
+
# Run all component tests
|
178 |
+
./quick_test.sh
|
179 |
+
|
180 |
+
# Additional integration tests
|
181 |
+
echo "🧪 Running integration tests..."
|
182 |
+
|
183 |
+
# Test with different configurations
|
184 |
+
# Test error handling
|
185 |
+
# Test edge cases
|
186 |
+
# Performance tests
|
187 |
+
|
188 |
+
echo "📊 Generating test report..."
|
189 |
+
# Generate detailed test report
|
190 |
+
```
|
191 |
+
|
192 |
+
## Regression Test Checklist
|
193 |
+
|
194 |
+
After each commit, verify:
|
195 |
+
|
196 |
+
- [ ] All existing functionality still works
|
197 |
+
- [ ] New features don't break existing features
|
198 |
+
- [ ] Generated spaces deploy successfully to HuggingFace
|
199 |
+
- [ ] Documentation is updated appropriately
|
200 |
+
- [ ] Dependencies are correctly specified
|
201 |
+
- [ ] Security patterns are maintained
|
202 |
+
|
203 |
+
## Performance Benchmarks
|
204 |
+
|
205 |
+
### Metrics to Track
|
206 |
+
- Application startup time
|
207 |
+
- Space generation time
|
208 |
+
- Document processing time (for various file sizes)
|
209 |
+
- Memory usage during RAG operations
|
210 |
+
- API response times
|
211 |
+
|
212 |
+
### Benchmark Commands
|
213 |
+
```bash
|
214 |
+
# Startup time
|
215 |
+
time python -c "import app; print('App loaded')"
|
216 |
+
|
217 |
+
# Space generation time
|
218 |
+
time python -c "
|
219 |
+
import app
|
220 |
+
app.generate_zip('Benchmark', 'Test', 'Role', 'Audience', 'Tasks', '', [], '', '', 'gpt-3.5-turbo', 0.7, 4000, [], False, False, None)
|
221 |
+
"
|
222 |
+
|
223 |
+
# RAG processing time
|
224 |
+
time python -c "from test_vector_db import test_rag_tool; test_rag_tool()"
|
225 |
+
```
|
226 |
+
|
227 |
+
## Test Data Management
|
228 |
+
|
229 |
+
### Sample Test Files
|
230 |
+
- `test_document.txt` - Basic text document
|
231 |
+
- `sample.pdf` - PDF document for upload testing
|
232 |
+
- `sample.docx` - Word document for testing
|
233 |
+
- `sample.md` - Markdown document for testing
|
234 |
+
|
235 |
+
### Test Configuration Profiles
|
236 |
+
- Minimal configuration (basic chat only)
|
237 |
+
- Research assistant template
|
238 |
+
- Full-featured (RAG + URL grounding + access control)
|
239 |
+
- Edge case configurations
|
240 |
+
|
241 |
+
## Continuous Integration Integration
|
242 |
+
|
243 |
+
### GitHub Actions Integration
|
244 |
+
```yaml
|
245 |
+
# .github/workflows/test.yml
|
246 |
+
name: Test Chat UI Helper
|
247 |
+
on: [push, pull_request]
|
248 |
+
jobs:
|
249 |
+
test:
|
250 |
+
runs-on: ubuntu-latest
|
251 |
+
steps:
|
252 |
+
- uses: actions/checkout@v3
|
253 |
+
- name: Set up Python
|
254 |
+
uses: actions/setup-python@v4
|
255 |
+
with:
|
256 |
+
python-version: '3.9'
|
257 |
+
- name: Install dependencies
|
258 |
+
run: pip install -r requirements.txt
|
259 |
+
- name: Run test suite
|
260 |
+
run: ./quick_test.sh
|
261 |
+
```
|
262 |
+
|
263 |
+
## Future Test Enhancements
|
264 |
+
|
265 |
+
### Planned Additions
|
266 |
+
- [ ] Automated UI testing with Selenium
|
267 |
+
- [ ] Load testing for generated spaces
|
268 |
+
- [ ] Cross-browser compatibility testing
|
269 |
+
- [ ] Mobile responsiveness testing
|
270 |
+
- [ ] Accessibility testing
|
271 |
+
- [ ] Multi-language content testing
|
272 |
+
|
273 |
+
### Test Coverage Goals
|
274 |
+
- [ ] 90%+ code coverage for core components
|
275 |
+
- [ ] All user workflows tested end-to-end
|
276 |
+
- [ ] Error conditions properly tested
|
277 |
+
- [ ] Performance regression detection
|
278 |
+
|
279 |
+
---
|
280 |
+
|
281 |
+
**Last Updated**: 2025-07-13
|
282 |
+
**Version**: 1.0
|
283 |
+
**Maintained by**: Development Team
|
284 |
+
|
285 |
+
This test procedure should be updated whenever new features are added or existing functionality is modified.
|
app.py
CHANGED
@@ -232,14 +232,14 @@ def verify_access_code(code):
|
|
232 |
global _access_granted_global
|
233 |
if not ACCESS_CODE:
|
234 |
_access_granted_global = True
|
235 |
-
return gr.update(visible=False), gr.update(visible=True), True
|
236 |
|
237 |
if code == ACCESS_CODE:
|
238 |
_access_granted_global = True
|
239 |
-
return gr.update(visible=False), gr.update(visible=True), True
|
240 |
else:
|
241 |
_access_granted_global = False
|
242 |
-
return gr.update(visible=True, value="❌ Incorrect access code. Please try again."), gr.update(visible=False), False
|
243 |
|
244 |
def protected_generate_response(message, history):
|
245 |
\"\"\"Protected response function that checks access\"\"\"
|
@@ -272,7 +272,7 @@ with gr.Blocks(title=SPACE_NAME) as demo:
|
|
272 |
fn=protected_generate_response,
|
273 |
title="", # Title already shown above
|
274 |
description="", # Description already shown above
|
275 |
-
examples=
|
276 |
)
|
277 |
|
278 |
# Connect access verification
|
@@ -469,7 +469,7 @@ def create_requirements(enable_vector_rag=False):
|
|
469 |
|
470 |
return base_requirements
|
471 |
|
472 |
-
def generate_zip(name, description,
|
473 |
"""Generate deployable zip file"""
|
474 |
|
475 |
# Process examples
|
@@ -489,24 +489,13 @@ def generate_zip(name, description, role_purpose, intended_audience, key_tasks,
|
|
489 |
if url and url.strip():
|
490 |
grounding_urls.append(url.strip())
|
491 |
|
492 |
-
#
|
493 |
-
system_prompt_parts = []
|
494 |
-
if role_purpose and role_purpose.strip():
|
495 |
-
system_prompt_parts.append(role_purpose.strip())
|
496 |
-
if intended_audience and intended_audience.strip():
|
497 |
-
system_prompt_parts.append(intended_audience.strip())
|
498 |
-
if key_tasks and key_tasks.strip():
|
499 |
-
system_prompt_parts.append(key_tasks.strip())
|
500 |
-
if additional_context and additional_context.strip():
|
501 |
-
system_prompt_parts.append(additional_context.strip())
|
502 |
-
|
503 |
-
combined_system_prompt = " ".join(system_prompt_parts)
|
504 |
|
505 |
# Create config
|
506 |
config = {
|
507 |
'name': name,
|
508 |
'description': description,
|
509 |
-
'system_prompt':
|
510 |
'model': model,
|
511 |
'api_key_var': api_key_var,
|
512 |
'temperature': temperature,
|
@@ -594,12 +583,57 @@ def process_documents(files, current_rag_tool):
|
|
594 |
except Exception as e:
|
595 |
return f"❌ Error processing documents: {str(e)}", current_rag_tool
|
596 |
|
597 |
-
def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
598 |
if not name or not name.strip():
|
599 |
return gr.update(value="Error: Please provide a Space Title", visible=True), gr.update(visible=False)
|
600 |
|
601 |
-
if not role_purpose or not role_purpose.strip():
|
602 |
-
return gr.update(value="Error: Please provide a Role and Purpose for the assistant", visible=True), gr.update(visible=False)
|
603 |
|
604 |
try:
|
605 |
# Get RAG data if enabled
|
@@ -607,7 +641,29 @@ def on_generate(name, description, role_purpose, intended_audience, key_tasks, a
|
|
607 |
if enable_vector_rag and rag_tool_state:
|
608 |
rag_data = rag_tool_state.get_serialized_data()
|
609 |
|
610 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
611 |
|
612 |
success_msg = f"""**Deployment package ready!**
|
613 |
|
@@ -626,7 +682,20 @@ def on_generate(name, description, role_purpose, intended_audience, key_tasks, a
|
|
626 |
|
627 |
**Your Space will be live in minutes!**"""
|
628 |
|
629 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
630 |
|
631 |
except Exception as e:
|
632 |
return gr.update(value=f"Error: {str(e)}", visible=True), gr.update(visible=False)
|
@@ -805,29 +874,71 @@ def remove_chat_urls(count):
|
|
805 |
else:
|
806 |
return (gr.update(), gr.update(), gr.update(), gr.update(), count)
|
807 |
|
808 |
-
def
|
809 |
-
"""
|
810 |
-
if
|
|
|
811 |
return (
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
812 |
gr.update(value=""),
|
813 |
gr.update(value=""),
|
814 |
gr.update(value=""),
|
815 |
-
gr.update(value=
|
816 |
-
gr.update(value=False) #
|
|
|
817 |
)
|
818 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
819 |
return (
|
820 |
-
gr.update(
|
821 |
-
gr.update(value=
|
822 |
-
gr.update(
|
823 |
-
|
824 |
-
|
|
|
|
|
|
|
|
|
825 |
)
|
826 |
|
827 |
# Create Gradio interface with proper tab structure
|
828 |
with gr.Blocks(title="Chat U/I Helper") as demo:
|
|
|
|
|
|
|
829 |
with gr.Tabs():
|
830 |
-
with gr.Tab("
|
831 |
gr.Markdown("# Spaces Configuration")
|
832 |
gr.Markdown("Convert custom assistants from HuggingChat into chat interfaces with HuggingFace Spaces. Configure and download everything needed to deploy a simple HF space using Gradio.")
|
833 |
|
@@ -867,52 +978,113 @@ with gr.Blocks(title="Chat U/I Helper") as demo:
|
|
867 |
|
868 |
with gr.Accordion("Assistant Configuration", open=True):
|
869 |
gr.Markdown("### Configure your assistant's behavior and capabilities")
|
870 |
-
|
871 |
-
|
872 |
-
|
873 |
-
|
874 |
-
|
875 |
-
|
876 |
-
|
877 |
-
value="System Prompt (Custom)",
|
878 |
-
info="Choose a starting point for your assistant configuration"
|
879 |
-
)
|
880 |
-
|
881 |
-
role_purpose = gr.Textbox(
|
882 |
-
label="Role and Purpose",
|
883 |
-
placeholder="You are a research assistant that...",
|
884 |
-
lines=2,
|
885 |
value="",
|
886 |
-
info="Define
|
887 |
)
|
888 |
|
889 |
-
|
890 |
-
|
891 |
-
|
892 |
-
|
893 |
-
|
894 |
-
|
895 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
896 |
|
897 |
-
|
898 |
-
|
899 |
-
|
900 |
-
|
901 |
-
|
902 |
-
|
903 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
904 |
|
905 |
-
|
906 |
-
|
907 |
-
|
908 |
-
|
909 |
-
|
910 |
-
|
911 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
912 |
|
913 |
-
|
914 |
-
|
915 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
916 |
enable_dynamic_urls = gr.Checkbox(
|
917 |
label="Enable Dynamic URL Fetching",
|
918 |
value=False,
|
@@ -923,7 +1095,7 @@ with gr.Blocks(title="Chat U/I Helper") as demo:
|
|
923 |
label="Enable Document RAG",
|
924 |
value=False,
|
925 |
info="Upload documents for context-aware responses (PDF, DOCX, TXT, MD)",
|
926 |
-
visible=HAS_RAG
|
927 |
)
|
928 |
|
929 |
with gr.Column(visible=False) as rag_section:
|
@@ -1007,13 +1179,36 @@ with gr.Blocks(title="Chat U/I Helper") as demo:
|
|
1007 |
status = gr.Markdown(visible=False)
|
1008 |
download_file = gr.File(label="Download your zip package", visible=False)
|
1009 |
|
1010 |
-
# Connect the
|
1011 |
-
|
1012 |
-
|
1013 |
-
inputs=[
|
1014 |
-
outputs=[role_purpose, intended_audience, key_tasks, additional_context, enable_dynamic_urls]
|
1015 |
)
|
1016 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1017 |
# Connect the URL management buttons
|
1018 |
add_url_btn.click(
|
1019 |
add_urls,
|
@@ -1043,11 +1238,12 @@ with gr.Blocks(title="Chat U/I Helper") as demo:
|
|
1043 |
# Connect the generate button
|
1044 |
generate_btn.click(
|
1045 |
on_generate,
|
1046 |
-
inputs=[name, description, role_purpose, intended_audience, key_tasks, additional_context, model, api_key_var, temperature, max_tokens, examples_text, access_code, enable_dynamic_urls, url1, url2, url3, url4, enable_vector_rag, rag_tool_state],
|
1047 |
-
outputs=[status, download_file]
|
1048 |
)
|
|
|
1049 |
|
1050 |
-
with gr.Tab("
|
1051 |
gr.Markdown("# Chat Support")
|
1052 |
gr.Markdown("Get personalized guidance on configuring chat assistants as HuggingFace Spaces for educational & research purposes.")
|
1053 |
|
@@ -1141,6 +1337,21 @@ with gr.Blocks(title="Chat U/I Helper") as demo:
|
|
1141 |
submit.click(respond_with_cache_update, [msg, chatbot, chat_url1, chat_url2, chat_url3, chat_url4], [msg, chatbot, cache_status])
|
1142 |
msg.submit(respond_with_cache_update, [msg, chatbot, chat_url1, chat_url2, chat_url3, chat_url4], [msg, chatbot, cache_status])
|
1143 |
clear.click(clear_chat, outputs=[msg, chatbot])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1144 |
|
1145 |
if __name__ == "__main__":
|
1146 |
-
|
|
|
|
|
|
|
|
|
|
232 |
global _access_granted_global
|
233 |
if not ACCESS_CODE:
|
234 |
_access_granted_global = True
|
235 |
+
return gr.update(visible=False), gr.update(visible=True), gr.update(value=True)
|
236 |
|
237 |
if code == ACCESS_CODE:
|
238 |
_access_granted_global = True
|
239 |
+
return gr.update(visible=False), gr.update(visible=True), gr.update(value=True)
|
240 |
else:
|
241 |
_access_granted_global = False
|
242 |
+
return gr.update(visible=True, value="❌ Incorrect access code. Please try again."), gr.update(visible=False), gr.update(value=False)
|
243 |
|
244 |
def protected_generate_response(message, history):
|
245 |
\"\"\"Protected response function that checks access\"\"\"
|
|
|
272 |
fn=protected_generate_response,
|
273 |
title="", # Title already shown above
|
274 |
description="", # Description already shown above
|
275 |
+
examples=None
|
276 |
)
|
277 |
|
278 |
# Connect access verification
|
|
|
469 |
|
470 |
return base_requirements
|
471 |
|
472 |
+
def generate_zip(name, description, system_prompt, model, api_key_var, temperature, max_tokens, examples_text, access_code="", enable_dynamic_urls=False, url1="", url2="", url3="", url4="", enable_vector_rag=False, rag_data=None):
|
473 |
"""Generate deployable zip file"""
|
474 |
|
475 |
# Process examples
|
|
|
489 |
if url and url.strip():
|
490 |
grounding_urls.append(url.strip())
|
491 |
|
492 |
+
# Use the provided system prompt directly
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
493 |
|
494 |
# Create config
|
495 |
config = {
|
496 |
'name': name,
|
497 |
'description': description,
|
498 |
+
'system_prompt': system_prompt,
|
499 |
'model': model,
|
500 |
'api_key_var': api_key_var,
|
501 |
'temperature': temperature,
|
|
|
583 |
except Exception as e:
|
584 |
return f"❌ Error processing documents: {str(e)}", current_rag_tool
|
585 |
|
586 |
+
def update_sandbox_preview(config_data):
|
587 |
+
"""Update the sandbox preview with generated content"""
|
588 |
+
if not config_data:
|
589 |
+
return "Generate a space configuration to see preview here.", "<div style='text-align: center; padding: 50px; color: #666;'>No preview available</div>"
|
590 |
+
|
591 |
+
# Create preview info
|
592 |
+
preview_text = f"""**Space Configuration:**
|
593 |
+
- **Name:** {config_data.get('name', 'N/A')}
|
594 |
+
- **Model:** {config_data.get('model', 'N/A')}
|
595 |
+
- **Temperature:** {config_data.get('temperature', 'N/A')}
|
596 |
+
- **Max Tokens:** {config_data.get('max_tokens', 'N/A')}
|
597 |
+
- **Dynamic URLs:** {'✅ Enabled' if config_data.get('enable_dynamic_urls') else '❌ Disabled'}
|
598 |
+
- **Vector RAG:** {'✅ Enabled' if config_data.get('enable_vector_rag') else '❌ Disabled'}
|
599 |
+
|
600 |
+
**System Prompt Preview:**
|
601 |
+
```
|
602 |
+
{config_data.get('system_prompt', 'No system prompt configured')[:500]}{'...' if len(config_data.get('system_prompt', '')) > 500 else ''}
|
603 |
+
```
|
604 |
+
|
605 |
+
**Deployment Package:** `{config_data.get('filename', 'Not generated')}`"""
|
606 |
+
|
607 |
+
# Create a basic HTML preview of the chat interface
|
608 |
+
preview_html = f"""
|
609 |
+
<div style="border: 1px solid #ddd; border-radius: 8px; padding: 20px; background: #f9f9f9;">
|
610 |
+
<h3 style="margin-top: 0; color: #333;">{config_data.get('name', 'Chat Interface')}</h3>
|
611 |
+
<p style="color: #666; margin-bottom: 20px;">{config_data.get('description', 'A customizable AI chat interface')}</p>
|
612 |
+
|
613 |
+
<div style="border: 1px solid #ccc; border-radius: 4px; background: white; min-height: 200px; padding: 15px; margin-bottom: 15px;">
|
614 |
+
<div style="color: #888; text-align: center; padding: 50px 0;">Chat Interface Preview</div>
|
615 |
+
<div style="background: #f0f8ff; padding: 10px; border-radius: 4px; margin-bottom: 10px; border-left: 3px solid #0066cc;">
|
616 |
+
<strong>Assistant:</strong> Hello! I'm ready to help you. How can I assist you today?
|
617 |
+
</div>
|
618 |
+
</div>
|
619 |
+
|
620 |
+
<div style="border: 1px solid #ccc; border-radius: 4px; padding: 10px; background: white;">
|
621 |
+
<input type="text" placeholder="Type your message here..." style="width: 70%; padding: 8px; border: 1px solid #ddd; border-radius: 4px; margin-right: 10px;">
|
622 |
+
<button style="padding: 8px 15px; background: #0066cc; color: white; border: none; border-radius: 4px; cursor: pointer;">Send</button>
|
623 |
+
</div>
|
624 |
+
|
625 |
+
<div style="margin-top: 15px; padding: 10px; background: #f0f0f0; border-radius: 4px; font-size: 12px; color: #666;">
|
626 |
+
<strong>Configuration:</strong> Model: {config_data.get('model', 'N/A')} | Temperature: {config_data.get('temperature', 'N/A')} | Max Tokens: {config_data.get('max_tokens', 'N/A')}
|
627 |
+
</div>
|
628 |
+
</div>
|
629 |
+
"""
|
630 |
+
|
631 |
+
return preview_text, preview_html
|
632 |
+
|
633 |
+
def on_generate(name, description, system_prompt, enable_research_assistant, role_purpose, intended_audience, key_tasks, additional_context, custom_role_purpose, custom_intended_audience, custom_key_tasks, custom_additional_context, model, api_key_var, temperature, max_tokens, examples_text, access_code, enable_dynamic_urls, url1, url2, url3, url4, enable_vector_rag, rag_tool_state):
|
634 |
if not name or not name.strip():
|
635 |
return gr.update(value="Error: Please provide a Space Title", visible=True), gr.update(visible=False)
|
636 |
|
|
|
|
|
637 |
|
638 |
try:
|
639 |
# Get RAG data if enabled
|
|
|
641 |
if enable_vector_rag and rag_tool_state:
|
642 |
rag_data = rag_tool_state.get_serialized_data()
|
643 |
|
644 |
+
# Combine system prompt components if research assistant is enabled
|
645 |
+
if enable_research_assistant:
|
646 |
+
# Use the research assistant fields if enabled
|
647 |
+
if not role_purpose or not role_purpose.strip():
|
648 |
+
return gr.update(value="Error: Please provide a Role and Purpose for the research assistant", visible=True), gr.update(visible=False)
|
649 |
+
system_prompt_parts = []
|
650 |
+
if role_purpose and role_purpose.strip():
|
651 |
+
system_prompt_parts.append(role_purpose.strip())
|
652 |
+
if intended_audience and intended_audience.strip():
|
653 |
+
system_prompt_parts.append(intended_audience.strip())
|
654 |
+
if key_tasks and key_tasks.strip():
|
655 |
+
system_prompt_parts.append(key_tasks.strip())
|
656 |
+
if additional_context and additional_context.strip():
|
657 |
+
system_prompt_parts.append(additional_context.strip())
|
658 |
+
|
659 |
+
final_system_prompt = " ".join(system_prompt_parts)
|
660 |
+
else:
|
661 |
+
# Use the direct system prompt field
|
662 |
+
if not system_prompt or not system_prompt.strip():
|
663 |
+
return gr.update(value="Error: Please provide a System Prompt for the assistant", visible=True), gr.update(visible=False)
|
664 |
+
final_system_prompt = system_prompt.strip()
|
665 |
+
|
666 |
+
filename = generate_zip(name, description, final_system_prompt, model, api_key_var, temperature, max_tokens, examples_text, access_code, enable_dynamic_urls, url1, url2, url3, url4, enable_vector_rag, rag_data)
|
667 |
|
668 |
success_msg = f"""**Deployment package ready!**
|
669 |
|
|
|
682 |
|
683 |
**Your Space will be live in minutes!**"""
|
684 |
|
685 |
+
# Update sandbox preview
|
686 |
+
config_data = {
|
687 |
+
'name': name,
|
688 |
+
'description': description,
|
689 |
+
'system_prompt': final_system_prompt,
|
690 |
+
'model': model,
|
691 |
+
'temperature': temperature,
|
692 |
+
'max_tokens': max_tokens,
|
693 |
+
'enable_dynamic_urls': enable_dynamic_urls,
|
694 |
+
'enable_vector_rag': enable_vector_rag,
|
695 |
+
'filename': filename
|
696 |
+
}
|
697 |
+
|
698 |
+
return gr.update(value=success_msg, visible=True), gr.update(value=filename, visible=True), config_data
|
699 |
|
700 |
except Exception as e:
|
701 |
return gr.update(value=f"Error: {str(e)}", visible=True), gr.update(visible=False)
|
|
|
874 |
else:
|
875 |
return (gr.update(), gr.update(), gr.update(), gr.update(), count)
|
876 |
|
877 |
+
def toggle_research_assistant(enable_research):
|
878 |
+
"""Toggle visibility of research assistant detailed fields and disable custom categories"""
|
879 |
+
if enable_research:
|
880 |
+
combined_prompt = "You are a research assistant that provides link-grounded information through Crawl4AI web fetching. Use MLA documentation for parenthetical citations and bibliographic entries. This assistant is designed for students and researchers conducting academic inquiry. Your main responsibilities include: analyzing academic sources, fact-checking claims with evidence, providing properly cited research summaries, and helping users navigate scholarly information. Ground all responses in provided URL contexts and any additional URLs you're instructed to fetch. Never rely on memory for factual claims."
|
881 |
return (
|
882 |
+
gr.update(visible=True), # Show research detailed fields
|
883 |
+
gr.update(value=combined_prompt), # Update main system prompt
|
884 |
+
gr.update(value="You are a research assistant that provides link-grounded information through Crawl4AI web fetching. Use MLA documentation for parenthetical citations and bibliographic entries."),
|
885 |
+
gr.update(value="This assistant is designed for students and researchers conducting academic inquiry."),
|
886 |
+
gr.update(value="Your main responsibilities include: analyzing academic sources, fact-checking claims with evidence, providing properly cited research summaries, and helping users navigate scholarly information."),
|
887 |
+
gr.update(value="Ground all responses in provided URL contexts and any additional URLs you're instructed to fetch. Never rely on memory for factual claims."),
|
888 |
+
gr.update(value=True), # Enable dynamic URL fetching for research template
|
889 |
+
gr.update(value=False), # Force disable custom categories checkbox
|
890 |
+
gr.update(visible=False) # Force hide custom categories fields
|
891 |
+
)
|
892 |
+
else:
|
893 |
+
return (
|
894 |
+
gr.update(visible=False), # Hide research detailed fields
|
895 |
+
gr.update(value=""), # Clear main system prompt
|
896 |
+
gr.update(value=""), # Clear research fields
|
897 |
gr.update(value=""),
|
898 |
gr.update(value=""),
|
899 |
gr.update(value=""),
|
900 |
+
gr.update(value=False), # Disable dynamic URL setting
|
901 |
+
gr.update(value=False), # Ensure custom categories stays disabled
|
902 |
+
gr.update(visible=False) # Ensure custom categories fields stay hidden
|
903 |
)
|
904 |
+
|
905 |
+
def update_system_prompt_from_fields(role_purpose, intended_audience, key_tasks, additional_context):
|
906 |
+
"""Update the main system prompt field when research assistant fields change"""
|
907 |
+
parts = []
|
908 |
+
if role_purpose and role_purpose.strip():
|
909 |
+
parts.append(role_purpose.strip())
|
910 |
+
if intended_audience and intended_audience.strip():
|
911 |
+
parts.append(intended_audience.strip())
|
912 |
+
if key_tasks and key_tasks.strip():
|
913 |
+
parts.append(key_tasks.strip())
|
914 |
+
if additional_context and additional_context.strip():
|
915 |
+
parts.append(additional_context.strip())
|
916 |
+
|
917 |
+
combined = " ".join(parts)
|
918 |
+
return gr.update(value=combined)
|
919 |
+
|
920 |
+
def toggle_custom_categories(enable_custom):
|
921 |
+
"""Toggle visibility of custom categories fields and disable research assistant"""
|
922 |
+
if enable_custom:
|
923 |
return (
|
924 |
+
gr.update(visible=True), # Show custom categories fields
|
925 |
+
gr.update(value=False), # Force disable research assistant checkbox
|
926 |
+
gr.update(visible=False) # Force hide research assistant fields
|
927 |
+
)
|
928 |
+
else:
|
929 |
+
return (
|
930 |
+
gr.update(visible=False), # Hide custom categories fields
|
931 |
+
gr.update(value=False), # Ensure research assistant stays disabled
|
932 |
+
gr.update(visible=False) # Ensure research assistant fields stay hidden
|
933 |
)
|
934 |
|
935 |
# Create Gradio interface with proper tab structure
|
936 |
with gr.Blocks(title="Chat U/I Helper") as demo:
|
937 |
+
# Global state for cross-tab functionality
|
938 |
+
sandbox_state = gr.State({})
|
939 |
+
|
940 |
with gr.Tabs():
|
941 |
+
with gr.Tab("Configuration"):
|
942 |
gr.Markdown("# Spaces Configuration")
|
943 |
gr.Markdown("Convert custom assistants from HuggingChat into chat interfaces with HuggingFace Spaces. Configure and download everything needed to deploy a simple HF space using Gradio.")
|
944 |
|
|
|
978 |
|
979 |
with gr.Accordion("Assistant Configuration", open=True):
|
980 |
gr.Markdown("### Configure your assistant's behavior and capabilities")
|
981 |
+
gr.Markdown("Define the system prompt and assistant settings. You can use pre-configured templates or custom fields.")
|
982 |
+
|
983 |
+
# Main system prompt field - always visible
|
984 |
+
system_prompt = gr.Textbox(
|
985 |
+
label="System Prompt",
|
986 |
+
placeholder="You are a helpful assistant that...",
|
987 |
+
lines=4,
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
988 |
value="",
|
989 |
+
info="Define the assistant's role, purpose, and behavior in a single prompt"
|
990 |
)
|
991 |
|
992 |
+
# Assistant configuration options
|
993 |
+
with gr.Row():
|
994 |
+
enable_research_assistant = gr.Checkbox(
|
995 |
+
label="Research Template",
|
996 |
+
value=False,
|
997 |
+
info="Enable to use pre-configured research assistant settings"
|
998 |
+
)
|
999 |
+
|
1000 |
+
enable_custom_categories = gr.Checkbox(
|
1001 |
+
label="Use Custom Categories",
|
1002 |
+
value=False,
|
1003 |
+
info="Enable structured fields for defining your assistant"
|
1004 |
+
)
|
1005 |
|
1006 |
+
# Detailed fields for research assistant (initially hidden)
|
1007 |
+
with gr.Column(visible=False) as research_detailed_fields:
|
1008 |
+
gr.Markdown("*The system prompt above will be automatically populated with these fields when enabled*")
|
1009 |
+
|
1010 |
+
role_purpose = gr.Textbox(
|
1011 |
+
label="Role and Purpose",
|
1012 |
+
placeholder="You are a research assistant that...",
|
1013 |
+
lines=2,
|
1014 |
+
value="",
|
1015 |
+
info="Define what the assistant is and its primary function"
|
1016 |
+
)
|
1017 |
+
|
1018 |
+
intended_audience = gr.Textbox(
|
1019 |
+
label="Intended Audience",
|
1020 |
+
placeholder="This assistant is designed for undergraduate students...",
|
1021 |
+
lines=2,
|
1022 |
+
value="",
|
1023 |
+
info="Specify who will be using this assistant and their context"
|
1024 |
+
)
|
1025 |
+
|
1026 |
+
key_tasks = gr.Textbox(
|
1027 |
+
label="Key Tasks",
|
1028 |
+
placeholder="Your main responsibilities include...",
|
1029 |
+
lines=3,
|
1030 |
+
value="",
|
1031 |
+
info="List the specific tasks and capabilities the assistant should focus on"
|
1032 |
+
)
|
1033 |
+
|
1034 |
+
additional_context = gr.Textbox(
|
1035 |
+
label="Additional Context",
|
1036 |
+
placeholder="Remember to always...",
|
1037 |
+
lines=2,
|
1038 |
+
value="",
|
1039 |
+
info="Any additional instructions, constraints, or behavioral guidelines"
|
1040 |
+
)
|
1041 |
|
1042 |
+
# Custom categories fields (initially hidden)
|
1043 |
+
with gr.Column(visible=False) as custom_categories_fields:
|
1044 |
+
gr.Markdown("#### Custom Assistant Categories")
|
1045 |
+
gr.Markdown("*The system prompt above will be automatically populated with these fields when enabled*")
|
1046 |
+
|
1047 |
+
custom_role_purpose = gr.Textbox(
|
1048 |
+
label="Role and Purpose",
|
1049 |
+
placeholder="Define what the assistant is and its primary function",
|
1050 |
+
lines=2,
|
1051 |
+
value="",
|
1052 |
+
info="Define what the assistant is and its primary function"
|
1053 |
+
)
|
1054 |
+
|
1055 |
+
custom_intended_audience = gr.Textbox(
|
1056 |
+
label="Intended Audience",
|
1057 |
+
placeholder="Specify who will be using this assistant and their context",
|
1058 |
+
lines=2,
|
1059 |
+
value="",
|
1060 |
+
info="Specify who will be using this assistant and their context"
|
1061 |
+
)
|
1062 |
+
|
1063 |
+
custom_key_tasks = gr.Textbox(
|
1064 |
+
label="Key Tasks",
|
1065 |
+
placeholder="List the specific tasks and capabilities the assistant should focus on",
|
1066 |
+
lines=3,
|
1067 |
+
value="",
|
1068 |
+
info="List the specific tasks and capabilities the assistant should focus on"
|
1069 |
+
)
|
1070 |
+
|
1071 |
+
custom_additional_context = gr.Textbox(
|
1072 |
+
label="Additional Context",
|
1073 |
+
placeholder="Any additional instructions, constraints, or behavioral guidelines",
|
1074 |
+
lines=2,
|
1075 |
+
value="",
|
1076 |
+
info="Any additional instructions, constraints, or behavioral guidelines"
|
1077 |
+
)
|
1078 |
|
1079 |
+
examples_text = gr.Textbox(
|
1080 |
+
label="Example Prompts (one per line)",
|
1081 |
+
placeholder="Can you analyze this research paper: https://example.com/paper.pdf\nWhat are the latest findings on climate change adaptation?\nHelp me fact-check claims about renewable energy efficiency",
|
1082 |
+
lines=3,
|
1083 |
+
info="These will appear as clickable examples in the chat interface"
|
1084 |
+
)
|
1085 |
+
|
1086 |
+
with gr.Accordion("Tool Settings", open=False):
|
1087 |
+
|
1088 |
enable_dynamic_urls = gr.Checkbox(
|
1089 |
label="Enable Dynamic URL Fetching",
|
1090 |
value=False,
|
|
|
1095 |
label="Enable Document RAG",
|
1096 |
value=False,
|
1097 |
info="Upload documents for context-aware responses (PDF, DOCX, TXT, MD)",
|
1098 |
+
visible=True if HAS_RAG else False
|
1099 |
)
|
1100 |
|
1101 |
with gr.Column(visible=False) as rag_section:
|
|
|
1179 |
status = gr.Markdown(visible=False)
|
1180 |
download_file = gr.File(label="Download your zip package", visible=False)
|
1181 |
|
1182 |
+
# Connect the research assistant checkbox
|
1183 |
+
enable_research_assistant.change(
|
1184 |
+
toggle_research_assistant,
|
1185 |
+
inputs=[enable_research_assistant],
|
1186 |
+
outputs=[research_detailed_fields, system_prompt, role_purpose, intended_audience, key_tasks, additional_context, enable_dynamic_urls, enable_custom_categories, custom_categories_fields]
|
1187 |
)
|
1188 |
|
1189 |
+
# Connect the custom categories checkbox
|
1190 |
+
enable_custom_categories.change(
|
1191 |
+
toggle_custom_categories,
|
1192 |
+
inputs=[enable_custom_categories],
|
1193 |
+
outputs=[custom_categories_fields, enable_research_assistant, research_detailed_fields]
|
1194 |
+
)
|
1195 |
+
|
1196 |
+
# Connect research assistant fields to update main system prompt
|
1197 |
+
for field in [role_purpose, intended_audience, key_tasks, additional_context]:
|
1198 |
+
field.change(
|
1199 |
+
update_system_prompt_from_fields,
|
1200 |
+
inputs=[role_purpose, intended_audience, key_tasks, additional_context],
|
1201 |
+
outputs=[system_prompt]
|
1202 |
+
)
|
1203 |
+
|
1204 |
+
# Connect custom categories fields to update main system prompt
|
1205 |
+
for field in [custom_role_purpose, custom_intended_audience, custom_key_tasks, custom_additional_context]:
|
1206 |
+
field.change(
|
1207 |
+
update_system_prompt_from_fields,
|
1208 |
+
inputs=[custom_role_purpose, custom_intended_audience, custom_key_tasks, custom_additional_context],
|
1209 |
+
outputs=[system_prompt]
|
1210 |
+
)
|
1211 |
+
|
1212 |
# Connect the URL management buttons
|
1213 |
add_url_btn.click(
|
1214 |
add_urls,
|
|
|
1238 |
# Connect the generate button
|
1239 |
generate_btn.click(
|
1240 |
on_generate,
|
1241 |
+
inputs=[name, description, system_prompt, enable_research_assistant, role_purpose, intended_audience, key_tasks, additional_context, custom_role_purpose, custom_intended_audience, custom_key_tasks, custom_additional_context, model, api_key_var, temperature, max_tokens, examples_text, access_code, enable_dynamic_urls, url1, url2, url3, url4, enable_vector_rag, rag_tool_state],
|
1242 |
+
outputs=[status, download_file, sandbox_state]
|
1243 |
)
|
1244 |
+
|
1245 |
|
1246 |
+
with gr.Tab("Support"):
|
1247 |
gr.Markdown("# Chat Support")
|
1248 |
gr.Markdown("Get personalized guidance on configuring chat assistants as HuggingFace Spaces for educational & research purposes.")
|
1249 |
|
|
|
1337 |
submit.click(respond_with_cache_update, [msg, chatbot, chat_url1, chat_url2, chat_url3, chat_url4], [msg, chatbot, cache_status])
|
1338 |
msg.submit(respond_with_cache_update, [msg, chatbot, chat_url1, chat_url2, chat_url3, chat_url4], [msg, chatbot, cache_status])
|
1339 |
clear.click(clear_chat, outputs=[msg, chatbot])
|
1340 |
+
|
1341 |
+
with gr.Tab("Sandbox"):
|
1342 |
+
gr.Markdown("# Generated Space Preview")
|
1343 |
+
gr.Markdown("Preview your generated HuggingFace Space before deployment.")
|
1344 |
+
|
1345 |
+
with gr.Row():
|
1346 |
+
with gr.Column(scale=1):
|
1347 |
+
preview_info_display = gr.Markdown("Generate a space configuration to see preview here.")
|
1348 |
+
with gr.Column(scale=2):
|
1349 |
+
preview_iframe_display = gr.HTML("<div style='text-align: center; padding: 50px; color: #666;'>No preview available</div>")
|
1350 |
+
|
1351 |
|
1352 |
if __name__ == "__main__":
|
1353 |
+
# Check if running in local development with dev tunnels
|
1354 |
+
if os.environ.get('CODESPACES') or 'devtunnels.ms' in os.environ.get('GRADIO_SERVER_NAME', ''):
|
1355 |
+
demo.launch(share=True, allowed_paths=[], server_name="0.0.0.0")
|
1356 |
+
else:
|
1357 |
+
demo.launch(share=True)
|
requirements.txt
CHANGED
@@ -1,4 +1,4 @@
|
|
1 |
-
gradio
|
2 |
requests>=2.32.3
|
3 |
beautifulsoup4>=4.12.3
|
4 |
python-dotenv>=1.0.0
|
@@ -7,7 +7,7 @@ aiofiles>=24.0
|
|
7 |
|
8 |
# Vector RAG dependencies (optional)
|
9 |
sentence-transformers>=2.2.2
|
10 |
-
faiss-cpu
|
11 |
PyMuPDF>=1.23.0
|
12 |
python-docx>=0.8.11
|
13 |
-
numpy
|
|
|
1 |
+
gradio==5.35.0
|
2 |
requests>=2.32.3
|
3 |
beautifulsoup4>=4.12.3
|
4 |
python-dotenv>=1.0.0
|
|
|
7 |
|
8 |
# Vector RAG dependencies (optional)
|
9 |
sentence-transformers>=2.2.2
|
10 |
+
faiss-cpu==1.7.4
|
11 |
PyMuPDF>=1.23.0
|
12 |
python-docx>=0.8.11
|
13 |
+
numpy==1.26.4
|
test_minimal.py
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
|
3 |
+
# Minimal test to isolate the boolean iteration error
|
4 |
+
with gr.Blocks() as demo:
|
5 |
+
with gr.Tab("Test"):
|
6 |
+
name = gr.Textbox(label="Name")
|
7 |
+
checkbox = gr.Checkbox(label="Test", value=False)
|
8 |
+
button = gr.Button("Test")
|
9 |
+
|
10 |
+
def test_func(name_val, checkbox_val):
|
11 |
+
return f"Hello {name_val}, checkbox: {checkbox_val}"
|
12 |
+
|
13 |
+
button.click(
|
14 |
+
test_func,
|
15 |
+
inputs=[name, checkbox],
|
16 |
+
outputs=[name]
|
17 |
+
)
|
18 |
+
|
19 |
+
if __name__ == "__main__":
|
20 |
+
demo.launch()
|