milwright commited on
Commit
1e474ae
·
1 Parent(s): 8207555

Add academic models and focus

Browse files

- Add anthropic/claude-3-haiku and nvidia/nemotron-4-340b-instruct
- Update tagline and system prompt for academic research
- Include recent .gitignore and requirement updates

.gitignore ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Environment variables
2
+ .env
3
+ .env.local
4
+
5
+ # Python
6
+ __pycache__/
7
+ *.py[cod]
8
+ *$py.class
9
+ *.so
10
+ .Python
11
+ env/
12
+ venv/
13
+ ENV/
14
+
15
+ # IDE
16
+ .vscode/
17
+ .idea/
18
+ *.swp
19
+ *.swo
20
+
21
+ # OS
22
+ .DS_Store
23
+ Thumbs.db
24
+
25
+ # Logs
26
+ *.log
CLAUDE.md CHANGED
@@ -17,33 +17,60 @@ pip install -r requirements.txt
17
 
18
  ## Code Architecture
19
 
20
- This is a single-file Gradio application (`app.py`) that helps users create and deploy chat interfaces on HuggingFace Spaces. The application has two main features:
21
 
22
  1. **Spaces Configuration Tool**: Generates complete deployment packages for chat interfaces
23
- - Uses the `SPACE_TEMPLATE` string (lines 9-81) to generate Python code
24
- - Creates zip files containing app.py, requirements.txt, and README.md
25
  - Supports multiple LLM models via OpenRouter API
 
 
 
 
26
 
27
  2. **Chat Support Assistant**: Provides configuration help using Gemma-2-27B
28
  - Located in the second tab of the interface
29
  - Uses OpenRouter API with environment variable `OPENROUTER_API_KEY`
 
30
 
31
  ### Key Functions
32
- - `create_readme()`: Generates deployment instructions (lines 99-117)
33
- - `create_requirements()`: Generates requirements.txt content (lines 119-127)
34
- - `generate_space_config()`: Main function that creates the deployment package (lines 129-180)
35
- - `create_support_assistant()`: Creates the chat support interface (lines 396-449)
 
 
 
36
 
37
  ### Template System
38
  The app uses string templating to generate Python code. The main template (`SPACE_TEMPLATE`) contains placeholders that are filled with user configuration:
39
  - `{name}`, `{description}`, `{system_prompt}`, `{model}`
40
  - `{api_key_var}`, `{temperature}`, `{max_tokens}`, `{examples}`
 
 
 
 
 
 
 
 
 
 
 
 
 
 
41
 
42
  ## Environment Variables
43
  - `OPENROUTER_API_KEY`: Required for the Chat Support feature to work
 
44
 
45
  ## Important Notes
46
  - This is a HuggingFace Spaces application (see YAML frontmatter in README.md)
47
  - No test suite or linting configuration exists
48
  - The generated packages are self-contained chat applications ready for deployment
49
- - All generated code uses OpenRouter API for LLM access
 
 
 
 
 
17
 
18
  ## Code Architecture
19
 
20
+ This is a single-file Gradio 4.32.0 application (`app.py`) that helps users create and deploy chat interfaces on HuggingFace Spaces. The application has two main features:
21
 
22
  1. **Spaces Configuration Tool**: Generates complete deployment packages for chat interfaces
23
+ - Uses the `SPACE_TEMPLATE` string (lines 15-137) to generate Python code
24
+ - Creates zip files containing app.py, requirements.txt, README.md, and config.json
25
  - Supports multiple LLM models via OpenRouter API
26
+ - **URL Grounding**: Supports up to 4 discrete URLs for context grounding
27
+ - Fetches web content from provided URLs using BeautifulSoup
28
+ - Injects content as context into the system prompt
29
+ - Automatically truncates content to ~4000 characters per URL
30
 
31
  2. **Chat Support Assistant**: Provides configuration help using Gemma-2-27B
32
  - Located in the second tab of the interface
33
  - Uses OpenRouter API with environment variable `OPENROUTER_API_KEY`
34
+ - Includes URL grounding functionality in collapsible accordion
35
 
36
  ### Key Functions
