diff options
Diffstat (limited to '')
| -rw-r--r-- | src/commands/ai.rs | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/src/commands/ai.rs b/src/commands/ai.rs new file mode 100644 index 0000000..a75f164 --- /dev/null +++ b/src/commands/ai.rs | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | use crate::Data; | ||
| 2 | use crate::error::Error; | ||
| 3 | use crate::lang; | ||
| 4 | |||
| 5 | type Context<'a> = poise::Context<'a, Data, Error>; | ||
| 6 | |||
| 7 | /// Query the AI senator via OpenRouter | ||
| 8 | #[poise::command(slash_command)] | ||
| 9 | pub async fn senator( | ||
| 10 | ctx: Context<'_>, | ||
| 11 | #[description = "Wiadomość do wysłania"] text: String, | ||
| 12 | #[description = "Przemówić w kanale głosowym?"] tts_vc: Option<bool>, | ||
| 13 | ) -> crate::error::Result<()> { | ||
| 14 | ctx.defer().await?; | ||
| 15 | |||
| 16 | let api_key = ctx | ||
| 17 | .data() | ||
| 18 | .config | ||
| 19 | .openrouter_api_key | ||
| 20 | .as_ref() | ||
| 21 | .ok_or_else(|| Error::Custom(lang::L_OPENROUTER_NO_KEY.into()))?; | ||
| 22 | let model = ctx | ||
| 23 | .data() | ||
| 24 | .config | ||
| 25 | .openrouter_model | ||
| 26 | .as_deref() | ||
| 27 | .unwrap_or("cognitivecomputations/dolphin-mistral-24b-venice-edition:free"); | ||
| 28 | |||
| 29 | let client = crate::openrouter::OpenRouterClient::new(api_key.clone(), model.to_string()); | ||
| 30 | let response = client.chat(lang::SENATOR_SYSTEM_PROMPT, &text).await?; | ||
| 31 | |||
| 32 | if tts_vc.unwrap_or(false) { | ||
| 33 | let guild_id = ctx.guild_id().ok_or_else(|| lang::err_not_in_guild())?; | ||
| 34 | let channel_id = ctx | ||
| 35 | .serenity_context() | ||
| 36 | .cache | ||
| 37 | .guild(guild_id) | ||
| 38 | .and_then(|g| { | ||
| 39 | g.voice_states | ||
| 40 | .get(&ctx.author().id) | ||
| 41 | .and_then(|vs| vs.channel_id) | ||
| 42 | }) | ||
| 43 | .ok_or_else(|| lang::err_not_in_voice())?; | ||
| 44 | |||
| 45 | let tts_url = format!( | ||
| 46 | "https://translate.google.com/translate_tts?ie=UTF-8&q={}&tl=pl&client=tw-ob", | ||
| 47 | crate::commands::tts::urlencoding(&response) | ||
| 48 | ); | ||
| 49 | let audio_data = ctx | ||
| 50 | .data() | ||
| 51 | .http_client | ||
| 52 | .get(&tts_url) | ||
| 53 | .send() | ||
| 54 | .await? | ||
| 55 | .bytes() | ||
| 56 | .await?; | ||
| 57 | |||
| 58 | let call = ctx | ||
| 59 | .data() | ||
| 60 | .voice_manager | ||
| 61 | .connect(guild_id, channel_id) | ||
| 62 | .await?; | ||
| 63 | let input = crate::voice::decode_audio(&audio_data)?; | ||
| 64 | let mut call_lock = call.lock().await; | ||
| 65 | if call_lock.current_channel().is_some() { | ||
| 66 | call_lock.play_input(input); | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | ctx.say(response).await?; | ||
| 71 | Ok(()) | ||
| 72 | } | ||
| 73 | |||
| 74 | pub fn commands() -> Vec<poise::Command<Data, Error>> { | ||
| 75 | vec![senator()] | ||
| 76 | } | ||
