milwright commited on
Commit
fbacb2e
·
1 Parent(s): 2e22d1e

Simplify UI and auto-enable dynamic URL fetching

Browse files

- Move title/description to top of Quick Start (single-column)
- Move assistant template to Assistant Instructions section
- Simplify environment variable names: API_KEY, ACCESS_CODE, CONFIG_CODE
- Make Space Secrets Configuration single-column with better descriptions
- Remove Dynamic URL Fetching checkbox - always enabled by default
- Clean up all related function signatures

Files changed (1) hide show
  1. app.py +60 -66
app.py CHANGED
@@ -161,8 +161,8 @@ MODEL = "{model}"
161
  THEME = "{theme}" # Gradio theme name
162
  GROUNDING_URLS = {grounding_urls}
163
  # Get access code from environment variable for security
164
- # If SPACE_ACCESS_CODE is not set, no access control is applied
165
- ACCESS_CODE = os.environ.get("SPACE_ACCESS_CODE")
166
  ENABLE_DYNAMIC_URLS = {enable_dynamic_urls}
167
 
168
  # Get API key from environment - customizable variable name with validation
@@ -707,10 +707,10 @@ with gr.Blocks(title=SPACE_NAME, theme=theme_class()) as demo:
707
 
708
  # Faculty Configuration Section - appears at the bottom with password protection
709
  with gr.Accordion("🔧 Faculty Configuration", open=False, visible=True) as faculty_section:
710
- gr.Markdown("**Faculty Only:** Edit assistant configuration. Requires FACULTY_CONFIG_PASSWORD secret.")
711
 
712
  # Check if faculty password is configured
713
- FACULTY_PASSWORD = os.environ.get("FACULTY_CONFIG_PASSWORD", "").strip()
714
 
715
  if FACULTY_PASSWORD:
716
  faculty_auth_state = gr.State(False)
@@ -881,7 +881,7 @@ with gr.Blocks(title=SPACE_NAME, theme=theme_class()) as demo:
881
  outputs=[config_status, edit_system_prompt, edit_temperature, edit_max_tokens]
882
  )
883
  else:
884
- gr.Markdown("ℹ️ Faculty configuration is not enabled. Set FACULTY_CONFIG_PASSWORD in Space secrets to enable.")
885
 
886
  if __name__ == "__main__":
887
  demo.launch()
@@ -924,7 +924,7 @@ def create_requirements():
924
  """Generate requirements.txt with latest versions"""
925
  return "gradio>=5.38.0\nrequests>=2.32.3\nbeautifulsoup4>=4.12.3\npython-dotenv>=1.0.0"
926
 
927
- def generate_zip(title, description, system_prompt, model, api_key_var, temperature, max_tokens, examples_text, access_code_field="", enable_dynamic_urls=False, theme="default", url1="", url2="", url3="", url4="", url5="", url6="", url7="", url8="", url9="", url10=""):
928
  """Generate deployable zip file"""
929
 
930
  # Process examples
@@ -957,7 +957,7 @@ def generate_zip(title, description, system_prompt, model, api_key_var, temperat
957
  'max_tokens': int(max_tokens),
958
  'examples': examples_python,
959
  'grounding_urls': json.dumps(grounding_urls),
960
- 'enable_dynamic_urls': enable_dynamic_urls,
961
  'theme': theme.capitalize() if theme != "default" else "Default" # Capitalize theme name for gr.themes
962
  }
963
 
@@ -1028,7 +1028,7 @@ def update_sandbox_preview(config_data):
1028
 
1029
  return preview_text, preview_html
1030
 
1031
- def on_preview_combined(title, description, system_prompt, model, theme, temperature, max_tokens, examples_text, enable_dynamic_urls, url1="", url2="", url3="", url4="", url5="", url6="", url7="", url8="", url9="", url10=""):
1032
  """Generate configuration and return preview updates"""
1033
  # Removed name validation since title field no longer exists
1034
 
