diff --git a/src/adapters/discord_bot.py b/src/adapters/discord_bot.py index 3f69318..e6f6842 100644 --- a/src/adapters/discord_bot.py +++ b/src/adapters/discord_bot.py @@ -909,6 +909,51 @@ def create_bot(config: Config) -> discord.Client: f"Error reading logs: {e}", ephemeral=True ) + @tree.command(name="audio", description="TTS: convertește text sau URL în voice note") + @app_commands.describe( + voce="Voce (M1-M5 masculin, F1-F5 feminin; default M2)", + text_sau_url="Text direct, URL articol, sau gol pentru ultimul răspuns Echo", + ) + @app_commands.choices( + voce=[ + app_commands.Choice(name="M1 — Masculin 1", value="M1"), + app_commands.Choice(name="M2 — Masculin 2 (default)", value="M2"), + app_commands.Choice(name="M3 — Masculin 3", value="M3"), + app_commands.Choice(name="M4 — Masculin 4", value="M4"), + app_commands.Choice(name="M5 — Masculin 5", value="M5"), + app_commands.Choice(name="F1 — Feminin 1", value="F1"), + app_commands.Choice(name="F2 — Feminin 2", value="F2"), + app_commands.Choice(name="F3 — Feminin 3", value="F3"), + app_commands.Choice(name="F4 — Feminin 4", value="F4"), + app_commands.Choice(name="F5 — Feminin 5", value="F5"), + ] + ) + async def audio_cmd( + interaction: discord.Interaction, + voce: str | None = None, + text_sau_url: str | None = None, + ) -> None: + await interaction.response.defer() + args: list[str] = [] + if voce: + args.append(voce) + if text_sau_url: + args.extend(text_sau_url.split()) + result = await asyncio.to_thread(fast_dispatch, "audio", args) + if result and result.startswith("__AUDIO__:"): + wav_path = result[len("__AUDIO__:"):] + try: + await interaction.followup.send( + file=discord.File(wav_path, filename="echo-audio.wav") + ) + finally: + try: + os.unlink(wav_path) + except OSError: + pass + else: + await interaction.followup.send(result or "Eroare TTS.") + # --- Ralph commands (autonomous project execution) --- async def _autocomplete_by_status(