Spaces:
Sleeping
Sleeping
import os | |
import json | |
from flask import Flask, jsonify, request, send_file, send_from_directory | |
from langchain_core.messages import HumanMessage | |
from langchain_google_genai import ChatGoogleGenerativeAI | |
import assemblyai as aai | |
from dotenv import load_dotenv | |
# Load environment variables from the .env file | |
load_dotenv() | |
# Initialize the Flask app | |
app = Flask(__name__) | |
# Get API keys from environment variables | |
ASSEMBLYAI_API_KEY = os.getenv("ASSEMBLYAI_API_KEY") | |
GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY") | |
# Set AssemblyAI API key | |
aai.settings.api_key = ASSEMBLYAI_API_KEY | |
# Set Google API key for Gemini model | |
os.environ["GOOGLE_API_KEY"] = GOOGLE_API_KEY | |
# Define a directory to save uploaded audio files | |
UPLOAD_FOLDER = 'uploads' | |
os.makedirs(UPLOAD_FOLDER, exist_ok=True) | |
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER | |
# Refined Instructions for Gemini | |
GEMINI_INSTRUCTIONS = """ | |
The purpose of the category 'Reason for Outbound Call' is to identify the reason that a connected call was placed by the caller. | |
Consider the following options and select the one that best matches the content of the call: | |
1. Yes: The agent attempted to discuss buying, selling, trading, leasing, or test driving a vehicle. This includes any discussion of vehicle needs, interests, or potential sales, but this only applies if the call was live. | |
2. No: The agent followed up on a previous purchase or had a general discussion. This option should be selected if the call does not include any sales-related discussion. | |
3. No: The agent only confirmed, changed, or canceled an existing appointment. This includes any mention of scheduling, rescheduling, confirming, or canceling appointments. | |
4. Correction: The call was not connected to the intended party (e.g., it was a voicemail or a one-sided message). | |
Remember: | |
- Option 1 should only be selected if there was a live conversation with the intended contact. | |
- Option 4 should be selected if the call was not connected (e.g., it was a voicemail or no live interaction occurred). | |
- Option 4 if it is voicemail, make it option 4 | |
""" | |
# Home route to serve the index.html file from the root directory | |
def home(): | |
return send_file('index.html') | |
# API route to handle file upload, transcription, and model interaction | |
def generate_api(): | |
if request.method == "POST": | |
try: | |
# Check if an audio file was uploaded | |
if 'audio_file' not in request.files: | |
return jsonify({"error": "No audio file provided"}), 400 | |
audio_file = request.files['audio_file'] | |
if audio_file.filename == '': | |
return jsonify({"error": "No selected file"}), 400 | |
# Save the uploaded file to the server | |
file_path = os.path.join(app.config['UPLOAD_FOLDER'], audio_file.filename) | |
audio_file.save(file_path) | |
# Transcribe the audio using AssemblyAI | |
transcriber = aai.Transcriber() | |
transcript = transcriber.transcribe(file_path) | |
# Send transcription and instructions to Gemini model | |
model = ChatGoogleGenerativeAI(model="gemini-pro") | |
message = HumanMessage(content=f"{GEMINI_INSTRUCTIONS}\n\nCall Transcription: {transcript.text}") | |
response = model.stream([message]) | |
# Interpret the model's response to select the correct option | |
buffer = [] | |
for chunk in response: | |
buffer.append(chunk.content) | |
result_text = ''.join(buffer).lower() | |
# Adjusted logic to determine the correct option | |
if ("option 4" in result_text or "voicemail" in result_text or | |
"just wanted to reach out" in result_text or "thank you, bye" in result_text or | |
"this is" in result_text and "see if" in result_text and not "response" in result_text): | |
selected_option = 4 | |
elif "option 1" in result_text or "yes" in result_text or "vehicle needs" in result_text: | |
selected_option = 1 | |
elif "option 2" in result_text: | |
selected_option = 2 | |
elif "option 3" in result_text or "reschedule" in result_text or "confirm" in result_text or "cancel" in result_text: | |
selected_option = 3 | |
else: | |
selected_option = "Could not determine the correct option." | |
# Return the transcription and selected option | |
return jsonify({ | |
"transcription": transcript.text, | |
"selected_option": selected_option | |
}), 200 | |
except Exception as e: | |
return jsonify({"error": str(e)}) | |
# Route to serve static files | |
def serve_static(path): | |
return send_from_directory('.', path) | |
# Run the Flask application | |
if __name__ == '__main__': | |
app.run(debug=True) | |