@@ -1068,7 +1068,7 @@ def on_preview_combined(title, description, system_prompt, model, theme, tempera
1068
  'theme': theme,
1069
  'temperature': temperature,
1070
  'max_tokens': max_tokens,
1071
- 'enable_dynamic_urls': enable_dynamic_urls,
1072
  'url1': url1,
1073
  'url2': url2,
1074
  'url3': url3,
@@ -1366,7 +1366,7 @@ def export_preview_conversation(history, config_data=None):
1366
 
1367
  return gr.update(value=temp_file, visible=True)
1368
 
1369
- def on_generate(title, description, system_prompt, model, theme, api_key_var, temperature, max_tokens, examples_text, access_code, enable_dynamic_urls, url1, url2, url3, url4, url5, url6, url7, url8, url9, url10):
1370
  try:
1371
  # Validate required fields
1372
  if not system_prompt or not system_prompt.strip():
@@ -1377,7 +1377,7 @@ def on_generate(title, description, system_prompt, model, theme, api_key_var, te
1377
 
1378
  final_system_prompt = system_prompt.strip()
1379
 
1380
- filename = generate_zip(title, description, final_system_prompt, model, api_key_var, temperature, max_tokens, examples_text, access_code, enable_dynamic_urls, theme, url1, url2, url3, url4, url5, url6, url7, url8, url9, url10)
1381
 
1382
  success_msg = f"""**Deployment package ready!**
1383
 
@@ -1404,7 +1404,7 @@ def on_generate(title, description, system_prompt, model, theme, api_key_var, te
1404
  'model': model,
1405
  'temperature': temperature,
1406
  'max_tokens': max_tokens,
1407
- 'enable_dynamic_urls': enable_dynamic_urls,
1408
  'filename': filename
1409
  }
1410
 
@@ -1594,21 +1594,18 @@ def toggle_template(template_choice, current_prompt, cached_custom_prompt):
1594
  research_prompt = "You are a research aid specializing in academic literature search and analysis. Your expertise spans discovering peer-reviewed sources, assessing research methodologies, synthesizing findings across studies, and delivering properly formatted citations. When responding, anchor claims in specific sources from provided URL contexts, differentiate between direct evidence and interpretive analysis, and note any limitations or contradictory results. Employ clear, accessible language that demystifies complex research, and propose connected research directions when appropriate. Your purpose is to serve as an informed research tool supporting users through initial concept development, exploratory investigation, information collection, and source compilation."
1595
  return (
1596
  gr.update(value=research_prompt), # Update main system prompt
1597
- gr.update(value=True), # Enable dynamic URL fetching for research template
1598
  cached_custom_prompt # Return the cached prompt
1599
  )
1600
  elif template_choice == "Socratic Template":
1601
  socratic_prompt = "You are a pedagogically-minded academic assistant designed for introductory courses. Your approach follows constructivist learning principles: build on students' prior knowledge, scaffold complex concepts through graduated questioning, and use Socratic dialogue to guide discovery. Provide concise, evidence-based explanations that connect theory to lived experiences. Each response should model critical thinking by acknowledging multiple perspectives, identifying assumptions, and revealing conceptual relationships. Conclude with open-ended questions that promote higher-order thinking—analysis, synthesis, or evaluation—rather than recall."
1602
  return (
1603
  gr.update(value=socratic_prompt), # Update main system prompt
1604
- gr.update(value=False), # Socratic template doesn't need dynamic URLs by default
1605
  cached_custom_prompt # Return the cached prompt
1606
  )
1607
  elif template_choice == "Mathematics Template":
1608
  mathematics_prompt = r"You are an AI assistant specialized in mathematics and statistics who guides users through problem-solving rather than providing direct answers. You help users discover solutions by asking strategic questions ('What do we know so far?' 'What method might apply here?' 'Can you identify a pattern?'), prompting them to explain their reasoning, and offering hints that build on their current understanding. Format all mathematical expressions in LaTeX (inline: $x^2 + y^2 = r^2$, display: $$\int_a^b f(x)dx$$). When users are stuck, provide scaffolded support: suggest examining simpler cases, identifying relevant formulas or theorems, or breaking the problem into smaller parts. Use multiple representations to illuminate different aspects of the problem, validate partial progress to build confidence, and help users recognize and correct their own errors through targeted questions rather than corrections. Your goal is to develop problem-solving skills and mathematical reasoning, not just arrive at answers."
1609
  return (
1610
  gr.update(value=mathematics_prompt), # Update main system prompt
1611
- gr.update(value=False), # Mathematics template doesn't need dynamic URLs by default
1612
  cached_custom_prompt # Return the cached prompt
1613
  )
1614
  else: # "None" or any other value
@@ -1616,7 +1613,6 @@ def toggle_template(template_choice, current_prompt, cached_custom_prompt):
1616
  prompt_value = cached_custom_prompt if cached_custom_prompt else ""
1617
  return (
1618
  gr.update(value=prompt_value), # Restore cached prompt or clear
1619
- gr.update(value=False), # Disable dynamic URL setting
1620
  cached_custom_prompt # Return the cached prompt
1621
  )
1622
 
@@ -1750,6 +1746,21 @@ with gr.Blocks(
1750
  with gr.Accordion("🚀 Quick Start", open=True):
1751
  gr.Markdown("Essential settings to get your assistant running quickly.")
1752
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1753
  model = gr.Dropdown(
1754
  label="Model",
1755
  choices=MODELS,
@@ -1757,14 +1768,6 @@ with gr.Blocks(
1757
  info="Choose the AI model that best fits your needs"
1758
  )
1759
 
1760
- # Template selection moved to Quick Start
1761
- template_selector = gr.Radio(
1762
- label="Assistant Template",
1763
- choices=["None (Custom)", "Research Template", "Socratic Template", "Mathematics Template"],
1764
- value="None (Custom)",
1765
- info="Start with a pre-configured template or create your own"
1766
- )
1767
-
1768
  # NEW: Gradio Theme selection
1769
  theme = gr.Dropdown(
1770
  label="Gradio Theme",
@@ -1783,22 +1786,15 @@ with gr.Blocks(
1783
 
1784
  # Assistant Instructions section
1785
  with gr.Accordion("📝 Assistant Instructions", open=True):
1786
- gr.Markdown("Define your assistant's identity and behavior.")
1787
 
1788
- with gr.Row():
1789
- title = gr.Textbox(
1790
- label="Assistant Name",
1791
- placeholder="My AI Assistant",
1792
- value="AI Assistant",
1793
- info="Display name for your assistant"
1794
- )
1795
-
1796
- description = gr.Textbox(
1797
- label="Description",
1798
- placeholder="A helpful AI assistant for...",
1799
- value="A customizable AI assistant",
1800
- info="Brief description of your assistant's purpose"
1801
- )
1802
 
1803
  # Main system prompt field
1804
  system_prompt = gr.Textbox(
@@ -1925,33 +1921,31 @@ with gr.Blocks(
1925
  info="Maximum tokens (words) in each response"
1926
  )
1927
 
1928
- enable_dynamic_urls = gr.Checkbox(
1929
- label="Enable Dynamic URL Fetching",
1930
- value=True,
1931
- info="Allow the assistant to fetch URLs mentioned in conversations"
1932
- )
1933
 
1934
  # Environment Variables Configuration
1935
  gr.Markdown("### 🔑 Space Secrets Configuration")
1936
- with gr.Row():
1937
- api_key_var = gr.Textbox(
1938
- label="API Key (Required)",
1939
- value="OPENROUTER_API_KEY",
1940
- info="Required API key set as HF Space secret.",
1941
- interactive=False
1942
- )
1943
- access_code = gr.Textbox(
1944
- label="Student Access (Optional)",
1945
- value="SPACE_ACCESS_CODE",
1946
- info="Password for student access.",
1947
- interactive=False
1948
- )
1949
- faculty_password = gr.Textbox(
1950
- label="Faculty Edit Access (Optional)",
1951
- value="FACULTY_CONFIG_PASSWORD",
1952
- info="Post-deployment customization.",
1953
- interactive=False
1954
- )
 
 
 
1955
 
1956
  with gr.Row():
1957
  preview_btn = gr.Button("Preview Deployment Package", variant="secondary")
@@ -1967,7 +1961,7 @@ with gr.Blocks(
1967
  template_selector.change(
1968
  toggle_template,
1969
  inputs=[template_selector, system_prompt, custom_prompt_cache],
1970
- outputs=[system_prompt, enable_dynamic_urls, custom_prompt_cache]
1971
  )
1972
 
1973
  # Web search checkbox is now just for enabling/disabling the feature
@@ -1993,7 +1987,7 @@ with gr.Blocks(
1993
  # Connect the generate button
1994
  generate_btn.click(
1995
  on_generate,
1996
- inputs=[title, description, system_prompt, model, theme, api_key_var, temperature, max_tokens, examples_text, access_code, enable_dynamic_urls, url1, url2, url3, url4, url5, url6, url7, url8, url9, url10],
1997
  outputs=[status, download_file, sandbox_state]
1998
  )
1999
 
@@ -2191,7 +2185,7 @@ with gr.Blocks(
2191
  # Connect cross-tab functionality after all components are defined
2192
  preview_btn.click(
2193
  on_preview_combined,
2194
- inputs=[title, description, system_prompt, model, theme, temperature, max_tokens, examples_text, enable_dynamic_urls, url1, url2, url3, url4, url5, url6, url7, url8, url9, url10],
2195
  outputs=[preview_config_state, preview_status_comp, preview_chat_section_comp, config_display_comp, preview_url1, preview_url2, preview_url3, preview_url4, preview_url5, preview_url6, preview_url7, preview_url8, preview_url9, preview_url10, preview_add_url_btn, preview_remove_url_btn, preview_url_count, preview_example_btn1, preview_example_btn2, preview_example_btn3]
2196
  )
2197
 
 
161
  THEME = "{theme}" # Gradio theme name
162
  GROUNDING_URLS = {grounding_urls}
163
  # Get access code from environment variable for security
164
+ # If ACCESS_CODE is not set, no access control is applied
165
+ ACCESS_CODE = os.environ.get("ACCESS_CODE")
166
  ENABLE_DYNAMIC_URLS = {enable_dynamic_urls}
167
 
168
  # Get API key from environment - customizable variable name with validation
 
707
 
708
  # Faculty Configuration Section - appears at the bottom with password protection
709
  with gr.Accordion("🔧 Faculty Configuration", open=False, visible=True) as faculty_section:
710
+ gr.Markdown("**Faculty Only:** Edit assistant configuration. Requires CONFIG_CODE secret.")
711
 
712
  # Check if faculty password is configured
713
+ FACULTY_PASSWORD = os.environ.get("CONFIG_CODE", "").strip()
714
 
715
  if FACULTY_PASSWORD:
716
  faculty_auth_state = gr.State(False)
 
881
  outputs=[config_status, edit_system_prompt, edit_temperature, edit_max_tokens]
882
  )
883
  else:
884
+ gr.Markdown("ℹ️ Faculty configuration is not enabled. Set CONFIG_CODE in Space secrets to enable.")
885
 
886
  if __name__ == "__main__":
887
  demo.launch()
 
924
  """Generate requirements.txt with latest versions"""
925
  return "gradio>=5.38.0\nrequests>=2.32.3\nbeautifulsoup4>=4.12.3\npython-dotenv>=1.0.0"
926
 
927
+ def generate_zip(title, description, system_prompt, model, api_key_var, temperature, max_tokens, examples_text, access_code_field="", theme="default", url1="", url2="", url3="", url4="", url5="", url6="", url7="", url8="", url9="", url10=""):
928
  """Generate deployable zip file"""
929
 
930
  # Process examples
 
957
  'max_tokens': int(max_tokens),
958
  'examples': examples_python,
959
  'grounding_urls': json.dumps(grounding_urls),
960
+ 'enable_dynamic_urls': True, # Always enabled
961
  'theme': theme.capitalize() if theme != "default" else "Default" # Capitalize theme name for gr.themes
962
  }
963
 
 
1028
 
1029
  return preview_text, preview_html
1030
 
1031
+ def on_preview_combined(title, description, system_prompt, model, theme, temperature, max_tokens, examples_text, url1="", url2="", url3="", url4="", url5="", url6="", url7="", url8="", url9="", url10=""):
1032
  """Generate configuration and return preview updates"""
1033
  # Removed name validation since title field no longer exists
1034
 
 
1068
  'theme': theme,
1069
  'temperature': temperature,
1070
  'max_tokens': max_tokens,
1071
+ 'enable_dynamic_urls': True, # Always enabled
1072
  'url1': url1,
1073
  'url2': url2,
1074
  'url3': url3,
 
1366
 
1367
  return gr.update(value=temp_file, visible=True)
1368
 
1369
+ def on_generate(title, description, system_prompt, model, theme, api_key_var, temperature, max_tokens, examples_text, access_code, url1, url2, url3, url4, url5, url6, url7, url8, url9, url10):
1370
  try:
1371
  # Validate required fields
1372
  if not system_prompt or not system_prompt.strip():
 
1377
 
1378
  final_system_prompt = system_prompt.strip()
1379
 
1380
+ filename = generate_zip(title, description, final_system_prompt, model, api_key_var, temperature, max_tokens, examples_text, access_code, theme, url1, url2, url3, url4, url5, url6, url7, url8, url9, url10)
1381
 
1382
  success_msg = f"""**Deployment package ready!**
1383
 
 
1404
  'model': model,
1405
  'temperature': temperature,
1406
  'max_tokens': max_tokens,
1407
+ 'enable_dynamic_urls': True, # Always enabled
1408
  'filename': filename
1409
  }
1410
 
 
1594
  research_prompt = "You are a research aid specializing in academic literature search and analysis. Your expertise spans discovering peer-reviewed sources, assessing research methodologies, synthesizing findings across studies, and delivering properly formatted citations. When responding, anchor claims in specific sources from provided URL contexts, differentiate between direct evidence and interpretive analysis, and note any limitations or contradictory results. Employ clear, accessible language that demystifies complex research, and propose connected research directions when appropriate. Your purpose is to serve as an informed research tool supporting users through initial concept development, exploratory investigation, information collection, and source compilation."
1595
  return (
1596
  gr.update(value=research_prompt), # Update main system prompt
 
1597
  cached_custom_prompt # Return the cached prompt
1598
  )
1599
  elif template_choice == "Socratic Template":
1600
  socratic_prompt = "You are a pedagogically-minded academic assistant designed for introductory courses. Your approach follows constructivist learning principles: build on students' prior knowledge, scaffold complex concepts through graduated questioning, and use Socratic dialogue to guide discovery. Provide concise, evidence-based explanations that connect theory to lived experiences. Each response should model critical thinking by acknowledging multiple perspectives, identifying assumptions, and revealing conceptual relationships. Conclude with open-ended questions that promote higher-order thinking—analysis, synthesis, or evaluation—rather than recall."
1601
  return (
1602
  gr.update(value=socratic_prompt), # Update main system prompt
 
1603
  cached_custom_prompt # Return the cached prompt
1604
  )
1605
  elif template_choice == "Mathematics Template":
1606
  mathematics_prompt = r"You are an AI assistant specialized in mathematics and statistics who guides users through problem-solving rather than providing direct answers. You help users discover solutions by asking strategic questions ('What do we know so far?' 'What method might apply here?' 'Can you identify a pattern?'), prompting them to explain their reasoning, and offering hints that build on their current understanding. Format all mathematical expressions in LaTeX (inline: $x^2 + y^2 = r^2$, display: $$\int_a^b f(x)dx$$). When users are stuck, provide scaffolded support: suggest examining simpler cases, identifying relevant formulas or theorems, or breaking the problem into smaller parts. Use multiple representations to illuminate different aspects of the problem, validate partial progress to build confidence, and help users recognize and correct their own errors through targeted questions rather than corrections. Your goal is to develop problem-solving skills and mathematical reasoning, not just arrive at answers."
1607
  return (
1608
  gr.update(value=mathematics_prompt), # Update main system prompt
 
1609
  cached_custom_prompt # Return the cached prompt
1610
  )
1611
  else: # "None" or any other value
 
1613
  prompt_value = cached_custom_prompt if cached_custom_prompt else ""
1614
  return (
1615
  gr.update(value=prompt_value), # Restore cached prompt or clear
 
1616
  cached_custom_prompt # Return the cached prompt
1617
  )
1618
 
 
1746
  with gr.Accordion("🚀 Quick Start", open=True):
1747
  gr.Markdown("Essential settings to get your assistant running quickly.")
1748
 
1749
+ # Title and Description - single column at the top
1750
+ title = gr.Textbox(
1751
+ label="Assistant Name",
1752
+ placeholder="My AI Assistant",
1753
+ value="AI Assistant",
1754
+ info="Display name for your assistant"
1755
+ )
1756
+
1757
+ description = gr.Textbox(
1758
+ label="Description",
1759
+ placeholder="A helpful AI assistant for...",
1760
+ value="A customizable AI assistant",
1761
+ info="Brief description of your assistant's purpose"
1762
+ )
1763
+
1764
  model = gr.Dropdown(
1765
  label="Model",
1766
  choices=MODELS,
 
1768
  info="Choose the AI model that best fits your needs"
1769
  )
1770
 
 
 
 
 
 
 
 
 
1771
  # NEW: Gradio Theme selection
1772
  theme = gr.Dropdown(
1773
  label="Gradio Theme",
 
1786
 
1787
  # Assistant Instructions section
1788
  with gr.Accordion("📝 Assistant Instructions", open=True):
1789
+ gr.Markdown("Define your assistant's behavior and provide example prompts.")
1790
 
1791
+ # Template selection moved to Assistant Instructions
1792
+ template_selector = gr.Radio(
1793
+ label="Assistant Template",
1794
+ choices=["None (Custom)", "Research Template", "Socratic Template", "Mathematics Template"],
1795
+ value="None (Custom)",
1796
+ info="Start with a pre-configured template or create your own"
1797
+ )
 
 
 
 
 
 
 
1798
 
1799
  # Main system prompt field
1800
  system_prompt = gr.Textbox(
 
1921
  info="Maximum tokens (words) in each response"
1922
  )
1923
 
 
 
 
 
 
1924
 
1925
  # Environment Variables Configuration
1926
  gr.Markdown("### 🔑 Space Secrets Configuration")
1927
+ gr.Markdown("Configure these environment variables in your HuggingFace Space Settings → Variables and secrets")
1928
+
1929
+ api_key_var = gr.Textbox(
1930
+ label="API Key Variable (Required)",
1931
+ value="API_KEY",
1932
+ info="Environment variable name for your OpenRouter API key.",
1933
+ interactive=False
1934
+ )
1935
+
1936
+ access_code = gr.Textbox(
1937
+ label="Student Access Code Variable (Optional)",
1938
+ value="ACCESS_CODE",
1939
+ info="Environment variable for password-protecting the Space. Leave unset for public access.",
1940
+ interactive=False
1941
+ )
1942
+
1943
+ faculty_password = gr.Textbox(
1944
+ label="Faculty Configuration Password Variable (Optional)",
1945
+ value="CONFIG_CODE",
1946
+ info="Environment variable for faculty to edit configuration after deployment. Enables live customization.",
1947
+ interactive=False
1948
+ )
1949
 
1950
  with gr.Row():
1951
  preview_btn = gr.Button("Preview Deployment Package", variant="secondary")
 
1961
  template_selector.change(
1962
  toggle_template,
1963
  inputs=[template_selector, system_prompt, custom_prompt_cache],
1964
+ outputs=[system_prompt, custom_prompt_cache]
1965
  )
1966
 
1967
  # Web search checkbox is now just for enabling/disabling the feature
 
1987
  # Connect the generate button
1988
  generate_btn.click(
1989
  on_generate,
1990
+ inputs=[title, description, system_prompt, model, theme, api_key_var, temperature, max_tokens, examples_text, access_code, url1, url2, url3, url4, url5, url6, url7, url8, url9, url10],
1991
  outputs=[status, download_file, sandbox_state]
1992
  )
1993
 
 
2185
  # Connect cross-tab functionality after all components are defined
2186
  preview_btn.click(
2187
  on_preview_combined,
2188
+ inputs=[title, description, system_prompt, model, theme, temperature, max_tokens, examples_text, url1, url2, url3, url4, url5, url6, url7, url8, url9, url10],
2189
  outputs=[preview_config_state, preview_status_comp, preview_chat_section_comp, config_display_comp, preview_url1, preview_url2, preview_url3, preview_url4, preview_url5, preview_url6, preview_url7, preview_url8, preview_url9, preview_url10, preview_add_url_btn, preview_remove_url_btn, preview_url_count, preview_example_btn1, preview_example_btn2, preview_example_btn3]
2190
  )
2191