37
+ - `create_readme()`: Generates deployment instructions with HuggingFace YAML frontmatter
38
+ - `create_requirements()`: Generates requirements.txt content including beautifulsoup4
39
+ - `generate_zip()`: Main function that creates the deployment package with URL grounding support
40
+ - `on_generate()`: Callback function for the generate button handling all input parameters
41
+ - `fetch_url_content()`: Fetches and extracts text from URLs (both in template and main app)
42
+ - `get_grounding_context()`: Combines URL content into context (both in template and main app)
43
+ - `respond()`: Chat support function with URL grounding parameters
44
 
45
  ### Template System
46
  The app uses string templating to generate Python code. The main template (`SPACE_TEMPLATE`) contains placeholders that are filled with user configuration:
47
  - `{name}`, `{description}`, `{system_prompt}`, `{model}`
48
  - `{api_key_var}`, `{temperature}`, `{max_tokens}`, `{examples}`
49
+ - `{grounding_urls}`: JSON array of URLs for context grounding
50
+
51
+ ### Model Configuration
52
+ Available models are limited to three open-source options:
53
+ - `google/gemma-2-27b-it` (default)
54
+ - `mistralai/mixtral-8x7b-instruct`
55
+ - `meta-llama/llama-3.1-70b-instruct`
56
+
57
+ ### URL Grounding Architecture
58
+ URL grounding is implemented in both the main app and generated templates:
59
+ - Web scraping uses BeautifulSoup4 with 10-second timeout
60
+ - Content is cleaned (scripts/styles removed) and truncated to 4000 characters
61
+ - Error handling for failed requests returns descriptive error messages
62
+ - Context is injected into system prompts for enhanced responses
63
 
64
  ## Environment Variables
65
  - `OPENROUTER_API_KEY`: Required for the Chat Support feature to work
66
+ - Uses python-dotenv to load from `.env` file automatically
67
 
68
  ## Important Notes
69
  - This is a HuggingFace Spaces application (see YAML frontmatter in README.md)
70
  - No test suite or linting configuration exists
71
  - The generated packages are self-contained chat applications ready for deployment
72
+ - All generated code uses OpenRouter API for LLM access
73
+ - Generated spaces include BeautifulSoup4 for URL content extraction
74
+ - URL grounding fetches content at runtime, adding context to each conversation
75
+ - Generated README.md files include proper HuggingFace Spaces YAML frontmatter
76
+ - Template uses double braces `{{}}` for literal braces in generated code, single braces `{}` for template variables
__pycache__/app.cpython-312.pyc CHANGED
Binary files a/__pycache__/app.cpython-312.pyc and b/__pycache__/app.cpython-312.pyc differ
 
app.py CHANGED
@@ -4,30 +4,86 @@ import zipfile
4
  import io
5
  import os
6
  from datetime import datetime
 
 
 
 
 
 
7
 
8
  # Template for generated space app (based on mvp_simple.py)
