GamerC0der commited on
Commit
a5397a6
·
verified ·
1 Parent(s): cbace36

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +9 -1
app.py CHANGED
@@ -3,6 +3,7 @@ import socketserver
3
  import json
4
  from curl_cffi import requests
5
  from openai import OpenAI
 
6
 
7
  PORT = 7860
8
  STT_URL = "https://multi-modal.ai.cloudflare.com/api/inference?model=@cf/deepgram/nova-3&field=audio"
@@ -13,8 +14,15 @@ client = OpenAI(
13
  api_key="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"
14
  )
15
 
 
 
 
 
 
 
 
16
  HTML = """
17
- <!DOCTYPE html><html><body><h1>Multi-Modal Playground</h1><div id="tabs"><button onclick="showTab('stt')">STT (Nova-3)</button><button onclick="showTab('tts')">TTS (AURA-1)</button><button onclick="showTab('chat')">Chat (Llama)</button></div><div id="sttTabContent" style="display:block;"><p>Upload audio:</p><input type="file" id="audioFile" accept="audio/*"><button onclick="transcribe()">Transcribe</button><p>Status: <span id="status">Idle</span></p><pre id="result" style="background:#eee;padding:10px"></pre></div><div id="ttsTabContent" style="display:none;"><p>Enter text:</p><input type="text" id="textInput" placeholder="Enter text to speak" style="width:100%;"><button onclick="generateAudio()">Generate Audio</button><p>Status: <span id="statusTTS">Idle</span></p><audio id="audioPlayer" controls style="width:100%;"></audio></div><div id="chatTabContent" style="display:none;"><div id="messages" style="height:300px;overflow-y:scroll;border:1px solid #ccc;padding:10px;margin-bottom:10px;background:#eee;"></div><input type="text" id="chatInput" placeholder="Type message..." style="width:70%;"><button onclick="sendMessage()">Send</button><p>Status: <span id="statusChat">Idle</span></p></div><script>let messages=[];function showTab(tab){document.getElementById('sttTabContent').style.display=tab==='stt'?'block':'none';document.getElementById('ttsTabContent').style.display=tab==='tts'?'block':'none';document.getElementById('chatTabContent').style.display=tab==='chat'?'block':'none';if(tab==='chat'){document.getElementById('chatInput').focus();}}function addMessage(role,content){const div=document.getElementById('messages');const msg=document.createElement('div');msg.innerText=`${role}: ${content}`;div.appendChild(msg);div.scrollTop=div.scrollHeight;}async function sendMessage(){const input=document.getElementById('chatInput');const text=input.value.trim();if(!text)return;addMessage('user',text);input.value='';document.getElementById('statusChat').innerText='Thinking...';messages.push({role:'user',content:text});try{const res=await fetch('/api/chat',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({messages:messages})});const data=await res.json();const response=data.response;addMessage('assistant',response);messages.push({role:'assistant',content:response});document.getElementById('statusChat').innerText='Done';}catch(e){document.getElementById('statusChat').innerText='Error';}}async function transcribe(){const file=document.getElementById('audioFile').files[0];if(!file)return;document.getElementById('status').innerText='Processing...';try{const res=await fetch('/api/stt',{method:'POST',body:file});const data=await res.json();document.getElementById('result').innerText=JSON.stringify(data,null,2);document.getElementById('status').innerText='Done';}catch(e){document.getElementById('status').innerText='Error';}}async function generateAudio(){const text=document.getElementById('textInput').value;if(!text)return;document.getElementById('statusTTS').innerText='Generating...';try{const res=await fetch('/api/tts',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({text:text})});const data=await res.json();document.getElementById('audioPlayer').src='data:audio/webm;base64,'+data.audio;document.getElementById('statusTTS').innerText='Done';}catch(e){document.getElementById('statusTTS').innerText='Error';}}</script></body></html>
18
  """
19
 
20
  class Handler(http.server.BaseHTTPRequestHandler):
 
3
  import json
4
  from curl_cffi import requests
5
  from openai import OpenAI
6
+ import re
7
 
8
  PORT = 7860
9
  STT_URL = "https://multi-modal.ai.cloudflare.com/api/inference?model=@cf/deepgram/nova-3&field=audio"
 
14
  api_key="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"
15
  )
16
 
