seawolf2357 commited on
Commit
f98e6c2
ยท
verified ยท
1 Parent(s): e32f3fb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +84 -9
app.py CHANGED
@@ -32,10 +32,17 @@ load_dotenv()
32
 
33
  SAMPLE_RATE = 24000
34
 
35
- # Use Persistent Storage path if available (Hugging Face Space)
36
- PERSISTENT_DIR = os.environ.get("PERSISTENT_DIR", "./data")
 
 
 
 
 
37
  os.makedirs(PERSISTENT_DIR, exist_ok=True)
38
  DB_PATH = os.path.join(PERSISTENT_DIR, "personal_assistant.db")
 
 
39
 
40
  # HTML content embedded as a string
41
  HTML_CONTENT = """<!DOCTYPE html>
@@ -397,12 +404,12 @@ HTML_CONTENT = """<!DOCTYPE html>
397
  background: linear-gradient(135deg, #27ae60, #229954);
398
  }
399
  #end-session-button {
400
- background: linear-gradient(135deg, #e74c3c, #c0392b);
401
  padding: 8px 16px;
402
  font-size: 13px;
403
  }
404
  #end-session-button:hover {
405
- background: linear-gradient(135deg, #c0392b, #a93226);
406
  }
407
  #audio-output {
408
  display: none;
@@ -562,7 +569,7 @@ HTML_CONTENT = """<!DOCTYPE html>
562
 
563
  <div class="controls">
564
  <button id="start-button">๋Œ€ํ™” ์‹œ์ž‘</button>
565
- <button id="end-session-button" style="display: none;">์„ธ์…˜ ์ข…๋ฃŒ</button>
566
  </div>
567
  </div>
568
 
@@ -685,7 +692,7 @@ HTML_CONTENT = """<!DOCTYPE html>
685
  }
686
  } catch (error) {
687
  console.error('Failed to end session:', error);
688
- showError('์„ธ์…˜ ์ข…๋ฃŒ ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.');
689
  }
690
  }
691
 
@@ -1489,11 +1496,20 @@ async def process_text_chat(message: str, web_search_enabled: bool, session_id:
1489
  user_name: str = "", memories: Dict = None) -> Dict[str, str]:
1490
  """Process text chat using GPT-4o-mini model"""
1491
  try:
 
 
 
 
 
 
 
 
1492
  # Build system prompt with memories
1493
  base_prompt = f"""You are a personal AI assistant for {user_name if user_name else 'the user'}.
1494
  You remember all previous conversations and personal information about the user.
1495
  Be friendly, helpful, and personalized in your responses.
1496
- Always use the information you remember to make conversations more personal and relevant."""
 
1497
 
1498
  # Add memories to prompt
1499
  if memories:
@@ -1577,6 +1593,8 @@ class OpenAIHandler(AsyncStreamHandler):
1577
  self.session_id = session_id
1578
  self.user_name = user_name
1579
  self.memories = memories or {}
 
 
1580
 
1581
  print(f"[INIT] Handler created with web_search={web_search_enabled}, session_id={session_id}, user={user_name}")
1582
 
@@ -1654,7 +1672,8 @@ class OpenAIHandler(AsyncStreamHandler):
1654
  base_instructions = f"""You are a personal AI assistant for {self.user_name if self.user_name else 'the user'}.
1655
  You remember all previous conversations and personal information about the user.
1656
  Be friendly, helpful, and personalized in your responses.
1657
- Always use the information you remember to make conversations more personal and relevant."""
 
1658
 
1659
  # Add memories to prompt
1660
  if self.memories:
@@ -1695,7 +1714,12 @@ Always use the information you remember to make conversations more personal and
1695
  model="gpt-4o-mini-realtime-preview-2024-12-17"
1696
  ) as conn:
1697
  session_update = {
1698
- "turn_detection": {"type": "server_vad"},
 
 
 
 
 
1699
  "instructions": instructions,
1700
  "tools": tools,
1701
  "tool_choice": "auto" if tools else "none",
@@ -1710,7 +1734,37 @@ Always use the information you remember to make conversations more personal and
1710
  print(f"Connected with tools: {len(tools)} functions")
1711
 
1712
  async for event in self.connection:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1713
  if event.type == "response.audio_transcript.done":
 
 
 
 
 
 
1714
  print(f"[RESPONSE] Transcript: {event.transcript[:100]}...")
1715
 
1716
  # Detect language
@@ -1731,7 +1785,17 @@ Always use the information you remember to make conversations more personal and
1731
  }