9
  SPACE_TEMPLATE = '''import gradio as gr
10
  import os
11
  import requests
12
  import json
 
13
 
14
  # Configuration
15
  SPACE_NAME = "{name}"
16
  SPACE_DESCRIPTION = "{description}"
17
  SYSTEM_PROMPT = """{system_prompt}"""
18
  MODEL = "{model}"
 
19
 
20
  # Get API key from environment - customizable variable name
21
  API_KEY = os.environ.get("{api_key_var}")
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  def generate_response(message, history):
24
  """Generate response using OpenRouter API"""
25
 
26
  if not API_KEY:
27
  return "Please set your {api_key_var} in the Space settings."
28
 
 
 
 
 
 
 
29
  # Build messages array for the API
30
- messages = [{{"role": "system", "content": SYSTEM_PROMPT}}]
31
 
32
  # Add conversation history - compatible with Gradio 5.x format
33
  for chat in history:
@@ -84,12 +140,67 @@ if __name__ == "__main__":
84
  MODELS = [
85
  "google/gemma-2-27b-it",
86
  "mistralai/mixtral-8x7b-instruct",
87
- "meta-llama/llama-3.1-70b-instruct"
 
 
88
  ]
89
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
90
  def create_readme(config):
91
  """Generate README with deployment instructions"""
92
- return f"""# {config['name']}
 
 
 
 
 
 
 
 
 
 
 
93
 
94
  {config['description']}
95
 
@@ -174,9 +285,9 @@ Generated on {datetime.now().strftime('%Y-%m-%d %H:%M:%S')} with Chat U/I Helper
174
 
175
  def create_requirements():
176
  """Generate requirements.txt"""
177
- return "gradio==5.34.0\nrequests==2.31.0"
178
 
179
- def generate_zip(name, description, system_prompt, model, api_key_var, temperature, max_tokens, examples_text):
180
  """Generate deployable zip file"""
181
 
182
  # Process examples
@@ -190,6 +301,12 @@ def generate_zip(name, description, system_prompt, model, api_key_var, temperatu
190
  "What can you do?"
191
  ])
192
 
 
 
 
 
 
 
193
  # Create config
194
  config = {
195
  'name': name,
@@ -199,7 +316,8 @@ def generate_zip(name, description, system_prompt, model, api_key_var, temperatu
199
  'api_key_var': api_key_var,
200
  'temperature': temperature,
201
  'max_tokens': int(max_tokens),
202
- 'examples': examples_json
 
203
  }
204
 
205
  # Generate files
@@ -226,7 +344,7 @@ def generate_zip(name, description, system_prompt, model, api_key_var, temperatu
226
  return filename
227
 
228
  # Define callback functions outside the interface
229
- def on_generate(name, description, system_prompt, model, api_key_var, temperature, max_tokens, examples_text):
230
  if not name or not name.strip():
231
  return gr.update(value="Error: Please provide a Space Title", visible=True), gr.update(visible=False)
232
 
@@ -234,7 +352,7 @@ def on_generate(name, description, system_prompt, model, api_key_var, temperatur
234
  return gr.update(value="Error: Please provide a System Prompt", visible=True), gr.update(visible=False)
235
 
236
  try:
237
- filename = generate_zip(name, description, system_prompt, model, api_key_var, temperature, max_tokens, examples_text)
238
 
239
  success_msg = f"""**Deployment package ready!**
240
 
@@ -258,7 +376,7 @@ def on_generate(name, description, system_prompt, model, api_key_var, temperatur
258
  except Exception as e:
259
  return gr.update(value=f"Error: {str(e)}", visible=True), gr.update(visible=False)
260
 
261
- def respond(message, chat_history):
262
  # Make actual API request to OpenRouter
263
  import os
264
  import requests
@@ -268,25 +386,38 @@ def respond(message, chat_history):
268
 
269
  if not api_key:
270
  response = "Please set your OPENROUTER_API_KEY in the Space settings to use the chat support."
271
- chat_history.append({"role": "user", "content": message})
272
- chat_history.append({"role": "assistant", "content": response})
273
  return "", chat_history
274
 
275
- # Build conversation history for API
276
- messages = [{
277
- "role": "system",
278
- "content": """You are a helpful assistant specializing in creating chat UIs for HuggingFace Spaces. You help users configure assistants for education and research. Provide concise, practical advice about:
 
 
279
  - System prompts for different use cases (courses, research, tutoring)
280
  - Model selection (recommending google/gemma-2-27b-it as a great balance)
281
  - HuggingFace Space deployment tips
282
  - Customization options
283
 
284
  Keep responses brief and actionable. Focus on what the user is specifically asking about."""
 
 
 
 
 
 
 
285
  }]
286
 
287
- # Add conversation history
288
  for chat in chat_history:
289
- messages.append(chat)
 
 
 
 
 
290
 
291
  # Add current message
292
  messages.append({"role": "user", "content": message})
@@ -315,8 +446,7 @@ Keep responses brief and actionable. Focus on what the user is specifically aski
315
  except Exception as e:
316
  assistant_response = f"Error: {str(e)}"
317
 
318
- chat_history.append({"role": "user", "content": message})
319
- chat_history.append({"role": "assistant", "content": assistant_response})
320
  return "", chat_history
321
 
322
  def clear_chat():
@@ -340,7 +470,7 @@ with gr.Blocks(title="Chat U/I Helper") as demo:
340
  label="Space Description",
341
  placeholder="A customizable AI chat interface for...",
342
  lines=2,
343
- value="A customizable AI chat interface for your specific needs"
344
  )
345
 
346
  model = gr.Dropdown(
@@ -360,7 +490,7 @@ with gr.Blocks(title="Chat U/I Helper") as demo:
360
  label="System Prompt",
361
  placeholder="You are a research assistant...",
362
  lines=4,
363
- value="You are a clear and concise research assistant. Provide accurate, succinct, and responsive support."
364
  )
365
 
366
  examples_text = gr.Textbox(
@@ -370,6 +500,33 @@ with gr.Blocks(title="Chat U/I Helper") as demo:
370
  info="These will appear as clickable examples in the chat interface"
371
  )
372
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
373
  with gr.Row():
374
  temperature = gr.Slider(
375
  label="Temperature",
@@ -396,7 +553,7 @@ with gr.Blocks(title="Chat U/I Helper") as demo:
396
  # Connect the generate button
397
  generate_btn.click(
398
  on_generate,
399
- inputs=[name, description, system_prompt, model, api_key_var, temperature, max_tokens, examples_text],
400
  outputs=[status, download_file]
401
  )
402
 
@@ -409,14 +566,36 @@ with gr.Blocks(title="Chat U/I Helper") as demo:
409
  chatbot = gr.Chatbot(
410
  value=[],
411
  label="Chat Support Assistant",
412
- height=400,
413
- type="messages"
414
  )
415
  msg = gr.Textbox(
416
  label="Ask about configuring chat UIs for courses, research, or custom HuggingFace Spaces",
417
  placeholder="How can I configure a chat UI for my senior seminar?",
418
  lines=2
419
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
420
  with gr.Row():
421
  submit = gr.Button("Send", variant="primary")
422
  clear = gr.Button("Clear")
@@ -434,9 +613,9 @@ with gr.Blocks(title="Chat U/I Helper") as demo:
434
  )
435
 
436
  # Connect the chat functionality
437
- submit.click(respond, [msg, chatbot], [msg, chatbot])
438
- msg.submit(respond, [msg, chatbot], [msg, chatbot])
439
  clear.click(clear_chat, outputs=[msg, chatbot])
440
 
441
  if __name__ == "__main__":
442
- demo.launch()
 
4
  import io
5
  import os
6
  from datetime import datetime
7
+ from dotenv import load_dotenv
8
+ import requests
9
+ from bs4 import BeautifulSoup
10
+
11
+ # Load environment variables from .env file
12
+ load_dotenv()
13
 
14
  # Template for generated space app (based on mvp_simple.py)
15
  SPACE_TEMPLATE = '''import gradio as gr
