Spaces:
Running
Running
Restructure application with improved UI and preview functionality
Browse filesMajor changes:
- Restructure from 2 tabs to 3 tabs: Configuration, Sandbox Preview, Support Docs
- Move URL grounding under Tool Settings accordion
- Add Preview and Generate buttons side-by-side
- Implement real-time preview functionality in Sandbox tab
- Add interactive chat interface for testing configurations
- Remove redundant Example Prompts sections
- Move Advanced Settings (temperature, max tokens) to accordion
- Add conversation export functionality
- Improve cross-tab state management
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
app.py
CHANGED
@@ -9,6 +9,7 @@ import requests
|
|
9 |
from bs4 import BeautifulSoup
|
10 |
import tempfile
|
11 |
from pathlib import Path
|
|
|
12 |
# Simple URL content fetching using requests and BeautifulSoup
|
13 |
def get_grounding_context_simple(urls):
|
14 |
"""Fetch grounding context using simple HTTP requests"""
|
@@ -631,6 +632,203 @@ def update_sandbox_preview(config_data):
|
|
631 |
|
632 |
return preview_text, preview_html
|
633 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
634 |
def on_generate(name, description, system_prompt, enable_research_assistant, role_purpose, intended_audience, key_tasks, additional_context, custom_role_purpose, custom_intended_audience, custom_key_tasks, custom_additional_context, model, api_key_var, temperature, max_tokens, examples_text, access_code, enable_dynamic_urls, url1, url2, url3, url4, enable_vector_rag, rag_tool_state):
|
635 |
if not name or not name.strip():
|
636 |
return gr.update(value="Error: Please provide a Space Title", visible=True), gr.update(visible=False)
|
@@ -937,6 +1135,12 @@ def toggle_custom_categories(enable_custom):
|
|
937 |
with gr.Blocks(title="Chat U/I Helper") as demo:
|
938 |
# Global state for cross-tab functionality
|
939 |
sandbox_state = gr.State({})
|
|
|
|
|
|
|
|
|
|
|
|
|
940 |
|
941 |
with gr.Tabs():
|
942 |
with gr.Tab("Configuration"):
|
@@ -1096,7 +1300,7 @@ with gr.Blocks(title="Chat U/I Helper") as demo:
|
|
1096 |
label="Enable Document RAG",
|
1097 |
value=False,
|
1098 |
info="Upload documents for context-aware responses (PDF, DOCX, TXT, MD)",
|
1099 |
-
visible=
|
1100 |
)
|
1101 |
|
1102 |
with gr.Column(visible=False) as rag_section:
|
@@ -1104,78 +1308,73 @@ with gr.Blocks(title="Chat U/I Helper") as demo:
|
|
1104 |
file_upload = gr.File(
|
1105 |
label="Upload Documents",
|
1106 |
file_types=[".pdf", ".docx", ".txt", ".md"],
|
1107 |
-
file_count="multiple"
|
1108 |
-
type="filepath"
|
1109 |
)
|
1110 |
process_btn = gr.Button("Process Documents", variant="secondary")
|
1111 |
rag_status = gr.Markdown()
|
1112 |
|
1113 |
# State to store RAG tool
|
1114 |
rag_tool_state = gr.State(None)
|
1115 |
-
|
1116 |
-
with gr.Accordion("URL Grounding (Optional)", open=False):
|
1117 |
-
gr.Markdown("Add URLs to provide context. Content will be fetched and added to the system prompt.")
|
1118 |
-
|
1119 |
-
# Initial URL fields
|
1120 |
-
url1 = gr.Textbox(
|
1121 |
-
label="URL 1",
|
1122 |
-
placeholder="https://example.com/page1",
|
1123 |
-
info="First URL for context grounding"
|
1124 |
-
)
|
1125 |
-
|
1126 |
-
url2 = gr.Textbox(
|
1127 |
-
label="URL 2",
|
1128 |
-
placeholder="https://example.com/page2",
|
1129 |
-
info="Second URL for context grounding"
|
1130 |
-
)
|
1131 |
-
|
1132 |
-
# Additional URL fields (initially hidden)
|
1133 |
-
url3 = gr.Textbox(
|
1134 |
-
label="URL 3",
|
1135 |
-
placeholder="https://example.com/page3",
|
1136 |
-
info="Third URL for context grounding",
|
1137 |
-
visible=False
|
1138 |
-
)
|
1139 |
-
|
1140 |
-
url4 = gr.Textbox(
|
1141 |
-
label="URL 4",
|
1142 |
-
placeholder="https://example.com/page4",
|
1143 |
-
info="Fourth URL for context grounding",
|
1144 |
-
visible=False
|
1145 |
-
)
|
1146 |
|
1147 |
-
|
1148 |
-
|
1149 |
-
|
1150 |
-
|
1151 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1152 |
|
1153 |
-
|
1154 |
-
|
1155 |
-
|
1156 |
-
|
1157 |
-
|
1158 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1159 |
|
1160 |
with gr.Row():
|
1161 |
-
|
1162 |
-
|
1163 |
-
minimum=0,
|
1164 |
-
maximum=2,
|
1165 |
-
value=0.7,
|
1166 |
-
step=0.1,
|
1167 |
-
info="Higher = more creative, Lower = more focused"
|
1168 |
-
)
|
1169 |
-
|
1170 |
-
max_tokens = gr.Slider(
|
1171 |
-
label="Max Response Tokens",
|
1172 |
-
minimum=50,
|
1173 |
-
maximum=4096,
|
1174 |
-
value=500,
|
1175 |
-
step=50
|
1176 |
-
)
|
1177 |
-
|
1178 |
-
generate_btn = gr.Button("Generate Deployment Package", variant="primary")
|
1179 |
|
1180 |
status = gr.Markdown(visible=False)
|
1181 |
download_file = gr.File(label="Download your zip package", visible=False)
|
@@ -1236,6 +1435,7 @@ with gr.Blocks(title="Chat U/I Helper") as demo:
|
|
1236 |
outputs=[rag_status, rag_tool_state]
|
1237 |
)
|
1238 |
|
|
|
1239 |
# Connect the generate button
|
1240 |
generate_btn.click(
|
1241 |
on_generate,
|
@@ -1244,111 +1444,73 @@ with gr.Blocks(title="Chat U/I Helper") as demo:
|
|
1244 |
)
|
1245 |
|
1246 |
|
1247 |
-
with gr.Tab("
|
1248 |
-
gr.Markdown("#
|
1249 |
-
gr.Markdown("
|
1250 |
|
1251 |
-
# Meta chat interface
|
1252 |
with gr.Column():
|
1253 |
-
|
1254 |
-
|
1255 |
-
label="Chat Support Assistant",
|
1256 |
-
height=400,
|
1257 |
-
type="messages"
|
1258 |
-
)
|
1259 |
-
msg = gr.Textbox(
|
1260 |
-
label="Ask about configuring chat UIs for courses, research, or custom HuggingFace Spaces",
|
1261 |
-
placeholder="How can I configure a chat UI for my senior seminar?",
|
1262 |
-
lines=2
|
1263 |
-
)
|
1264 |
|
1265 |
-
|
1266 |
-
|
1267 |
-
|
1268 |
-
|
1269 |
-
|
1270 |
-
|
1271 |
-
)
|
1272 |
-
chat_url2 = gr.Textbox(
|
1273 |
-
label="URL 2",
|
1274 |
-
value="",
|
1275 |
-
placeholder="https://example.com/page2",
|
1276 |
-
info="Additional context URL"
|
1277 |
)
|
1278 |
-
|
1279 |
-
|
1280 |
-
|
1281 |
-
|
1282 |
-
placeholder="https://example.com/page3",
|
1283 |
-
info="Additional context URL",
|
1284 |
-
visible=False
|
1285 |
-
)
|
1286 |
-
|
1287 |
-
chat_url4 = gr.Textbox(
|
1288 |
-
label="URL 4",
|
1289 |
-
placeholder="https://example.com/page4",
|
1290 |
-
info="Additional context URL",
|
1291 |
-
visible=False
|
1292 |
)
|
1293 |
|
1294 |
-
# Chat URL management buttons
|
1295 |
with gr.Row():
|
1296 |
-
|
1297 |
-
|
1298 |
-
|
1299 |
|
1300 |
-
#
|
1301 |
-
|
1302 |
-
cache_status = gr.Markdown("🔄 No URLs cached")
|
1303 |
-
clear_cache_btn = gr.Button("Clear URL Cache", size="sm")
|
1304 |
|
1305 |
-
|
1306 |
-
|
1307 |
-
clear = gr.Button("Clear")
|
1308 |
|
1309 |
-
gr.Examples(
|
1310 |
-
examples=[
|
1311 |
-
"How do I set up a course assistant?",
|
1312 |
-
"Which model should I use?",
|
1313 |
-
"What's a good system prompt?",
|
1314 |
-
"Why Gradio? What is it?",
|
1315 |
-
"How do I customize the chat interface?",
|
1316 |
-
"Can you help me troubleshoot?",
|
1317 |
-
],
|
1318 |
-
inputs=msg
|
1319 |
-
)
|
1320 |
|
1321 |
-
|
1322 |
-
|
1323 |
-
|
1324 |
-
|
1325 |
-
|
|
|
1326 |
)
|
1327 |
|
1328 |
-
|
1329 |
-
|
1330 |
-
inputs=[
|
1331 |
-
outputs=[
|
1332 |
)
|
1333 |
|
1334 |
-
|
1335 |
-
|
|
|
|
|
1336 |
|
1337 |
-
|
1338 |
-
|
1339 |
-
|
1340 |
-
|
|
|
1341 |
|
1342 |
-
with gr.Tab("
|
1343 |
-
|
1344 |
-
|
1345 |
-
|
1346 |
-
|
1347 |
-
|
1348 |
-
|
1349 |
-
|
1350 |
-
|
1351 |
-
|
1352 |
|
1353 |
if __name__ == "__main__":
|
1354 |
# Check if running in local development with dev tunnels
|
|
|
9 |
from bs4 import BeautifulSoup
|
10 |
import tempfile
|
11 |
from pathlib import Path
|
12 |
+
from support_docs import create_support_docs, export_conversation_to_markdown
|
13 |
# Simple URL content fetching using requests and BeautifulSoup
|
14 |
def get_grounding_context_simple(urls):
|
15 |
"""Fetch grounding context using simple HTTP requests"""
|
|
|
632 |
|
633 |
return preview_text, preview_html
|
634 |
|
635 |
+
def on_preview_combined(name, description, system_prompt, enable_research_assistant, role_purpose, intended_audience, key_tasks, additional_context, model, temperature, max_tokens, examples_text, enable_dynamic_urls, enable_vector_rag):
|
636 |
+
"""Generate configuration and return preview updates"""
|
637 |
+
if not name or not name.strip():
|
638 |
+
return (
|
639 |
+
{},
|
640 |
+
gr.update(value="**Error:** Please provide a Space Title to preview", visible=True),
|
641 |
+
gr.update(visible=False),
|
642 |
+
gr.update(value="Configuration will appear here after preview generation.")
|
643 |
+
)
|
644 |
+
|
645 |
+
try:
|
646 |
+
# Combine system prompt components if research assistant is enabled
|
647 |
+
if enable_research_assistant:
|
648 |
+
if not role_purpose or not role_purpose.strip():
|
649 |
+
return (
|
650 |
+
{},
|
651 |
+
gr.update(value="**Error:** Please provide a Role and Purpose for the research assistant", visible=True),
|
652 |
+
gr.update(visible=False),
|
653 |
+
gr.update(value="Configuration will appear here after preview generation.")
|
654 |
+
)
|
655 |
+
system_prompt_parts = []
|
656 |
+
if role_purpose and role_purpose.strip():
|
657 |
+
system_prompt_parts.append(role_purpose.strip())
|
658 |
+
if intended_audience and intended_audience.strip():
|
659 |
+
system_prompt_parts.append(intended_audience.strip())
|
660 |
+
if key_tasks and key_tasks.strip():
|
661 |
+
system_prompt_parts.append(key_tasks.strip())
|
662 |
+
if additional_context and additional_context.strip():
|
663 |
+
system_prompt_parts.append(additional_context.strip())
|
664 |
+
|
665 |
+
final_system_prompt = " ".join(system_prompt_parts)
|
666 |
+
else:
|
667 |
+
if not system_prompt or not system_prompt.strip():
|
668 |
+
return (
|
669 |
+
{},
|
670 |
+
gr.update(value="**Error:** Please provide a System Prompt for the assistant", visible=True),
|
671 |
+
gr.update(visible=False),
|
672 |
+
gr.update(value="Configuration will appear here after preview generation.")
|
673 |
+
)
|
674 |
+
final_system_prompt = system_prompt.strip()
|
675 |
+
|
676 |
+
# Create configuration for preview
|
677 |
+
config_data = {
|
678 |
+
'name': name,
|
679 |
+
'description': description,
|
680 |
+
'system_prompt': final_system_prompt,
|
681 |
+
'model': model,
|
682 |
+
'temperature': temperature,
|
683 |
+
'max_tokens': max_tokens,
|
684 |
+
'enable_dynamic_urls': enable_dynamic_urls,
|
685 |
+
'enable_vector_rag': enable_vector_rag,
|
686 |
+
'examples_text': examples_text,
|
687 |
+
'preview_ready': True
|
688 |
+
}
|
689 |
+
|
690 |
+
# Generate preview displays
|
691 |
+
preview_text = f"""**Preview Ready!**
|
692 |
+
|
693 |
+
Your assistant "{name}" is configured and ready to test.
|
694 |
+
|
695 |
+
**Configuration:**
|
696 |
+
- **Model:** {model}
|
697 |
+
- **Temperature:** {temperature}
|
698 |
+
- **Max Tokens:** {max_tokens}
|
699 |
+
- **Dynamic URLs:** {'✅ Enabled' if enable_dynamic_urls else '❌ Disabled'}
|
700 |
+
- **Vector RAG:** {'✅ Enabled' if enable_vector_rag else '❌ Disabled'}
|
701 |
+
|
702 |
+
**System Prompt:**
|
703 |
+
{final_system_prompt[:200]}{'...' if len(final_system_prompt) > 200 else ''}
|
704 |
+
|
705 |
+
Use the chat interface below to test your assistant before generating the deployment package."""
|
706 |
+
|
707 |
+
config_display = f"""### Current Configuration
|
708 |
+
|
709 |
+
**Space Details:**
|
710 |
+
- **Name:** {name}
|
711 |
+
- **Description:** {description or 'No description provided'}
|
712 |
+
|
713 |
+
**Model Settings:**
|
714 |
+
- **Model:** {model}
|
715 |
+
- **Temperature:** {temperature}
|
716 |
+
- **Max Response Tokens:** {max_tokens}
|
717 |
+
|
718 |
+
**Features:**
|
719 |
+
- **Dynamic URL Fetching:** {'✅ Enabled' if enable_dynamic_urls else '❌ Disabled'}
|
720 |
+
- **Document RAG:** {'✅ Enabled' if enable_vector_rag else '❌ Disabled'}
|
721 |
+
|
722 |
+
**System Prompt:**
|
723 |
+
```
|
724 |
+
{final_system_prompt}
|
725 |
+
```
|
726 |
+
|
727 |
+
**Example Prompts:**
|
728 |
+
{examples_text if examples_text and examples_text.strip() else 'No example prompts configured'}
|
729 |
+
"""
|
730 |
+
|
731 |
+
return (
|
732 |
+
config_data,
|
733 |
+
gr.update(value=preview_text, visible=True),
|
734 |
+
gr.update(visible=True),
|
735 |
+
gr.update(value=config_display)
|
736 |
+
)
|
737 |
+
|
738 |
+
except Exception as e:
|
739 |
+
return (
|
740 |
+
{},
|
741 |
+
gr.update(value=f"**Error:** {str(e)}", visible=True),
|
742 |
+
gr.update(visible=False),
|
743 |
+
gr.update(value="Configuration will appear here after preview generation.")
|
744 |
+
)
|
745 |
+
|
746 |
+
def update_preview_display(config_data):
|
747 |
+
"""Update preview display based on config data"""
|
748 |
+
if not config_data or not config_data.get('preview_ready'):
|
749 |
+
return (
|
750 |
+
gr.update(value="**Status:** Configure your space in the Configuration tab and click 'Preview Deployment Package' to see your assistant here.", visible=True),
|
751 |
+
gr.update(visible=False),
|
752 |
+
gr.update(value="Configuration will appear here after preview generation.")
|
753 |
+
)
|
754 |
+
|
755 |
+
preview_text = f"""**Preview Ready!**
|
756 |
+
|
757 |
+
Your assistant "{config_data['name']}" is configured and ready to test.
|
758 |
+
|
759 |
+
**Configuration:**
|
760 |
+
- **Model:** {config_data['model']}
|
761 |
+
- **Temperature:** {config_data['temperature']}
|
762 |
+
- **Max Tokens:** {config_data['max_tokens']}
|
763 |
+
- **Dynamic URLs:** {'✅ Enabled' if config_data['enable_dynamic_urls'] else '❌ Disabled'}
|
764 |
+
- **Vector RAG:** {'✅ Enabled' if config_data['enable_vector_rag'] else '❌ Disabled'}
|
765 |
+
|
766 |
+
**System Prompt:**
|
767 |
+
{config_data['system_prompt'][:200]}{'...' if len(config_data['system_prompt']) > 200 else ''}
|
768 |
+
|
769 |
+
Use the chat interface below to test your assistant before generating the deployment package."""
|
770 |
+
|
771 |
+
config_display = f"""### Current Configuration
|
772 |
+
|
773 |
+
**Space Details:**
|
774 |
+
- **Name:** {config_data['name']}
|
775 |
+
- **Description:** {config_data.get('description', 'No description provided')}
|
776 |
+
|
777 |
+
**Model Settings:**
|
778 |
+
- **Model:** {config_data['model']}
|
779 |
+
- **Temperature:** {config_data['temperature']}
|
780 |
+
- **Max Response Tokens:** {config_data['max_tokens']}
|
781 |
+
|
782 |
+
**Features:**
|
783 |
+
- **Dynamic URL Fetching:** {'✅ Enabled' if config_data['enable_dynamic_urls'] else '❌ Disabled'}
|
784 |
+
- **Document RAG:** {'✅ Enabled' if config_data['enable_vector_rag'] else '❌ Disabled'}
|
785 |
+
|
786 |
+
**System Prompt:**
|
787 |
+
```
|
788 |
+
{config_data['system_prompt']}
|
789 |
+
```
|
790 |
+
|
791 |
+
**Example Prompts:**
|
792 |
+
{config_data.get('examples_text', 'No example prompts configured') if config_data.get('examples_text', '').strip() else 'No example prompts configured'}
|
793 |
+
"""
|
794 |
+
|
795 |
+
return (
|
796 |
+
gr.update(value=preview_text, visible=True),
|
797 |
+
gr.update(visible=True),
|
798 |
+
gr.update(value=config_display)
|
799 |
+
)
|
800 |
+
|
801 |
+
def preview_chat_response(message, history, config_data):
|
802 |
+
"""Generate response for preview chat"""
|
803 |
+
if not config_data or not message:
|
804 |
+
return "", history
|
805 |
+
|
806 |
+
# Simple simulated response for preview
|
807 |
+
response = f"[Preview Mode] I'm {config_data.get('name', 'your assistant')} running on {config_data.get('model', 'unknown model')}. This is a preview of how I would respond. In the actual deployment, I would use the OpenRouter API with your configured system prompt: {config_data.get('system_prompt', '')[:100]}..."
|
808 |
+
|
809 |
+
history.append({"role": "user", "content": message})
|
810 |
+
history.append({"role": "assistant", "content": response})
|
811 |
+
return "", history
|
812 |
+
|
813 |
+
def clear_preview_chat():
|
814 |
+
"""Clear preview chat"""
|
815 |
+
return "", []
|
816 |
+
|
817 |
+
def export_preview_conversation(history):
|
818 |
+
"""Export preview conversation to markdown"""
|
819 |
+
if not history:
|
820 |
+
return gr.update(visible=False)
|
821 |
+
|
822 |
+
markdown_content = export_conversation_to_markdown(history)
|
823 |
+
|
824 |
+
# Save to temporary file
|
825 |
+
import tempfile
|
826 |
+
with tempfile.NamedTemporaryFile(mode='w', suffix='.md', delete=False) as f:
|
827 |
+
f.write(markdown_content)
|
828 |
+
temp_file = f.name
|
829 |
+
|
830 |
+
return gr.update(value=temp_file, visible=True)
|
831 |
+
|
832 |
def on_generate(name, description, system_prompt, enable_research_assistant, role_purpose, intended_audience, key_tasks, additional_context, custom_role_purpose, custom_intended_audience, custom_key_tasks, custom_additional_context, model, api_key_var, temperature, max_tokens, examples_text, access_code, enable_dynamic_urls, url1, url2, url3, url4, enable_vector_rag, rag_tool_state):
|
833 |
if not name or not name.strip():
|
834 |
return gr.update(value="Error: Please provide a Space Title", visible=True), gr.update(visible=False)
|
|
|
1135 |
with gr.Blocks(title="Chat U/I Helper") as demo:
|
1136 |
# Global state for cross-tab functionality
|
1137 |
sandbox_state = gr.State({})
|
1138 |
+
preview_config_state = gr.State({})
|
1139 |
+
|
1140 |
+
# Global status components that will be defined later
|
1141 |
+
preview_status = None
|
1142 |
+
preview_chat_section = None
|
1143 |
+
config_display = None
|
1144 |
|
1145 |
with gr.Tabs():
|
1146 |
with gr.Tab("Configuration"):
|
|
|
1300 |
label="Enable Document RAG",
|
1301 |
value=False,
|
1302 |
info="Upload documents for context-aware responses (PDF, DOCX, TXT, MD)",
|
1303 |
+
visible=HAS_RAG
|
1304 |
)
|
1305 |
|
1306 |
with gr.Column(visible=False) as rag_section:
|
|
|
1308 |
file_upload = gr.File(
|
1309 |
label="Upload Documents",
|
1310 |
file_types=[".pdf", ".docx", ".txt", ".md"],
|
1311 |
+
file_count="multiple"
|
|
|
1312 |
)
|
1313 |
process_btn = gr.Button("Process Documents", variant="secondary")
|
1314 |
rag_status = gr.Markdown()
|
1315 |
|
1316 |
# State to store RAG tool
|
1317 |
rag_tool_state = gr.State(None)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1318 |
|
1319 |
+
with gr.Accordion("URL Grounding (Optional)", open=False):
|
1320 |
+
gr.Markdown("Add URLs to provide context. Content will be fetched and added to the system prompt.")
|
1321 |
+
|
1322 |
+
# Initial URL fields
|
1323 |
+
url1 = gr.Textbox(
|
1324 |
+
label="URL 1",
|
1325 |
+
placeholder="https://example.com/page1",
|
1326 |
+
info="First URL for context grounding"
|
1327 |
+
)
|
1328 |
+
|
1329 |
+
url2 = gr.Textbox(
|
1330 |
+
label="URL 2",
|
1331 |
+
placeholder="https://example.com/page2",
|
1332 |
+
info="Second URL for context grounding"
|
1333 |
+
)
|
1334 |
+
|
1335 |
+
# Additional URL fields (initially hidden)
|
1336 |
+
url3 = gr.Textbox(
|
1337 |
+
label="URL 3",
|
1338 |
+
placeholder="https://example.com/page3",
|
1339 |
+
info="Third URL for context grounding",
|
1340 |
+
visible=False
|
1341 |
+
)
|
1342 |
+
|
1343 |
+
url4 = gr.Textbox(
|
1344 |
+
label="URL 4",
|
1345 |
+
placeholder="https://example.com/page4",
|
1346 |
+
info="Fourth URL for context grounding",
|
1347 |
+
visible=False
|
1348 |
+
)
|
1349 |
+
|
1350 |
+
# URL management buttons
|
1351 |
+
with gr.Row():
|
1352 |
+
add_url_btn = gr.Button("+ Add URLs", size="sm")
|
1353 |
+
remove_url_btn = gr.Button("- Remove URLs", size="sm", visible=False)
|
1354 |
+
url_count = gr.State(2) # Track number of visible URLs
|
1355 |
|
1356 |
+
with gr.Accordion("Advanced Settings", open=False):
|
1357 |
+
with gr.Row():
|
1358 |
+
temperature = gr.Slider(
|
1359 |
+
label="Temperature",
|
1360 |
+
minimum=0,
|
1361 |
+
maximum=2,
|
1362 |
+
value=0.7,
|
1363 |
+
step=0.1,
|
1364 |
+
info="Higher = more creative, Lower = more focused"
|
1365 |
+
)
|
1366 |
+
|
1367 |
+
max_tokens = gr.Slider(
|
1368 |
+
label="Max Response Tokens",
|
1369 |
+
minimum=50,
|
1370 |
+
maximum=4096,
|
1371 |
+
value=500,
|
1372 |
+
step=50
|
1373 |
+
)
|
1374 |
|
1375 |
with gr.Row():
|
1376 |
+
preview_btn = gr.Button("Preview Deployment Package", variant="secondary")
|
1377 |
+
generate_btn = gr.Button("Generate Deployment Package", variant="primary")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1378 |
|
1379 |
status = gr.Markdown(visible=False)
|
1380 |
download_file = gr.File(label="Download your zip package", visible=False)
|
|
|
1435 |
outputs=[rag_status, rag_tool_state]
|
1436 |
)
|
1437 |
|
1438 |
+
|
1439 |
# Connect the generate button
|
1440 |
generate_btn.click(
|
1441 |
on_generate,
|
|
|
1444 |
)
|
1445 |
|
1446 |
|
1447 |
+
with gr.Tab("Sandbox Preview"):
|
1448 |
+
gr.Markdown("# Sandbox Preview")
|
1449 |
+
gr.Markdown("Preview your generated assistant exactly as it will appear in the deployed HuggingFace Space.")
|
1450 |
|
|
|
1451 |
with gr.Column():
|
1452 |
+
# Preview status - assign to global variable
|
1453 |
+
preview_status_comp = gr.Markdown("**Status:** Configure your space in the Configuration tab and click 'Preview Deployment Package' to see your assistant here.", visible=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1454 |
|
1455 |
+
# Simulated chat interface for preview
|
1456 |
+
with gr.Column(visible=False) as preview_chat_section_comp:
|
1457 |
+
preview_chatbot = gr.Chatbot(
|
1458 |
+
value=[],
|
1459 |
+
label="Preview Chat Interface",
|
1460 |
+
height=400
|
|
|
|
|
|
|
|
|
|
|
|
|
1461 |
)
|
1462 |
+
preview_msg = gr.Textbox(
|
1463 |
+
label="Test your assistant",
|
1464 |
+
placeholder="Type a message to test your assistant...",
|
1465 |
+
lines=2
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1466 |
)
|
1467 |
|
|
|
1468 |
with gr.Row():
|
1469 |
+
preview_send = gr.Button("Send", variant="primary")
|
1470 |
+
preview_clear = gr.Button("Clear")
|
1471 |
+
export_btn = gr.Button("Export Conversation", variant="secondary")
|
1472 |
|
1473 |
+
# Export functionality
|
1474 |
+
export_file = gr.File(label="Download Conversation", visible=False)
|
|
|
|
|
1475 |
|
1476 |
+
# Configuration display - assign to global variable
|
1477 |
+
config_display_comp = gr.Markdown("Configuration will appear here after preview generation.")
|
|
|
1478 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1479 |
|
1480 |
+
|
1481 |
+
# Connect preview chat functionality
|
1482 |
+
preview_send.click(
|
1483 |
+
preview_chat_response,
|
1484 |
+
inputs=[preview_msg, preview_chatbot, preview_config_state],
|
1485 |
+
outputs=[preview_msg, preview_chatbot]
|
1486 |
)
|
1487 |
|
1488 |
+
preview_msg.submit(
|
1489 |
+
preview_chat_response,
|
1490 |
+
inputs=[preview_msg, preview_chatbot, preview_config_state],
|
1491 |
+
outputs=[preview_msg, preview_chatbot]
|
1492 |
)
|
1493 |
|
1494 |
+
preview_clear.click(
|
1495 |
+
clear_preview_chat,
|
1496 |
+
outputs=[preview_msg, preview_chatbot]
|
1497 |
+
)
|
1498 |
|
1499 |
+
export_btn.click(
|
1500 |
+
export_preview_conversation,
|
1501 |
+
inputs=[preview_chatbot],
|
1502 |
+
outputs=[export_file]
|
1503 |
+
)
|
1504 |
|
1505 |
+
with gr.Tab("Support Docs"):
|
1506 |
+
create_support_docs()
|
1507 |
+
|
1508 |
+
# Connect cross-tab functionality after all components are defined
|
1509 |
+
preview_btn.click(
|
1510 |
+
on_preview_combined,
|
1511 |
+
inputs=[name, description, system_prompt, enable_research_assistant, role_purpose, intended_audience, key_tasks, additional_context, model, temperature, max_tokens, examples_text, enable_dynamic_urls, enable_vector_rag],
|
1512 |
+
outputs=[preview_config_state, preview_status_comp, preview_chat_section_comp, config_display_comp]
|
1513 |
+
)
|
|
|
1514 |
|
1515 |
if __name__ == "__main__":
|
1516 |
# Check if running in local development with dev tunnels
|