seawolf2357 commited on
Commit
c88aa2b
ยท
verified ยท
1 Parent(s): 637b6bc

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +143 -7
app.py CHANGED
@@ -546,6 +546,7 @@ HTML_CONTENT = """<!DOCTYPE html>
546
  let animationFrame;
547
  let audioContext, analyser, audioSource;
548
  let dataChannel = null;
 
549
 
550
  // Web search toggle functionality
551
  searchToggle.addEventListener('click', () => {
@@ -575,16 +576,57 @@ HTML_CONTENT = """<!DOCTYPE html>
575
 
576
  sendButton.addEventListener('click', sendTextMessage);
577
 
578
- function sendTextMessage() {
579
  const message = textInput.value.trim();
580
- if (!message || !dataChannel || dataChannel.readyState !== 'open') return;
581
 
 
582
  addMessage('user', message);
583
- dataChannel.send(JSON.stringify({
584
- type: 'text_message',
585
- content: message
586
- }));
587
  textInput.value = '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
588
  }
589
 
590
  function updateStatus(state) {
@@ -592,12 +634,14 @@ HTML_CONTENT = """<!DOCTYPE html>
592
  if (state === 'connected') {
593
  statusText.textContent = '์—ฐ๊ฒฐ๋จ';
594
  sendButton.style.display = 'block';
 
595
  } else if (state === 'connecting') {
596
  statusText.textContent = '์—ฐ๊ฒฐ ์ค‘...';
597
  sendButton.style.display = 'none';
598
  } else {
599
  statusText.textContent = '์—ฐ๊ฒฐ ๋Œ€๊ธฐ ์ค‘';
600
- sendButton.style.display = 'none';
 
601
  }
602
  }
603
  function updateButtonState() {
@@ -885,11 +929,80 @@ print(f"Search client initialized: {search_client is not None}, API key present:
885
  # Store connection settings
886
  connection_settings = {}
887
 
 
 
 
888
  def update_chatbot(chatbot: list[dict], response: ResponseAudioTranscriptDoneEvent):
889
  chatbot.append({"role": "assistant", "content": response.transcript})
890
  return chatbot
891
 
892
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
893
  class OpenAIHandler(AsyncStreamHandler):
894
  def __init__(self, web_search_enabled: bool = False, target_language: str = "",
895
  system_prompt: str = "", webrtc_id: str = None) -> None:
@@ -1231,6 +1344,29 @@ async def custom_offer(request: Request):
1231
  return response
1232
 
1233
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1234
  @app.post("/text_message/{webrtc_id}")
1235
  async def receive_text_message(webrtc_id: str, request: Request):
1236
  """Receive text message from client"""
 
546
  let animationFrame;
547
  let audioContext, analyser, audioSource;
548
  let dataChannel = null;
549
+ let isVoiceActive = false;
550
 
551
  // Web search toggle functionality
552
  searchToggle.addEventListener('click', () => {
 
576
 
577
  sendButton.addEventListener('click', sendTextMessage);
578
 
579
+ async function sendTextMessage() {
580
  const message = textInput.value.trim();
581
+ if (!message) return;
582
 
583
+ // Add user message to chat
584
  addMessage('user', message);
 
 
 
 
585
  textInput.value = '';
586
+
587
+ // Show sending indicator
588
+ const typingIndicator = document.createElement('div');
589
+ typingIndicator.classList.add('message', 'assistant');
590
+ typingIndicator.textContent = '์ž…๋ ฅ ์ค‘...';
591
+ typingIndicator.id = 'typing-indicator';
592
+ chatMessages.appendChild(typingIndicator);
593
+ chatMessages.scrollTop = chatMessages.scrollHeight;
594
+
595
+ try {
596
+ // Send to text chat endpoint
597
+ const response = await fetch('/chat/text', {
598
+ method: 'POST',
599
+ headers: { 'Content-Type': 'application/json' },
600
+ body: JSON.stringify({
601
+ message: message,
602
+ web_search_enabled: webSearchEnabled,
603
+ target_language: selectedLanguage,
604
+ system_prompt: systemPrompt
605
+ })
606
+ });
607
+
608
+ const data = await response.json();
609
+
610
+ // Remove typing indicator
611
+ const indicator = document.getElementById('typing-indicator');
612
+ if (indicator) indicator.remove();
613
+
614
+ if (data.error) {
615
+ showError(data.error);
616
+ } else {
617
+ // Add assistant response
618
+ let content = data.response;
619
+ if (selectedLanguage && data.language) {
620
+ content += ` <span class="language-info">[${data.language}]</span>`;
621
+ }
622
+ addMessage('assistant', content);
623
+ }
624
+ } catch (error) {
625
+ console.error('Error sending text message:', error);
626
+ const indicator = document.getElementById('typing-indicator');
627
+ if (indicator) indicator.remove();
628
+ showError('๋ฉ”์‹œ์ง€ ์ „์†ก ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.');
629
+ }
630
  }
631
 
632
  function updateStatus(state) {
 
634
  if (state === 'connected') {
635
  statusText.textContent = '์—ฐ๊ฒฐ๋จ';
636
  sendButton.style.display = 'block';
637
+ isVoiceActive = true;
638
  } else if (state === 'connecting') {
639
  statusText.textContent = '์—ฐ๊ฒฐ ์ค‘...';
640
  sendButton.style.display = 'none';
641
  } else {
642
  statusText.textContent = '์—ฐ๊ฒฐ ๋Œ€๊ธฐ ์ค‘';
643
+ sendButton.style.display = 'block'; // Show send button even when disconnected for text chat
644
+ isVoiceActive = false;
645
  }
646
  }
647
  function updateButtonState() {
 
929
  # Store connection settings
930
  connection_settings = {}
931
 
932
+ # Initialize OpenAI client for text chat
933
+ client = openai.AsyncOpenAI()
934
+
935
  def update_chatbot(chatbot: list[dict], response: ResponseAudioTranscriptDoneEvent):
936
  chatbot.append({"role": "assistant", "content": response.transcript})
937
  return chatbot
938
 
939
 
940
+ def get_translation_instructions(target_language: str) -> str:
941
+ """Get instructions for translation based on target language"""
942
+ if not target_language:
943
+ return ""
944
+
945
+ language_name = SUPPORTED_LANGUAGES.get(target_language, target_language)
946
+ return (
947
+ f"\n\nIMPORTANT: You must respond in {language_name} ({target_language}). "
948
+ f"Translate all your responses to {language_name}."
949
+ )
950
+
951
+
952
+ async def process_text_chat(message: str, web_search_enabled: bool, target_language: str,
953
+ system_prompt: str) -> Dict[str, str]:
954
+ """Process text chat using GPT-4o-mini model"""
955
+ try:
956
+ # Prepare system message
957
+ base_instructions = system_prompt or "You are a helpful assistant."
958
+ translation_instructions = get_translation_instructions(target_language)
959
+
960
+ messages = [
961
+ {"role": "system", "content": base_instructions + translation_instructions}
962
+ ]
963
+
964
+ # Handle web search if enabled
965
+ if web_search_enabled and search_client:
966
+ # Check if the message requires web search
967
+ search_keywords = ["๋‚ ์”จ", "๊ธฐ์˜จ", "๋น„", "๋ˆˆ", "๋‰ด์Šค", "์†Œ์‹", "ํ˜„์žฌ", "์ตœ๊ทผ",
968
+ "์˜ค๋Š˜", "์ง€๊ธˆ", "๊ฐ€๊ฒฉ", "ํ™˜์œจ", "์ฃผ๊ฐ€", "weather", "news",
969
+ "current", "today", "price", "2024", "2025"]
970
+
971
+ should_search = any(keyword in message.lower() for keyword in search_keywords)
972
+
973
+ if should_search:
974
+ # Perform web search
975
+ search_results = await search_client.search(message)
976
+ if search_results:
977
+ search_context = "์›น ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ:\n\n"
978
+ for i, result in enumerate(search_results[:5], 1):
979
+ search_context += f"{i}. {result['title']}\n{result['description']}\n\n"
980
+
981
+ messages.append({
982
+ "role": "system",
983
+ "content": f"๋‹ค์Œ ์›น ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ๋‹ต๋ณ€ํ•˜์„ธ์š”:\n\n{search_context}"
984
+ })
985
+
986
+ messages.append({"role": "user", "content": message})
987
+
988
+ # Call GPT-4o-mini
989
+ response = await client.chat.completions.create(
990
+ model="gpt-4o-mini",
991
+ messages=messages,
992
+ temperature=0.7,
993
+ max_tokens=2000
994
+ )
995
+
996
+ return {
997
+ "response": response.choices[0].message.content,
998
+ "language": SUPPORTED_LANGUAGES.get(target_language, "") if target_language else ""
999
+ }
1000
+
1001
+ except Exception as e:
1002
+ print(f"Error in text chat: {e}")
1003
+ return {"error": str(e)}
1004
+
1005
+
1006
  class OpenAIHandler(AsyncStreamHandler):
1007
  def __init__(self, web_search_enabled: bool = False, target_language: str = "",
1008
  system_prompt: str = "", webrtc_id: str = None) -> None:
 
1344
  return response
1345
 
1346
 
1347
+ @app.post("/chat/text")
1348
+ async def chat_text(request: Request):
1349
+ """Handle text chat messages using GPT-4o-mini"""
1350
+ try:
1351
+ body = await request.json()
1352
+ message = body.get("message", "")
1353
+ web_search_enabled = body.get("web_search_enabled", False)
1354
+ target_language = body.get("target_language", "")
1355
+ system_prompt = body.get("system_prompt", "")
1356
+
1357
+ if not message:
1358
+ return {"error": "๋ฉ”์‹œ์ง€๊ฐ€ ๋น„์–ด์žˆ์Šต๋‹ˆ๋‹ค."}
1359
+
1360
+ # Process text chat
1361
+ result = await process_text_chat(message, web_search_enabled, target_language, system_prompt)
1362
+
1363
+ return result
1364
+
1365
+ except Exception as e:
1366
+ print(f"Error in chat_text endpoint: {e}")
1367
+ return {"error": "์ฑ„ํŒ… ์ฒ˜๋ฆฌ ์ค‘ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค."}
1368
+
1369
+
1370
  @app.post("/text_message/{webrtc_id}")
1371
  async def receive_text_message(webrtc_id: str, request: Request):
1372
  """Receive text message from client"""