16
  import os
17
  import requests
18
  import json
19
+ from bs4 import BeautifulSoup
20
 
21
  # Configuration
22
  SPACE_NAME = "{name}"
23
  SPACE_DESCRIPTION = "{description}"
24
  SYSTEM_PROMPT = """{system_prompt}"""
25
  MODEL = "{model}"
26
+ GROUNDING_URLS = {grounding_urls}
27
 
28
  # Get API key from environment - customizable variable name
29
  API_KEY = os.environ.get("{api_key_var}")
30
 
31
+ def fetch_url_content(url):
32
+ """Fetch and extract text content from a URL"""
33
+ try:
34
+ response = requests.get(url, timeout=10)
35
+ response.raise_for_status()
36
+ soup = BeautifulSoup(response.content, 'html.parser')
37
+
38
+ # Remove script and style elements
39
+ for script in soup(["script", "style"]):
40
+ script.decompose()
41
+
42
+ # Get text content
43
+ text = soup.get_text()
44
+
45
+ # Clean up whitespace
46
+ lines = (line.strip() for line in text.splitlines())
47
+ chunks = (phrase.strip() for line in lines for phrase in line.split(" "))
48
+ text = ' '.join(chunk for chunk in chunks if chunk)
49
+
50
+ # Truncate to ~4000 characters
51
+ if len(text) > 4000:
52
+ text = text[:4000] + "..."
53
+
54
+ return text
55
+ except Exception as e:
56
+ return f"Error fetching {{url}}: {{str(e)}}"
57
+
58
+ def get_grounding_context():
59
+ """Fetch context from grounding URLs"""
60
+ if not GROUNDING_URLS:
61
+ return ""
62
+
63
+ context_parts = []
64
+ for i, url in enumerate(GROUNDING_URLS, 1):
65
+ if url.strip():
66
+ content = fetch_url_content(url.strip())
67
+ context_parts.append(f"Context from URL {{i}} ({{url}}):\\n{{content}}")
68
+
69
+ if context_parts:
70
+ return "\\n\\n" + "\\n\\n".join(context_parts) + "\\n\\n"
71
+ return ""
72
+
73
  def generate_response(message, history):
