Spaces:
Sleeping
Sleeping
import os | |
import time | |
import uuid | |
import base64 | |
import tempfile | |
from flask import Flask, request, render_template, jsonify, session | |
from dotenv import load_dotenv | |
from groq import Groq | |
from deepgram import DeepgramClient, SpeakOptions | |
# Load environment variables | |
load_dotenv() | |
# Fetch API keys from environment variables | |
GROQ_API_KEY = os.getenv("GROQ_API_KEY") | |
DEEPGRAM_API_KEY = os.getenv("DEEPGRAM_API_KEY") | |
# Set up the Groq client | |
client = Groq(api_key=GROQ_API_KEY) | |
# Set up Deepgram client | |
deepgram = DeepgramClient(DEEPGRAM_API_KEY) | |
# Flask app | |
app = Flask(__name__) | |
app.secret_key = os.urandom(24) | |
# Store conversation history | |
conversation_history = [] | |
# Synthesize therapist response to speech without permanently storing the file | |
def synthesize_audio(text): | |
try: | |
# Retrieve the selected voice or default to "aura-asteria-en" | |
model = session.get('selected_voice', 'aura-asteria-en') | |
options = SpeakOptions(model=model) | |
# Use a temporary file to store the synthesized audio | |
with tempfile.NamedTemporaryFile(suffix=".mp3", delete=False) as tmp_file: | |
tmp_filename = tmp_file.name | |
# Synthesize the response and save to the temporary file | |
deepgram.speak.v("1").save(tmp_filename, {"text": text}, options) | |
# Read the audio data into memory | |
with open(tmp_filename, "rb") as f: | |
audio_data = f.read() | |
# Remove the temporary file | |
os.remove(tmp_filename) | |
# Encode the audio data as base64 and return a data URI | |
audio_base64 = base64.b64encode(audio_data).decode('utf-8') | |
audio_data_uri = f"data:audio/mpeg;base64,{audio_base64}" | |
return audio_data_uri | |
except Exception as e: | |
raise ValueError(f"Speech synthesis failed: {str(e)}") | |
def choose_voice(): | |
return render_template('chose voice page.html') | |
def start_chat(): | |
selected_voice = request.args.get('voice', 'aura-asteria-en') | |
session['selected_voice'] = selected_voice | |
return render_template('index.html') | |
def process_audio(): | |
global conversation_history | |
# Step 1: Accept audio input | |
audio_data = request.files.get('audio_data') | |
if not audio_data: | |
return jsonify({'error': 'No audio file uploaded'}), 400 | |
try: | |
# Step 2: Transcribe the audio using Groq Whisper | |
transcription = client.audio.transcriptions.create( | |
file=('recording.wav', audio_data.read()), | |
model="whisper-large-v3", | |
prompt="Transcribe the audio accurately.", | |
response_format="text" | |
) | |
user_input = transcription.strip() | |
if not user_input: | |
return jsonify({'error': 'No valid transcription from audio'}), 400 | |
# Append user input to conversation history | |
conversation_history.append({"role": "user", "content": user_input}) | |
# Step 3: Generate therapist response | |
fixed_prompt = [ | |
{"role": "system", "content": """ | |
You are an AI therapist named Virtual Therapist, designed to provide conversational support and mental health guidance in a clear, concise, and professional manner. Your responses should: | |
1. Be short and to the point. | |
2. Maintain a professional tone. | |
3. Encourage open dialogue. | |
4. Provide solutions or suggestions where appropriate. | |
5. Stay respectful and non-judgmental. | |
6. Avoid lengthy explanations. | |
"""} | |
] | |
conversation_history_with_prompt = fixed_prompt + conversation_history | |
response = client.chat.completions.create( | |
messages=conversation_history_with_prompt, | |
model="llama3-8b-8192" | |
) | |
assistant_reply = response.choices[0].message.content | |
# Append assistant reply to conversation history | |
conversation_history.append({"role": "assistant", "content": assistant_reply}) | |
# Step 4: Synthesize therapist response to speech (in memory, no permanent files) | |
audio_url = synthesize_audio(assistant_reply) | |
# Return data URI instead of file URL | |
return jsonify({ | |
'transcription': user_input, | |
'response': assistant_reply, | |
'audioUrl': audio_url | |
}) | |
except Exception as e: | |
return jsonify({'error': str(e)}), 500 | |
if __name__ == '__main__': | |
app.run(debug=True) | |