Update app.py
Browse files
app.py
CHANGED
@@ -31,10 +31,11 @@ When you respond:
|
|
31 |
- Keep the user engaged and offer follow-up questions or related topics where appropriate.
|
32 |
- Ensure your responses are suitable for text-to-speech conversion.
|
33 |
- Provide factual and accurate information.
|
|
|
|
|
34 |
"""
|
35 |
|
36 |
genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
|
37 |
-
# Initialize the model with the system instruction
|
38 |
model = genai.GenerativeModel(
|
39 |
'gemini-2.5-flash',
|
40 |
system_instruction=system_instruction_text
|
@@ -47,6 +48,27 @@ def convert_markdown_to_html(text):
|
|
47 |
html = re.sub(r'\*(.*?)\*', r'<em>\1</em>', html)
|
48 |
return html
|
49 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
50 |
@app.route('/chat', methods=['POST'])
|
51 |
def chat():
|
52 |
try:
|
@@ -56,13 +78,30 @@ def chat():
|
|
56 |
if not user_message:
|
57 |
return jsonify({"error": "No message provided"}), 400
|
58 |
|
|
|
|
|
|
|
59 |
response = model.generate_content(user_message)
|
60 |
plain_text_response = response.text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
html_response = convert_markdown_to_html(plain_text_response)
|
62 |
|
63 |
return jsonify({
|
64 |
"response_html": html_response,
|
65 |
-
"response_text": plain_text_response
|
|
|
66 |
})
|
67 |
|
68 |
except Exception as e:
|
@@ -82,7 +121,7 @@ def generate_audio():
|
|
82 |
cleaned_text = re.sub(r'\s+', ' ', cleaned_text).strip()
|
83 |
|
84 |
if not cleaned_text:
|
85 |
-
return jsonify({"error": "Text became empty after cleaning
|
86 |
|
87 |
filename = f"{uuid.uuid4()}.mp3"
|
88 |
filepath = os.path.join(AUDIO_FOLDER, filename)
|
@@ -90,13 +129,17 @@ def generate_audio():
|
|
90 |
tts = gTTS(text=cleaned_text, lang='en', slow=False)
|
91 |
tts.save(filepath)
|
92 |
|
93 |
-
audio_url = f"/{
|
94 |
return jsonify({"audio_url": audio_url})
|
95 |
|
96 |
except Exception as e:
|
97 |
app.logger.error(f"Audio Generation Error: {e}")
|
98 |
return jsonify({"error": str(e)}), 500
|
99 |
|
|
|
|
|
|
|
|
|
100 |
@app.route('/')
|
101 |
def serve_index():
|
102 |
return send_from_directory('static', 'index.html')
|
|
|
31 |
- Keep the user engaged and offer follow-up questions or related topics where appropriate.
|
32 |
- Ensure your responses are suitable for text-to-speech conversion.
|
33 |
- Provide factual and accurate information.
|
34 |
+
- If the user asks for audio or to speak the response, include π at the start of your response.
|
35 |
+
- For coding questions, provide well-formatted code blocks with syntax highlighting.
|
36 |
"""
|
37 |
|
38 |
genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
|
|
|
39 |
model = genai.GenerativeModel(
|
40 |
'gemini-2.5-flash',
|
41 |
system_instruction=system_instruction_text
|
|
|
48 |
html = re.sub(r'\*(.*?)\*', r'<em>\1</em>', html)
|
49 |
return html
|
50 |
|
51 |
+
def detect_audio_request(text):
|
52 |
+
"""Detect if user is requesting audio"""
|
53 |
+
audio_keywords = ['audio', 'speak', 'say it', 'read aloud', 'hear', 'listen']
|
54 |
+
return any(keyword in text.lower() for keyword in audio_keywords)
|
55 |
+
|
56 |
+
def generate_audio_file(text):
|
57 |
+
"""Generate audio file from text and return filename"""
|
58 |
+
cleaned_text = re.sub(r'[\*_`#]', '', text)
|
59 |
+
cleaned_text = re.sub(r'\s+', ' ', cleaned_text).strip()
|
60 |
+
|
61 |
+
if not cleaned_text:
|
62 |
+
return None
|
63 |
+
|
64 |
+
filename = f"{uuid.uuid4()}.mp3"
|
65 |
+
filepath = os.path.join(AUDIO_FOLDER, filename)
|
66 |
+
|
67 |
+
tts = gTTS(text=cleaned_text, lang='en', slow=False)
|
68 |
+
tts.save(filepath)
|
69 |
+
|
70 |
+
return filename
|
71 |
+
|
72 |
@app.route('/chat', methods=['POST'])
|
73 |
def chat():
|
74 |
try:
|
|
|
78 |
if not user_message:
|
79 |
return jsonify({"error": "No message provided"}), 400
|
80 |
|
81 |
+
# Detect if user is requesting audio
|
82 |
+
audio_requested = detect_audio_request(user_message)
|
83 |
+
|
84 |
response = model.generate_content(user_message)
|
85 |
plain_text_response = response.text
|
86 |
+
|
87 |
+
# Generate audio if requested
|
88 |
+
audio_url = None
|
89 |
+
if audio_requested:
|
90 |
+
# Add audio indicator if not already present
|
91 |
+
if not plain_text_response.startswith("π"):
|
92 |
+
plain_text_response = "π " + plain_text_response
|
93 |
+
|
94 |
+
# Generate audio file
|
95 |
+
audio_filename = generate_audio_file(plain_text_response)
|
96 |
+
if audio_filename:
|
97 |
+
audio_url = f"/static/audio/{audio_filename}"
|
98 |
+
|
99 |
html_response = convert_markdown_to_html(plain_text_response)
|
100 |
|
101 |
return jsonify({
|
102 |
"response_html": html_response,
|
103 |
+
"response_text": plain_text_response,
|
104 |
+
"audio_url": audio_url
|
105 |
})
|
106 |
|
107 |
except Exception as e:
|
|
|
121 |
cleaned_text = re.sub(r'\s+', ' ', cleaned_text).strip()
|
122 |
|
123 |
if not cleaned_text:
|
124 |
+
return jsonify({"error": "Text became empty after cleaning"}), 400
|
125 |
|
126 |
filename = f"{uuid.uuid4()}.mp3"
|
127 |
filepath = os.path.join(AUDIO_FOLDER, filename)
|
|
|
129 |
tts = gTTS(text=cleaned_text, lang='en', slow=False)
|
130 |
tts.save(filepath)
|
131 |
|
132 |
+
audio_url = f"/static/audio/{filename}"
|
133 |
return jsonify({"audio_url": audio_url})
|
134 |
|
135 |
except Exception as e:
|
136 |
app.logger.error(f"Audio Generation Error: {e}")
|
137 |
return jsonify({"error": str(e)}), 500
|
138 |
|
139 |
+
@app.route('/static/audio/<filename>')
|
140 |
+
def serve_audio(filename):
|
141 |
+
return send_from_directory(AUDIO_FOLDER, filename)
|
142 |
+
|
143 |
@app.route('/')
|
144 |
def serve_index():
|
145 |
return send_from_directory('static', 'index.html')
|