milwright commited on
Commit
c98afe3
·
verified ·
1 Parent(s): 7aa19d1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +45 -42
app.py CHANGED
@@ -12,24 +12,24 @@ from typing import List, Dict, Optional, Any, Tuple
12
 
13
 
14
  # Configuration
15
- SPACE_NAME = 'Language Learning Partner'
16
- SPACE_DESCRIPTION = 'AI Italian conversation partner'
17
 
18
  # Default configuration values
19
  DEFAULT_CONFIG = {
20
  'name': SPACE_NAME,
21
  'description': SPACE_DESCRIPTION,
22
- 'system_prompt': "You are Domenico from Sicily, a Juventus football fan, native Italian speaker serving as a conversational partner for university students in an Italian 101 class. Students will interact and converse with you in Italian, and you must respond EXCLUSIVELY IN ITALIAN without providing English translations, using vocabulary appropriate for beginner-level Italian 101 students. Focus your responses on topics suitable for beginners such as sports, daily life, routines, food, numbers, and hobbies. When students make errors, model the correct forms naturally in your response without explicitly pointing out mistakes, allowing them to learn through exposure to proper usage. Recognize when students demonstrate more advanced abilities and adjust your language complexity accordingly, while ensuring your Italian remains error-free. Keep all responses between 5-50 words, making sure sentences are grammatically complete. Limit all verb conjugations to the present tense only, avoiding all other verb forms and tenses. Address students using the informal second-person singular 'tu' form.",
23
- 'temperature': 0.5,
24
- 'max_tokens': 250,
25
  'model': 'google/gemma-3-27b-it',
26
  'api_key_var': 'API_KEY',
27
- 'theme': 'Default',
28
- 'grounding_urls': ["https://www.pnac.org/wp-content/uploads/Italian-Study-Guide.pdf"],
29
  'enable_dynamic_urls': True,
30
  'enable_file_upload': True,
31
- 'examples': ['Ciao! Come stai oggi?', 'Mi piace giocare a calcio. E tu?', 'Cosa mangi di solito a colazione?', 'A che ora ti svegli la mattina?', 'Qual è il tuo sport preferito?'],
32
- 'language': 'Italian',
33
  'locked': False
34
  }
35
 
@@ -183,13 +183,7 @@ def fetch_url_content(url: str, max_length: int = 3000) -> str:
183
  return f"❌ Invalid URL format: {url}"
184
 
185
  headers = {
186
- 'User-Agent': 'Mozilla/5.0 (compatible; HuggingFace-Space/1.0)',
187
- 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
188
- 'Accept-Language': 'en-US,en;q=0.5',
189
- 'Accept-Encoding': 'gzip, deflate',
190
- 'DNT': '1',
191
- 'Connection': 'keep-alive',
192
- 'Upgrade-Insecure-Requests': '1'
193
  }
194
 
195
  response = requests.get(url, headers=headers, timeout=5)
@@ -235,7 +229,7 @@ def fetch_url_content(url: str, max_length: int = 3000) -> str:
235
 
236
  def extract_urls_from_text(text: str) -> List[str]:
237
  """Extract URLs from message text"""
238
- url_pattern = r'https?://[^\s<>"{}|\\^`\[\]]+(?:\.[^\s<>"{}|\\^`\[\]])*'
239
  urls = re.findall(url_pattern, text)
240
  return [url.rstrip('.,;:)?!') for url in urls]
241
 
@@ -335,17 +329,18 @@ def get_grounding_context() -> str:
335
  return ""
336
 
337
 
338
- def export_conversation_to_markdown(history: List[Dict[str, str]]) -> str:
339
- """Export conversation history to markdown"""
340
  if not history:
341
  return "No conversation to export."
342
 
343
- markdown_content = f"""# Conversation Export
 
344
  Generated on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
345
  Space: {SPACE_NAME}
346
  Model: {MODEL}
347
 
348
- ---
349
 
350
  """
351
 
@@ -355,15 +350,28 @@ Model: {MODEL}
355
  role = message.get('role', 'unknown')
356
  content = message.get('content', '')
357
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
358
  if role == 'user':
359
  message_count += 1
360
- markdown_content += f"## User Message {message_count}\n\n{content}\n\n"
361
  elif role == 'assistant':
362
- markdown_content += f"## Assistant Response {message_count}\n\n{content}\n\n---\n\n"
363
 