74
  """Generate response using OpenRouter API"""
75
 
76
  if not API_KEY:
77
  return "Please set your {api_key_var} in the Space settings."
78
 
79
+ # Get grounding context
80
+ grounding_context = get_grounding_context()
81
+
82
+ # Build enhanced system prompt with grounding context
83
+ enhanced_system_prompt = SYSTEM_PROMPT + grounding_context
84
+
85
  # Build messages array for the API
86
+ messages = [{{"role": "system", "content": enhanced_system_prompt}}]
87
 
88
  # Add conversation history - compatible with Gradio 5.x format
89
  for chat in history:
 
140
  MODELS = [
141
  "google/gemma-2-27b-it",
142
  "mistralai/mixtral-8x7b-instruct",
143
+ "meta-llama/llama-3.1-70b-instruct",
144
+ "anthropic/claude-3-haiku",
145
+ "nvidia/nemotron-4-340b-instruct"
146
  ]
147
 
148
+ def fetch_url_content(url):
149
+ """Fetch and extract text content from a URL"""
150
+ try:
151
+ response = requests.get(url, timeout=10)
152
+ response.raise_for_status()
153
+ soup = BeautifulSoup(response.content, 'html.parser')
154
+
155
+ # Remove script and style elements
156
+ for script in soup(["script", "style"]):
157
+ script.decompose()
158
+
159
+ # Get text content
160
+ text = soup.get_text()
161
+
162
+ # Clean up whitespace
163
+ lines = (line.strip() for line in text.splitlines())
164
+ chunks = (phrase.strip() for line in lines for phrase in line.split(" "))
165
+ text = ' '.join(chunk for chunk in chunks if chunk)
166
+
167
+ # Truncate to ~4000 characters
168
+ if len(text) > 4000:
169
+ text = text[:4000] + "..."
170
+
171
+ return text
172
+ except Exception as e:
173
+ return f"Error fetching {url}: {str(e)}"
174
+
175
+ def get_grounding_context(urls):
176
+ """Fetch context from grounding URLs"""
177
+ if not urls:
178
+ return ""
179
+
180
+ context_parts = []
181
+ for i, url in enumerate(urls, 1):
182
+ if url and url.strip():
183
+ content = fetch_url_content(url.strip())
184
+ context_parts.append(f"Context from URL {i} ({url}):\n{content}")
185
+
186
+ if context_parts:
187
+ return "\n\n" + "\n\n".join(context_parts) + "\n\n"
188
+ return ""
189
+
190
  def create_readme(config):
191
  """Generate README with deployment instructions"""
192
+ return f"""---
193
+ title: {config['name']}
194
+ emoji: 🤖
195
+ colorFrom: blue
196
+ colorTo: red
197
+ sdk: gradio
198
+ sdk_version: 4.32.0
199
+ app_file: app.py
200
+ pinned: false
201
+ ---
202
+
203
+ # {config['name']}
204
 
205
  {config['description']}
206
 
 
285
 
286
  def create_requirements():
287
  """Generate requirements.txt"""
288
+ return "gradio==4.44.1\nrequests==2.32.3\nbeautifulsoup4==4.12.3"
289
 
290
+ def generate_zip(name, description, system_prompt, model, api_key_var, temperature, max_tokens, examples_text, url1="", url2="", url3="", url4=""):
291
  """Generate deployable zip file"""
292
 
293
  # Process examples
 
301
  "What can you do?"
302
  ])
303
 
304
+ # Process grounding URLs
305
+ grounding_urls = []
306
+ for url in [url1, url2, url3, url4]:
307
+ if url and url.strip():
308
+ grounding_urls.append(url.strip())
309
+
310
  # Create config
311
  config = {
312
  'name': name,
 
316
  'api_key_var': api_key_var,
317
  'temperature': temperature,
318
  'max_tokens': int(max_tokens),
319
+ 'examples': examples_json,
320
+ 'grounding_urls': json.dumps(grounding_urls)
321
  }
322
 
323
  # Generate files
 
344
  return filename
345
 
346
  # Define callback functions outside the interface
347
+ def on_generate(name, description, system_prompt, model, api_key_var, temperature, max_tokens, examples_text, url1, url2, url3, url4):
348
  if not name or not name.strip():
349
  return gr.update(value="Error: Please provide a Space Title", visible=True), gr.update(visible=False)
350
 
 
352
  return gr.update(value="Error: Please provide a System Prompt", visible=True), gr.update(visible=False)
353
 
354
  try:
355
+ filename = generate_zip(name, description, system_prompt, model, api_key_var, temperature, max_tokens, examples_text, url1, url2, url3, url4)
356
 
357
  success_msg = f"""**Deployment package ready!**
