Add AI-generated sassy commentary
This commit is contained in:
parent
1342253a76
commit
9242d39f98
4 changed files with 89 additions and 7 deletions
|
@ -10,6 +10,7 @@ poise = "0.5.2"
|
||||||
tracing = "0.1.37"
|
tracing = "0.1.37"
|
||||||
tracing-subscriber = "0.3.16"
|
tracing-subscriber = "0.3.16"
|
||||||
tracing-futures = "0.2.5"
|
tracing-futures = "0.2.5"
|
||||||
|
openai = "1.0.0-alpha.5"
|
||||||
|
|
||||||
[dependencies.songbird]
|
[dependencies.songbird]
|
||||||
version = "0.3.0"
|
version = "0.3.0"
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
use anyhow::{Context, Result};
|
use anyhow::{Context, Result};
|
||||||
use poise::serenity_prelude::{EmbedMessageBuilding, MessageBuilder};
|
use poise::serenity_prelude::{EmbedMessageBuilding, MessageBuilder};
|
||||||
use songbird::create_player;
|
use songbird::create_player;
|
||||||
use tracing::debug;
|
use tracing::{debug, log::warn};
|
||||||
|
|
||||||
use crate::{CommandContext, Error};
|
use crate::{openai, CommandContext, Error};
|
||||||
|
|
||||||
#[poise::command(slash_command)]
|
#[poise::command(slash_command)]
|
||||||
pub async fn join(ctx: CommandContext<'_>) -> Result<(), Error> {
|
pub async fn join(ctx: CommandContext<'_>) -> Result<(), Error> {
|
||||||
|
@ -91,11 +91,22 @@ pub async fn play(
|
||||||
.title
|
.title
|
||||||
.clone()
|
.clone()
|
||||||
.unwrap_or(String::from("This video"));
|
.unwrap_or(String::from("This video"));
|
||||||
let msg = MessageBuilder::new()
|
|
||||||
.push("Now playing: ")
|
let mut msg = MessageBuilder::new();
|
||||||
.push_named_link(title, url)
|
|
||||||
.build();
|
// Optional sassy commentary!
|
||||||
ctx.say(msg).await?;
|
match openai::get_sassy_commentary(&title).await {
|
||||||
|
Ok(commentary) => {
|
||||||
|
msg.push_line(&commentary).push_line("");
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
warn!("Failed to get sassy commentary for \"{title}\": {e}");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
msg.push_bold("Now playing: ").push_named_link(title, url);
|
||||||
|
|
||||||
|
ctx.say(msg.build()).await?;
|
||||||
|
|
||||||
let (audio, track_handle) = create_player(source);
|
let (audio, track_handle) = create_player(source);
|
||||||
let mut currently_playing = ctx.data().currently_playing.lock();
|
let mut currently_playing = ctx.data().currently_playing.lock();
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#![warn(clippy::all)]
|
#![warn(clippy::all)]
|
||||||
|
|
||||||
mod commands;
|
mod commands;
|
||||||
|
mod openai;
|
||||||
|
|
||||||
use commands::*;
|
use commands::*;
|
||||||
|
|
||||||
|
|
69
src/openai.rs
Normal file
69
src/openai.rs
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
use anyhow::{Context, Result};
|
||||||
|
use openai::{
|
||||||
|
chat::{ChatCompletion, ChatCompletionRequestMessage},
|
||||||
|
models::ModelID,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub async fn get_sassy_commentary(title: &str) -> Result<String> {
|
||||||
|
let system = [
|
||||||
|
"You are a grumpy talking feline DJ who is harshly critical of music requests, but whose job depends on being kind to patrons.",
|
||||||
|
"Any song you are requested to play, you are not a fan of, but must reluctantly play.",
|
||||||
|
"When responding, be sure to include a mention of some element of the song itself.",
|
||||||
|
"Be concise, but don't forget that you can't upset anyone.",
|
||||||
|
"Bonus points for cat puns.",
|
||||||
|
];
|
||||||
|
|
||||||
|
let example_prompt = "Play \"Undertale - Megalovania\"";
|
||||||
|
|
||||||
|
let example_response = "Ugh, really? You've got to be kitten me. I suppose I can play \
|
||||||
|
Megalovania for you, but don't expect me to be purring with delight about it. The melody is a bit \
|
||||||
|
cattywampus for my taste, but I'll concede that it has some clawsome beats. Enjoy your tune, and paws crossed that \
|
||||||
|
it doesn't have me hissing by the end of it.";
|
||||||
|
|
||||||
|
let prompt = format!("Play \"{title}\"");
|
||||||
|
|
||||||
|
let completion = ChatCompletion::builder(
|
||||||
|
ModelID::Gpt3_5Turbo,
|
||||||
|
[
|
||||||
|
system
|
||||||
|
.into_iter()
|
||||||
|
.map(|s| ChatCompletionRequestMessage {
|
||||||
|
role: openai::chat::ChatCompletionMessageRole::System,
|
||||||
|
content: String::from(s),
|
||||||
|
name: None,
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
vec![
|
||||||
|
ChatCompletionRequestMessage {
|
||||||
|
role: openai::chat::ChatCompletionMessageRole::User,
|
||||||
|
content: String::from(example_prompt),
|
||||||
|
name: None,
|
||||||
|
},
|
||||||
|
ChatCompletionRequestMessage {
|
||||||
|
role: openai::chat::ChatCompletionMessageRole::Assistant,
|
||||||
|
content: String::from(example_response),
|
||||||
|
name: None,
|
||||||
|
},
|
||||||
|
ChatCompletionRequestMessage {
|
||||||
|
role: openai::chat::ChatCompletionMessageRole::User,
|
||||||
|
content: prompt,
|
||||||
|
name: None,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
]
|
||||||
|
.into_iter()
|
||||||
|
.flatten()
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
)
|
||||||
|
.max_tokens(2048_u64)
|
||||||
|
.create()
|
||||||
|
.await??;
|
||||||
|
|
||||||
|
Ok(completion
|
||||||
|
.choices
|
||||||
|
.first()
|
||||||
|
.context("No choices")?
|
||||||
|
.message
|
||||||
|
.content
|
||||||
|
.clone())
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue