milwright Claude commited on
Commit
78423cd
·
1 Parent(s): 1770bc8

Restructure application with improved UI and preview functionality

Browse files

Major 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]>

Files changed (1) hide show
  1. app.py +313 -151
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=True if HAS_RAG else False
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
- # URL management buttons
1148
- with gr.Row():
1149
- add_url_btn = gr.Button("+ Add URLs", size="sm")
1150
- remove_url_btn = gr.Button("- Remove URLs", size="sm", visible=False)
1151
- url_count = gr.State(2) # Track number of visible URLs
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1152
 
1153
- examples_text = gr.Textbox(
1154
- label="Example Prompts (one per line)",
1155
- placeholder="Can you analyze this research paper: https://example.com/paper.pdf\nWhat are the latest findings on climate change adaptation?\nHelp me fact-check claims about renewable energy efficiency",
1156
- lines=3,
1157
- info="These will appear as clickable examples in the chat interface"
1158
- )
 
 
 
 
 
 
 
 
 
 
 
 
1159
 
1160
  with gr.Row():
1161
- temperature = gr.Slider(
1162
- label="Temperature",
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("Support"):
1248
- gr.Markdown("# Chat Support")
1249
- gr.Markdown("Get personalized guidance on configuring chat assistants as HuggingFace Spaces for educational & research purposes.")
1250
 
1251
- # Meta chat interface
1252
  with gr.Column():
1253
- chatbot = gr.Chatbot(
1254
- value=[],
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
- with gr.Accordion("URL Grounding (Optional)", open=False):
1266
- gr.Markdown("Add URLs to provide additional context for more informed responses")
1267
- chat_url1 = gr.Textbox(
1268
- label="URL 1",
1269
- value="https://huggingface.co/docs/hub/en/spaces-overview",
1270
- info="HuggingFace Spaces Overview"
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
- # Additional URL fields for chat (initially hidden)
1280
- chat_url3 = gr.Textbox(
1281
- label="URL 3",
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
- add_chat_url_btn = gr.Button("+ Add URLs", size="sm")
1297
- remove_chat_url_btn = gr.Button("- Remove URLs", size="sm", visible=False)
1298
- chat_url_count = gr.State(2) # Track number of visible chat URLs
1299
 
1300
- # Cache controls
1301
- with gr.Row():
1302
- cache_status = gr.Markdown("🔄 No URLs cached")
1303
- clear_cache_btn = gr.Button("Clear URL Cache", size="sm")
1304
 
1305
- with gr.Row():
1306
- submit = gr.Button("Send", variant="primary")
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
- # Connect the chat URL management buttons
1322
- add_chat_url_btn.click(
1323
- add_chat_urls,
1324
- inputs=[chat_url_count],
1325
- outputs=[chat_url3, chat_url4, add_chat_url_btn, remove_chat_url_btn, chat_url_count]
 
1326
  )
1327
 
1328
- remove_chat_url_btn.click(
1329
- remove_chat_urls,
1330
- inputs=[chat_url_count],
1331
- outputs=[chat_url3, chat_url4, add_chat_url_btn, remove_chat_url_btn, chat_url_count]
1332
  )
1333
 
1334
- # Connect cache controls
1335
- clear_cache_btn.click(clear_url_cache, outputs=[cache_status])
 
 
1336
 
1337
- # Connect the chat functionality
1338
- submit.click(respond_with_cache_update, [msg, chatbot, chat_url1, chat_url2, chat_url3, chat_url4], [msg, chatbot, cache_status])
1339
- msg.submit(respond_with_cache_update, [msg, chatbot, chat_url1, chat_url2, chat_url3, chat_url4], [msg, chatbot, cache_status])
1340
- clear.click(clear_chat, outputs=[msg, chatbot])
 
1341
 
1342
- with gr.Tab("Sandbox"):
1343
- gr.Markdown("# Generated Space Preview")
1344
- gr.Markdown("Preview your generated HuggingFace Space before deployment.")
1345
-
1346
- with gr.Row():
1347
- with gr.Column(scale=1):
1348
- preview_info_display = gr.Markdown("Generate a space configuration to see preview here.")
1349
- with gr.Column(scale=2):
1350
- preview_iframe_display = gr.HTML("<div style='text-align: center; padding: 50px; color: #666;'>No preview available</div>")
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