358
 
 
376
  except Exception as e:
377
  return gr.update(value=f"Error: {str(e)}", visible=True), gr.update(visible=False)
378
 
379
+ def respond(message, chat_history, url1="", url2="", url3="", url4=""):
380
  # Make actual API request to OpenRouter
381
  import os
382
  import requests
 
386
 
387
  if not api_key:
388
  response = "Please set your OPENROUTER_API_KEY in the Space settings to use the chat support."
389
+ chat_history.append([message, response])
 
390
  return "", chat_history
391
 
392
+ # Get grounding context from URLs
393
+ grounding_urls = [url1, url2, url3, url4]
394
+ grounding_context = get_grounding_context(grounding_urls)
395
+
396
+ # Build enhanced system prompt with grounding context
397
+ base_system_prompt = """You are a helpful assistant specializing in creating chat UIs for HuggingFace Spaces. You help users configure assistants for education and research. Provide concise, practical advice about:
398
  - System prompts for different use cases (courses, research, tutoring)
399
  - Model selection (recommending google/gemma-2-27b-it as a great balance)
400
  - HuggingFace Space deployment tips
401
  - Customization options
402
 
403
  Keep responses brief and actionable. Focus on what the user is specifically asking about."""
404
+
405
+ enhanced_system_prompt = base_system_prompt + grounding_context
406
+
407
+ # Build conversation history for API
408
+ messages = [{
409
+ "role": "system",
410
+ "content": enhanced_system_prompt
411
  }]
412
 
413
+ # Add conversation history - Gradio 4.x uses list/tuple format
414
  for chat in chat_history:
415
+ if isinstance(chat, (list, tuple)) and len(chat) >= 2:
416
+ user_msg, assistant_msg = chat[0], chat[1]
417
+ if user_msg:
418
+ messages.append({"role": "user", "content": user_msg})
419
+ if assistant_msg:
420
+ messages.append({"role": "assistant", "content": assistant_msg})
421
 
422
  # Add current message
423
  messages.append({"role": "user", "content": message})
 
446
  except Exception as e:
447
  assistant_response = f"Error: {str(e)}"
448
 
449
+ chat_history.append([message, assistant_response])
 
450
  return "", chat_history
451
 
452
  def clear_chat():
 
470
  label="Space Description",
471
  placeholder="A customizable AI chat interface for...",
472
  lines=2,
473
+ value="An AI research assistant tailored for academic inquiry and scholarly dialogue"
474
  )
475
 
476
  model = gr.Dropdown(
 
490
  label="System Prompt",
491
  placeholder="You are a research assistant...",
492
  lines=4,
493
+ value="You are a knowledgeable academic research assistant. Provide thoughtful, evidence-based guidance for scholarly work, literature reviews, and academic writing. Support students and researchers with clear explanations and critical thinking."
494
  )
495
 
496
  examples_text = gr.Textbox(
 
500
  info="These will appear as clickable examples in the chat interface"
501
  )
502
 
