Spaces:
Running
Running
milwright
commited on
Commit
Β·
9ad9eac
1
Parent(s):
a51de86
update project files: add config.json, test_app.py, update app.py, readme, and gitignore
Browse files- .gitignore +4 -1
- README.md +3 -0
- app.py +29 -7
- config.json +5 -0
- test_app.py +191 -0
.gitignore
CHANGED
|
@@ -56,4 +56,7 @@ testing/
|
|
| 56 |
|
| 57 |
# Test files
|
| 58 |
test_complete_system.py
|
| 59 |
-
test_grounding.py
|
|
|
|
|
|
|
|
|
|
|
|
| 56 |
|
| 57 |
# Test files
|
| 58 |
test_complete_system.py
|
| 59 |
+
test_grounding.py
|
| 60 |
+
|
| 61 |
+
# Markdown files
|
| 62 |
+
tts_integration_guide.md
|
README.md
CHANGED
|
@@ -89,6 +89,9 @@ Through OpenRouter integration:
|
|
| 89 |
|
| 90 |
## π Documentation
|
| 91 |
|
|
|
|
|
|
|
|
|
|
| 92 |
The application includes comprehensive built-in documentation:
|
| 93 |
- **Step 1**: Configure & Preview Your Space
|
| 94 |
- Templates & Identity
|
|
|
|
| 89 |
|
| 90 |
## π Documentation
|
| 91 |
|
| 92 |
+
### [π Full Documentation](docs.md)
|
| 93 |
+
Complete step-by-step guide with screenshots and detailed instructions.
|
| 94 |
+
|
| 95 |
The application includes comprehensive built-in documentation:
|
| 96 |
- **Step 1**: Configure & Preview Your Space
|
| 97 |
- Templates & Identity
|
app.py
CHANGED
|
@@ -153,7 +153,8 @@ class SpaceGenerator:
|
|
| 153 |
self.system_prompt_input = gr.Textbox(
|
| 154 |
label="System Prompt",
|
| 155 |
placeholder="You are a helpful AI assistant...",
|
| 156 |
-
lines=5
|
|
|
|
| 157 |
)
|
| 158 |
|
| 159 |
self.model_input = gr.Dropdown(
|
|
@@ -242,9 +243,9 @@ class SpaceGenerator:
|
|
| 242 |
add_url_btn = gr.Button("β Add URL", size="sm")
|
| 243 |
remove_url_btn = gr.Button("β Remove URL", size="sm", visible=False)
|
| 244 |
|
| 245 |
-
#
|
| 246 |
with gr.Group():
|
| 247 |
-
gr.Markdown("### π
|
| 248 |
gr.Markdown(
|
| 249 |
"Configure the required secrets in your HuggingFace Space settings."
|
| 250 |
)
|
|
@@ -273,7 +274,7 @@ class SpaceGenerator:
|
|
| 273 |
interactive=False # Make non-editable
|
| 274 |
)
|
| 275 |
|
| 276 |
-
# Instructions
|
| 277 |
with gr.Accordion("π Step-by-Step Instructions", open=False):
|
| 278 |
gr.Markdown(
|
| 279 |
"""### How to Configure Secrets in HuggingFace Spaces
|
|
@@ -288,9 +289,13 @@ class SpaceGenerator:
|
|
| 288 |
|
| 289 |
**Step 3: Add Required Secrets**
|
| 290 |
|
|
|
|
|
|
|
|
|
|
| 291 |
Add the following secrets to your Space:
|
| 292 |
|
| 293 |
1. **API_KEY** - Your OpenRouter API key (required)
|
|
|
|
| 294 |
- Get your key at: https://openrouter.ai/keys
|
| 295 |
- Value should start with `sk-or-`
|
| 296 |
- This enables AI responses
|
|
@@ -669,9 +674,26 @@ class SpaceGenerator:
|
|
| 669 |
)
|
| 670 |
|
| 671 |
def _create_documentation_tab(self):
|
| 672 |
-
"""Create the documentation tab"""
|
| 673 |
-
|
| 674 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 675 |
|
| 676 |
def _apply_template(self, template_name, prev_template, cache,
|
| 677 |
name, tagline, desc, prompt, model, language, temp, tokens, *args):
|
|
|
|
| 153 |
self.system_prompt_input = gr.Textbox(
|
| 154 |
label="System Prompt",
|
| 155 |
placeholder="You are a helpful AI assistant...",
|
| 156 |
+
lines=5,
|
| 157 |
+
info="The system prompt that guides the AI's behavior and responses."
|
| 158 |
)
|
| 159 |
|
| 160 |
self.model_input = gr.Dropdown(
|
|
|
|
| 243 |
add_url_btn = gr.Button("β Add URL", size="sm")
|
| 244 |
remove_url_btn = gr.Button("β Remove URL", size="sm", visible=False)
|
| 245 |
|
| 246 |
+
# Environment Variables
|
| 247 |
with gr.Group():
|
| 248 |
+
gr.Markdown("### π Environment Variables")
|
| 249 |
gr.Markdown(
|
| 250 |
"Configure the required secrets in your HuggingFace Space settings."
|
| 251 |
)
|
|
|
|
| 274 |
interactive=False # Make non-editable
|
| 275 |
)
|
| 276 |
|
| 277 |
+
# Instructions
|
| 278 |
with gr.Accordion("π Step-by-Step Instructions", open=False):
|
| 279 |
gr.Markdown(
|
| 280 |
"""### How to Configure Secrets in HuggingFace Spaces
|
|
|
|
| 289 |
|
| 290 |
**Step 3: Add Required Secrets**
|
| 291 |
|
| 292 |
+
> π‘ **Visual Guide**: The screenshot below shows the "New secret" dialog where you'll enter your API key:
|
| 293 |
+
> 
|
| 294 |
+
|
| 295 |
Add the following secrets to your Space:
|
| 296 |
|
| 297 |
1. **API_KEY** - Your OpenRouter API key (required)
|
| 298 |
+
- Name: `API_KEY` (exactly as shown)
|
| 299 |
- Get your key at: https://openrouter.ai/keys
|
| 300 |
- Value should start with `sk-or-`
|
| 301 |
- This enables AI responses
|
|
|
|
| 674 |
)
|
| 675 |
|
| 676 |
def _create_documentation_tab(self):
|
| 677 |
+
"""Create the documentation tab with external link"""
|
| 678 |
+
with gr.Column():
|
| 679 |
+
gr.Markdown("""
|
| 680 |
+
# π Documentation
|
| 681 |
+
|
| 682 |
+
For detailed instructions on using ChatUI Helper, please refer to our comprehensive documentation.
|
| 683 |
+
|
| 684 |
+
### π [View Documentation β](docs.md)
|
| 685 |
+
|
| 686 |
+
The documentation includes:
|
| 687 |
+
- π Quick Start Guide
|
| 688 |
+
- π Step-by-step configuration instructions
|
| 689 |
+
- π³οΈ Deployment guide for HuggingFace Spaces
|
| 690 |
+
- π§ Troubleshooting common issues
|
| 691 |
+
- π Additional resources and links
|
| 692 |
+
|
| 693 |
+
---
|
| 694 |
+
|
| 695 |
+
**Tip:** You can open the documentation in a new tab to reference it while configuring your Space.
|
| 696 |
+
""")
|
| 697 |
|
| 698 |
def _apply_template(self, template_name, prev_template, cache,
|
| 699 |
name, tagline, desc, prompt, model, language, temp, tokens, *args):
|
config.json
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"assistant_name": "Test Assistant",
|
| 3 |
+
"system_prompt": "Test prompt",
|
| 4 |
+
"model_id": "gemini/gemini-1.5-flash-latest"
|
| 5 |
+
}
|
test_app.py
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/usr/bin/env python3
|
| 2 |
+
"""Test script for ChatUI Helper application"""
|
| 3 |
+
|
| 4 |
+
import sys
|
| 5 |
+
import json
|
| 6 |
+
from pathlib import Path
|
| 7 |
+
|
| 8 |
+
def test_imports():
|
| 9 |
+
"""Test all module imports"""
|
| 10 |
+
try:
|
| 11 |
+
from app import SpaceGenerator
|
| 12 |
+
print("β
app.py imports successfully")
|
| 13 |
+
|
| 14 |
+
from utils import ConfigurationManager, AVAILABLE_THEMES, fetch_url_content
|
| 15 |
+
print("β
utils.py imports successfully")
|
| 16 |
+
|
| 17 |
+
from space_template import get_template, validate_template
|
| 18 |
+
print("β
space_template.py imports successfully")
|
| 19 |
+
|
| 20 |
+
from support_docs import create_support_docs
|
| 21 |
+
print("β
support_docs.py imports successfully")
|
| 22 |
+
|
| 23 |
+
return True
|
| 24 |
+
except Exception as e:
|
| 25 |
+
print(f"β Import error: {e}")
|
| 26 |
+
return False
|
| 27 |
+
|
| 28 |
+
def test_configuration():
|
| 29 |
+
"""Test configuration management"""
|
| 30 |
+
try:
|
| 31 |
+
from utils import ConfigurationManager
|
| 32 |
+
|
| 33 |
+
test_config = {
|
| 34 |
+
"assistant_name": "Test Assistant",
|
| 35 |
+
"system_prompt": "Test prompt",
|
| 36 |
+
"model_id": "gemini/gemini-1.5-flash-latest"
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
cm = ConfigurationManager(test_config)
|
| 40 |
+
print("β
ConfigurationManager initialized")
|
| 41 |
+
|
| 42 |
+
# Test save and load
|
| 43 |
+
cm.save_config(test_config)
|
| 44 |
+
loaded = cm.load_config()
|
| 45 |
+
print("β
Config save/load works")
|
| 46 |
+
|
| 47 |
+
return True
|
| 48 |
+
except Exception as e:
|
| 49 |
+
print(f"β Configuration error: {e}")
|
| 50 |
+
return False
|
| 51 |
+
|
| 52 |
+
def test_templates():
|
| 53 |
+
"""Test academic templates"""
|
| 54 |
+
try:
|
| 55 |
+
with open('academic_templates.json', 'r') as f:
|
| 56 |
+
templates = json.load(f)
|
| 57 |
+
|
| 58 |
+
print(f"β
Loaded {len(templates)} academic templates")
|
| 59 |
+
|
| 60 |
+
for name, template in templates.items():
|
| 61 |
+
required_fields = ['assistant_name', 'tagline', 'system_prompt', 'example_prompts']
|
| 62 |
+
for field in required_fields:
|
| 63 |
+
if field not in template:
|
| 64 |
+
print(f"β Template '{name}' missing field: {field}")
|
| 65 |
+
return False
|
| 66 |
+
|
| 67 |
+
print("β
All templates have required fields")
|
| 68 |
+
return True
|
| 69 |
+
except Exception as e:
|
| 70 |
+
print(f"β Template error: {e}")
|
| 71 |
+
return False
|
| 72 |
+
|
| 73 |
+
def test_space_template():
|
| 74 |
+
"""Test space template generation"""
|
| 75 |
+
try:
|
| 76 |
+
from space_template import get_template, validate_template
|
| 77 |
+
|
| 78 |
+
validate_template()
|
| 79 |
+
print("β
Template validation passed")
|
| 80 |
+
|
| 81 |
+
template = get_template()
|
| 82 |
+
print(f"β
Template size: {len(template)} characters")
|
| 83 |
+
|
| 84 |
+
# Check for critical placeholders
|
| 85 |
+
placeholders = [
|
| 86 |
+
'{assistant_name}',
|
| 87 |
+
'{system_prompt}',
|
| 88 |
+
'{model_id}',
|
| 89 |
+
'{temperature}',
|
| 90 |
+
'{max_tokens}'
|
| 91 |
+
]
|
| 92 |
+
|
| 93 |
+
for placeholder in placeholders:
|
| 94 |
+
if placeholder not in template:
|
| 95 |
+
print(f"β Missing placeholder: {placeholder}")
|
| 96 |
+
return False
|
| 97 |
+
|
| 98 |
+
print("β
All critical placeholders present")
|
| 99 |
+
return True
|
| 100 |
+
except Exception as e:
|
| 101 |
+
print(f"β Space template error: {e}")
|
| 102 |
+
return False
|
| 103 |
+
|
| 104 |
+
def test_themes():
|
| 105 |
+
"""Test theme availability"""
|
| 106 |
+
try:
|
| 107 |
+
from utils import AVAILABLE_THEMES
|
| 108 |
+
|
| 109 |
+
print(f"β
{len(AVAILABLE_THEMES)} themes available")
|
| 110 |
+
|
| 111 |
+
for name, theme_class in AVAILABLE_THEMES.items():
|
| 112 |
+
print(f" - {name}")
|
| 113 |
+
|
| 114 |
+
return True
|
| 115 |
+
except Exception as e:
|
| 116 |
+
print(f"β Theme error: {e}")
|
| 117 |
+
return False
|
| 118 |
+
|
| 119 |
+
def test_docs():
|
| 120 |
+
"""Test documentation files"""
|
| 121 |
+
try:
|
| 122 |
+
# Check docs.md exists and has content
|
| 123 |
+
docs_path = Path('docs.md')
|
| 124 |
+
if not docs_path.exists():
|
| 125 |
+
print("β docs.md not found")
|
| 126 |
+
return False
|
| 127 |
+
|
| 128 |
+
content = docs_path.read_text()
|
| 129 |
+
print(f"β
docs.md exists ({len(content)} characters)")
|
| 130 |
+
|
| 131 |
+
# Check for images
|
| 132 |
+
import re
|
| 133 |
+
img_pattern = r'<img[^>]+src="([^"]+)"'
|
| 134 |
+
images = re.findall(img_pattern, content)
|
| 135 |
+
print(f"β
Found {len(images)} image references in docs.md")
|
| 136 |
+
|
| 137 |
+
# Check image files exist
|
| 138 |
+
img_dir = Path('img')
|
| 139 |
+
if img_dir.exists():
|
| 140 |
+
img_files = list(img_dir.glob('*.png'))
|
| 141 |
+
print(f"β
Found {len(img_files)} image files")
|
| 142 |
+
|
| 143 |
+
return True
|
| 144 |
+
except Exception as e:
|
| 145 |
+
print(f"β Documentation error: {e}")
|
| 146 |
+
return False
|
| 147 |
+
|
| 148 |
+
def main():
|
| 149 |
+
"""Run all tests"""
|
| 150 |
+
print("=" * 50)
|
| 151 |
+
print("ChatUI Helper Test Suite")
|
| 152 |
+
print("=" * 50)
|
| 153 |
+
|
| 154 |
+
tests = [
|
| 155 |
+
("Imports", test_imports),
|
| 156 |
+
("Configuration", test_configuration),
|
| 157 |
+
("Templates", test_templates),
|
| 158 |
+
("Space Template", test_space_template),
|
| 159 |
+
("Themes", test_themes),
|
| 160 |
+
("Documentation", test_docs)
|
| 161 |
+
]
|
| 162 |
+
|
| 163 |
+
results = []
|
| 164 |
+
for name, test_func in tests:
|
| 165 |
+
print(f"\n Testing {name}...")
|
| 166 |
+
success = test_func()
|
| 167 |
+
results.append((name, success))
|
| 168 |
+
print()
|
| 169 |
+
|
| 170 |
+
print("=" * 50)
|
| 171 |
+
print("Test Results Summary")
|
| 172 |
+
print("=" * 50)
|
| 173 |
+
|
| 174 |
+
for name, success in results:
|
| 175 |
+
status = "β
PASS" if success else "β FAIL"
|
| 176 |
+
print(f"{name:20} {status}")
|
| 177 |
+
|
| 178 |
+
total = len(results)
|
| 179 |
+
passed = sum(1 for _, s in results if s)
|
| 180 |
+
|
| 181 |
+
print(f"\nTotal: {passed}/{total} tests passed")
|
| 182 |
+
|
| 183 |
+
if passed == total:
|
| 184 |
+
print("\nπ All tests passed!")
|
| 185 |
+
return 0
|
| 186 |
+
else:
|
| 187 |
+
print(f"\nβ οΈ {total - passed} test(s) failed")
|
| 188 |
+
return 1
|
| 189 |
+
|
| 190 |
+
if __name__ == "__main__":
|
| 191 |
+
sys.exit(main())
|