aboutsummaryrefslogtreecommitdiffstats
path: root/src/commands/ai.rs
blob: a75f1649e8ba44e8af8e647d74e33a3d0e2ea2ab (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
use crate::Data;
use crate::error::Error;
use crate::lang;

type Context<'a> = poise::Context<'a, Data, Error>;

/// Query the AI senator via OpenRouter
#[poise::command(slash_command)]
pub async fn senator(
    ctx: Context<'_>,
    #[description = "Wiadomość do wysłania"] text: String,
    #[description = "Przemówić w kanale głosowym?"] tts_vc: Option<bool>,
) -> crate::error::Result<()> {
    ctx.defer().await?;

    let api_key = ctx
        .data()
        .config
        .openrouter_api_key
        .as_ref()
        .ok_or_else(|| Error::Custom(lang::L_OPENROUTER_NO_KEY.into()))?;
    let model = ctx
        .data()
        .config
        .openrouter_model
        .as_deref()
        .unwrap_or("cognitivecomputations/dolphin-mistral-24b-venice-edition:free");

    let client = crate::openrouter::OpenRouterClient::new(api_key.clone(), model.to_string());
    let response = client.chat(lang::SENATOR_SYSTEM_PROMPT, &text).await?;

    if tts_vc.unwrap_or(false) {
        let guild_id = ctx.guild_id().ok_or_else(|| lang::err_not_in_guild())?;
        let channel_id = ctx
            .serenity_context()
            .cache
            .guild(guild_id)
            .and_then(|g| {
                g.voice_states
                    .get(&ctx.author().id)
                    .and_then(|vs| vs.channel_id)
            })
            .ok_or_else(|| lang::err_not_in_voice())?;

        let tts_url = format!(
            "https://translate.google.com/translate_tts?ie=UTF-8&q={}&tl=pl&client=tw-ob",
            crate::commands::tts::urlencoding(&response)
        );
        let audio_data = ctx
            .data()
            .http_client
            .get(&tts_url)
            .send()
            .await?
            .bytes()
            .await?;

        let call = ctx
            .data()
            .voice_manager
            .connect(guild_id, channel_id)
            .await?;
        let input = crate::voice::decode_audio(&audio_data)?;
        let mut call_lock = call.lock().await;
        if call_lock.current_channel().is_some() {
            call_lock.play_input(input);
        }
    }

    ctx.say(response).await?;
    Ok(())
}

pub fn commands() -> Vec<poise::Command<Data, Error>> {
    vec![senator()]
}