503
+ gr.Markdown("### URL Grounding (Optional)")
504
+ gr.Markdown("Add up to 4 URLs to provide context. Content will be fetched and added to the system prompt.")
505
+
506
+ url1 = gr.Textbox(
507
+ label="URL 1",
508
+ placeholder="https://example.com/page1",
509
+ info="First URL for context grounding"
510
+ )
511
+
512
+ url2 = gr.Textbox(
513
+ label="URL 2",
514
+ placeholder="https://example.com/page2",
515
+ info="Second URL for context grounding"
516
+ )
517
+
518
+ url3 = gr.Textbox(
519
+ label="URL 3",
520
+ placeholder="https://example.com/page3",
521
+ info="Third URL for context grounding"
522
+ )
523
+
524
+ url4 = gr.Textbox(
525
+ label="URL 4",
526
+ placeholder="https://example.com/page4",
527
+ info="Fourth URL for context grounding"
528
+ )
529
+
530
  with gr.Row():
531
  temperature = gr.Slider(
532
  label="Temperature",
 
553
  # Connect the generate button
554
  generate_btn.click(
555
  on_generate,
556
+ inputs=[name, description, system_prompt, model, api_key_var, temperature, max_tokens, examples_text, url1, url2, url3, url4],
557
  outputs=[status, download_file]
558
  )
559
 
 
566
  chatbot = gr.Chatbot(
567
  value=[],
568
  label="Chat Support Assistant",
569
+ height=400
 
570
  )
571
  msg = gr.Textbox(
572
  label="Ask about configuring chat UIs for courses, research, or custom HuggingFace Spaces",
573
  placeholder="How can I configure a chat UI for my senior seminar?",
574
  lines=2
575
  )
576
+
577
+ with gr.Accordion("URL Grounding (Optional)", open=False):
578
+ gr.Markdown("Add URLs to provide additional context for more informed responses")
579
+ chat_url1 = gr.Textbox(
580
+ label="URL 1",
581
+ placeholder="https://example.com/context1",
582
+ info="First URL for context"
583
+ )
584
+ chat_url2 = gr.Textbox(
585
+ label="URL 2",
586
+ placeholder="https://example.com/context2",
587
+ info="Second URL for context"
588
+ )
589
+ chat_url3 = gr.Textbox(
590
+ label="URL 3",
591
+ placeholder="https://example.com/context3",
592
+ info="Third URL for context"
593
+ )
594
+ chat_url4 = gr.Textbox(
595
+ label="URL 4",
596
+ placeholder="https://example.com/context4",
597
+ info="Fourth URL for context"
598
+ )
599
  with gr.Row():
600
  submit = gr.Button("Send", variant="primary")
601
  clear = gr.Button("Clear")
 
613
  )
614
 
615
  # Connect the chat functionality
616
+ submit.click(respond, [msg, chatbot, chat_url1, chat_url2, chat_url3, chat_url4], [msg, chatbot])
617
+ msg.submit(respond, [msg, chatbot, chat_url1, chat_url2, chat_url3, chat_url4], [msg, chatbot])
618
  clear.click(clear_chat, outputs=[msg, chatbot])
619
 
620
  if __name__ == "__main__":
