Spaces:
Running
Running
Remove RAG functionality and enhance template system
Browse files- Add enhanced template system with Research and Socratic templates
- Remove all RAG/vector search functionality and dependencies
- Clean up requirements.txt to remove RAG-related packages
- Update documentation to remove RAG references
- Maintain core functionality: URL grounding, dynamic URL fetching, template system
- Fix preview functionality and export features
- Update support documentation
- README.md +4 -6
- app.py +143 -258
- requirements.txt +1 -8
- support_docs.py +6 -13
README.md
CHANGED
|
@@ -14,14 +14,14 @@ short_description: Configure, download, and deploy a simple chat interface
|
|
| 14 |
|
| 15 |
# Chat UI Helper
|
| 16 |
|
| 17 |
-
A Gradio-based tool for generating and configuring chat interfaces for HuggingFace Spaces. Create deployable packages with custom assistants
|
| 18 |
|
| 19 |
## Features
|
| 20 |
|
| 21 |
### Spaces Configuration
|
| 22 |
- **Custom Assistant Creation**: Define role, purpose, audience, and tasks
|
| 23 |
-
- **Template System**: Choose from research assistant template or build from scratch
|
| 24 |
-
- **Tool Integration**: Optional dynamic URL fetching
|
| 25 |
- **Access Control**: Secure access code protection for educational use
|
| 26 |
- **Complete Deployment Package**: Generates app.py, requirements.txt, README.md, and config.json
|
| 27 |
|
|
@@ -48,14 +48,12 @@ Set your OpenRouter API key as a secret:
|
|
| 48 |
Each generated space includes:
|
| 49 |
- **OpenRouter API Integration**: Support for multiple LLM models
|
| 50 |
- **Web Scraping**: Simple HTTP requests with BeautifulSoup for URL content fetching
|
| 51 |
-
- **Document RAG**: Optional upload and search through PDF, DOCX, TXT, MD files
|
| 52 |
- **Access Control**: Environment-based student access codes
|
| 53 |
- **Modern UI**: Gradio 5.x ChatInterface with proper message formatting
|
| 54 |
|
| 55 |
## Architecture
|
| 56 |
|
| 57 |
-
- **Main Application**: `app.py` with
|
| 58 |
-
- **Document Processing**: RAG pipeline with FAISS vector search
|
| 59 |
- **Web Scraping**: HTTP requests with BeautifulSoup for content extraction
|
| 60 |
- **Template Generation**: Complete HuggingFace Space creation
|
| 61 |
|
|
|
|
| 14 |
|
| 15 |
# Chat UI Helper
|
| 16 |
|
| 17 |
+
A Gradio-based tool for generating and configuring chat interfaces for HuggingFace Spaces. Create deployable packages with custom assistants and web scraping capabilities.
|
| 18 |
|
| 19 |
## Features
|
| 20 |
|
| 21 |
### Spaces Configuration
|
| 22 |
- **Custom Assistant Creation**: Define role, purpose, audience, and tasks
|
| 23 |
+
- **Template System**: Choose from research assistant template or build from scratch
|
| 24 |
+
- **Tool Integration**: Optional dynamic URL fetching
|
| 25 |
- **Access Control**: Secure access code protection for educational use
|
| 26 |
- **Complete Deployment Package**: Generates app.py, requirements.txt, README.md, and config.json
|
| 27 |
|
|
|
|
| 48 |
Each generated space includes:
|
| 49 |
- **OpenRouter API Integration**: Support for multiple LLM models
|
| 50 |
- **Web Scraping**: Simple HTTP requests with BeautifulSoup for URL content fetching
|
|
|
|
| 51 |
- **Access Control**: Environment-based student access codes
|
| 52 |
- **Modern UI**: Gradio 5.x ChatInterface with proper message formatting
|
| 53 |
|
| 54 |
## Architecture
|
| 55 |
|
| 56 |
+
- **Main Application**: `app.py` with three-tab interface
|
|
|
|
| 57 |
- **Web Scraping**: HTTP requests with BeautifulSoup for content extraction
|
| 58 |
- **Template Generation**: Complete HuggingFace Space creation
|
| 59 |
|
app.py
CHANGED
|
@@ -39,13 +39,7 @@ def get_grounding_context_simple(urls):
|
|
| 39 |
return "\n\n" + "\n\n".join(context_parts) + "\n\n"
|
| 40 |
return ""
|
| 41 |
|
| 42 |
-
#
|
| 43 |
-
try:
|
| 44 |
-
from rag_tool import RAGTool
|
| 45 |
-
HAS_RAG = True
|
| 46 |
-
except ImportError:
|
| 47 |
-
HAS_RAG = False
|
| 48 |
-
RAGTool = None
|
| 49 |
|
| 50 |
# Load environment variables from .env file
|
| 51 |
load_dotenv()
|
|
@@ -152,8 +146,7 @@ GROUNDING_URLS = {grounding_urls}
|
|
| 152 |
# Get access code from environment variable for security
|
| 153 |
ACCESS_CODE = os.environ.get("SPACE_ACCESS_CODE", "{access_code}")
|
| 154 |
ENABLE_DYNAMIC_URLS = {enable_dynamic_urls}
|
| 155 |
-
|
| 156 |
-
RAG_DATA = {rag_data_json}
|
| 157 |
|
| 158 |
# Get API key from environment - customizable variable name with validation
|
| 159 |
API_KEY = os.environ.get("{api_key_var}")
|
|
@@ -309,10 +302,31 @@ def export_conversation_to_markdown(conversation_history):
|
|
| 309 |
markdown_content = f"""# Conversation Export
|
| 310 |
Generated on: {{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}}
|
| 311 |
|
| 312 |
-
|
| 313 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 314 |
"""
|
| 315 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 316 |
message_pair_count = 0
|
| 317 |
for i, message in enumerate(conversation_history):
|
| 318 |
if isinstance(message, dict):
|
|
@@ -335,35 +349,7 @@ Generated on: {{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}}
|
|
| 335 |
|
| 336 |
return markdown_content
|
| 337 |
|
| 338 |
-
#
|
| 339 |
-
if ENABLE_VECTOR_RAG and RAG_DATA:
|
| 340 |
-
try:
|
| 341 |
-
import faiss
|
| 342 |
-
import numpy as np
|
| 343 |
-
import base64
|
| 344 |
-
|
| 345 |
-
class SimpleRAGContext:
|
| 346 |
-
def __init__(self, rag_data):
|
| 347 |
-
# Deserialize FAISS index
|
| 348 |
-
index_bytes = base64.b64decode(rag_data['index_base64'])
|
| 349 |
-
self.index = faiss.deserialize_index(index_bytes)
|
| 350 |
-
|
| 351 |
-
# Restore chunks and mappings
|
| 352 |
-
self.chunks = rag_data['chunks']
|
| 353 |
-
self.chunk_ids = rag_data['chunk_ids']
|
| 354 |
-
|
| 355 |
-
def get_context(self, query, max_chunks=3):
|
| 356 |
-
"""Get relevant context - simplified version"""
|
| 357 |
-
# In production, you'd compute query embedding here
|
| 358 |
-
# For now, return a simple message
|
| 359 |
-
return "\\n\\n[RAG context would be retrieved here based on similarity search]\\n\\n"
|
| 360 |
-
|
| 361 |
-
rag_context_provider = SimpleRAGContext(RAG_DATA)
|
| 362 |
-
except Exception as e:
|
| 363 |
-
print(f"Failed to initialize RAG: {{e}}")
|
| 364 |
-
rag_context_provider = None
|
| 365 |
-
else:
|
| 366 |
-
rag_context_provider = None
|
| 367 |
|
| 368 |
def generate_response(message, history):
|
| 369 |
"""Generate response using OpenRouter API"""
|
|
@@ -383,11 +369,7 @@ def generate_response(message, history):
|
|
| 383 |
# Get grounding context
|
| 384 |
grounding_context = get_grounding_context()
|
| 385 |
|
| 386 |
-
#
|
| 387 |
-
if ENABLE_VECTOR_RAG and rag_context_provider:
|
| 388 |
-
rag_context = rag_context_provider.get_context(message)
|
| 389 |
-
if rag_context:
|
| 390 |
-
grounding_context += rag_context
|
| 391 |
|
| 392 |
# If dynamic URLs are enabled, check message for URLs to fetch
|
| 393 |
if ENABLE_DYNAMIC_URLS:
|
|
@@ -643,9 +625,6 @@ def get_configuration_status():
|
|
| 643 |
|
| 644 |
if ENABLE_DYNAMIC_URLS:
|
| 645 |
status_parts.append("🔄 **Dynamic URLs:** Enabled")
|
| 646 |
-
|
| 647 |
-
if ENABLE_VECTOR_RAG:
|
| 648 |
-
status_parts.append("📚 **Document RAG:** Enabled")
|
| 649 |
|
| 650 |
if ACCESS_CODE:
|
| 651 |
status_parts.append("🔐 **Access Control:** Enabled")
|
|
@@ -861,18 +840,11 @@ Generated on {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} with Chat U/I Helper
|
|
| 861 |
|
| 862 |
return readme_content
|
| 863 |
|
| 864 |
-
def create_requirements(
|
| 865 |
"""Generate requirements.txt"""
|
| 866 |
-
|
| 867 |
-
|
| 868 |
-
|
| 869 |
-
if enable_vector_rag:
|
| 870 |
-
base_requirements += "\n\n# Vector RAG dependencies"
|
| 871 |
-
base_requirements += "\nfaiss-cpu>=1.11.0\nnumpy>=1.25.0,<3.0\nsentence-transformers>=2.2.2\nPyMuPDF>=1.23.0\npython-docx>=0.8.11"
|
| 872 |
-
|
| 873 |
-
return base_requirements
|
| 874 |
|
| 875 |
-
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=""
|
| 876 |
"""Generate deployable zip file"""
|
| 877 |
|
| 878 |
# Process examples
|
|
@@ -906,9 +878,7 @@ def generate_zip(name, description, system_prompt, model, api_key_var, temperatu
|
|
| 906 |
'examples': examples_json,
|
| 907 |
'grounding_urls': json.dumps(grounding_urls),
|
| 908 |
'access_code': "", # Access code stored in environment variable for security
|
| 909 |
-
'enable_dynamic_urls': enable_dynamic_urls
|
| 910 |
-
'enable_vector_rag': enable_vector_rag,
|
| 911 |
-
'rag_data_json': json.dumps(rag_data) if rag_data else 'None'
|
| 912 |
}
|
| 913 |
|
| 914 |
# Generate files
|
|
@@ -917,7 +887,7 @@ def generate_zip(name, description, system_prompt, model, api_key_var, temperatu
|
|
| 917 |
readme_config = config.copy()
|
| 918 |
readme_config['access_code'] = access_code or ""
|
| 919 |
readme_content = create_readme(readme_config)
|
| 920 |
-
requirements_content = create_requirements(
|
| 921 |
|
| 922 |
# Create zip file with clean naming
|
| 923 |
filename = f"{name.lower().replace(' ', '_').replace('-', '_')}.zip"
|
|
@@ -938,93 +908,7 @@ def generate_zip(name, description, system_prompt, model, api_key_var, temperatu
|
|
| 938 |
return filename
|
| 939 |
|
| 940 |
# Define callback functions outside the interface
|
| 941 |
-
|
| 942 |
-
"""Toggle visibility of RAG section"""
|
| 943 |
-
return gr.update(visible=enable_rag)
|
| 944 |
-
|
| 945 |
-
def process_documents(files, current_rag_tool):
|
| 946 |
-
"""Process uploaded documents"""
|
| 947 |
-
if not files:
|
| 948 |
-
return "Please upload files first", current_rag_tool
|
| 949 |
-
|
| 950 |
-
if not HAS_RAG:
|
| 951 |
-
return "RAG functionality not available. Please install required dependencies.", current_rag_tool
|
| 952 |
-
|
| 953 |
-
try:
|
| 954 |
-
# Check file paths are valid
|
| 955 |
-
file_paths = []
|
| 956 |
-
for file in files:
|
| 957 |
-
if hasattr(file, 'name'):
|
| 958 |
-
file_paths.append(file.name)
|
| 959 |
-
else:
|
| 960 |
-
file_paths.append(str(file))
|
| 961 |
-
|
| 962 |
-
print(f"Processing {len(file_paths)} files for RAG...")
|
| 963 |
-
|
| 964 |
-
# Initialize RAG tool if not exists
|
| 965 |
-
if not current_rag_tool and RAGTool is not None:
|
| 966 |
-
print("Initializing RAG tool...")
|
| 967 |
-
current_rag_tool = RAGTool()
|
| 968 |
-
|
| 969 |
-
# Process files with progress feedback
|
| 970 |
-
print("Processing documents and creating embeddings...")
|
| 971 |
-
result = current_rag_tool.process_uploaded_files(file_paths)
|
| 972 |
-
|
| 973 |
-
if result['success']:
|
| 974 |
-
# Create status message
|
| 975 |
-
status_parts = [f"✅ {result['message']}"]
|
| 976 |
-
|
| 977 |
-
# Add file summary
|
| 978 |
-
if result['summary']['files_processed']:
|
| 979 |
-
status_parts.append("\n**Processed files:**")
|
| 980 |
-
for file_info in result['summary']['files_processed']:
|
| 981 |
-
status_parts.append(f"- {file_info['name']} ({file_info['chunks']} chunks)")
|
| 982 |
-
|
| 983 |
-
# Add errors if any
|
| 984 |
-
if result.get('errors'):
|
| 985 |
-
status_parts.append("\n**Errors:**")
|
| 986 |
-
for error in result['errors']:
|
| 987 |
-
status_parts.append(f"- {error['file']}: {error['error']}")
|
| 988 |
-
|
| 989 |
-
# Add index stats
|
| 990 |
-
if result.get('index_stats'):
|
| 991 |
-
stats = result['index_stats']
|
| 992 |
-
status_parts.append(f"\n**Index stats:** {stats['total_chunks']} chunks, {stats['dimension']}D embeddings")
|
| 993 |
-
|
| 994 |
-
return "\n".join(status_parts), current_rag_tool
|
| 995 |
-
else:
|
| 996 |
-
return f"❌ {result['message']}", current_rag_tool
|
| 997 |
-
|
| 998 |
-
except ImportError as e:
|
| 999 |
-
error_msg = f"❌ Missing dependencies: {str(e)}\n\n"
|
| 1000 |
-
error_msg += "To use RAG functionality, install:\n"
|
| 1001 |
-
error_msg += "- sentence-transformers>=2.2.2\n"
|
| 1002 |
-
error_msg += "- faiss-cpu==1.7.4\n"
|
| 1003 |
-
error_msg += "- PyMuPDF>=1.23.0 (for PDF files)\n"
|
| 1004 |
-
error_msg += "- python-docx>=0.8.11 (for DOCX files)"
|
| 1005 |
-
return error_msg, current_rag_tool
|
| 1006 |
-
except RuntimeError as e:
|
| 1007 |
-
error_msg = f"❌ Model initialization error: {str(e)}\n\n"
|
| 1008 |
-
if "network" in str(e).lower() or "download" in str(e).lower():
|
| 1009 |
-
error_msg += "This appears to be a network issue. Please:\n"
|
| 1010 |
-
error_msg += "1. Check your internet connection\n"
|
| 1011 |
-
error_msg += "2. Try again in a few moments\n"
|
| 1012 |
-
error_msg += "3. If the problem persists, restart the application"
|
| 1013 |
-
elif "memory" in str(e).lower():
|
| 1014 |
-
error_msg += "This appears to be a memory issue. Please:\n"
|
| 1015 |
-
error_msg += "1. Try uploading smaller documents\n"
|
| 1016 |
-
error_msg += "2. Process documents one at a time\n"
|
| 1017 |
-
error_msg += "3. Restart the application if needed"
|
| 1018 |
-
return error_msg, current_rag_tool
|
| 1019 |
-
except Exception as e:
|
| 1020 |
-
error_msg = f"❌ Unexpected error processing documents: {str(e)}\n\n"
|
| 1021 |
-
error_msg += "This may be due to:\n"
|
| 1022 |
-
error_msg += "- Large files causing memory issues\n"
|
| 1023 |
-
error_msg += "- Network problems downloading the embedding model\n"
|
| 1024 |
-
error_msg += "- File format issues\n\n"
|
| 1025 |
-
error_msg += "Try: uploading smaller files, checking your internet connection, or restarting the application."
|
| 1026 |
-
print(f"RAG processing error: {e}")
|
| 1027 |
-
return error_msg, current_rag_tool
|
| 1028 |
|
| 1029 |
def update_sandbox_preview(config_data):
|
| 1030 |
"""Update the sandbox preview with generated content"""
|
|
@@ -1038,7 +922,7 @@ def update_sandbox_preview(config_data):
|
|
| 1038 |
- **Temperature:** {config_data.get('temperature', 'N/A')}
|
| 1039 |
- **Max Tokens:** {config_data.get('max_tokens', 'N/A')}
|
| 1040 |
- **Dynamic URLs:** {'✅ Enabled' if config_data.get('enable_dynamic_urls') else '❌ Disabled'}
|
| 1041 |
-
|
| 1042 |
|
| 1043 |
**System Prompt Preview:**
|
| 1044 |
```
|
|
@@ -1073,14 +957,21 @@ def update_sandbox_preview(config_data):
|
|
| 1073 |
|
| 1074 |
return preview_text, preview_html
|
| 1075 |
|
| 1076 |
-
def on_preview_combined(name, description, system_prompt, model, temperature, max_tokens, examples_text, enable_dynamic_urls,
|
| 1077 |
"""Generate configuration and return preview updates"""
|
| 1078 |
if not name or not name.strip():
|
| 1079 |
return (
|
| 1080 |
{},
|
| 1081 |
gr.update(value="**Error:** Please provide a Space Title to preview", visible=True),
|
| 1082 |
gr.update(visible=False),
|
| 1083 |
-
gr.update(value="Configuration will appear here after preview generation.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1084 |
)
|
| 1085 |
|
| 1086 |
try:
|
|
@@ -1090,7 +981,14 @@ def on_preview_combined(name, description, system_prompt, model, temperature, ma
|
|
| 1090 |
{},
|
| 1091 |
gr.update(value="**Error:** Please provide a System Prompt for the assistant", visible=True),
|
| 1092 |
gr.update(visible=False),
|
| 1093 |
-
gr.update(value="Configuration will appear here after preview generation.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1094 |
)
|
| 1095 |
|
| 1096 |
final_system_prompt = system_prompt.strip()
|
|
@@ -1108,8 +1006,6 @@ def on_preview_combined(name, description, system_prompt, model, temperature, ma
|
|
| 1108 |
'url2': url2,
|
| 1109 |
'url3': url3,
|
| 1110 |
'url4': url4,
|
| 1111 |
-
'enable_vector_rag': enable_vector_rag,
|
| 1112 |
-
'rag_tool_state': rag_tool_state,
|
| 1113 |
'examples_text': examples_text,
|
| 1114 |
'preview_ready': True
|
| 1115 |
}
|
|
@@ -1119,9 +1015,7 @@ def on_preview_combined(name, description, system_prompt, model, temperature, ma
|
|
| 1119 |
> *{final_system_prompt[:600]}{'...' if len(final_system_prompt) > 600 else '...'}*
|
| 1120 |
|
| 1121 |
Tip: Try different configurations of your space before generating the deployment package."""
|
| 1122 |
-
config_display = f"""
|
| 1123 |
-
|
| 1124 |
-
> **Configuration**:
|
| 1125 |
- **Name:** {name}
|
| 1126 |
- **Description:** {description or 'No description provided'}
|
| 1127 |
- **Model:** {model}
|
|
@@ -1140,11 +1034,42 @@ Tip: Try different configurations of your space before generating the deployment
|
|
| 1140 |
# Show success notification
|
| 1141 |
gr.Info(f"✅ Preview generated successfully for '{name}'! Switch to Preview tab.")
|
| 1142 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1143 |
return (
|
| 1144 |
config_data,
|
| 1145 |
gr.update(value=preview_text, visible=True),
|
| 1146 |
gr.update(visible=True),
|
| 1147 |
-
gr.update(value=config_display)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1148 |
)
|
| 1149 |
|
| 1150 |
except Exception as e:
|
|
@@ -1152,7 +1077,14 @@ Tip: Try different configurations of your space before generating the deployment
|
|
| 1152 |
{},
|
| 1153 |
gr.update(value=f"**Error:** {str(e)}", visible=True),
|
| 1154 |
gr.update(visible=False),
|
| 1155 |
-
gr.update(value="Configuration will appear here after preview generation.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1156 |
)
|
| 1157 |
|
| 1158 |
def update_preview_display(config_data):
|
|
@@ -1173,7 +1105,7 @@ Your assistant "{config_data['name']}" is configured and ready to test.
|
|
| 1173 |
- **Temperature:** {config_data['temperature']}
|
| 1174 |
- **Max Tokens:** {config_data['max_tokens']}
|
| 1175 |
- **Dynamic URLs:** {'✅ Enabled' if config_data['enable_dynamic_urls'] else '❌ Disabled'}
|
| 1176 |
-
|
| 1177 |
|
| 1178 |
**System Prompt:**
|
| 1179 |
{config_data['system_prompt'][:600]}{'...' if len(config_data['system_prompt']) > 600 else ''}
|
|
@@ -1193,7 +1125,7 @@ Use the chat interface below to test your assistant before generating the deploy
|
|
| 1193 |
|
| 1194 |
**Features:**
|
| 1195 |
- **Dynamic URL Fetching:** {'✅ Enabled' if config_data['enable_dynamic_urls'] else '❌ Disabled'}
|
| 1196 |
-
|
| 1197 |
|
| 1198 |
**System Prompt:**
|
| 1199 |
```
|
|
@@ -1253,20 +1185,7 @@ Once you set your API key, you'll be able to test real conversations in this pre
|
|
| 1253 |
grounding_urls = config_urls if any(url for url in config_urls if url) else [url1, url2, url3, url4]
|
| 1254 |
grounding_context = get_cached_grounding_context([url for url in grounding_urls if url and url.strip()])
|
| 1255 |
|
| 1256 |
-
#
|
| 1257 |
-
rag_context = ""
|
| 1258 |
-
if config_data.get('enable_vector_rag') and HAS_RAG:
|
| 1259 |
-
try:
|
| 1260 |
-
# Get RAG tool from config_data if available
|
| 1261 |
-
rag_tool_state = config_data.get('rag_tool_state')
|
| 1262 |
-
if rag_tool_state:
|
| 1263 |
-
rag_context = rag_tool_state.get_relevant_context(message, max_chunks=2)
|
| 1264 |
-
if rag_context:
|
| 1265 |
-
rag_context = f"\n\n**RAG Context (Preview):**\n{rag_context}\n\n"
|
| 1266 |
-
else:
|
| 1267 |
-
rag_context = "\n\n[RAG: No processed documents available for context]\n\n"
|
| 1268 |
-
except Exception as e:
|
| 1269 |
-
rag_context = f"\n\n[RAG context error: {str(e)}]\n\n"
|
| 1270 |
|
| 1271 |
# If dynamic URLs are enabled, check message for URLs to fetch
|
| 1272 |
dynamic_context = ""
|
|
@@ -1281,7 +1200,7 @@ Once you set your API key, you'll be able to test real conversations in this pre
|
|
| 1281 |
dynamic_context = "\n".join(dynamic_context_parts)
|
| 1282 |
|
| 1283 |
# Build enhanced system prompt with all contexts
|
| 1284 |
-
enhanced_system_prompt = config_data.get('system_prompt', '') + grounding_context +
|
| 1285 |
|
| 1286 |
# Build messages array for the API
|
| 1287 |
messages = [{"role": "system", "content": enhanced_system_prompt}]
|
|
@@ -1360,12 +1279,12 @@ def clear_preview_chat():
|
|
| 1360 |
"""Clear preview chat"""
|
| 1361 |
return "", []
|
| 1362 |
|
| 1363 |
-
def export_preview_conversation(history):
|
| 1364 |
"""Export preview conversation to markdown"""
|
| 1365 |
if not history:
|
| 1366 |
return gr.update(visible=False)
|
| 1367 |
|
| 1368 |
-
markdown_content = export_conversation_to_markdown(history)
|
| 1369 |
|
| 1370 |
# Save to temporary file
|
| 1371 |
import tempfile
|
|
@@ -1375,24 +1294,19 @@ def export_preview_conversation(history):
|
|
| 1375 |
|
| 1376 |
return gr.update(value=temp_file, visible=True)
|
| 1377 |
|
| 1378 |
-
def on_generate(name, description, system_prompt, model, api_key_var, temperature, max_tokens, examples_text, access_code, enable_dynamic_urls, url1, url2, url3, url4
|
| 1379 |
if not name or not name.strip():
|
| 1380 |
return gr.update(value="Error: Please provide a Space Title", visible=True), gr.update(visible=False), {}
|
| 1381 |
|
| 1382 |
|
| 1383 |
try:
|
| 1384 |
-
# Get RAG data if enabled
|
| 1385 |
-
rag_data = None
|
| 1386 |
-
if enable_vector_rag and rag_tool_state:
|
| 1387 |
-
rag_data = rag_tool_state.get_serialized_data()
|
| 1388 |
-
|
| 1389 |
# Use the system prompt directly (template selector already updates it)
|
| 1390 |
if not system_prompt or not system_prompt.strip():
|
| 1391 |
return gr.update(value="Error: Please provide a System Prompt for the assistant", visible=True), gr.update(visible=False), {}
|
| 1392 |
|
| 1393 |
final_system_prompt = system_prompt.strip()
|
| 1394 |
|
| 1395 |
-
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
|
| 1396 |
|
| 1397 |
success_msg = f"""**Deployment package ready!**
|
| 1398 |
|
|
@@ -1420,7 +1334,6 @@ def on_generate(name, description, system_prompt, model, api_key_var, temperatur
|
|
| 1420 |
'temperature': temperature,
|
| 1421 |
'max_tokens': max_tokens,
|
| 1422 |
'enable_dynamic_urls': enable_dynamic_urls,
|
| 1423 |
-
'enable_vector_rag': enable_vector_rag,
|
| 1424 |
'filename': filename
|
| 1425 |
}
|
| 1426 |
|
|
@@ -1834,63 +1747,8 @@ with gr.Blocks(
|
|
| 1834 |
|
| 1835 |
|
| 1836 |
|
| 1837 |
-
#
|
| 1838 |
-
enable_vector_rag = gr.Checkbox(
|
| 1839 |
-
label="Enable Document RAG",
|
| 1840 |
-
value=False,
|
| 1841 |
-
info="Upload documents for context-aware responses (PDF, DOCX, TXT, MD)",
|
| 1842 |
-
visible=HAS_RAG
|
| 1843 |
-
)
|
| 1844 |
|
| 1845 |
-
with gr.Column(visible=False) as rag_section:
|
| 1846 |
-
gr.Markdown("### Document Upload")
|
| 1847 |
-
file_upload = gr.File(
|
| 1848 |
-
label="Upload Documents",
|
| 1849 |
-
file_types=[".pdf", ".docx", ".txt", ".md"],
|
| 1850 |
-
file_count="multiple"
|
| 1851 |
-
)
|
| 1852 |
-
process_btn = gr.Button("Process Documents", variant="secondary")
|
| 1853 |
-
rag_status = gr.Markdown()
|
| 1854 |
-
|
| 1855 |
-
# State to store RAG tool
|
| 1856 |
-
rag_tool_state = gr.State(None)
|
| 1857 |
-
|
| 1858 |
-
with gr.Accordion("URL Grounding (Optional)", open=True):
|
| 1859 |
-
gr.Markdown("Add URLs to provide context. Content will be fetched and added to the system prompt.")
|
| 1860 |
-
|
| 1861 |
-
# Initial URL fields
|
| 1862 |
-
url1 = gr.Textbox(
|
| 1863 |
-
label="URL 1",
|
| 1864 |
-
placeholder="https://example.com/page1",
|
| 1865 |
-
info="First URL for context grounding"
|
| 1866 |
-
)
|
| 1867 |
-
|
| 1868 |
-
url2 = gr.Textbox(
|
| 1869 |
-
label="URL 2",
|
| 1870 |
-
placeholder="https://example.com/page2",
|
| 1871 |
-
info="Second URL for context grounding"
|
| 1872 |
-
)
|
| 1873 |
-
|
| 1874 |
-
# Additional URL fields (initially hidden)
|
| 1875 |
-
url3 = gr.Textbox(
|
| 1876 |
-
label="URL 3",
|
| 1877 |
-
placeholder="https://example.com/page3",
|
| 1878 |
-
info="Third URL for context grounding",
|
| 1879 |
-
visible=False
|
| 1880 |
-
)
|
| 1881 |
-
|
| 1882 |
-
url4 = gr.Textbox(
|
| 1883 |
-
label="URL 4",
|
| 1884 |
-
placeholder="https://example.com/page4",
|
| 1885 |
-
info="Fourth URL for context grounding",
|
| 1886 |
-
visible=False
|
| 1887 |
-
)
|
| 1888 |
-
|
| 1889 |
-
# URL management buttons
|
| 1890 |
-
with gr.Row():
|
| 1891 |
-
add_url_btn = gr.Button("+ Add URLs", size="sm")
|
| 1892 |
-
remove_url_btn = gr.Button("- Remove URLs", size="sm", visible=False)
|
| 1893 |
-
url_count = gr.State(2) # Track number of visible URLs
|
| 1894 |
|
| 1895 |
examples_text = gr.Textbox(
|
| 1896 |
label="Example Prompts (one per line)",
|
|
@@ -1925,6 +1783,44 @@ with gr.Blocks(
|
|
| 1925 |
value=1500,
|
| 1926 |
step=50
|
| 1927 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1928 |
|
| 1929 |
with gr.Row():
|
| 1930 |
preview_btn = gr.Button("Preview Deployment Package", variant="secondary")
|
|
@@ -1960,24 +1856,13 @@ with gr.Blocks(
|
|
| 1960 |
outputs=[url3, url4, add_url_btn, remove_url_btn, url_count]
|
| 1961 |
)
|
| 1962 |
|
| 1963 |
-
#
|
| 1964 |
-
enable_vector_rag.change(
|
| 1965 |
-
toggle_rag_section,
|
| 1966 |
-
inputs=[enable_vector_rag],
|
| 1967 |
-
outputs=[rag_section]
|
| 1968 |
-
)
|
| 1969 |
-
|
| 1970 |
-
process_btn.click(
|
| 1971 |
-
process_documents,
|
| 1972 |
-
inputs=[file_upload, rag_tool_state],
|
| 1973 |
-
outputs=[rag_status, rag_tool_state]
|
| 1974 |
-
)
|
| 1975 |
|
| 1976 |
|
| 1977 |
# Connect the generate button
|
| 1978 |
generate_btn.click(
|
| 1979 |
on_generate,
|
| 1980 |
-
inputs=[name, description, system_prompt, model, api_key_var, temperature, max_tokens, examples_text, access_code, enable_dynamic_urls, url1, url2, url3, url4
|
| 1981 |
outputs=[status, download_file, sandbox_state]
|
| 1982 |
)
|
| 1983 |
|
|
@@ -2073,7 +1958,7 @@ with gr.Blocks(
|
|
| 2073 |
|
| 2074 |
preview_export_btn.click(
|
| 2075 |
export_preview_conversation,
|
| 2076 |
-
inputs=[preview_chatbot],
|
| 2077 |
outputs=[export_file]
|
| 2078 |
)
|
| 2079 |
|
|
@@ -2096,8 +1981,8 @@ with gr.Blocks(
|
|
| 2096 |
# Connect cross-tab functionality after all components are defined
|
| 2097 |
preview_btn.click(
|
| 2098 |
on_preview_combined,
|
| 2099 |
-
inputs=[name, description, system_prompt, model, temperature, max_tokens, examples_text, enable_dynamic_urls,
|
| 2100 |
-
outputs=[preview_config_state, preview_status_comp, preview_chat_section_comp, config_display_comp]
|
| 2101 |
)
|
| 2102 |
|
| 2103 |
if __name__ == "__main__":
|
|
|
|
| 39 |
return "\n\n" + "\n\n".join(context_parts) + "\n\n"
|
| 40 |
return ""
|
| 41 |
|
| 42 |
+
# RAG functionality removed
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 43 |
|
| 44 |
# Load environment variables from .env file
|
| 45 |
load_dotenv()
|
|
|
|
| 146 |
# Get access code from environment variable for security
|
| 147 |
ACCESS_CODE = os.environ.get("SPACE_ACCESS_CODE", "{access_code}")
|
| 148 |
ENABLE_DYNAMIC_URLS = {enable_dynamic_urls}
|
| 149 |
+
# RAG functionality removed
|
|
|
|
| 150 |
|
| 151 |
# Get API key from environment - customizable variable name with validation
|
| 152 |
API_KEY = os.environ.get("{api_key_var}")
|
|
|
|
| 302 |
markdown_content = f"""# Conversation Export
|
| 303 |
Generated on: {{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}}
|
| 304 |
|
| 305 |
+
## Configuration Information
|
| 306 |
|
| 307 |
+
**Assistant Name:** {name}
|
| 308 |
+
**Description:** {description}
|
| 309 |
+
**Model:** {{MODEL}}
|
| 310 |
+
**Temperature:** {temperature}
|
| 311 |
+
**Max Tokens:** {max_tokens}
|
| 312 |
+
**API Key Variable:** {api_key_var}
|
| 313 |
"""
|
| 314 |
|
| 315 |
+
# Add URL grounding information
|
| 316 |
+
if GROUNDING_URLS:
|
| 317 |
+
markdown_content += f"\\n**URL Grounding ({{len(GROUNDING_URLS)}} URLs):**\\n"
|
| 318 |
+
for i, url in enumerate(GROUNDING_URLS, 1):
|
| 319 |
+
markdown_content += f"- URL {{i}}: {{url}}\\n"
|
| 320 |
+
|
| 321 |
+
# Add feature flags
|
| 322 |
+
if ENABLE_DYNAMIC_URLS:
|
| 323 |
+
markdown_content += f"\\n**Dynamic URL Fetching:** Enabled\\n"
|
| 324 |
+
|
| 325 |
+
# Add system prompt
|
| 326 |
+
markdown_content += f"\\n**System Prompt:**\\n```\\n{{SYSTEM_PROMPT}}\\n```\\n"
|
| 327 |
+
|
| 328 |
+
markdown_content += "\\n---\\n\\n"
|
| 329 |
+
|
| 330 |
message_pair_count = 0
|
| 331 |
for i, message in enumerate(conversation_history):
|
| 332 |
if isinstance(message, dict):
|
|
|
|
| 349 |
|
| 350 |
return markdown_content
|
| 351 |
|
| 352 |
+
# RAG functionality removed
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 353 |
|
| 354 |
def generate_response(message, history):
|
| 355 |
"""Generate response using OpenRouter API"""
|
|
|
|
| 369 |
# Get grounding context
|
| 370 |
grounding_context = get_grounding_context()
|
| 371 |
|
| 372 |
+
# RAG functionality removed
|
|
|
|
|
|
|
|
|
|
|
|
|
| 373 |
|
| 374 |
# If dynamic URLs are enabled, check message for URLs to fetch
|
| 375 |
if ENABLE_DYNAMIC_URLS:
|
|
|
|
| 625 |
|
| 626 |
if ENABLE_DYNAMIC_URLS:
|
| 627 |
status_parts.append("🔄 **Dynamic URLs:** Enabled")
|
|
|
|
|
|
|
|
|
|
| 628 |
|
| 629 |
if ACCESS_CODE:
|
| 630 |
status_parts.append("🔐 **Access Control:** Enabled")
|
|
|
|
| 840 |
|
| 841 |
return readme_content
|
| 842 |
|
| 843 |
+
def create_requirements():
|
| 844 |
"""Generate requirements.txt"""
|
| 845 |
+
return "gradio>=4.44.1\nrequests>=2.32.3\nbeautifulsoup4>=4.12.3\npython-dotenv>=1.0.0"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 846 |
|
| 847 |
+
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=""):
|
| 848 |
"""Generate deployable zip file"""
|
| 849 |
|
| 850 |
# Process examples
|
|
|
|
| 878 |
'examples': examples_json,
|
| 879 |
'grounding_urls': json.dumps(grounding_urls),
|
| 880 |
'access_code': "", # Access code stored in environment variable for security
|
| 881 |
+
'enable_dynamic_urls': enable_dynamic_urls
|
|
|
|
|
|
|
| 882 |
}
|
| 883 |
|
| 884 |
# Generate files
|
|
|
|
| 887 |
readme_config = config.copy()
|
| 888 |
readme_config['access_code'] = access_code or ""
|
| 889 |
readme_content = create_readme(readme_config)
|
| 890 |
+
requirements_content = create_requirements()
|
| 891 |
|
| 892 |
# Create zip file with clean naming
|
| 893 |
filename = f"{name.lower().replace(' ', '_').replace('-', '_')}.zip"
|
|
|
|
| 908 |
return filename
|
| 909 |
|
| 910 |
# Define callback functions outside the interface
|
| 911 |
+
# RAG functionality removed
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 912 |
|
| 913 |
def update_sandbox_preview(config_data):
|
| 914 |
"""Update the sandbox preview with generated content"""
|
|
|
|
| 922 |
- **Temperature:** {config_data.get('temperature', 'N/A')}
|
| 923 |
- **Max Tokens:** {config_data.get('max_tokens', 'N/A')}
|
| 924 |
- **Dynamic URLs:** {'✅ Enabled' if config_data.get('enable_dynamic_urls') else '❌ Disabled'}
|
| 925 |
+
# RAG functionality removed
|
| 926 |
|
| 927 |
**System Prompt Preview:**
|
| 928 |
```
|
|
|
|
| 957 |
|
| 958 |
return preview_text, preview_html
|
| 959 |
|
| 960 |
+
def on_preview_combined(name, description, system_prompt, model, temperature, max_tokens, examples_text, enable_dynamic_urls, url1="", url2="", url3="", url4=""):
|
| 961 |
"""Generate configuration and return preview updates"""
|
| 962 |
if not name or not name.strip():
|
| 963 |
return (
|
| 964 |
{},
|
| 965 |
gr.update(value="**Error:** Please provide a Space Title to preview", visible=True),
|
| 966 |
gr.update(visible=False),
|
| 967 |
+
gr.update(value="Configuration will appear here after preview generation."),
|
| 968 |
+
gr.update(), # preview_url1
|
| 969 |
+
gr.update(), # preview_url2
|
| 970 |
+
gr.update(), # preview_url3
|
| 971 |
+
gr.update(), # preview_url4
|
| 972 |
+
gr.update(), # preview_add_url_btn
|
| 973 |
+
gr.update(), # preview_remove_url_btn
|
| 974 |
+
2 # preview_url_count
|
| 975 |
)
|
| 976 |
|
| 977 |
try:
|
|
|
|
| 981 |
{},
|
| 982 |
gr.update(value="**Error:** Please provide a System Prompt for the assistant", visible=True),
|
| 983 |
gr.update(visible=False),
|
| 984 |
+
gr.update(value="Configuration will appear here after preview generation."),
|
| 985 |
+
gr.update(), # preview_url1
|
| 986 |
+
gr.update(), # preview_url2
|
| 987 |
+
gr.update(), # preview_url3
|
| 988 |
+
gr.update(), # preview_url4
|
| 989 |
+
gr.update(), # preview_add_url_btn
|
| 990 |
+
gr.update(), # preview_remove_url_btn
|
| 991 |
+
2 # preview_url_count
|
| 992 |
)
|
| 993 |
|
| 994 |
final_system_prompt = system_prompt.strip()
|
|
|
|
| 1006 |
'url2': url2,
|
| 1007 |
'url3': url3,
|
| 1008 |
'url4': url4,
|
|
|
|
|
|
|
| 1009 |
'examples_text': examples_text,
|
| 1010 |
'preview_ready': True
|
| 1011 |
}
|
|
|
|
| 1015 |
> *{final_system_prompt[:600]}{'...' if len(final_system_prompt) > 600 else '...'}*
|
| 1016 |
|
| 1017 |
Tip: Try different configurations of your space before generating the deployment package."""
|
| 1018 |
+
config_display = f"""> **Configuration**:
|
|
|
|
|
|
|
| 1019 |
- **Name:** {name}
|
| 1020 |
- **Description:** {description or 'No description provided'}
|
| 1021 |
- **Model:** {model}
|
|
|
|
| 1034 |
# Show success notification
|
| 1035 |
gr.Info(f"✅ Preview generated successfully for '{name}'! Switch to Preview tab.")
|
| 1036 |
|
| 1037 |
+
# Determine how many URLs are configured
|
| 1038 |
+
url_count = 2 # Start with 2 (always visible)
|
| 1039 |
+
if url3 and url3.strip():
|
| 1040 |
+
url_count = 3
|
| 1041 |
+
if url4 and url4.strip():
|
| 1042 |
+
url_count = 4
|
| 1043 |
+
|
| 1044 |
+
# Update preview URL visibility and button states based on count
|
| 1045 |
+
if url_count == 2:
|
| 1046 |
+
preview_url3_update = gr.update(value=url3, visible=False)
|
| 1047 |
+
preview_url4_update = gr.update(value=url4, visible=False)
|
| 1048 |
+
preview_add_btn_update = gr.update(value="+ Add URLs", interactive=True)
|
| 1049 |
+
preview_remove_btn_update = gr.update(visible=False)
|
| 1050 |
+
elif url_count == 3:
|
| 1051 |
+
preview_url3_update = gr.update(value=url3, visible=True)
|
| 1052 |
+
preview_url4_update = gr.update(value=url4, visible=False)
|
| 1053 |
+
preview_add_btn_update = gr.update(value="+ Add URLs", interactive=True)
|
| 1054 |
+
preview_remove_btn_update = gr.update(visible=True)
|
| 1055 |
+
else: # url_count == 4
|
| 1056 |
+
preview_url3_update = gr.update(value=url3, visible=True)
|
| 1057 |
+
preview_url4_update = gr.update(value=url4, visible=True)
|
| 1058 |
+
preview_add_btn_update = gr.update(value="Max URLs", interactive=False)
|
| 1059 |
+
preview_remove_btn_update = gr.update(visible=True)
|
| 1060 |
+
|
| 1061 |
return (
|
| 1062 |
config_data,
|
| 1063 |
gr.update(value=preview_text, visible=True),
|
| 1064 |
gr.update(visible=True),
|
| 1065 |
+
gr.update(value=config_display),
|
| 1066 |
+
gr.update(value=url1), # preview_url1
|
| 1067 |
+
gr.update(value=url2), # preview_url2
|
| 1068 |
+
preview_url3_update, # preview_url3
|
| 1069 |
+
preview_url4_update, # preview_url4
|
| 1070 |
+
preview_add_btn_update, # preview_add_url_btn
|
| 1071 |
+
preview_remove_btn_update, # preview_remove_url_btn
|
| 1072 |
+
url_count # preview_url_count
|
| 1073 |
)
|
| 1074 |
|
| 1075 |
except Exception as e:
|
|
|
|
| 1077 |
{},
|
| 1078 |
gr.update(value=f"**Error:** {str(e)}", visible=True),
|
| 1079 |
gr.update(visible=False),
|
| 1080 |
+
gr.update(value="Configuration will appear here after preview generation."),
|
| 1081 |
+
gr.update(), # preview_url1
|
| 1082 |
+
gr.update(), # preview_url2
|
| 1083 |
+
gr.update(), # preview_url3
|
| 1084 |
+
gr.update(), # preview_url4
|
| 1085 |
+
gr.update(), # preview_add_url_btn
|
| 1086 |
+
gr.update(), # preview_remove_url_btn
|
| 1087 |
+
2 # preview_url_count
|
| 1088 |
)
|
| 1089 |
|
| 1090 |
def update_preview_display(config_data):
|
|
|
|
| 1105 |
- **Temperature:** {config_data['temperature']}
|
| 1106 |
- **Max Tokens:** {config_data['max_tokens']}
|
| 1107 |
- **Dynamic URLs:** {'✅ Enabled' if config_data['enable_dynamic_urls'] else '❌ Disabled'}
|
| 1108 |
+
# RAG functionality removed
|
| 1109 |
|
| 1110 |
**System Prompt:**
|
| 1111 |
{config_data['system_prompt'][:600]}{'...' if len(config_data['system_prompt']) > 600 else ''}
|
|
|
|
| 1125 |
|
| 1126 |
**Features:**
|
| 1127 |
- **Dynamic URL Fetching:** {'✅ Enabled' if config_data['enable_dynamic_urls'] else '❌ Disabled'}
|
| 1128 |
+
# RAG functionality removed
|
| 1129 |
|
| 1130 |
**System Prompt:**
|
| 1131 |
```
|
|
|
|
| 1185 |
grounding_urls = config_urls if any(url for url in config_urls if url) else [url1, url2, url3, url4]
|
| 1186 |
grounding_context = get_cached_grounding_context([url for url in grounding_urls if url and url.strip()])
|
| 1187 |
|
| 1188 |
+
# RAG functionality removed
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1189 |
|
| 1190 |
# If dynamic URLs are enabled, check message for URLs to fetch
|
| 1191 |
dynamic_context = ""
|
|
|
|
| 1200 |
dynamic_context = "\n".join(dynamic_context_parts)
|
| 1201 |
|
| 1202 |
# Build enhanced system prompt with all contexts
|
| 1203 |
+
enhanced_system_prompt = config_data.get('system_prompt', '') + grounding_context + dynamic_context
|
| 1204 |
|
| 1205 |
# Build messages array for the API
|
| 1206 |
messages = [{"role": "system", "content": enhanced_system_prompt}]
|
|
|
|
| 1279 |
"""Clear preview chat"""
|
| 1280 |
return "", []
|
| 1281 |
|
| 1282 |
+
def export_preview_conversation(history, config_data=None):
|
| 1283 |
"""Export preview conversation to markdown"""
|
| 1284 |
if not history:
|
| 1285 |
return gr.update(visible=False)
|
| 1286 |
|
| 1287 |
+
markdown_content = export_conversation_to_markdown(history, config_data)
|
| 1288 |
|
| 1289 |
# Save to temporary file
|
| 1290 |
import tempfile
|
|
|
|
| 1294 |
|
| 1295 |
return gr.update(value=temp_file, visible=True)
|
| 1296 |
|
| 1297 |
+
def on_generate(name, description, system_prompt, model, api_key_var, temperature, max_tokens, examples_text, access_code, enable_dynamic_urls, url1, url2, url3, url4):
|
| 1298 |
if not name or not name.strip():
|
| 1299 |
return gr.update(value="Error: Please provide a Space Title", visible=True), gr.update(visible=False), {}
|
| 1300 |
|
| 1301 |
|
| 1302 |
try:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1303 |
# Use the system prompt directly (template selector already updates it)
|
| 1304 |
if not system_prompt or not system_prompt.strip():
|
| 1305 |
return gr.update(value="Error: Please provide a System Prompt for the assistant", visible=True), gr.update(visible=False), {}
|
| 1306 |
|
| 1307 |
final_system_prompt = system_prompt.strip()
|
| 1308 |
|
| 1309 |
+
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)
|
| 1310 |
|
| 1311 |
success_msg = f"""**Deployment package ready!**
|
| 1312 |
|
|
|
|
| 1334 |
'temperature': temperature,
|
| 1335 |
'max_tokens': max_tokens,
|
| 1336 |
'enable_dynamic_urls': enable_dynamic_urls,
|
|
|
|
| 1337 |
'filename': filename
|
| 1338 |
}
|
| 1339 |
|
|
|
|
| 1747 |
|
| 1748 |
|
| 1749 |
|
| 1750 |
+
# RAG functionality removed
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1751 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1752 |
|
| 1753 |
examples_text = gr.Textbox(
|
| 1754 |
label="Example Prompts (one per line)",
|
|
|
|
| 1783 |
value=1500,
|
| 1784 |
step=50
|
| 1785 |
)
|
| 1786 |
+
|
| 1787 |
+
# URL Grounding section
|
| 1788 |
+
gr.Markdown("**URL Grounding (Optional)**")
|
| 1789 |
+
gr.Markdown("Add URLs to provide context. Content will be fetched and added to the system prompt.")
|
| 1790 |
+
|
| 1791 |
+
# Initial URL fields
|
| 1792 |
+
url1 = gr.Textbox(
|
| 1793 |
+
label="URL 1",
|
| 1794 |
+
placeholder="https://example.com/page1",
|
| 1795 |
+
info="First URL for context grounding"
|
| 1796 |
+
)
|
| 1797 |
+
|
| 1798 |
+
url2 = gr.Textbox(
|
| 1799 |
+
label="URL 2",
|
| 1800 |
+
placeholder="https://example.com/page2",
|
| 1801 |
+
info="Second URL for context grounding"
|
| 1802 |
+
)
|
| 1803 |
+
|
| 1804 |
+
# Additional URL fields (initially hidden)
|
| 1805 |
+
url3 = gr.Textbox(
|
| 1806 |
+
label="URL 3",
|
| 1807 |
+
placeholder="https://example.com/page3",
|
| 1808 |
+
info="Third URL for context grounding",
|
| 1809 |
+
visible=False
|
| 1810 |
+
)
|
| 1811 |
+
|
| 1812 |
+
url4 = gr.Textbox(
|
| 1813 |
+
label="URL 4",
|
| 1814 |
+
placeholder="https://example.com/page4",
|
| 1815 |
+
info="Fourth URL for context grounding",
|
| 1816 |
+
visible=False
|
| 1817 |
+
)
|
| 1818 |
+
|
| 1819 |
+
# URL management buttons
|
| 1820 |
+
with gr.Row():
|
| 1821 |
+
add_url_btn = gr.Button("+ Add URLs", size="sm")
|
| 1822 |
+
remove_url_btn = gr.Button("- Remove URLs", size="sm", visible=False)
|
| 1823 |
+
url_count = gr.State(2) # Track number of visible URLs
|
| 1824 |
|
| 1825 |
with gr.Row():
|
| 1826 |
preview_btn = gr.Button("Preview Deployment Package", variant="secondary")
|
|
|
|
| 1856 |
outputs=[url3, url4, add_url_btn, remove_url_btn, url_count]
|
| 1857 |
)
|
| 1858 |
|
| 1859 |
+
# RAG functionality removed
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1860 |
|
| 1861 |
|
| 1862 |
# Connect the generate button
|
| 1863 |
generate_btn.click(
|
| 1864 |
on_generate,
|
| 1865 |
+
inputs=[name, description, system_prompt, model, api_key_var, temperature, max_tokens, examples_text, access_code, enable_dynamic_urls, url1, url2, url3, url4],
|
| 1866 |
outputs=[status, download_file, sandbox_state]
|
| 1867 |
)
|
| 1868 |
|
|
|
|
| 1958 |
|
| 1959 |
preview_export_btn.click(
|
| 1960 |
export_preview_conversation,
|
| 1961 |
+
inputs=[preview_chatbot, preview_config_state],
|
| 1962 |
outputs=[export_file]
|
| 1963 |
)
|
| 1964 |
|
|
|
|
| 1981 |
# Connect cross-tab functionality after all components are defined
|
| 1982 |
preview_btn.click(
|
| 1983 |
on_preview_combined,
|
| 1984 |
+
inputs=[name, description, system_prompt, model, temperature, max_tokens, examples_text, enable_dynamic_urls, url1, url2, url3, url4],
|
| 1985 |
+
outputs=[preview_config_state, preview_status_comp, preview_chat_section_comp, config_display_comp, preview_url1, preview_url2, preview_url3, preview_url4, preview_add_url_btn, preview_remove_url_btn, preview_url_count]
|
| 1986 |
)
|
| 1987 |
|
| 1988 |
if __name__ == "__main__":
|
requirements.txt
CHANGED
|
@@ -1,11 +1,4 @@
|
|
| 1 |
gradio>=4.44.1
|
| 2 |
requests>=2.32.3
|
| 3 |
beautifulsoup4>=4.12.3
|
| 4 |
-
python-dotenv>=1.0.0
|
| 5 |
-
|
| 6 |
-
# Vector RAG dependencies (optional)
|
| 7 |
-
sentence-transformers>=2.2.2
|
| 8 |
-
faiss-cpu>=1.11.0
|
| 9 |
-
PyMuPDF>=1.23.0
|
| 10 |
-
python-docx>=0.8.11
|
| 11 |
-
numpy>=1.25.0,<3.0
|
|
|
|
| 1 |
gradio>=4.44.1
|
| 2 |
requests>=2.32.3
|
| 3 |
beautifulsoup4>=4.12.3
|
| 4 |
+
python-dotenv>=1.0.0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
support_docs.py
CHANGED
|
@@ -25,7 +25,7 @@ def create_support_docs():
|
|
| 25 |
**Workflow Steps:**
|
| 26 |
1. **Configure your Space** in the Configuration tab (space title, description, model selection)
|
| 27 |
2. **Set up Assistant** with system prompt and optional research template
|
| 28 |
-
3. **Enable Tools** like
|
| 29 |
4. **Preview & Test** using the Preview tab to validate your configuration
|
| 30 |
5. **Generate Package** with the "Generate Deployment Package" button
|
| 31 |
6. **Deploy to HuggingFace** following the included README instructions
|
|
@@ -213,7 +213,7 @@ def create_support_docs():
|
|
| 213 |
- **System Prompt**: Main field defining assistant behavior and knowledge
|
| 214 |
- **Research Template**: Pre-configured academic research assistant checkbox
|
| 215 |
- **Web Search Integration**: Enable crawl4ai web search capabilities
|
| 216 |
-
|
| 217 |
- **URL Grounding**: Add up to 4 static URLs for context (dynamic add/remove)
|
| 218 |
- **Example Prompts**: Clickable suggestions for users (one per line)
|
| 219 |
- **Dynamic URL Fetching**: Hidden field (always enabled) for runtime URL processing
|
|
@@ -233,11 +233,7 @@ def create_support_docs():
|
|
| 233 |
- Advanced content extraction and crawling
|
| 234 |
- Automatically enabled with Research Template
|
| 235 |
|
| 236 |
-
|
| 237 |
-
- Upload files: PDF, DOCX, TXT, MD (10MB max each)
|
| 238 |
-
- Semantic chunking and FAISS vector search
|
| 239 |
-
- Embedded in deployment package for offline use
|
| 240 |
-
- Requires `sentence-transformers` and `faiss-cpu`
|
| 241 |
|
| 242 |
**URL Grounding (Static Context)**
|
| 243 |
- Add 2-4 URLs for consistent context across all responses
|
|
@@ -270,7 +266,7 @@ def create_support_docs():
|
|
| 270 |
|
| 271 |
**Token Usage Notes:**
|
| 272 |
- Tokens include both input (your prompt + context) and output
|
| 273 |
-
- Longer contexts (
|
| 274 |
- Consider costs when setting high token limits
|
| 275 |
""")
|
| 276 |
|
|
@@ -359,10 +355,7 @@ def create_support_docs():
|
|
| 359 |
- Check for typos in the access code
|
| 360 |
- Case-sensitive matching
|
| 361 |
|
| 362 |
-
|
| 363 |
-
- Check file formats are supported (PDF, DOCX, TXT, MD)
|
| 364 |
-
- Verify file sizes are under 10MB
|
| 365 |
-
- Ensure RAG dependencies are installed
|
| 366 |
|
| 367 |
**URLs not fetching content**
|
| 368 |
- Check URLs are publicly accessible
|
|
@@ -378,7 +371,7 @@ def create_support_docs():
|
|
| 378 |
- Use appropriate model for your use case
|
| 379 |
- Set reasonable token limits
|
| 380 |
- Cache static content with URL grounding
|
| 381 |
-
|
| 382 |
|
| 383 |
**User Experience**
|
| 384 |
- Write clear, helpful example prompts
|
|
|
|
| 25 |
**Workflow Steps:**
|
| 26 |
1. **Configure your Space** in the Configuration tab (space title, description, model selection)
|
| 27 |
2. **Set up Assistant** with system prompt and optional research template
|
| 28 |
+
3. **Enable Tools** like dynamic URL fetching or URL grounding as needed
|
| 29 |
4. **Preview & Test** using the Preview tab to validate your configuration
|
| 30 |
5. **Generate Package** with the "Generate Deployment Package" button
|
| 31 |
6. **Deploy to HuggingFace** following the included README instructions
|
|
|
|
| 213 |
- **System Prompt**: Main field defining assistant behavior and knowledge
|
| 214 |
- **Research Template**: Pre-configured academic research assistant checkbox
|
| 215 |
- **Web Search Integration**: Enable crawl4ai web search capabilities
|
| 216 |
+
# Document RAG functionality removed
|
| 217 |
- **URL Grounding**: Add up to 4 static URLs for context (dynamic add/remove)
|
| 218 |
- **Example Prompts**: Clickable suggestions for users (one per line)
|
| 219 |
- **Dynamic URL Fetching**: Hidden field (always enabled) for runtime URL processing
|
|
|
|
| 233 |
- Advanced content extraction and crawling
|
| 234 |
- Automatically enabled with Research Template
|
| 235 |
|
| 236 |
+
# Document RAG functionality removed
|
|
|
|
|
|
|
|
|
|
|
|
|
| 237 |
|
| 238 |
**URL Grounding (Static Context)**
|
| 239 |
- Add 2-4 URLs for consistent context across all responses
|
|
|
|
| 266 |
|
| 267 |
**Token Usage Notes:**
|
| 268 |
- Tokens include both input (your prompt + context) and output
|
| 269 |
+
- Longer contexts (URLs) use more input tokens
|
| 270 |
- Consider costs when setting high token limits
|
| 271 |
""")
|
| 272 |
|
|
|
|
| 355 |
- Check for typos in the access code
|
| 356 |
- Case-sensitive matching
|
| 357 |
|
| 358 |
+
# Document RAG functionality removed
|
|
|
|
|
|
|
|
|
|
| 359 |
|
| 360 |
**URLs not fetching content**
|
| 361 |
- Check URLs are publicly accessible
|
|
|
|
| 371 |
- Use appropriate model for your use case
|
| 372 |
- Set reasonable token limits
|
| 373 |
- Cache static content with URL grounding
|
| 374 |
+
# Document RAG functionality removed
|
| 375 |
|
| 376 |
**User Experience**
|
| 377 |
- Write clear, helpful example prompts
|