1732
  await self.output_queue.put(AdditionalOutputs(output_data))
1733
 
 
 
 
 
 
 
1734
  elif event.type == "response.audio.delta":
 
 
 
 
1735
  await self.output_queue.put(
1736
  (
1737
  self.output_sample_rate,
@@ -1847,6 +1911,17 @@ async def startup_event():
1847
  await PersonalAssistantDB.init()
1848
  print(f"Database initialized at: {DB_PATH}")
1849
  print(f"Persistent directory: {PERSISTENT_DIR}")
 
 
 
 
 
 
 
 
 
 
 
1850
 
1851
  # Intercept offer to capture settings
1852
  @app.post("/webrtc/offer", include_in_schema=False)
 
32
 
33
  SAMPLE_RATE = 24000
34
 
35
+ # Use Persistent Storage path for Hugging Face Space
36
+ # In HF Spaces, persistent storage is at /data
37
+ if os.path.exists("/data"):
38
+ PERSISTENT_DIR = "/data"
39
+ else:
40
+ PERSISTENT_DIR = "./data"
41
+
42
  os.makedirs(PERSISTENT_DIR, exist_ok=True)
43
  DB_PATH = os.path.join(PERSISTENT_DIR, "personal_assistant.db")
44
+ print(f"Using persistent directory: {PERSISTENT_DIR}")
45
+ print(f"Database path: {DB_PATH}")
46
 
47
  # HTML content embedded as a string
48
  HTML_CONTENT = """<!DOCTYPE html>
 
404
  background: linear-gradient(135deg, #27ae60, #229954);
405
  }
406
  #end-session-button {
407
+ background: linear-gradient(135deg, #4a9eff, #3a7ed8);
408
  padding: 8px 16px;
409
  font-size: 13px;
410
  }
411
  #end-session-button:hover {
412
+ background: linear-gradient(135deg, #3a7ed8, #2a5eb8);
413
  }
414
  #audio-output {
415
  display: none;
 
569
 
570
  <div class="controls">
571
  <button id="start-button">๋Œ€ํ™” ์‹œ์ž‘</button>
572
+ <button id="end-session-button" style="display: none;">๊ธฐ์–ต ์—…๋ฐ์ดํŠธ</button>
573
  </div>
574
  </div>
575
 
 
692
  }
693
  } catch (error) {
694
  console.error('Failed to end session:', error);
695
+ showError('๊ธฐ์–ต ์—…๋ฐ์ดํŠธ ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.');
696
  }
697
  }
698
 
 
1496
  user_name: str = "", memories: Dict = None) -> Dict[str, str]:
1497
  """Process text chat using GPT-4o-mini model"""
1498
  try:
1499
+ # Check for stop words
1500
+ stop_words = ["์ค‘๋‹จ", "๊ทธ๋งŒ", "์Šคํ†ฑ", "stop", "๋‹ฅ์ณ", "๋ฉˆ์ถฐ", "์ค‘์ง€"]
1501
+ if any(word in message.lower() for word in stop_words):
1502
+ return {
1503
+ "response": "๋Œ€ํ™”๋ฅผ ์ค‘๋‹จํ•ฉ๋‹ˆ๋‹ค.",
1504
+ "detected_language": "ko"
1505
+ }
1506
+
1507
  # Build system prompt with memories
1508
  base_prompt = f"""You are a personal AI assistant for {user_name if user_name else 'the user'}.
1509
  You remember all previous conversations and personal information about the user.
1510
  Be friendly, helpful, and personalized in your responses.
1511
+ Always use the information you remember to make conversations more personal and relevant.
1512
+ IMPORTANT: Give only ONE response. Do not repeat or give multiple answers."""
1513
 
1514
  # Add memories to prompt
1515
  if memories:
 
1593
  self.session_id = session_id
1594
  self.user_name = user_name
1595
  self.memories = memories or {}
1596
+ self.is_responding = False # Track if already responding
1597
+ self.should_stop = False # Track if conversation should stop
1598
 
1599
  print(f"[INIT] Handler created with web_search={web_search_enabled}, session_id={session_id}, user={user_name}")
1600
 
 
1672
  base_instructions = f"""You are a personal AI assistant for {self.user_name if self.user_name else 'the user'}.
1673
  You remember all previous conversations and personal information about the user.
1674
  Be friendly, helpful, and personalized in your responses.
1675
+ Always use the information you remember to make conversations more personal and relevant.
1676
+ IMPORTANT: Give only ONE response per user input. Do not repeat yourself or give multiple answers."""
1677
 
1678
  # Add memories to prompt
1679
  if self.memories:
 
1714
  model="gpt-4o-mini-realtime-preview-2024-12-17"
1715
  ) as conn:
1716
  session_update = {
1717
+ "turn_detection": {
1718
+ "type": "server_vad",
1719
+ "threshold": 0.5,
1720
+ "prefix_padding_ms": 300,
1721
+ "silence_duration_ms": 200
1722
+ },
1723
  "instructions": instructions,
1724
  "tools": tools,
1725
  "tool_choice": "auto" if tools else "none",
 
1734
  print(f"Connected with tools: {len(tools)} functions")
1735
 
1736
  async for event in self.connection:
1737
+ # Handle user transcription for stop detection
1738
+ if event.type == "conversation.item.created":
1739
+ if hasattr(event, 'item') and hasattr(event.item, 'role') and event.item.role == "user":
1740
+ if hasattr(event.item, 'content') and event.item.content:
1741
+ for content_item in event.item.content:
1742
+ if hasattr(content_item, 'transcript'):
1743
+ user_text = content_item.transcript.lower()
1744
+ stop_words = ["์ค‘๋‹จ", "๊ทธ๋งŒ", "์Šคํ†ฑ", "stop", "๋‹ฅ์ณ", "๋ฉˆ์ถฐ", "์ค‘์ง€"]
1745
+
1746
+ if any(word in user_text for word in stop_words):
1747
+ print(f"[STOP DETECTED] User said: {content_item.transcript}")
1748
+ self.should_stop = True
1749
+ # Cancel any ongoing response
1750
+ if self.connection:
1751
+ try:
1752
+ await self.connection.response.cancel()
1753
+ except:
1754
+ pass
1755
+ continue
1756
+
1757
+ # Save user message to database
1758
+ if self.session_id:
1759
+ await PersonalAssistantDB.save_message(self.session_id, "user", content_item.transcript)
1760
+
1761
  if event.type == "response.audio_transcript.done":
1762
+ # Prevent multiple responses
1763
+ if self.is_responding:
1764
+ print("[DUPLICATE RESPONSE] Skipping duplicate response")
1765
+ continue
1766
+
1767
+ self.is_responding = True
1768
  print(f"[RESPONSE] Transcript: {event.transcript[:100]}...")
1769
 
1770
  # Detect language
 
1785
  }
1786
  await self.output_queue.put(AdditionalOutputs(output_data))
1787
 
1788
+ elif event.type == "response.done":
1789
+ # Reset responding flag when response is complete
1790
+ self.is_responding = False
1791
+ self.should_stop = False
1792
+ print("[RESPONSE DONE] Response completed")
1793
+
1794
  elif event.type == "response.audio.delta":
1795
+ # Check if we should stop
1796
+ if self.should_stop:
1797
+ continue
1798
+
1799
  await self.output_queue.put(
1800
  (
1801
  self.output_sample_rate,
 
1911
  await PersonalAssistantDB.init()
1912
  print(f"Database initialized at: {DB_PATH}")
1913
  print(f"Persistent directory: {PERSISTENT_DIR}")
1914
+ print(f"DB file exists: {os.path.exists(DB_PATH)}")
1915
+
1916
+ # Check if we're in Hugging Face Space
1917
+ if os.path.exists("/data"):
1918
+ print("Running in Hugging Face Space with persistent storage")
1919
+ # List files in persistent directory
1920
+ try:
1921
+ files = os.listdir(PERSISTENT_DIR)
1922
+ print(f"Files in persistent directory: {files}")
1923
+ except Exception as e:
1924
+ print(f"Error listing files: {e}")
1925
 
1926
  # Intercept offer to capture settings
1927
  @app.post("/webrtc/offer", include_in_schema=False)