621
+ demo.launch(share=True)
local-files/claude.md DELETED
@@ -1,108 +0,0 @@
1
- # CLAUDE.md
2
-
3
- This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
-
5
- ## Architecture Overview
6
-
7
- This is a **Chat UI Helper** that generates ready-to-deploy HuggingFace Spaces for educational and research chat interfaces. The project combines a Gradio-based package generator with an AI-powered configuration assistant.
8
-
9
- ### Core Components
10
-
11
- 1. **Main Application (`app.py`)**: Two-tab Gradio interface:
12
- - **Space Generator Tab**: Creates deployable HuggingFace Space packages
13
- - **Chat UI Helper Tab**: AI assistant for configuration guidance (imported from `chat_helper.py`)
14
-
15
- 2. **Template System**:
16
- - `SPACE_TEMPLATE` string contains complete deployable chat interface code
17
- - Uses Python `.format()` to inject user configurations into template
18
- - Generates zip packages with `app.py`, `requirements.txt`, `README.md`, and `config.json`
19
-
20
- 3. **Chat Helper (`chat_helper.py`)**:
21
- - Modular AI assistant component for configuration guidance
22
- - Rule-based responses for common educational/research chat UI questions
23
- - Emphasizes Mixtral-8x7B as cost-effective recommended model
24
-
25
- ### Key Architecture Patterns
26
-
27
- - **Template Injection**: Uses `{{}}` for literal braces in generated code, `{}` for template variables
28
- - **Modular Design**: Chat helper is separate module imported by main app
29
- - **Configuration-Driven**: All generated spaces use environment-based API key configuration
30
- - **Educational Focus**: Specialized for academic and research use cases
31
-
32
- ## Development Commands
33
-
34
- ### Local Development
35
- ```bash
36
- # Install dependencies
37
- pip install -r requirements.txt
38
-
39
- # Run the main application
40
- python app.py
41
-
42
- # Test a basic assistant template
43
- python default.py
44
- ```
45
-
46
- ### Testing Generated Packages
47
- ```bash
48
- # Extract and test a generated zip package
49
- unzip my_custom_space.zip
50
- cd extracted_package
51
- export OPENROUTER_API_KEY="your-key-here"
52
- python app.py
53
- ```
54
-
55
- ### Requirements
56
- - All generated chat interfaces require OpenRouter API keys
57
- - Current Gradio version: 5.34.0 (updated from legacy 4.16.0)
58
- - Template generates Gradio ChatInterface applications
59
-
60
- ## Template System Details
61
-
62
- ### SPACE_TEMPLATE Structure
63
- The template generates complete HuggingFace Spaces with:
64
- - OpenRouter API integration using configurable environment variables
65
- - Gradio 5.x compatible ChatInterface implementation
66
- - Error handling for missing API keys
67
- - Configurable model, temperature, and token limits
68
- - Support for custom example prompts
69
-
70
- ### Configuration Variables
71
- Standard variables injected into templates:
72
- - `{name}`: Space title/name
73
- - `{description}`: Space description
74
- - `{system_prompt}`: AI behavior instructions
75
- - `{model}`: OpenRouter model identifier
76
- - `{api_key_var}`: Environment variable name for API key
77
- - `{temperature}`: Model temperature setting
78
- - `{max_tokens}`: Maximum response tokens
79
- - `{examples}`: JSON array of example prompts
80
-
81
- ### Template Compatibility
82
- - Template uses double braces `{{API_KEY}}` for variables that should appear literally in generated code
83
- - Single braces `{model}` are replaced during template formatting
84
- - Generated code is compatible with HuggingFace Spaces deployment
85
-
86
- ## Model Configuration
87
-
88
- ### Default Model List
89
- Available models prioritized by use case:
90
- - **Budget**: `google/gemma-2-9b-it`, `mistralai/mistral-7b-instruct`
91
- - **Recommended**: `mistralai/mixtral-8x7b-instruct` (balanced cost/performance)
92
- - **Premium**: `anthropic/claude-3.5-sonnet`, `openai/gpt-4o`
93
-
94
- ### Chat Helper Integration
95
- The `chat_helper.py` module provides AI-powered guidance specifically recommending Mixtral-8x7B for most educational and research use cases, with configuration examples and cost considerations.
96
-
97
- ## File Structure Patterns
98
-
99
- - `app.py`: Main two-tab application
100
- - `chat_helper.py`: Modular AI assistant component
101
- - `default.py`: Basic working assistant template for testing
102
- - `config.json`: Example configuration file
103
- - `exp/`: Legacy experimental versions and documentation
104
- - Generated zip files follow pattern: `{name}_{timestamp}.zip` → `{name}.zip`
105
-
106
- ## Current State
107
-
108
- The project has evolved from experimental multi-SDK generator (`exp/` folder) to focused educational/research chat UI helper. Current production stack generates HuggingFace Spaces optimized for academic use cases with built-in configuration guidance.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
my_custom_space.zip ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2c11e277aba67311812d79895394435b16238996ac1e6cad634a0dd5c1c09297
3
+ size 3683
requirements.txt CHANGED
@@ -1,2 +1,4 @@
1
- gradio==5.34.0
2
- requests==2.31.0
 
 
 
1
+ gradio==4.32.0
2
+ requests==2.32.3
3
+ beautifulsoup4==4.12.3
4
+ python-dotenv==1.0.0
test_assistant_with_grounding.zip ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:66147023e9f806ed65916773337a4f7a6a874f080300c097824b95de322aea85
3
+ size 3489
test_bot.zip ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2ba01cfc6f9dd205102f0f065fb9184397126aaba5b3225ee98b8cb369433eee
3
+ size 3353