aboutsummaryrefslogtreecommitdiffstats
path: root/src/commands/ai.rs
diff options
context:
space:
mode:
authorsalmonik <raisersoft@proton.me>2026-07-08 02:13:35 +0200
committersalmonik <raisersoft@proton.me>2026-07-08 02:13:35 +0200
commitcd8ed8bc5793985df2c1692072a932ceee517b95 (patch)
tree42d18a4140259b5c68b4dd05b7fcb398f78b8d7f /src/commands/ai.rs
parentMerge pull request 'Voice related fixes, alongside simplifying assistant' (#5... (diff)
downloadsenator-sperma-cd8ed8bc5793985df2c1692072a932ceee517b95.tar.gz
senator-sperma-cd8ed8bc5793985df2c1692072a932ceee517b95.zip
OPEN THE RUST GATES
Signed-off-by: salmonik <raisersoft@proton.me>
Diffstat (limited to 'src/commands/ai.rs')
-rw-r--r--src/commands/ai.rs76
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 @@
1use crate::Data;
2use crate::error::Error;
3use crate::lang;
4
5type Context<'a> = poise::Context<'a, Data, Error>;
6
7/// Query the AI senator via OpenRouter
8#[poise::command(slash_command)]
9pub 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
74pub fn commands() -> Vec<poise::Command<Data, Error>> {
75 vec![senator()]
76}