alive-ai 0.1.8 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/core/message_handler.py +6 -1
- package/input/telegram/listener.py +21 -6
- package/output/voice/gtts_tts.py +17 -4
- package/package.json +1 -1
- package/pyproject.toml +1 -1
package/core/message_handler.py
CHANGED
|
@@ -1102,7 +1102,12 @@ async def _send_response(self, response, emotion, chat_id, text, user_id="defaul
|
|
|
1102
1102
|
await self.nervous.emit("chat_action_voice", {})
|
|
1103
1103
|
vp = await self._voice.generate(response, mood=mood)
|
|
1104
1104
|
if vp:
|
|
1105
|
-
await self.nervous.emit("send_voice_file", {
|
|
1105
|
+
await self.nervous.emit("send_voice_file", {
|
|
1106
|
+
"file_path": vp,
|
|
1107
|
+
"chat_id": chat_id,
|
|
1108
|
+
"fallback_text": response,
|
|
1109
|
+
"mood": mood,
|
|
1110
|
+
})
|
|
1106
1111
|
return
|
|
1107
1112
|
await self.nervous.emit("send_text", {"text": response, "mood": mood, "chat_id": chat_id})
|
|
1108
1113
|
|
|
@@ -359,12 +359,13 @@ class TelegramListener:
|
|
|
359
359
|
print(f"[Telegram] Send text error: {e}")
|
|
360
360
|
|
|
361
361
|
async def _send_voice_file(self, data: dict):
|
|
362
|
-
"""Send voice file
|
|
362
|
+
"""Send voice file, falling back to audio/text if Telegram rejects it."""
|
|
363
363
|
if not self.app:
|
|
364
364
|
return
|
|
365
365
|
|
|
366
366
|
chat_id = data.get("chat_id", self.chat_id)
|
|
367
367
|
file_path = data.get("file_path", "")
|
|
368
|
+
fallback_text = data.get("fallback_text", "")
|
|
368
369
|
|
|
369
370
|
if not chat_id or not file_path:
|
|
370
371
|
return
|
|
@@ -372,18 +373,32 @@ class TelegramListener:
|
|
|
372
373
|
path = Path(file_path)
|
|
373
374
|
if not path.exists():
|
|
374
375
|
print(f"[Telegram] Voice file not found: {file_path}")
|
|
376
|
+
if fallback_text:
|
|
377
|
+
await self._send_text({"chat_id": chat_id, "text": fallback_text})
|
|
375
378
|
return
|
|
376
379
|
|
|
377
380
|
try:
|
|
378
|
-
|
|
379
|
-
|
|
381
|
+
if path.suffix.lower() == ".ogg":
|
|
382
|
+
with open(path, "rb") as voice_file:
|
|
383
|
+
await self.app.bot.send_voice(
|
|
384
|
+
chat_id=chat_id,
|
|
385
|
+
voice=voice_file,
|
|
386
|
+
caption=data.get("caption", "")
|
|
387
|
+
)
|
|
388
|
+
print(f"[Telegram] Sent voice: {file_path}")
|
|
389
|
+
return
|
|
390
|
+
|
|
391
|
+
with open(path, "rb") as audio_file:
|
|
392
|
+
await self.app.bot.send_audio(
|
|
380
393
|
chat_id=chat_id,
|
|
381
|
-
|
|
394
|
+
audio=audio_file,
|
|
382
395
|
caption=data.get("caption", "")
|
|
383
396
|
)
|
|
384
|
-
print(f"[Telegram] Sent
|
|
397
|
+
print(f"[Telegram] Sent audio fallback: {file_path}")
|
|
385
398
|
except Exception as e:
|
|
386
|
-
print(f"[Telegram] Send voice error: {e}")
|
|
399
|
+
print(f"[Telegram] Send voice/audio error: {e}")
|
|
400
|
+
if fallback_text:
|
|
401
|
+
await self._send_text({"chat_id": chat_id, "text": fallback_text})
|
|
387
402
|
|
|
388
403
|
async def _send_image(self, data: dict):
|
|
389
404
|
"""Send image file"""
|
package/output/voice/gtts_tts.py
CHANGED
|
@@ -8,6 +8,7 @@ import asyncio
|
|
|
8
8
|
import re
|
|
9
9
|
import tempfile
|
|
10
10
|
import subprocess
|
|
11
|
+
import warnings
|
|
11
12
|
from pathlib import Path
|
|
12
13
|
from typing import Optional
|
|
13
14
|
from concurrent.futures import ThreadPoolExecutor
|
|
@@ -113,17 +114,29 @@ class GTTS:
|
|
|
113
114
|
tts.write_to_fp(mp3_buffer)
|
|
114
115
|
mp3_buffer.seek(0)
|
|
115
116
|
|
|
116
|
-
# Convert MP3 to OGG for Telegram
|
|
117
|
-
#
|
|
117
|
+
# Convert MP3 to OGG Opus for Telegram voice notes.
|
|
118
|
+
# pydub's default OGG codec can resolve to Vorbis, which Telegram
|
|
119
|
+
# does not want for voice notes and some ffmpeg builds do not ship.
|
|
118
120
|
try:
|
|
121
|
+
warnings.filterwarnings("ignore", category=SyntaxWarning, module=r"pydub\..*")
|
|
119
122
|
from pydub import AudioSegment
|
|
120
123
|
audio = AudioSegment.from_mp3(mp3_buffer)
|
|
121
124
|
ogg_buffer = io.BytesIO()
|
|
122
|
-
audio.export(
|
|
125
|
+
audio.export(
|
|
126
|
+
ogg_buffer,
|
|
127
|
+
format="ogg",
|
|
128
|
+
codec="libopus",
|
|
129
|
+
bitrate="32k",
|
|
130
|
+
parameters=["-application", "voip"],
|
|
131
|
+
)
|
|
123
132
|
ogg_buffer.seek(0)
|
|
124
133
|
return ogg_buffer.read()
|
|
125
134
|
except ImportError:
|
|
126
|
-
# No pydub - return MP3
|
|
135
|
+
# No pydub - return MP3 and let the sender use send_audio.
|
|
136
|
+
mp3_buffer.seek(0)
|
|
137
|
+
return mp3_buffer.read()
|
|
138
|
+
except Exception as exc:
|
|
139
|
+
print(f"[GTTS] OGG Opus conversion failed, falling back to MP3: {exc}")
|
|
127
140
|
mp3_buffer.seek(0)
|
|
128
141
|
return mp3_buffer.read()
|
|
129
142
|
|
package/package.json
CHANGED