feat: US-007 - Comandă Discord /voice engine

- Comandă nouă /voice engine <pockettts|supertonic> setează tts.default_engine în config, persistă via Config().set+save()
- Helper _default_voice_for_engine() confirmă vocea implicită a engine-ului ales (alba pentru pockettts, voice.default_voice pentru supertonic)
- Gates: pytest PASS (22 eșecuri preexistente neschimbate), review manual PASS, wiring comandă verificat izolat (fără restart pe bot-ul live)
This commit is contained in:
2026-07-11 10:31:38 +00:00
parent 7ede30d156
commit c7db236247

View File

@@ -100,6 +100,13 @@ def _get_default_voice() -> str:
return "M2"
def _default_voice_for_engine(engine: str) -> str:
"""Vocea implicită asociată engine-ului (nu vocea implicită globală per-guild)."""
if engine == "pockettts":
return "alba"
return _get_default_voice()
def register(tree: app_commands.CommandTree, bot: discord.Client) -> app_commands.Group:
"""Build the `/voice` slash command group and return it (caller registers)."""
voice_group = app_commands.Group(
@@ -285,6 +292,36 @@ def register(tree: app_commands.CommandTree, bot: discord.Client) -> app_command
msg = f"Default voce setată {new_voice}. Va intra în vigoare la următorul /voice join."
await interaction.followup.send(msg, ephemeral=True)
_ENGINE_CHOICES = [
app_commands.Choice(name="pocket-tts", value="pockettts"),
app_commands.Choice(name="Supertonic", value="supertonic"),
]
@voice_group.command(name="engine", description="Schimbă engine-ul TTS implicit (pockettts/supertonic)")
@app_commands.describe(engine="Engine TTS")
@app_commands.choices(engine=_ENGINE_CHOICES)
async def engine_cmd(
interaction: discord.Interaction,
engine: app_commands.Choice[str],
) -> None:
await interaction.response.defer(ephemeral=True)
new_engine = engine.value
try:
cfg = Config()
cfg.set("tts.default_engine", new_engine)
cfg.save()
except Exception as e:
log.warning("config save failed for tts.default_engine: %s", e)
await interaction.followup.send(
f"Eroare la salvarea engine-ului: {e}", ephemeral=True
)
return
default_voice = _default_voice_for_engine(new_engine)
await interaction.followup.send(
f"Engine TTS implicit setat pe **{new_engine}**. Voce implicită: {default_voice}.",
ephemeral=True,
)
@voice_group.command(name="stop", description="Oprește audio-ul curent (golește coada TTS)")
async def stop_audio(interaction: discord.Interaction) -> None:
await interaction.response.defer(ephemeral=True)