fix(voice): switch to gemini-3.5-flash, async to_thread, and 20MB file limit handling
This commit is contained in:
parent
ed71b84427
commit
353c7f73b3
1 changed files with 49 additions and 26 deletions
|
|
@ -240,39 +240,41 @@ async def transcribe_audio(audio_path: str) -> str:
|
||||||
clean_path = tmp_wav
|
clean_path = tmp_wav
|
||||||
|
|
||||||
models_to_try = [
|
models_to_try = [
|
||||||
'gemini-2.5-flash',
|
'gemini-3.5-flash',
|
||||||
'gemini-flash-latest',
|
'gemini-3-flash-preview',
|
||||||
'gemini-2.5-flash-lite',
|
'gemini-2.0-flash',
|
||||||
'gemini-3.5-transcribe'
|
'gemini-1.5-flash'
|
||||||
]
|
]
|
||||||
|
|
||||||
for model_name in models_to_try:
|
def _sync_transcribe(clean_file_path: str, m_name: str) -> str:
|
||||||
|
audio_file = genai.upload_file(path=clean_file_path)
|
||||||
try:
|
try:
|
||||||
logger.info(f"🎙 [Gemini STT] Распознавание {clean_path} через {model_name}...")
|
|
||||||
audio_file = genai.upload_file(path=clean_path)
|
|
||||||
|
|
||||||
prompt = (
|
prompt = (
|
||||||
"Точно транскрибируй эту аудиозапись на русском языке в текст. "
|
"Точно транскрибируй эту аудиозапись на русском языке в текст. "
|
||||||
"Не добавляй никаких вводных слов, пояснений и комментариев, отдай исключительно чистый текст произнесенных слов."
|
"Не добавляй никаких вводных слов, пояснений и комментариев, отдай исключительно чистый текст произнесенных слов."
|
||||||
)
|
)
|
||||||
|
model = genai.GenerativeModel(m_name)
|
||||||
model = genai.GenerativeModel(model_name)
|
resp = model.generate_content([audio_file, prompt])
|
||||||
response = model.generate_content([audio_file, prompt])
|
return resp.text.strip() if resp and resp.text else ""
|
||||||
|
finally:
|
||||||
try:
|
try:
|
||||||
genai.delete_file(name=audio_file.name)
|
genai.delete_file(name=audio_file.name)
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if response and response.text and response.text.strip():
|
for model_name in models_to_try:
|
||||||
text = response.text.strip()
|
try:
|
||||||
|
logger.info(f"🎙 [Gemini STT] Распознавание {clean_path} через {model_name}...")
|
||||||
|
text = await asyncio.to_thread(_sync_transcribe, clean_path, model_name)
|
||||||
|
|
||||||
|
if text:
|
||||||
logger.info(f"🎯 [Gemini STT] Успешно распознано ({model_name}): {text[:70]}...")
|
logger.info(f"🎯 [Gemini STT] Успешно распознано ({model_name}): {text[:70]}...")
|
||||||
if tmp_wav and os.path.exists(tmp_wav):
|
if tmp_wav and os.path.exists(tmp_wav):
|
||||||
os.remove(tmp_wav)
|
os.remove(tmp_wav)
|
||||||
return text
|
return text
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"⚠️ [Gemini STT] Ошибка на модели {model_name}: {e}")
|
logger.warning(f"⚠️ [Gemini STT] Ошибка на модели {model_name}: {e}")
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(0.5)
|
||||||
|
|
||||||
if tmp_wav and os.path.exists(tmp_wav):
|
if tmp_wav and os.path.exists(tmp_wav):
|
||||||
os.remove(tmp_wav)
|
os.remove(tmp_wav)
|
||||||
|
|
@ -306,25 +308,34 @@ async def execute_antigravity_agent(user_text: str) -> str:
|
||||||
"Внутри него напиши короткую (1-3 предложения), емкую, теплую голосовую выжимку от Майи без Markdown и эмодзи, которая будет озвучена голосом Шаде."
|
"Внутри него напиши короткую (1-3 предложения), емкую, теплую голосовую выжимку от Майи без Markdown и эмодзи, которая будет озвучена голосом Шаде."
|
||||||
)
|
)
|
||||||
|
|
||||||
models_to_try = ['gemini-2.5-flash', 'gemini-flash-latest', 'gemini-2.5-flash-lite', 'gemini-3.7-flash', 'gemini-2.5-pro']
|
models_to_try = [
|
||||||
|
'gemini-3.5-flash',
|
||||||
|
'gemini-3-flash-preview',
|
||||||
|
'gemini-2.0-flash',
|
||||||
|
'gemini-1.5-flash'
|
||||||
|
]
|
||||||
last_error = None
|
last_error = None
|
||||||
|
|
||||||
for model_name in models_to_try:
|
def _sync_run_agent(m_name: str, u_text: str) -> str:
|
||||||
try:
|
|
||||||
logger.info(f"🚀 [Maya Agent] Запуск с моделью: {model_name}")
|
|
||||||
model = genai.GenerativeModel(
|
model = genai.GenerativeModel(
|
||||||
model_name=model_name,
|
model_name=m_name,
|
||||||
system_instruction=system_instruction,
|
system_instruction=system_instruction,
|
||||||
tools=[query_bitrix24, execute_bash_command, save_to_obsidian]
|
tools=[query_bitrix24, execute_bash_command, save_to_obsidian]
|
||||||
)
|
)
|
||||||
chat = model.start_chat(enable_automatic_function_calling=True)
|
chat = model.start_chat(enable_automatic_function_calling=True)
|
||||||
response = chat.send_message(user_text)
|
resp = chat.send_message(u_text)
|
||||||
if response and response.text:
|
return resp.text.strip() if resp and resp.text else ""
|
||||||
return response.text.strip()
|
|
||||||
|
for model_name in models_to_try:
|
||||||
|
try:
|
||||||
|
logger.info(f"🚀 [Maya Agent] Запуск с моделью: {model_name}")
|
||||||
|
response_text = await asyncio.to_thread(_sync_run_agent, model_name, user_text)
|
||||||
|
if response_text:
|
||||||
|
return response_text
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warning(f"⚠️ [Maya Agent] Сбой на модели {model_name}: {e}")
|
logger.warning(f"⚠️ [Maya Agent] Сбой на модели {model_name}: {e}")
|
||||||
last_error = e
|
last_error = e
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(0.5)
|
||||||
|
|
||||||
return f"❌ Ошибка исполнения Maya Agent: {last_error}"
|
return f"❌ Ошибка исполнения Maya Agent: {last_error}"
|
||||||
|
|
||||||
|
|
@ -370,6 +381,18 @@ async def handle_voice_message(message: Message, bot: Bot):
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
target_obj = message.voice or message.video_note or message.audio or message.document
|
||||||
|
file_size = getattr(target_obj, "file_size", 0) or 0
|
||||||
|
if file_size > 20 * 1024 * 1024:
|
||||||
|
size_mb = round(file_size / (1024 * 1024), 1)
|
||||||
|
await message.reply(
|
||||||
|
f"⚠️ <b>Файл слишком большой ({size_mb} МБ).</b>\n\n"
|
||||||
|
"Telegram Bot API жестко ограничивает скачивание ботами файлов размером до 20 МБ.\n"
|
||||||
|
"💡 <b>Решение:</b> Сконвертируй запись диктофона в AAC/M4A/MP3 с более низким битрейтом (например, 64 kbps mono) или надиктуй голосовыми сообщениями прямо в чат!",
|
||||||
|
parse_mode="HTML"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
status_msg = await message.reply("🎙 <i>Слушаю и выполняю команду...</i>", parse_mode="HTML")
|
status_msg = await message.reply("🎙 <i>Слушаю и выполняю команду...</i>", parse_mode="HTML")
|
||||||
await bot.send_chat_action(message.chat.id, "typing")
|
await bot.send_chat_action(message.chat.id, "typing")
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue