"""Speech commands: text-to-speech and the voice catalog.""" from __future__ import annotations from typing import TYPE_CHECKING from discord.ext import commands from vibe_bot.commands._state import require_app, set_app from vibe_bot.config import VOICES_LIST from vibe_bot.textutil import split_message if TYPE_CHECKING: from discord.ext.commands import Bot from discord.ext.commands import Context as CommandsContext from vibe_bot.app import App def register(bot: commands.Bot, app: App) -> None: """Register the speech commands.""" set_app(app) bot.command(name="speak")(speak) bot.command(name="voices")(voices) async def voices(ctx: CommandsContext[Bot]) -> None: """List all available TTS voices organized by category.""" voice_list = "Available Voices:\n\n" for category, info in VOICES_LIST.items(): voice_list += f"{category} ({info['language']}):\n" for v in info["voices"]: voice_list += f"- {v}\n" voice_list += "\n" voice_list += "Use `!speak --voice ` to choose a voice." for chunk in split_message(voice_list): await ctx.send(chunk) @commands.cooldown(rate=3, per=30, type=commands.BucketType.user) async def speak( ctx: CommandsContext[Bot], *, message: str, ) -> None: """Have the bot speak the given text using Kokoro TTS, or have a custom bot speak. Usage: !speak --voice - plain text to speech Usage: !speak --voice - have a custom bot respond and speak Example: !speak hello world Example: !speak hello world --voice af_bella Example: !speak alfred what time is it --voice am_puck """ app = require_app() await app.speech.speak(ctx, message=message)