364
- return markdown_content
365
-
366
-
367
 
368
 
369
  def generate_response(message: str, history: List[Dict[str, str]], files: Optional[List] = None) -> str:
@@ -594,7 +602,7 @@ def create_interface():
594
  submit_btn = gr.Button("Send", variant="primary")
595
  clear_btn = gr.Button("Clear")
596
 
597
- # Export functionality
598
  with gr.Row():
599
  # Use a regular Button for triggering export
600
  export_trigger_btn = gr.Button(
@@ -615,18 +623,18 @@ def create_interface():
615
  return None
616
 
617
  try:
618
- content = export_conversation_to_markdown(chat_history)
619
 
620
  # Create filename
621
  space_name_safe = re.sub(r'[^a-zA-Z0-9]+', '_', SPACE_NAME).lower()
622
  timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
623
- filename = f"{space_name_safe}_conversation_{timestamp}.md"
624
 
625
  # Save to temp file
626
  temp_path = Path(tempfile.gettempdir()) / filename
627
  temp_path.write_text(content, encoding='utf-8')
628
 
629
- # Return the file path for download
630
  return gr.File(visible=True, value=str(temp_path))
631
  except Exception as e:
632
  gr.Error(f"Failed to export conversation: {str(e)}")
@@ -659,10 +667,13 @@ def create_interface():
659
  # Get response
660
  response = generate_response(message, formatted_history, files_state)
661
 
662
- # Update chat history
 
 
 
663
  chat_history = chat_history + [
664
- {"role": "user", "content": message},
665
- {"role": "assistant", "content": response}
666
  ]
667
 
668
  # Update stored history for export
@@ -1092,12 +1103,4 @@ def create_interface():
1092
  # Create and launch the interface
1093
  if __name__ == "__main__":
1094
  demo = create_interface()
1095
- # Launch with appropriate settings for HuggingFace Spaces
1096
- demo.launch(
1097
- server_name="0.0.0.0",
1098
- server_port=7860,
1099
- share=False,
1100
- # Add allowed CORS origins if needed
1101
- # Since this is a Gradio app, CORS is handled by Gradio itself
1102
- # For custom API endpoints, you would need to add CORS middleware
1103
- )
 
12
 
13
 
14
  # Configuration
15
+ SPACE_NAME = 'AmigAI Demo (v1.2b)'
16
+ SPACE_DESCRIPTION = 'Help AmigAI download an app to their phone while practicing imperative verbs and the prepositions "por" and "para" in Spanish'
17
 
18
  # Default configuration values
19
  DEFAULT_CONFIG = {
20
  'name': SPACE_NAME,
21
  'description': SPACE_DESCRIPTION,
22
+ 'system_prompt': 'Actuarás como una persona que no sabe manejar la tecnología y necesita instrucciones en español para descargar una aplicación a su celular. Tu nombre es AmigAI y dominas una variedad amplia del español que incluye todas las variedades habladas en Latinoamérica, menos la hablada en España. Tu interacción consistirá en saludar, presentarte y solicitar ayuda para entender el paso a paso de la descarga de una aplicación cualquiera a un smartphone. En el proceso puedes realizarle preguntas al estudiante para que especifique sus instrucciones usando las preposiciones por y para. Si el interlocutor no usa esas preposiciones de manera adecuada o no conjuga los verbos de la instrucción en imperativo de manera correcta, le pedirás que refórmele o que repita su instrucción. Si el error persiste, le darás opciones de respuesta posible para que elija la forma más adecuada y la escriba. El objetivo se logrará una vez que el estudiante te logre dar cinco instrucciones continuas de manera correcta. Una vez se logre el objetivo, le darás una devolución sobre los errores que cometió al escribir en español y las posibles formas de corregirlos, y le recordarás que debe descargar su interacción y enviarla por correo al profesor. Los estudiantes son de nivel intermedio bajo así que no usarás vocabulario muy complejo ni tampoco estructuras como el subjuntivo. Espera terminar cada respuesta en menos de 150 tokens.',
23
+ 'temperature': 0.7,
24
+ 'max_tokens': 150,
25
  'model': 'google/gemma-3-27b-it',
26
  'api_key_var': 'API_KEY',
27
+ 'theme': 'Base',
28
+ 'grounding_urls': [],
29
  'enable_dynamic_urls': True,
30
  'enable_file_upload': True,
31
+ 'examples': ['¡Saludos!', 'Buenas tardes', 'Buenos días'],
32
+ 'language': 'Spanish',
33
  'locked': False
34
  }
35
 
 
183
  return f"❌ Invalid URL format: {url}"
184
 
185
  headers = {
186
+ 'User-Agent': 'Mozilla/5.0 (compatible; HuggingFace-Space/1.0)'
 
 
 
 
 
 
187
  }
188
 
189
  response = requests.get(url, headers=headers, timeout=5)
 
229
 
230
  def extract_urls_from_text(text: str) -> List[str]:
231
  """Extract URLs from message text"""
232
+ url_pattern = r'https?://[^\s<>"{}\|\\^`\[\]]+(?:\.[^\s<>"{}\|\\^`\[\]])*'
233
  urls = re.findall(url_pattern, text)
234
  return [url.rstrip('.,;:)?!') for url in urls]
235
 
 
329
  return ""
330
 
331
 
332
+ def export_conversation_to_text(history: List[Dict[str, str]]) -> str:
333
+ """Export conversation history to text with timestamps"""
334
  if not history:
335
  return "No conversation to export."
336
 
337
+ text_content = f"""Conversation Export
338
+ ==================
339
  Generated on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
340
  Space: {SPACE_NAME}
341
  Model: {MODEL}
342
 
343
+ ==================
344
 
345
  """
346
 
 
350
  role = message.get('role', 'unknown')
351
  content = message.get('content', '')
352
 
353
+ # Get timestamp from message or use current time as fallback
354
+ timestamp_str = message.get('timestamp', '')
355
+ if timestamp_str:
356
+ try:
357
+ # Parse ISO format timestamp and format it nicely
358
+ timestamp = datetime.fromisoformat(timestamp_str)
359
+ formatted_timestamp = timestamp.strftime('%Y-%m-%d %H:%M:%S')
360
+ except:
361
+ formatted_timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
362
+ else:
363
+ formatted_timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
364
+
365
+ # Get message length
366
+ msg_length = message.get('length', len(content))
367
+
368
  if role == 'user':
369
  message_count += 1
370
+ text_content += f"[{formatted_timestamp}] User Message {message_count} ({msg_length} chars):\n{content}\n\n"
371
  elif role == 'assistant':
372
+ text_content += f"[{formatted_timestamp}] Assistant Response {message_count} ({msg_length} chars):\n{content}\n\n------------------\n\n"
373
 
374
+ return text_content
 
 
375
 
376
 
377
  def generate_response(message: str, history: List[Dict[str, str]], files: Optional[List] = None) -> str:
 
602
  submit_btn = gr.Button("Send", variant="primary")
603
  clear_btn = gr.Button("Clear")
604
 
605
+ # Export functionality
606
  with gr.Row():
607
  # Use a regular Button for triggering export
608
  export_trigger_btn = gr.Button(
 
623
  return None
624
 
625
  try:
626
+ content = export_conversation_to_text(chat_history)
627
 
628
  # Create filename
629
  space_name_safe = re.sub(r'[^a-zA-Z0-9]+', '_', SPACE_NAME).lower()
630
  timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
631
+ filename = f"{space_name_safe}_conversation_{timestamp}.txt"
632
 
633
  # Save to temp file
634
  temp_path = Path(tempfile.gettempdir()) / filename
635
  temp_path.write_text(content, encoding='utf-8')
636
 
637
+ # Return the file component with visibility and value
638
  return gr.File(visible=True, value=str(temp_path))
639
  except Exception as e:
640
  gr.Error(f"Failed to export conversation: {str(e)}")
 
667
  # Get response
668
  response = generate_response(message, formatted_history, files_state)
669
 
670
+ # Get current timestamp
671
+ current_time = datetime.now()
672
+
673
+ # Update chat history with timestamps and message lengths
674
  chat_history = chat_history + [
675
+ {"role": "user", "content": message, "timestamp": current_time.isoformat(), "length": len(message)},
676
+ {"role": "assistant", "content": response, "timestamp": current_time.isoformat(), "length": len(response)}
677
  ]
678
 
679
  # Update stored history for export
 
1103
  # Create and launch the interface
1104
  if __name__ == "__main__":
1105
  demo = create_interface()
1106
+ demo.launch()