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:
+45
-9
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user