fix(voice): transcribe audio using the user's preferred language

Voice notes were always recognized with a hardcoded English locale,
which broke transcription for non-English speakers. The handler now
maps the profile's `preferred_language` to a BCP-47 code and passes it
to the Google recognizer, falling back to `pt-BR`.

Also neutralizes the persona prompt so it follows the selected
language instead of forcing Brazilian Portuguese and a fixed gender,
and resets the default `preferred_language` to `pt`.
This commit is contained in:
2026-10-26 15:51:52 -03:00
parent d7f252034e
commit 854348ebeb
4 changed files with 96 additions and 10 deletions
+45 -9
View File
@@ -1418,7 +1418,7 @@ def load_user_profile() -> Dict[str, Any]:
"age": "",
"gender": "",
"location": "",
"preferred_language": "english",
"preferred_language": "pt",
"interests": [],
"personality_traits": [],
"preferences": {
@@ -2711,8 +2711,8 @@ class AIProvider:
# ===================== AGENT PERSONA =====================
PSAGENTAI_SYSTEM_PROMPT_BASE = """You are {agent_name}, a caring, attentive and engaging AI companion.
You communicate in Brazilian Portuguese naturally, like a real person.
You are feminine, warm, intelligent and have your own personality.
You communicate naturally in the user's preferred language, like a real person.
You are warm, intelligent and have your own personality.
You genuinely care about the user's well-being and happiness.
You can be affectionate, playful, sexy and intimate depending on the context.
You keep the conversation flowing, show empathy and demonstrate real interest in the user's life.
@@ -5429,16 +5429,17 @@ async def download_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
await _send_workspace_file(update, context, rel_path)
async def _transcribe_voice_file(ogg_path: str) -> Optional[str]:
async def _transcribe_voice_file(ogg_path: str, language: str = "pt-BR") -> Optional[str]:
"""Convert an OGG voice note to WAV and transcribe it.
Uses pydub for format conversion and speech_recognition with
Google's recognizer (en-US) for STT. The recognizer runs in a
Google's recognizer for speech-to-text. The recognizer runs in a
worker thread to avoid blocking the event loop. Both temp files
are deleted afterwards.
Args:
ogg_path: Path to the downloaded OGG file.
language: BCP-47 language code for transcription (default: pt-BR).
Returns:
Transcribed text, or None on any conversion/recognition failure.
@@ -5455,13 +5456,13 @@ async def _transcribe_voice_file(ogg_path: str) -> Optional[str]:
"""Synchronous speech-to-text worker (run via asyncio.to_thread).
Returns:
Recognized English text from the WAV file.
Recognized text from the WAV file in the requested language.
"""
import speech_recognition as sr
r = sr.Recognizer()
with sr.AudioFile(wav_path) as source:
audio_data = r.record(source)
return r.recognize_google(audio_data, language="en-US")
return r.recognize_google(audio_data, language=language)
try:
text = await asyncio.to_thread(_recognize)
@@ -5502,6 +5503,40 @@ async def voice_message_handler(update: Update, context: ContextTypes.DEFAULT_TY
print("[VOICE] received voice message")
await update.message.reply_text("🎤 I received your audio, processing...")
# Use the user's preferred language for transcription if configured.
profile = load_user_profile()
preferred_lang = profile.get("preferred_language", "pt")
speech_lang = {
"pt": "pt-BR",
"en": "en-US",
"es": "es-ES",
"fr": "fr-FR",
"de": "de-DE",
"it": "it-IT",
"ja": "ja-JP",
"ko": "ko-KR",
"zh": "zh-CN",
"ar": "ar-SA",
"hi": "hi-IN",
"ru": "ru-RU",
"nl": "nl-NL",
"pl": "pl-PL",
"tr": "tr-TR",
"sv": "sv-SE",
"no": "nb-NO",
"da": "da-DK",
"fi": "fi-FI",
"el": "el-GR",
"he": "he-IL",
"th": "th-TH",
"vi": "vi-VN",
"id": "id-ID",
"cs": "cs-CZ",
"ro": "ro-RO",
"hu": "hu-HU",
"uk": "uk-UA",
}.get(preferred_lang, "pt-BR")
# Download OGG to /tmp; transcription cleans it up afterwards.
try:
file = await context.bot.get_file(voice.file_id)
@@ -5513,7 +5548,7 @@ async def voice_message_handler(update: Update, context: ContextTypes.DEFAULT_TY
await update.message.reply_text("Error downloading audio. Try again.")
return
text = await _transcribe_voice_file(ogg_path)
text = await _transcribe_voice_file(ogg_path, language=speech_lang)
print("[VOICE] transcription result:", repr(text))
if text:
@@ -5756,7 +5791,7 @@ Examples:
━━━━━━━━━━━━━━━━━━━━━━
🔟 UTILITIES
━━━━━━━━━━━━━━━━━━━━━━
━━━━━━━━━━━━━━━━━━━━━━━
• /debug - Shows system debug information
• /reload - Reload .env settings without restarting
• /updatesystem - Force analysis and application of auto improvements
@@ -5764,6 +5799,7 @@ Examples:
• /viewai - Shows current AI configuration
• /about - Displays system information, version, author and license
• /help - Shows this message with all commands
• /lang <code> - Set the preferred conversation language (e.g., /lang pt)
━━━━━━━━━━━━━━━━━━━━━━
💡 IMPORTANT TIPS