- Replace /jarvis and /sage command groups with /moltmic join|leave|status - Remove AgentVoiceConfig, AgentsConfig now just has default agent - Remove voice file checks from run.py (cloud TTS doesn't need them) - Remove agent-to-voice mapping in bot.py on_speech_complete - Rename from 'Jarvis Voice Bot' to 'MoltMic' throughout
103 lines
4.2 KiB
Python
103 lines
4.2 KiB
Python
"""Discord slash commands for MoltMic voice bot."""
|
|
|
|
from typing import Optional
|
|
|
|
import discord
|
|
from discord import app_commands
|
|
|
|
from utils.logging import get_logger
|
|
|
|
try:
|
|
from discord.ext import voice_recv
|
|
HAS_VOICE_RECV = True
|
|
except ImportError:
|
|
voice_recv = None
|
|
HAS_VOICE_RECV = False
|
|
|
|
logger = get_logger(__name__)
|
|
|
|
|
|
class MoltMicCommands(app_commands.Group):
|
|
"""Slash commands for MoltMic voice bot."""
|
|
|
|
def __init__(self, bot):
|
|
super().__init__(name="moltmic", description="MoltMic voice commands")
|
|
self.bot = bot
|
|
|
|
@app_commands.command(name="join", description="Join your voice channel and start listening")
|
|
@app_commands.describe(channel="Voice channel to join (defaults to your current channel)")
|
|
async def join(self, interaction: discord.Interaction, channel: Optional[discord.VoiceChannel] = None):
|
|
await interaction.response.defer(thinking=True)
|
|
|
|
try:
|
|
target = channel or (interaction.user.voice and interaction.user.voice.channel)
|
|
if not target:
|
|
await interaction.followup.send("❌ You're not in a voice channel.", ephemeral=True)
|
|
return
|
|
|
|
# Already in this channel?
|
|
if interaction.guild.voice_client and interaction.guild.voice_client.channel.id == target.id:
|
|
await interaction.followup.send(f"Already in {target.mention}", ephemeral=True)
|
|
return
|
|
|
|
# Move or connect
|
|
if interaction.guild.voice_client:
|
|
await interaction.guild.voice_client.move_to(target)
|
|
voice_client = interaction.guild.voice_client
|
|
else:
|
|
connect_cls = voice_recv.VoiceRecvClient if HAS_VOICE_RECV else discord.VoiceClient
|
|
voice_client = await target.connect(cls=connect_cls, self_deaf=False, timeout=60.0)
|
|
|
|
await self.bot.on_voice_join(interaction.guild, target, voice_client)
|
|
await interaction.followup.send(f"🎙️ Joined {target.mention} and listening...")
|
|
|
|
except discord.errors.ClientException as e:
|
|
logger.error(f"Failed to join: {e}")
|
|
await interaction.followup.send(f"❌ Failed to join: {e}", ephemeral=True)
|
|
except Exception as e:
|
|
logger.exception(f"Join error: {e}")
|
|
await interaction.followup.send("❌ Unexpected error", ephemeral=True)
|
|
|
|
@app_commands.command(name="leave", description="Leave the voice channel")
|
|
async def leave(self, interaction: discord.Interaction):
|
|
await interaction.response.defer(thinking=True)
|
|
|
|
try:
|
|
if not interaction.guild.voice_client:
|
|
await interaction.followup.send("❌ Not in a voice channel.", ephemeral=True)
|
|
return
|
|
|
|
await self.bot.on_voice_leave(interaction.guild)
|
|
await interaction.followup.send("👋 Left voice channel.")
|
|
|
|
except Exception as e:
|
|
logger.exception(f"Leave error: {e}")
|
|
await interaction.followup.send("❌ Error leaving.", ephemeral=True)
|
|
|
|
@app_commands.command(name="status", description="Show bot status")
|
|
async def status(self, interaction: discord.Interaction):
|
|
await interaction.response.defer(thinking=True)
|
|
|
|
try:
|
|
session = self.bot.session_manager.get_session(interaction.guild.id)
|
|
if not session:
|
|
await interaction.followup.send("❌ Not in a voice channel.", ephemeral=True)
|
|
return
|
|
|
|
embed = discord.Embed(title="🎙️ MoltMic Status", color=discord.Color.green())
|
|
embed.add_field(name="Channel", value=f"<#{session.channel_id}>", inline=True)
|
|
embed.add_field(name="Duration", value=f"{session.duration:.0f}s", inline=True)
|
|
embed.add_field(name="Users", value=str(session.get_user_count()), inline=True)
|
|
await interaction.followup.send(embed=embed)
|
|
|
|
except Exception as e:
|
|
logger.exception(f"Status error: {e}")
|
|
await interaction.followup.send("❌ Error.", ephemeral=True)
|
|
|
|
|
|
async def setup_commands(bot):
|
|
"""Register slash commands."""
|
|
cmds = MoltMicCommands(bot)
|
|
bot.tree.add_command(cmds)
|
|
logger.info("Slash commands registered (moltmic: join, leave, status)")
|
|
return cmds
|