17
+ def simple_md(text):
18
+ text = re.sub(r'\*\*(.*?)\*\*', r'<b>\1</b>', text)
19
+ text = re.sub(r'\*(.*?)\*', r'<i>\1</i>', text)
20
+ text = re.sub(r'`(.*?)`', r'<code>\1</code>', text)
21
+ text = re.sub(r'\n', r'<br>', text)
22
+ return text
23
+
24
  HTML = """
25
+ <!DOCTYPE html><html><body><h1>Multi-Modal Playground</h1><div id="tabs"><button id="tab-stt" onclick="showTab('stt')" class="tab-btn active">STT (Nova-3)</button><button id="tab-tts" onclick="showTab('tts')" class="tab-btn">TTS (AURA-1)</button><button id="tab-chat" onclick="showTab('chat')" class="tab-btn">Chat (Llama)</button><button id="tab-voice" onclick="showTab('voice')" class="tab-btn">Voice Chat</button></div><div id="sttTabContent" style="display:block;"><p>Upload audio:</p><input type="file" id="audioFile" accept="audio/*"><button onclick="transcribe()">Transcribe</button><p>Status: <span id="status">Idle</span></p><pre id="result" style="background:#eee;padding:10px"></pre></div><div id="ttsTabContent" style="display:none;"><p>Enter text:</p><input type="text" id="textInput" placeholder="Enter text to speak" style="width:100%;"><button onclick="generateAudio()">Generate Audio</button><p>Status: <span id="statusTTS">Idle</span></p><audio id="audioPlayer" controls style="width:100%;"></audio></div><div id="chatTabContent" style="display:none;"><div id="messages" style="height:300px;overflow-y:scroll;border:1px solid #ccc;padding:10px;margin-bottom:10px;background:#eee;"></div><input type="text" id="chatInput" placeholder="Type message..." style="width:70%;"><button onclick="sendMessage()">Send</button><p>Status: <span id="statusChat">Idle</span></p></div><div id="voiceTabContent" style="display:none;"><button id="micBtn" onclick="toggleRecord()" style="font-size:48px;">🎤</button><p>Status: <span id="statusVoice">Click to start recording</span></p><audio id="voicePlayer" style="display:none;"></audio></div><script>let chatMessages=[];let mediaRecorder;let audioChunks=[];let voiceStream;function showTab(tab){const tabs=document.querySelectorAll('.tab-btn');tabs.forEach(t=>t.classList.remove('active'));document.getElementById(`tab-${tab}`).classList.add('active');document.getElementById('sttTabContent').style.display=tab==='stt'?'block':'none';document.getElementById('ttsTabContent').style.display=tab==='tts'?'block':'none';document.getElementById('chatTabContent').style.display=tab==='chat'?'block':'none';document.getElementById('voiceTabContent').style.display=tab==='voice'?'block':'none';if(tab==='chat'){document.getElementById('chatInput').focus();}}function renderMD(text){return text.replace(/\*\*(.*?)\*\*/g,'<b>$1</b>').replace(/\*(.*?)\*/g,'<i>$1</i>').replace(/`(.*?)`/g,'<code>$1</code>').replace(/\n/g,'<br>');}function addMessage(role,content){const div=document.getElementById('messages');const msg=document.createElement('div');msg.innerHTML=`<strong>${role}:</strong> ${renderMD(content)}`;div.appendChild(msg);div.scrollTop=div.scrollHeight;}async function sendMessage(){const input=document.getElementById('chatInput');const text=input.value.trim();if(!text)return;addMessage('user',text);input.value='';document.getElementById('statusChat').innerText='Thinking...';chatMessages.push({role:'user',content:text});try{const res=await fetch('/api/chat',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({messages:chatMessages})});const data=await res.json();const response=data.response;addMessage('assistant',response);chatMessages.push({role:'assistant',content:response});document.getElementById('statusChat').innerText='Done';}catch(e){document.getElementById('statusChat').innerText='Error';}}async function toggleRecord(){const btn=document.getElementById('micBtn');if(!mediaRecorder||mediaRecorder.state==='inactive'){try{voiceStream=await navigator.mediaDevices.getUserMedia({audio:true});mediaRecorder=new MediaRecorder(voiceStream);audioChunks=[];mediaRecorder.ondataavailable=e=>audioChunks.push(e.data);mediaRecorder.onstop=processVoice;mediaRecorder.start();btn.style.color='red';document.getElementById('statusVoice').innerText='Recording... Click to stop';}catch(e){document.getElementById('statusVoice').innerText='Error accessing mic';}}else{mediaRecorder.stop();btn.style.color='black';document.getElementById('statusVoice').innerText='Processing...';}}async function processVoice(){const audioBlob=new Blob(audioChunks,{type:'audio/webm'});voiceStream.getTracks().forEach(track=>track.stop());const formData=new FormData();formData.append('audio',audioBlob);document.getElementById('statusVoice').innerText='Transcribing...';try{const sttRes=await fetch('/api/stt',{method:'POST',body:formData});const sttData=await sttRes.json();let userText='';if(sttData.results&&sttData.results.channels&&sttData.results.channels[0]&&sttData.results.channels[0].alternatives&&sttData.results.channels[0].alternatives[0]){userText=sttData.results.channels[0].alternatives[0].transcript;}if(!userText){document.getElementById('statusVoice').innerText='No speech detected';return;}document.getElementById('statusVoice').innerText='Thinking...';const chatRes=await fetch('/api/chat',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({messages:[{role:'user',content:userText}]})});const chatData=await chatRes.json();const response=chatData.response;document.getElementById('statusVoice').innerText='Generating speech...';const ttsRes=await fetch('/api/tts',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({text:response})});const ttsData=await ttsRes.json();const audioPlayer=document.getElementById('voicePlayer');audioPlayer.src='data:audio/webm;base64,'+ttsData.audio;audioPlayer.play();document.getElementById('statusVoice').innerText='Done';}catch(e){document.getElementById('statusVoice').innerText='Error';}}async function transcribe(){const file=document.getElementById('audioFile').files[0];if(!file)return;document.getElementById('status').innerText='Processing...';const formData=new FormData();formData.append('file',file);try{const res=await fetch('/api/stt',{method:'POST',body:formData});const data=await res.json();document.getElementById('result').innerText=JSON.stringify(data,null,2);document.getElementById('status').innerText='Done';}catch(e){document.getElementById('status').innerText='Error';}}async function generateAudio(){const text=document.getElementById('textInput').value;if(!text)return;document.getElementById('statusTTS').innerText='Generating...';try{const res=await fetch('/api/tts',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({text:text})});const data=await res.json();document.getElementById('audioPlayer').src='data:audio/webm;base64,'+data.audio;document.getElementById('statusTTS').innerText='Done';}catch(e){document.getElementById('statusTTS').innerText='Error';}}</script><style>.tab-btn.active{background:#ddd;}</style></body></html>
26
  """
27
 
28
  class Handler(http.server.BaseHTTPRequestHandler):