milwright commited on
Commit
2186bf7
·
1 Parent(s): 975ba2b

Organize repository structure: move files to appropriate directories

Browse files
.gitignore CHANGED
@@ -29,22 +29,17 @@ Thumbs.db
29
  # Generated files
30
  *.zip
31
 
32
- # Test files
33
- test_*.py
34
- *_test.py
35
-
36
- # Documentation/notes (keep only essential docs)
37
- *_SUMMARY.md
38
- WEB_SEARCH_IMPLEMENTATION.md
39
- simplified_documentation.md
40
- file_upload_proposal.md
41
- TEST_PROCEDURE.md
42
 
43
  # Gradio cache
44
  .gradio/
45
  flagged/
46
 
47
- # Development images
48
  *.png
49
  !secret.png
50
  *.jpg
@@ -52,12 +47,4 @@ flagged/
52
  *.gif
53
 
54
  # Claude local files
55
- claude.local.md
56
- .claude/
57
-
58
- # Config files
59
- *.aiconfig.json
60
-
61
- # Sample/temp files
62
- test_*.txt
63
- *_sample.txt
 
29
  # Generated files
30
  *.zip
31
 
32
+ # Organized directories
33
+ docs/
34
+ tests/
35
+ development/
36
+ temp/
 
 
 
 
 
37
 
38
  # Gradio cache
39
  .gradio/
40
  flagged/
41
 
42
+ # Development images (except secret.png)
43
  *.png
44
  !secret.png
45
  *.jpg
 
47
  *.gif
48
 
49
  # Claude local files
