agent-discord-rs 0.2.7

A high-performance Discord Bot daemon supporting multiple AI agents (pi, opencode).
use async_trait::async_trait;
use serenity::all::{CommandInteraction, Context, CreateCommand, CreateCommandOption};

use crate::i18n::I18n;

pub mod abort;
pub mod agent;
pub mod clear;
pub mod compact;
pub mod config;
pub mod cron;
pub mod language;
pub mod mention_only;
pub mod model;
pub mod skill;
pub mod thinking;

#[async_trait]
pub trait SlashCommand: Send + Sync {
    fn name(&self) -> &'static str;
    fn description(&self, i18n: &I18n) -> String;
    fn options(&self, _i18n: &I18n) -> Vec<CreateCommandOption> {
        vec![]
    }

    fn create_command(&self, i18n: &I18n) -> CreateCommand {
        let mut cmd = CreateCommand::new(self.name()).description(self.description(i18n));
        for opt in self.options(i18n) {
            cmd = cmd.add_option(opt);
        }
        cmd
    }

    async fn execute(
        &self,
        ctx: &Context,
        command: &CommandInteraction,
        state: &crate::AppState,
    ) -> anyhow::Result<()>;
}

pub fn get_all_commands() -> Vec<Box<dyn SlashCommand>> {
    vec![
        Box::new(agent::AgentCommand),
        Box::new(model::ModelCommand),
        Box::new(thinking::ThinkingCommand),
        Box::new(compact::CompactCommand),
        Box::new(config::ConfigCommand),
        Box::new(clear::ClearCommand),
        Box::new(abort::AbortCommand),
        Box::new(skill::SkillCommand),
        Box::new(mention_only::MentionOnlyCommand),
        Box::new(language::LanguageCommand),
        Box::new(cron::CronCommand),
        Box::new(cron::CronListCommand),
    ]
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_all_commands_have_name_desc_and_buildable_options() {
        let i18n = crate::i18n::I18n::new("en");
        for cmd in get_all_commands() {
            let name = cmd.name();
            assert!(!name.trim().is_empty());
            let desc = cmd.description(&i18n);
            assert!(!desc.trim().is_empty());
            let _opts = cmd.options(&i18n);
            let _create = cmd.create_command(&i18n);
        }
    }
}