50
+ .claude/
 
 
 
 
 
 
 
 
TEST_PROCEDURE.md DELETED
@@ -1,285 +0,0 @@
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 HTTP requests
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.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
claude.local.md DELETED
@@ -1,314 +0,0 @@
1
- # CLAUDE.md
2
-
3
- This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
-
5
- ## Project Overview
6
-
7
- Chat UI Helper is a Gradio-based tool for generating and configuring chat interfaces for HuggingFace Spaces. It creates deployable packages with custom assistants, web scraping capabilities, and optional vector RAG functionality.
8
-
9
- ## Core Architecture
10
-
11
- ### Main Application Flow (`app.py`)
12
- The application follows a three-tab Gradio interface pattern:
13
- 1. **Configuration Tab**: Space setup, assistant configuration, tool settings (lines 1267-1589)
14
- 2. **Sandbox Preview Tab**: Interactive testing with real OpenRouter API integration (lines 1591-1699)
15
- 3. **Support Docs Tab**: Comprehensive guidance and templates via `support_docs.py`
16
-
17
- ### Template Generation System
18
- - `SPACE_TEMPLATE` (lines 50-347): Complete HuggingFace Space template with export functionality and legacy tuple format compatibility
19
- - `generate_zip()` function (lines 562-652): Orchestrates package creation with all dependencies
20
- - Key template variables: `{system_prompt}`, `{model}`, `{enable_vector_rag}`, `{api_key_var}`, `{grounding_urls}`, `{enable_dynamic_urls}`
21
-
22
- ### Preview Sandbox Architecture (Enhanced)
23
- - Real OpenRouter API integration in preview mode (`preview_chat_response()` line 855)
24
- - URL context testing with dynamic add/remove functionality
25
- - Configuration-aware responses using exact model and parameters from user configuration
26
- - Fallback messaging when `OPENROUTER_API_KEY` environment variable not set
27
- - Legacy tuple format compatibility for Gradio 4.44.1 ChatInterface
28
- - **Comprehensive Debugging**: Enhanced error handling with detailed API response validation (lines 928-955)
29
- - Empty response detection and logging
30
- - API structure validation (choices, message, content)
31
- - Request payload debugging for troubleshooting
32
- - Timeout handling (30 seconds) for API requests
33
-
34
- ### Document Processing Pipeline (RAG)
35
- - **RAGTool** (`rag_tool.py`): Main orchestrator with 10MB file size validation (lines 19-79)
36
- - **DocumentProcessor** (`document_processor.py`): PDF/DOCX/TXT/MD parsing with semantic chunking (800 chars, 100 overlap)
37
- - **VectorStore** (`vector_store.py`): FAISS-based similarity search and base64 serialization
38
-
39
- ### Web Scraping Architecture
40
- Simple HTTP + BeautifulSoup approach (replacing previous Crawl4AI):
41
- - `fetch_url_content()` (lines 390-415): Basic requests with timeout and user-agent headers
42
- - Content cleaning: Removes scripts, styles, navigation elements
43
- - Content limits: ~4000 character truncation for context management
44
- - URL content caching: `get_cached_grounding_context()` (line 1019) prevents redundant fetches
45
- - `extract_urls_from_text()` (line 44): Regex-based URL extraction for dynamic fetching
46
-
47
- ## Development-Only Utilities
48
-
49
- ### MCP Servers
50
- - **Gradio Docs**: Available at https://gradio-docs-mcp.hf.space/gradio_api/mcp/sse
51
- - Use `gradio_docs.py` utility for development assistance
52
- - **CRITICAL**: Do NOT import in main application - this is for development tooling only
53
-
54
- Usage for development:
55
- ```bash
56
- python -c "from gradio_docs import gradio_docs; print(gradio_docs.search_docs('ChatInterface'))"
57
- ```
58
-
59
- ## Development Commands
60
-
61
- ### Environment Setup
62
- **Important**: This application requires Python ≥3.10 for Gradio 5.x compatibility.
63
-
64
- ```bash
65
- # Recommended: Use Python 3.11+ environment
66
- python3.11 -m venv venv311
67
- source venv311/bin/activate # or venv311\Scripts\activate on Windows
68
- pip install -r requirements.txt
69
- ```
70
-
71
- ### Running the Application
72
- ```bash
73
- # With virtual environment activated
74
- python app.py
75
- ```
76
-
77
- ### Testing Commands
78
- ```bash
79
- # Test vector database functionality (requires all RAG dependencies)
80
- python test_vector_db.py
81
-
82
- # Test OpenRouter API key validation
83
- python test_api_key.py
84
-
85
- # Test minimal Gradio functionality (for debugging)
86
- python test_minimal.py
87
-
88
- # Test preview functionality components (new)
89
- python test_preview.py
90
-
91
- # Test individual RAG components
92
- python -c "from test_vector_db import test_document_processing; test_document_processing()"
93
- python -c "from test_vector_db import test_vector_store; test_vector_store()"
94
- python -c "from test_vector_db import test_rag_tool; test_rag_tool()"
95
- ```
96
-
97
- ### Pre-Test Setup for RAG Components
98
- ```bash
99
- # Create test document for vector database testing
100
- echo "This is a test document for RAG functionality testing." > test_document.txt
101
-
102
- # Verify all dependencies are installed
103
- python -c "import sentence_transformers, faiss, fitz; print('RAG dependencies available')"
104
- ```
105
-
106
- ### Key Dependencies and Versions
107
-
108
- #### Required Dependencies
109
- - **Gradio ≥4.44.1**: Main UI framework (5.37.0 recommended for Python ≥3.10)
110
- - **requests ≥2.32.3**: HTTP requests for web content fetching
111
- - **beautifulsoup4 ≥4.12.3**: HTML parsing for web scraping
112
- - **python-dotenv ≥1.0.0**: Environment variable management
113
-
114
- #### Optional RAG Dependencies
115
- - **sentence-transformers ≥2.2.2**: Text embeddings
116
- - **faiss-cpu ==1.7.4**: Vector similarity search
117
- - **PyMuPDF ≥1.23.0**: PDF text extraction
118
- - **python-docx ≥0.8.11**: DOCX document processing
119
- - **numpy ==1.26.4**: Numerical operations
120
-
121
- ## Configuration Patterns
122
-
123
- ### Conditional Dependency Loading
124
- ```python
125
- try:
126
- from rag_tool import RAGTool
127
- HAS_RAG = True
128
- except ImportError:
129
- HAS_RAG = False
130
- RAGTool = None
131
- ```
132
- This pattern allows graceful degradation when optional vector dependencies are unavailable.
133
-
134
- ### Template Variable Substitution
135
- Generated spaces use these key substitutions:
136
- - `{system_prompt}`: Combined assistant configuration
137
- - `{grounding_urls}`: Static URL list for context
138
- - `{enable_dynamic_urls}`: Runtime URL fetching capability
139
- - `{enable_vector_rag}`: Document search integration
140
- - `{rag_data_json}`: Serialized embeddings and chunks
141
- - `{api_key_var}`: Customizable API key environment variable name
142
-
143
- ### Access Control Pattern
144
- - Environment variable `SPACE_ACCESS_CODE` for student access control
145
- - Global state management for session-based access in generated spaces
146
- - Security-first approach storing credentials as HuggingFace Spaces secrets
147
-
148
- ### RAG Integration Workflow
149
- 1. Documents uploaded through Gradio File component with conditional visibility (`HAS_RAG` flag)
150
- 2. Processed via DocumentProcessor (PDF/DOCX/TXT/MD support) in `process_documents()` function
151
- 3. Chunked and embedded using sentence-transformers (800 chars, 100 overlap)
152
- 4. FAISS index created and serialized to base64 for deployment portability
153
- 5. Embedded in generated template via `{rag_data_json}` template variable
154
-
155
- ## Implementation Notes
156
-
157
- ### Research Template System (Simplified)
158
- - **Simple Toggle**: `toggle_research_assistant()` function (line 1225) now provides simple on/off functionality
159
- - **Direct System Prompt**: Enables predefined academic research prompt with DOI verification and LibKey integration
160
- - **Auto-Enable Dynamic URLs**: Research template automatically enables dynamic URL fetching for academic sources
161
- - **Template Content**: Academic inquiry focus with DOI-verified sources, fact-checking, and proper citation requirements
162
- - **Note**: Previous complex field system (Role and Purpose, Intended Audience, Key Tasks, Additional Context) has been removed for simplified architecture
163
-
164
- ### State Management Across Tabs
165
- - Extensive use of `gr.State()` for maintaining session data
166
- - Cross-tab functionality through shared state variables (`sandbox_state`, `preview_config_state`)
167
- - URL content caching to prevent redundant web requests (`url_content_cache` global variable)
168
- - Preview debugging with comprehensive error handling and API response validation
169
-
170
- ### Gradio Compatibility and Message Format Handling
171
- - **Target Version**: Gradio 5.37.0 (requires Python ≥3.10)
172
- - **Legacy Support**: Gradio 4.44.1 compatibility with JSON schema workarounds
173
- - **Message Format**: Preview uses legacy tuple format `[user_msg, bot_msg]` for ChatInterface compatibility
174
- - **Generated Spaces**: Use modern dictionary format `{"role": "user", "content": "..."}` for OpenRouter API
175
-
176
- ### Security Considerations
177
- - Never embed API keys or access codes in generated templates
178
- - Environment variable pattern for all sensitive configuration (`{api_key_var}` template variable)
179
- - Input validation for uploaded files and URL processing
180
- - Content length limits for web scraping operations
181
-
182
- ## Testing Infrastructure
183
-
184
- ### Current Test Structure
185
- - `test_vector_db.py`: Comprehensive RAG component testing (196 lines)
186
- - `test_api_key.py`: OpenRouter API validation (85 lines)
187
- - `test_minimal.py`: Basic Gradio functionality debugging (20 lines)
188
- - `test_preview.py`: Preview functionality component testing (URL extraction, fetching, chat response)
189
-
190
- ### Test Dependencies
191
- RAG testing requires: `sentence-transformers`, `faiss-cpu`, `PyMuPDF`, `python-docx`
192
-
193
- Core testing requires: `gradio`, `requests`, `beautifulsoup4`, `python-dotenv`
194
-
195
- ### Testing Status
196
- - **Functional**: Three main test files covering core functionality
197
- - **Missing**: Automated test scripts referenced in TEST_PROCEDURE.md (`quick_test.sh`, `full_test.sh`) are documented but not implemented
198
- - **Usage**: Run individual Python test modules directly
199
-
200
- ## File Structure Notes
201
-
202
- ### Generated Space Structure
203
- All generated HuggingFace Spaces follow consistent structure:
204
- 1. Configuration section with environment variable loading
205
- 2. Web scraping functions (simple HTTP requests with BeautifulSoup)
206
- 3. RAG context retrieval (if enabled)
207
- 4. OpenRouter API integration with conversation history
208
- 5. Gradio ChatInterface with access control
209
-
210
- ### Development Files Not For Production
211
- - `gradio_docs.py`: MCP server integration (development only)
212
- - `test_*.py`: Testing utilities
213
- - `TEST_PROCEDURE.md`: Comprehensive testing methodology
214
- - `file_upload_proposal.md`: Technical architecture proposals
215
-
216
- ## Known Issues and Compatibility
217
-
218
- ### Gradio 4.44.1 JSON Schema Bug
219
- - **Issue**: TypeError in `json_schema_to_python_type` prevents app startup in some environments
220
- - **Symptom**: "argument of type 'bool' is not iterable" error during API schema generation
221
- - **Workaround**: Individual component functions work correctly (as verified by `test_preview.py`)
222
- - **Solution**: Upgrade to Gradio 5.x for full compatibility, or wait for Gradio 4.x patch
223
-
224
- ### Message Format Compatibility
225
- - **Preview Mode**: Uses legacy tuple format `[user_msg, bot_msg]` for Gradio 4.44.1 ChatInterface
226
- - **Generated Spaces**: Use modern dictionary format for OpenRouter API compatibility
227
- - **Cross-Version Support**: Template generation handles both formats appropriately
228
-
229
- ### Python Version Requirements
230
- - **Minimum**: Python 3.9 (for Gradio 4.44.1)
231
- - **Recommended**: Python 3.11+ (for Gradio 5.x and optimal performance)
232
-
233
- ## Common Claude Code Anti-Patterns to Avoid
234
-
235
- ### Message Format Reversion
236
- **❌ Don't revert to:** New dictionary format in preview functions
237
- ```python
238
- # WRONG - breaks Gradio 4.44.1 ChatInterface
239
- history.append({"role": "user", "content": message})
240
- history.append({"role": "assistant", "content": response})
241
- ```
242
- **✅ Keep:** Legacy tuple format for preview compatibility
243
- ```python
244
- # CORRECT - works with current Gradio ChatInterface
245
- history.append([message, response])
246
- ```
247
-
248
- ### Template Variable Substitution
249
- **❌ Don't change:** Template string escaping patterns in `SPACE_TEMPLATE`
250
- - Keep double backslashes: `\\n\\n` (becomes `\n\n` after Python string processing)
251
- - Keep double braces: `{{variable}}` (becomes `{variable}` after format())
252
- - **Reason**: Template undergoes two levels of processing (Python format + HuggingFace deployment)
253
-
254
- ### Research Template Function Signature
255
- **✅ Current Implementation:** Simplified function signature for research template
256
- ```python
257
- # CURRENT - simplified toggle with direct system prompt management
258
- def toggle_research_assistant(enable_research):
259
- if enable_research:
260
- return (gr.update(value=combined_prompt), gr.update(value=True))
261
- else:
262
- return (gr.update(value=""), gr.update(value=False))
263
- ```
264
- **❌ Don't revert to:** Complex field management patterns that are no longer needed
265
- - The research template no longer uses separate fields for role, audience, tasks, context
266
- - Current implementation directly manages system prompt and dynamic URL setting only
267
-
268
- ### Import Organization Anti-Patterns
269
- **❌ Don't move:** `extract_urls_from_text()` back into template string
270
- - Function must remain in main app code (line 44) for preview functionality
271
- - Template version is for generated spaces only
272
-
273
- ### URL Management Simplification
274
- **❌ Don't remove:** Dynamic URL add/remove functionality
275
- - Keep `add_urls()`, `remove_urls()`, `add_chat_urls()`, `remove_chat_urls()` functions
276
- - Maintain URL count state management with `gr.State()`
277
- - **Reason**: Users expect scalable URL input interface
278
-
279
- ### Preview Functionality Degradation
280
- **❌ Don't revert to:** Simple mock responses in preview
281
- ```python
282
- # WRONG - provides no real testing value
283
- def preview_chat_response(message, history, config_data):
284
- return "", history + [[message, "Mock response"]]
285
- ```
286
- **✅ Keep:** Real API integration with comprehensive debugging
287
- - Actual OpenRouter API calls when `OPENROUTER_API_KEY` is set
288
- - URL context fetching and processing
289
- - Configuration-aware responses using exact user settings
290
- - Comprehensive debugging for empty responses and API errors (lines 928-955)
291
-
292
- ### Research Template Simplification
293
- **✅ Current Implementation:** Simplified research template system
294
- - Simple toggle functionality without complex field management
295
- - Direct system prompt injection for academic research use cases
296
- - Auto-enables dynamic URL fetching for academic sources
297
- - **Reason**: Simplified architecture reduces maintenance complexity while preserving core functionality
298
-
299
- ### Conditional Dependency Loading
300
- **❌ Don't remove:** `HAS_RAG` flag and conditional imports
301
- ```python
302
- # WRONG - breaks installations without vector dependencies
303
- from rag_tool import RAGTool
304
- ```
305
- **✅ Keep:** Graceful degradation pattern
306
- ```python
307
- # CORRECT - allows app to work without optional dependencies
308
- try:
309
- from rag_tool import RAGTool
310
- HAS_RAG = True
311
- except ImportError:
312
- HAS_RAG = False
313
- RAGTool = None
314
- ```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
file_upload_proposal.md DELETED
@@ -1,144 +0,0 @@
1
- # File Upload System Proposal for Faculty Course Materials
2
-
3
- Based on your existing architecture, here's a comprehensive proposal for implementing file uploads with efficient parsing and deployment preservation:
4
-
5
- ## Core Architecture Design
6
-
7
- ### 1. File Processing Pipeline
8
- ```
9
- Upload → Parse → Chunk → Vector Store → RAG Integration → Deployment Package
10
- ```
11
-
12
- ### 2. File Storage Structure
13
- ```
14
- /course_materials/
15
- ├── raw_files/ # Original uploaded files
16
- ├── processed/ # Parsed text content
17
- ├── embeddings/ # Vector representations
18
- └── metadata.json # File tracking & metadata
19
- ```
20
-
21
- ## Implementation Components
22
-
23
- ### File Upload Handler (app.py:352-408 enhancement)
24
- - Add `gr.File(file_types=[".pdf", ".docx", ".txt", ".md"])` component
25
- - Support multiple file uploads with `file_count="multiple"`
26
- - Implement file validation and size limits (10MB per file)
27
-
28
- ### Document Parser Service (new: `document_parser.py`)
29
- - **PDF**: PyMuPDF for text extraction with layout preservation
30
- - **DOCX**: python-docx for structured content
31
- - **TXT/MD**: Direct text processing with metadata extraction
32
- - **Auto-detection**: File type identification and appropriate parser routing
33
-
34
- ### RAG Integration (enhancement to existing web scraping system)
35
- - **Chunking Strategy**: Semantic chunking (500-1000 tokens with 100-token overlap)
36
- - **Embeddings**: sentence-transformers/all-MiniLM-L6-v2 (lightweight, fast)
37
- - **Vector Store**: In-memory FAISS index for deployment portability
38
- - **Retrieval**: Top-k similarity search (k=3-5) with relevance scoring
39
-
40
- ### Enhanced Template (SPACE_TEMPLATE modification)
41
- ```python
42
- # Add to generated app.py
43
- COURSE_MATERIALS = json.loads('''{{course_materials_json}}''')
44
- EMBEDDINGS_INDEX = pickle.loads(base64.b64decode('''{{embeddings_base64}}'''))
45
-
46
- def get_relevant_context(query, max_contexts=3):
47
- """Retrieve relevant course material context"""
48
- # Vector similarity search
49
- # Return formatted context snippets
50
- ```
51
-
52
- ## Speed & Accuracy Optimizations
53
-
54
- ### 1. Processing Speed
55
- - Batch processing during upload (not per-query)
56
- - Lightweight embedding model (384 dimensions vs 1536)
57
- - In-memory vector store (no database dependencies)
58
- - Cached embeddings in deployment package
59
-
60
- ### 2. Query Speed
61
- - Pre-computed embeddings (no real-time encoding)
62
- - Efficient FAISS indexing for similarity search
63
- - Context caching for repeated queries
64
- - Parallel processing for multiple files
65
-
66
- ### 3. Accuracy Enhancements
67
- - Semantic chunking preserves context boundaries
68
- - Query expansion with synonyms/related terms
69
- - Relevance scoring with threshold filtering
70
- - Metadata-aware retrieval (file type, section, date)
71
-
72
- ## Deployment Package Integration
73
-
74
- ### Package Structure Enhancement
75
- ```
76
- generated_space.zip
77
- ├── app.py # Enhanced with RAG
78
- ├── requirements.txt # + sentence-transformers, faiss-cpu
79
- ├── course_materials/ # Embedded materials
80
- │ ├── embeddings.pkl # FAISS index
81
- │ ├── chunks.json # Text chunks with metadata
82
- │ └── files_metadata.json # Original file info
83
- └── README.md # Updated instructions
84
- ```
85
-
86
- ### Size Management
87
- - Compress embeddings with pickle optimization
88
- - Base64 encode for template embedding
89
- - Implement file size warnings (>50MB total)
90
- - Optional: External storage links for large datasets
91
-
92
- ## User Interface Updates
93
-
94
- ### Configuration Tab Enhancements
95
- ```python
96
- with gr.Accordion("Course Materials Upload", open=False):
97
- file_upload = gr.File(
98
- label="Upload Course Materials",
99
- file_types=[".pdf", ".docx", ".txt", ".md"],
100
- file_count="multiple"
101
- )
102
- processing_status = gr.Markdown()
103
- material_summary = gr.DataFrame() # Show processed files
104
- ```
105
-
106
- ## Technical Implementation
107
-
108
- ### Dependencies Addition (requirements.txt)
109
- ```
110
- sentence-transformers==2.2.2
111
- faiss-cpu==1.7.4
112
- PyMuPDF==1.23.0
113
- python-docx==0.8.11
114
- tiktoken==0.5.1
115
- ```
116
-
117
- ### Processing Workflow
118
- 1. **Upload**: Faculty uploads syllabi, schedules, readings
119
- 2. **Parse**: Extract text with structure preservation
120
- 3. **Chunk**: Semantic segmentation with metadata
121
- 4. **Embed**: Generate vector representations
122
- 5. **Package**: Serialize index and chunks into deployment
123
- 6. **Deploy**: Single-file space with embedded knowledge
124
-
125
- ## Performance Metrics
126
-
127
- - **Upload Processing**: ~2-5 seconds per document
128
- - **Query Response**: <200ms additional latency
129
- - **Package Size**: +5-15MB for typical course materials
130
- - **Accuracy**: 85-95% relevant context retrieval
131
- - **Memory Usage**: +50-100MB runtime overhead
132
-
133
- ## Benefits
134
-
135
- This approach maintains your existing speed while adding powerful document understanding capabilities that persist in the deployed package. Faculty can upload course materials once during configuration, and students get contextually-aware responses based on actual course content without any external dependencies in the deployed space.
136
-
137
- ## Next Steps
138
-
139
- 1. Implement document parser service
140
- 2. Add file upload UI components
141
- 3. Integrate RAG system with existing web scraping architecture
142
- 4. Enhance SPACE_TEMPLATE with embedded materials
143
- 5. Test with sample course materials
144
- 6. Optimize for deployment package size
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
hf_comparisons.aiconfig.json DELETED
@@ -1,115 +0,0 @@
1
- {
2
- "name": "Hugging Face LLM Comparisons",
3
- "schema_version": "latest",
4
- "metadata": {
5
- "parameters": {
6
- "CoLA_ex_prompt": "Is the sentence grammatical or ungrammatical?\n\n\"This building is than that one.\"",
7
- "SST_2_ex_prompt": "Is the movie review positive, negative, or neutral?\n\n\"The movie is funny, smart, visually inventive, and most of all, alive.\"",
8
- "WNLI_ex_prompt": "Sentence B replaces sentence A's ambiguous pronoun with one of the nouns - is this the correct noun?\n\n\"A) Lily spoke to Donna, breaking her concentration.\nB) Lily spoke to Donna, breaking Lily's concentration.\""
9
- },
10
- "models": {},
11
- "default_model": null,
12
- "model_parsers": null
13
- },
14
- "description": "**In this notebook, we compare the individual performance of HF hosted LLMs () on a few example questions from the GLUE benchmarks (https://gluebenchmark.com/tasks).**\n\n**Example questions taken from \"What is the GLUE Benchmark\" medium post - https://angelina-yang.medium.com/what-is-the-glue-benchmark-for-nlu-systems-61127b3cab3f**\n\n---\n\n| General Language Understanding Evaluation (GLUE) Tasks | Example Question |\n| ----------- | ----------- |\n| Corpus of Linguistic Acceptability (CoLA) | Is the sentence grammatical or ungrammatical? \"This building is than that one.\" |\n| Stanford Sentiment Treebank (SST) | Is the movie review positive, negative, or neutral? \"The movie is funny, smart, visually inventive, and most of all, alive.\" |\n| Winograd NLI (WNLI) | Sentence B replaces sentence A's ambiguous pronoun with one of the nouns - is this the correct noun? \"A) Lily spoke to Donna, breaking her concentration. B) Lily spoke to Donna, breaking Lily's concentration.\" |",
15
- "prompts": [
16
- {
17
- "name": "mistral_7b_instruct_v0.1",
18
- "input": "Is the movie review positive, negative, or neutral?\n\n\n\"The movie is funny, smart, visually inventive, and most of all, alive.\"",
19
- "metadata": {
20
- "model": {
21
- "name": "Text Generation",
22
- "settings": {
23
- "model": "mistralai/Mistral-7B-Instruct-v0.1"
24
- }
25
- },
26
- "tags": null,
27
- "parameters": {}
28
- },
29
- "outputs": [
30
- {
31
- "output_type": "execute_result",
32
- "execution_count": 0,
33
- "data": "\n\nThe movie review is positive.</s>",
34
- "mime_type": null,
35
- "metadata": {}
36
- }
37
- ]
38
- },
39
- {
40
- "name": "google_flan_t5_sm",
41
- "input": "Is the movie review positive, negative, or neutral?\n\n\"The movie is funny, smart, visually inventive, and most of all, alive.\"",
42
- "metadata": {
43
- "model": {
44
- "name": "Conversational",
45
- "settings": {
46
- "model": "google/flan-t5-small",
47
- "max_new_tokens": 250,
48
- "stream": false
49
- }
50
- },
51
- "tags": null,
52
- "parameters": {}
53
- },
54
- "outputs": [
55
- {
56
- "output_type": "execute_result",
57
- "execution_count": 0,
58
- "data": "positive",
59
- "mime_type": null,
60
- "metadata": {
61
- "raw_response": {
62
- "generated_text": "positive",
63
- "conversation": {
64
- "generated_responses": [
65
- "positive"
66
- ],
67
- "past_user_inputs": [
68
- "Is the movie review positive, negative, or neutral?\n\n\"The movie is funny, smart, visually inventive, and most of all, alive.\""
69
- ]
70
- },
71
- "warnings": [
72
- "\nNo chat template is defined for this tokenizer - using a default chat template that implements the ChatML format (without BOS/EOS tokens!). If the default is not appropriate for your model, please set `tokenizer.chat_template` to an appropriate template. See https://huggingface.co/docs/transformers/main/chat_templating for more information.\n"
73
- ]
74
- }
75
- }
76
- }
77
- ]
78
- },
79
- {
80
- "name": "tinyllama-1_1B",
81
- "input": "<|system|>\nYou are to answer the following question by the user</s>\n<|user|>\n{{SST_2_ex_prompt}}</s>\n<|assistant|>",
82
- "metadata": {
83
- "model": {
84
- "name": "Conversational",
85
- "settings": {
86
- "model": "TinyLlama/TinyLlama-1.1B-Chat-v1.0"
87
- }
88
- },
89
- "tags": null,
90
- "parameters": {}
91
- },
92
- "outputs": [
93
- {
94
- "output_type": "execute_result",
95
- "execution_count": 0,
96
- "data": "The movie review is positive.",
97
- "mime_type": null,
98
- "metadata": {
99
- "raw_response": {
100
- "generated_text": "The movie review is positive.",
101
- "conversation": {
102
- "generated_responses": [
103
- "The movie review is positive."
104
- ],
105
- "past_user_inputs": [
106
- "<|system|>\nYou are to answer the following question by the user</s>\n<|user|>\nIs the movie review positive, negative, or neutral?\n\n&quot;The movie is funny, smart, visually inventive, and most of all, alive.&quot;</s>\n<|assistant|>"
107
- ]
108
- }
109
- }
110
- }
111
- }
112
- ]
113
- }
114
- ]
115
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
test_api_key.py DELETED
@@ -1,85 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Test OpenRouter API key functionality"""
3
-
4
- import requests
5
- import json
6
-
7
- def test_openrouter_api_key(api_key):
8
- """Test if an OpenRouter API key is valid by making a simple completion request"""
9
-
10
- url = "https://openrouter.ai/api/v1/chat/completions"
11
-
12
- headers = {
13
- "Authorization": f"Bearer {api_key}",
14
- "Content-Type": "application/json",
15
- "HTTP-Referer": "https://github.com/test-api-key", # Required by OpenRouter
16
- "X-Title": "API Key Test" # Optional but recommended
17
- }
18
-
19
- # Simple test message
20
- data = {
21
- "model": "openrouter/auto", # Auto-select cheapest available model
22
- "messages": [
23
- {"role": "user", "content": "Say 'API key is working!' in exactly 4 words."}
24
- ],
25
- "max_tokens": 10,
26
- "temperature": 0.1
27
- }
28
-
29
- try:
30
- print("Testing OpenRouter API key...")
31
- response = requests.post(url, headers=headers, json=data, timeout=30)
32
-
33
- if response.status_code == 200:
34
- result = response.json()
35
- if "choices" in result and len(result["choices"]) > 0:
36
- assistant_message = result["choices"][0]["message"]["content"]
37
- print(f"✓ API key is valid!")
38
- print(f"Response: {assistant_message}")
39
- print(f"Model used: {result.get('model', 'unknown')}")
40
- return True
41
- else:
42
- print("✗ Unexpected response format")
43
- return False
44
- else:
45
- error_data = response.json() if response.headers.get('content-type', '').startswith('application/json') else {}
46
- print(f"✗ API key test failed!")
47
- print(f"Status code: {response.status_code}")
48
- print(f"Error: {error_data.get('error', {}).get('message', response.text)}")
49
-
50
- # Common error interpretations
51
- if response.status_code == 401:
52
- print("→ The API key is invalid or has been revoked")
53
- elif response.status_code == 402:
54
- print("→ The API key has insufficient credits")
55
- elif response.status_code == 429:
56
- print("→ Rate limit exceeded")
57
-
58
- return False
59
-
60
- except requests.exceptions.Timeout:
61
- print("✗ Request timed out")
62
- return False
63
- except requests.exceptions.RequestException as e:
64
- print(f"✗ Network error: {e}")
65
- return False
66
- except Exception as e:
67
- print(f"✗ Unexpected error: {e}")
68
- return False
69
-
70
- if __name__ == "__main__":
71
- # Test the provided API key
72
- api_key = "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"
73
-
74
- print(f"API Key: {api_key[:20]}...{api_key[-10:]}")
75
- print("-" * 50)
76
-
77
- success = test_openrouter_api_key(api_key)
78
-
79
- print("-" * 50)
80
- if success:
81
- print("✓ The API key is working correctly!")
82
- print("You can use this key in your Chat UI Helper application.")
83
- else:
84
- print("✗ The API key is not working.")
85
- print("Please check that the key is correct and has available credits.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
test_connection_fix.py DELETED
@@ -1,137 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Test RAG connection error fix
4
- Tests the specific multiprocessing and connection timeout issues
5
- """
6
-
7
- import os
8
- import tempfile
9
- import warnings
10
-
11
- # Set environment variables before any imports
12
- os.environ['TOKENIZERS_PARALLELISM'] = 'false'
13
- os.environ['OMP_NUM_THREADS'] = '1'
14
- os.environ['MKL_NUM_THREADS'] = '1'
15
-
16
- # Suppress warnings for cleaner output
17
- warnings.filterwarnings("ignore", category=UserWarning)
18
- warnings.filterwarnings("ignore", category=FutureWarning)
19
-
20
- def test_connection_fix():
21
- """Test the connection error fix specifically"""
22
- print("Testing RAG connection error fix...")
23
-
24
- try:
25
- # Test conditional import
26
- try:
27
- from rag_tool import RAGTool
28
- has_rag = True
29
- print("✓ RAG dependencies available")
30
- except ImportError:
31
- print("✗ RAG dependencies not available")
32
- return False
33
-
34
- # Create a test document
35
- test_content = """This is a test document for connection error testing.
36
- It contains multiple sentences to test the embedding process.
37
- The document should be processed without connection errors.
38
- This tests multiprocessing fixes and memory management."""
39
-
40
- with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as f:
41
- f.write(test_content)
42
- test_file = f.name
43
-
44
- try:
45
- print("✓ Test document created")
46
-
47
- # Initialize RAG tool with environment variables already set
48
- print("Initializing RAG tool with connection fixes...")
49
- rag_tool = RAGTool()
50
- print("✓ RAG tool initialized successfully")
51
-
52
- # Process document - this was causing the connection error
53
- print("Processing document (this was causing connection errors)...")
54
- result = rag_tool.process_uploaded_files([test_file])
55
-
56
- if result['success']:
57
- print(f"✓ Document processed successfully: {result['message']}")
58
- print(f" - Chunks created: {result.get('index_stats', {}).get('total_chunks', 'unknown')}")
59
-
60
- # Test search to ensure embeddings work
61
- context = rag_tool.get_relevant_context("test document", max_chunks=1)
62
- print(f"✓ Search test successful, context length: {len(context)}")
63
-
64
- return True
65
- else:
66
- print(f"✗ Document processing failed: {result['message']}")
67
- return False
68
-
69
- finally:
70
- # Clean up
71
- if os.path.exists(test_file):
72
- os.unlink(test_file)
73
- print("✓ Test file cleaned up")
74
-
75
- except Exception as e:
76
- print(f"✗ Test failed with error: {e}")
77
- return False
78
-
79
- def test_gradio_integration():
80
- """Test integration with Gradio interface"""
81
- print("\nTesting Gradio integration...")
82
-
83
- try:
84
- import gradio as gr
85
-
86
- # Create a minimal Gradio interface similar to the main app
87
- def test_process_documents(files):
88
- """Minimal version of process_documents for testing"""
89
- if not files:
90
- return "No files uploaded"
91
-
92
- try:
93
- from rag_tool import RAGTool
94
- rag_tool = RAGTool()
95
-
96
- # Simulate file processing
97
- file_paths = [f.name if hasattr(f, 'name') else str(f) for f in files]
98
- result = rag_tool.process_uploaded_files(file_paths)
99
-
100
- if result['success']:
101
- return f"✓ Success: {result['message']}"
102
- else:
103
- return f"✗ Failed: {result['message']}"
104
-
105
- except Exception as e:
106
- return f"✗ Error: {str(e)}"
107
-
108
- # Create interface without launching
109
- with gr.Blocks() as interface:
110
- file_input = gr.File(file_count="multiple", label="Test Documents")
111
- output = gr.Textbox(label="Result")
112
- process_btn = gr.Button("Process")
113
-
114
- process_btn.click(
115
- test_process_documents,
116
- inputs=[file_input],
117
- outputs=[output]
118
- )
119
-
120
- print("✓ Gradio interface created successfully")
121
- print(" Interface can be launched without connection errors")
122
- return True
123
-
124
- except Exception as e:
125
- print(f"✗ Gradio integration test failed: {e}")
126
- return False
127
-
128
- if __name__ == "__main__":
129
- success = test_connection_fix()
130
- if success:
131
- success = test_gradio_integration()
132
-
133
- if success:
134
- print("\n🎉 All connection error fixes are working!")
135
- print("The RAG processing should now work without connection timeouts.")
136
- else:
137
- print("\n❌ Some tests failed. Check the error messages above.")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
test_document.txt DELETED
@@ -1,24 +0,0 @@
1
- Vector Database Test Document
2
-
3
- This is a test document for evaluating the vector database functionality.
4
-
5
- Section 1: Introduction to Vector Databases
6
- Vector databases store and query high-dimensional vector representations of data. They enable semantic search by finding vectors similar to a query vector in an embedding space.
7
-
8
- Section 2: Use Cases
9
- Common applications include:
10
- - Document retrieval and question answering
11
- - Similarity search for products or content
12
- - Recommendation systems
13
- - Semantic search in chatbots
14
-
15
- Section 3: Technical Implementation
16
- Vector databases typically use embedding models to convert text into dense vectors, then use algorithms like cosine similarity or approximate nearest neighbor search to find relevant results.
17
-
18
- Section 4: Benefits
19
- - Semantic understanding beyond keyword matching
20
- - Scalable retrieval for large document collections
21
- - Integration with modern AI systems and large language models
22
- - Support for multi-modal data (text, images, audio)
23
-
24
- This document should generate multiple chunks when processed by the system.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
test_gradio_simple.py DELETED
@@ -1,24 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Simple test to verify if the gradio app can start without schema errors
4
- """
5
-
6
- import gradio as gr
7
-
8
- def simple_function(message, history):
9
- return "", history + [[message, "Test response"]]
10
-
11
- # Create a simple interface to test
12
- with gr.Blocks() as demo:
13
- chatbot = gr.Chatbot()
14
- msg = gr.Textbox()
15
-
16
- msg.submit(simple_function, [msg, chatbot], [msg, chatbot])
17
-
18
- if __name__ == "__main__":
19
- print("Testing simple Gradio interface...")
20
- try:
21
- demo.launch(server_name="127.0.0.1", server_port=7862, share=False, prevent_thread_lock=True)
22
- print("✅ Simple Gradio interface works")
23
- except Exception as e:
24
- print(f"❌ Simple Gradio interface failed: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
test_minimal.py DELETED
@@ -1,20 +0,0 @@
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()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
test_preview.py DELETED
@@ -1,110 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Test script for preview functionality
4
- """
5
-
6
- import os
7
- import sys
8
- import tempfile
9
-
10
- # Add current directory to path for imports
11
- sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
12
-
13
- def test_preview_chat_response():
14
- """Test the preview chat response function"""
15
- try:
16
- from app import preview_chat_response
17
-
18
- # Mock config data
19
- config_data = {
20
- 'name': 'Test Assistant',
21
- 'model': 'google/gemini-2.0-flash-001',
22
- 'system_prompt': 'You are a helpful assistant.',
23
- 'temperature': 0.7,
24
- 'max_tokens': 500,
25
- 'enable_dynamic_urls': False,
26
- 'enable_vector_rag': False
27
- }
28
-
29
- # Test with no API key (should give preview message)
30
- if 'OPENROUTER_API_KEY' in os.environ:
31
- del os.environ['OPENROUTER_API_KEY']
32
-
33
- message = "Hello, how are you?"
34
- history = []
35
-
36
- result_msg, result_history = preview_chat_response(
37
- message, history, config_data, "", "", "", ""
38
- )
39
-
40
- print("✅ preview_chat_response function works")
41
- print(f"Result message: {result_msg}")
42
- print(f"History length: {len(result_history)}")
43
- print(f"Last response: {result_history[-1] if result_history else 'None'}")
44
-
45
- return True
46
-
47
- except Exception as e:
48
- print(f"❌ preview_chat_response failed: {e}")
49
- return False
50
-
51
- def test_url_extraction():
52
- """Test URL extraction function"""
53
- try:
54
- from app import extract_urls_from_text
55
-
56
- test_text = "Check out https://example.com and also https://test.org/page"
57
- urls = extract_urls_from_text(test_text)
58
-
59
- print("✅ extract_urls_from_text works")
60
- print(f"Extracted URLs: {urls}")
61
-
62
- return True
63
-
64
- except Exception as e:
65
- print(f"❌ extract_urls_from_text failed: {e}")
66
- return False
67
-
68
- def test_url_fetching():
69
- """Test URL content fetching"""
70
- try:
71
- from app import fetch_url_content
72
-
73
- # Test with a simple URL
74
- content = fetch_url_content("https://httpbin.org/get")
75
-
76
- print("✅ fetch_url_content works")
77
- print(f"Content length: {len(content)}")
78
- print(f"Content preview: {content[:100]}...")
79
-
80
- return True
81
-
82
- except Exception as e:
83
- print(f"❌ fetch_url_content failed: {e}")
84
- return False
85
-
86
- if __name__ == "__main__":
87
- print("Testing preview functionality components...")
88
-
89
- tests = [
90
- test_url_extraction,
91
- test_url_fetching,
92
- test_preview_chat_response
93
- ]
94
-
95
- passed = 0
96
- total = len(tests)
97
-
98
- for test in tests:
99
- if test():
100
- passed += 1
101
- print()
102
-
103
- print(f"Test Results: {passed}/{total} passed")
104
-
105
- if passed == total:
106
- print("✅ All preview functionality tests passed!")
107
- sys.exit(0)
108
- else:
109
- print("❌ Some tests failed")
110
- sys.exit(1)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
test_rag_fix.py DELETED
@@ -1,182 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Test script to verify RAG functionality fixes
4
- """
5
-
6
- import os
7
- import tempfile
8
- import warnings
9
- from pathlib import Path
10
-
11
- # Suppress known warnings
12
- warnings.filterwarnings("ignore", message=".*use_auth_token.*")
13
- warnings.filterwarnings("ignore", message=".*urllib3.*")
14
- warnings.filterwarnings("ignore", message=".*resource_tracker.*")
15
-
16
- # Set environment variables to prevent multiprocessing issues
17
- os.environ['TOKENIZERS_PARALLELISM'] = 'false'
18
-
19
- def test_rag_dependencies():
20
- """Test that RAG dependencies are available"""
21
- print("Testing RAG dependencies...")
22
-
23
- try:
24
- import sentence_transformers
25
- print("✅ sentence-transformers available")
26
- except ImportError:
27
- print("❌ sentence-transformers not available")
28
- return False
29
-
30
- try:
31
- import faiss
32
- print("✅ faiss-cpu available")
33
- except ImportError:
34
- print("❌ faiss-cpu not available")
35
- return False
36
-
37
- try:
38
- import fitz # PyMuPDF
39
- print("✅ PyMuPDF available")
40
- except ImportError:
41
- print("⚠️ PyMuPDF not available (PDF processing disabled)")
42
-
43
- try:
44
- from docx import Document
45
- print("✅ python-docx available")
46
- except ImportError:
47
- print("⚠️ python-docx not available (DOCX processing disabled)")
48
-
49
- return True
50
-
51
- def test_vector_store_initialization():
52
- """Test vector store initialization with improved error handling"""
53
- print("\nTesting vector store initialization...")
54
-
55
- try:
56
- from vector_store import VectorStore
57
-
58
- # Test with CPU-only settings
59
- store = VectorStore(embedding_model="all-MiniLM-L6-v2")
60
- print("✅ VectorStore created successfully")
61
-
62
- # Test a small embedding operation
63
- test_texts = ["This is a test sentence.", "Another test sentence."]
64
- embeddings = store.create_embeddings(test_texts)
65
- print(f"✅ Created embeddings: shape {embeddings.shape}")
66
-
67
- return True
68
-
69
- except Exception as e:
70
- print(f"❌ VectorStore initialization failed: {e}")
71
- return False
72
-
73
- def test_document_processing():
74
- """Test document processing with a simple text file"""
75
- print("\nTesting document processing...")
76
-
77
- try:
78
- from document_processor import DocumentProcessor
79
-
80
- # Create a temporary test file
81
- with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as f:
82
- f.write("This is a test document for RAG processing. ")
83
- f.write("It contains multiple sentences that should be processed into chunks. ")
84
- f.write("Each chunk should have proper metadata and be ready for embedding.")
85
- test_file = f.name
86
-
87
- try:
88
- processor = DocumentProcessor(chunk_size=50, chunk_overlap=10)
89
- chunks = processor.process_file(test_file)
90
-
91
- print(f"✅ Created {len(chunks)} chunks from test document")
92
- if chunks:
93
- print(f" First chunk: {chunks[0].text[:50]}...")
94
- print(f" Metadata keys: {list(chunks[0].metadata.keys())}")
95
-
96
- return True
97
-
98
- finally:
99
- # Clean up test file
100
- os.unlink(test_file)
101
-
102
- except Exception as e:
103
- print(f"❌ Document processing failed: {e}")
104
- return False
105
-
106
- def test_rag_tool_integration():
107
- """Test the complete RAG tool integration"""
108
- print("\nTesting complete RAG tool integration...")
109
-
110
- try:
111
- from rag_tool import RAGTool
112
-
113
- # Create a temporary test file
114
- with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as f:
115
- f.write("RAG integration test document. ")
116
- f.write("This document tests the complete RAG pipeline from file processing to vector search. ")
117
- f.write("The system should handle this without crashing the server.")
118
- test_file = f.name
119
-
120
- try:
121
- rag_tool = RAGTool()
122
- result = rag_tool.process_uploaded_files([test_file])
123
-
124
- if result['success']:
125
- print(f"✅ RAG processing succeeded: {result['message']}")
126
- print(f" Files processed: {len(result['summary']['files_processed'])}")
127
- print(f" Total chunks: {result['summary']['total_chunks']}")
128
-
129
- # Test search functionality
130
- context = rag_tool.get_relevant_context("test document")
131
- if context:
132
- print(f"✅ Search functionality working: {context[:100]}...")
133
- else:
134
- print("⚠️ Search returned no results")
135
-
136
- return True
137
- else:
138
- print(f"❌ RAG processing failed: {result['message']}")
139
- return False
140
-
141
- finally:
142
- # Clean up test file
143
- os.unlink(test_file)
144
-
145
- except Exception as e:
146
- print(f"❌ RAG tool integration failed: {e}")
147
- return False
148
-
149
- def main():
150
- """Run all RAG tests"""
151
- print("🚀 Testing RAG functionality fixes...")
152
- print("=" * 50)
153
-
154
- tests = [
155
- test_rag_dependencies,
156
- test_vector_store_initialization,
157
- test_document_processing,
158
- test_rag_tool_integration
159
- ]
160
-
161
- passed = 0
162
- total = len(tests)
163
-
164
- for test in tests:
165
- try:
166
- if test():
167
- passed += 1
168
- except Exception as e:
169
- print(f"❌ Test failed with exception: {e}")
170
-
171
- print("\n" + "=" * 50)
172
- print(f"📊 Test Results: {passed}/{total} tests passed")
173
-
174
- if passed == total:
175
- print("🎉 All tests passed! RAG functionality should work correctly.")
176
- return True
177
- else:
178
- print("⚠️ Some tests failed. Check error messages above.")
179
- return False
180
-
181
- if __name__ == "__main__":
182
- main()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
test_sample.txt DELETED
@@ -1,8 +0,0 @@
1
- This is a sample document for testing the RAG functionality.
2
- It contains multiple paragraphs of text that will be processed and chunked.
3
-
4
- The vector store will create embeddings for these chunks and allow semantic search.
5
- This enables context-aware responses based on uploaded documents.
6
-
7
- The system supports PDF, DOCX, TXT, and Markdown files.
8
- It uses FAISS for efficient similarity search and sentence transformers for embeddings.
 
 
 
 
 
 
 
 
 
test_vector_db.py DELETED
@@ -1,196 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Test script to verify vector database creation functionality
4
- """
5
-
6
- import sys
7
- import os
8
- from pathlib import Path
9
-
10
- # Add current directory to path to import modules
11
- sys.path.append(str(Path(__file__).parent))
12
-
13
- try:
14
- from rag_tool import RAGTool
15
- from vector_store import VectorStore
16
- from document_processor import DocumentProcessor
17
- print("✅ Successfully imported all RAG modules")
18
- except ImportError as e:
19
- print(f"❌ Failed to import RAG modules: {e}")
20
- sys.exit(1)
21
-
22
- def test_document_processing():
23
- """Test document processing functionality"""
24
- print("\n=== Testing Document Processing ===")
25
-
26
- processor = DocumentProcessor(chunk_size=200, chunk_overlap=50)
27
-
28
- # Test with our test document
29
- test_file = "test_document.txt"
30
- if not os.path.exists(test_file):
31
- print(f"❌ Test file {test_file} not found")
32
- return False
33
-
34
- try:
35
- chunks = processor.process_file(test_file)
36
- print(f"✅ Processed {test_file} into {len(chunks)} chunks")
37
-
38
- # Show first chunk
39
- if chunks:
40
- first_chunk = chunks[0]
41
- print(f"First chunk preview: {first_chunk.text[:100]}...")
42
- print(f"Chunk metadata: {first_chunk.metadata}")
43
-
44
- return True
45
- except Exception as e:
46
- print(f"❌ Failed to process document: {e}")
47
- return False
48
-
49
- def test_vector_store():
50
- """Test vector store functionality"""
51
- print("\n=== Testing Vector Store ===")
52
-
53
- try:
54
- # Initialize vector store
55
- vector_store = VectorStore()
56
- print("✅ Initialized vector store")
57
-
58
- # Create test data
59
- test_chunks = [
60
- {
61
- 'text': 'Vector databases are used for semantic search',
62
- 'chunk_id': 'test1',
63
- 'metadata': {'file_name': 'test.txt', 'chunk_index': 0}
64
- },
65
- {
66
- 'text': 'Machine learning models convert text to embeddings',
67
- 'chunk_id': 'test2',
68
- 'metadata': {'file_name': 'test.txt', 'chunk_index': 1}
69
- },
70
- {
71
- 'text': 'FAISS provides efficient similarity search capabilities',
72
- 'chunk_id': 'test3',
73
- 'metadata': {'file_name': 'test.txt', 'chunk_index': 2}
74
- }
75
- ]
76
-
77
- # Build index
78
- print("Building vector index...")
79
- vector_store.build_index(test_chunks, show_progress=True)
80
- print("✅ Built vector index")
81
-
82
- # Test search
83
- query = "How do vector databases work?"
84
- results = vector_store.search(query, top_k=2)
85
-
86
- print(f"Search results for '{query}':")
87
- for i, result in enumerate(results):
88
- print(f" {i+1}. Score: {result.score:.3f} - {result.text[:50]}...")
89
-
90
- # Test serialization
91
- serialized = vector_store.serialize()
92
- print(f"✅ Serialized data size: {len(serialized['index_base64'])} characters")
93
-
94
- return True
95
-
96
- except Exception as e:
97
- print(f"❌ Failed vector store test: {e}")
98
- import traceback
99
- traceback.print_exc()
100
- return False
101
-
102
- def test_rag_tool():
103
- """Test complete RAG tool functionality"""
104
- print("\n=== Testing RAG Tool ===")
105
-
106
- try:
107
- # Initialize RAG tool
108
- rag_tool = RAGTool()
109
- print("✅ Initialized RAG tool")
110
-
111
- # Process test document
112
- test_files = ["test_document.txt"]
113
- result = rag_tool.process_uploaded_files(test_files)
114
-
115
- if result['success']:
116
- print(f"✅ {result['message']}")
117
-
118
- # Show summary
119
- summary = result['summary']
120
- print(f"Files processed: {summary['total_files']}")
121
- print(f"Total chunks: {summary['total_chunks']}")
122
-
123
- # Test context retrieval
124
- query = "What are the benefits of vector databases?"
125
- context = rag_tool.get_relevant_context(query, max_chunks=2)
126
-
127
- if context:
128
- print(f"\nContext for '{query}':")
129
- print(context[:300] + "..." if len(context) > 300 else context)
130
- print("✅ Successfully retrieved context")
131
- else:
132
- print("⚠️ No context retrieved")
133
-
134
- # Test serialization for deployment
135
- serialized_data = rag_tool.get_serialized_data()
136
- if serialized_data:
137
- print("✅ Successfully serialized RAG data for deployment")
138
- print(f"Serialized keys: {list(serialized_data.keys())}")
139
- else:
140
- print("❌ Failed to serialize RAG data")
141
-
142
- return True
143
- else:
144
- print(f"❌ {result['message']}")
145
- return False
146
-
147
- except Exception as e:
148
- print(f"❌ Failed RAG tool test: {e}")
149
- import traceback
150
- traceback.print_exc()
151
- return False
152
-
153
- def main():
154
- """Run all tests"""
155
- print("=== Vector Database Testing ===")
156
- print("Testing vector database creation and functionality...")
157
-
158
- # Check dependencies
159
- print("\n=== Checking Dependencies ===")
160
- try:
161
- import sentence_transformers
162
- import faiss
163
- import fitz # PyMuPDF
164
- print("✅ All required dependencies available")
165
- except ImportError as e:
166
- print(f"❌ Missing dependency: {e}")
167
- return
168
-
169
- # Run tests
170
- tests = [
171
- ("Document Processing", test_document_processing),
172
- ("Vector Store", test_vector_store),
173
- ("RAG Tool", test_rag_tool)
174
- ]
175
-
176
- results = []
177
- for test_name, test_func in tests:
178
- print(f"\n{'='*20}")
179
- success = test_func()
180
- results.append((test_name, success))
181
-
182
- # Summary
183
- print(f"\n{'='*40}")
184
- print("TEST SUMMARY:")
185
- for test_name, success in results:
186
- status = "✅ PASS" if success else "❌ FAIL"
187
- print(f" {test_name}: {status}")
188
-
189
- all_passed = all(success for _, success in results)
190
- if all_passed:
191
- print("\n🎉 All tests passed! Vector database functionality is working.")
192
- else:
193
- print("\n⚠️ Some tests failed. Check the output above for details.")
194
-
195
- if __name__ == "__main__":
196
- main()