The world's most clever kitty cat
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add /forget

Ben C 662462c2 2beffd13

+93 -1
+1
README.md
··· 39 39 40 40 - `/markov`: For a reply from Bingus in the current channel 41 41 - `/weights`: View the weights for a specific token 42 + - *`/forget`: Clear a word from memory, this gets rid of any instance of the token 42 43 - *`/dump_chain`: Dump Bingus' "brain", his entire database of known words and relations 43 44 - *`/load_chain`: Additively load a brain file into Bingus 44 45
+43 -1
src/brain.rs
··· 65 65 None 66 66 } 67 67 68 + pub fn forget(&mut self, token: &Token) { 69 + if let Some(w) = self.0.remove(token) { 70 + self.1 -= w as u64; 71 + } 72 + } 73 + 68 74 pub fn iter_weights(&self) -> impl Iterator<Item = (&Token, Weight, f64)> { 69 75 self.0 70 76 .iter() ··· 137 143 .unwrap_or_default() 138 144 } 139 145 146 + pub fn forget(&mut self, word: &str) { 147 + let tok = Self::normalize_token(word); 148 + 149 + self.0.remove(&tok); 150 + 151 + for edge in self.0.values_mut() { 152 + edge.forget(&tok); 153 + } 154 + } 155 + 140 156 pub fn merge_from(&mut self, other: Self) { 141 157 for (k, v) in other.0.into_iter() { 142 158 if let Some(edges) = self.0.get_mut(&k) { ··· 226 242 } 227 243 228 244 pub fn get_weights(&self, tok: &str) -> Option<&Edges> { 229 - self.0.get(&Self::normalize_token(tok)) 245 + self.0 246 + .get(&Self::normalize_token(tok)) 247 + .filter(|e| !e.0.is_empty()) 230 248 } 231 249 232 250 fn legacy_token_format(tok: &Token) -> String { ··· 336 354 let reply = brain.respond("hello", false, false, None); 337 355 assert_eq!(reply, Some("world".to_string())); 338 356 } 357 + } 358 + 359 + #[test] 360 + fn forget_word() { 361 + let mut brain = Brain::default(); 362 + 363 + brain.ingest("hello world"); 364 + brain.ingest("hello evil world"); 365 + 366 + brain.forget("evil"); 367 + 368 + assert!( 369 + !brain.0.contains_key(&Some(String::from("evil"))), 370 + "Edges still exist for evil" 371 + ); 372 + let edges = brain 373 + .0 374 + .get(&Some(String::from("hello"))) 375 + .expect("No weights for hello"); 376 + assert!( 377 + !edges.0.contains_key(&Some(String::from("evil"))), 378 + "Edges for hello still has evil" 379 + ); 380 + assert_eq!(edges.1, 1); 339 381 } 340 382 341 383 #[test]
+45
src/cmd/forget.rs
··· 1 + use std::sync::Arc; 2 + 3 + use twilight_interactions::command::{CommandModel, CreateCommand}; 4 + use twilight_model::application::interaction::{Interaction, application_command::CommandData}; 5 + 6 + use crate::{BotContext, cmd::DEFER_INTER_RESP_EPHEMERAL, prelude::*, require_owner}; 7 + 8 + #[derive(CommandModel, CreateCommand)] 9 + #[command( 10 + name = "forget", 11 + desc = "Erase a word from all edges. THIS ACTION IS IRREVERSIBLE!" 12 + )] 13 + pub struct ForgetCommand { 14 + /// The token to forget 15 + token: String, 16 + } 17 + 18 + impl ForgetCommand { 19 + pub async fn handle(inter: Interaction, data: CommandData, ctx: Arc<BotContext>) -> Result { 20 + let client = ctx.http.interaction(ctx.app_id); 21 + 22 + require_owner!(inter, ctx, client); 23 + 24 + let Self { token } = 25 + Self::from_interaction(data.into()).context("Failed to parse command data")?; 26 + 27 + client 28 + .create_response(inter.id, &inter.token, &DEFER_INTER_RESP_EPHEMERAL) 29 + .await 30 + .context("Failed to defer")?; 31 + 32 + { 33 + let mut brain = ctx.brain_handle.write().await; 34 + brain.forget(token.as_str()); 35 + } 36 + 37 + client 38 + .update_response(&inter.token) 39 + .content(Some("Token forgotten")) 40 + .await 41 + .context("Failed to send brain")?; 42 + 43 + Ok(()) 44 + } 45 + }
+4
src/cmd/mod.rs
··· 1 1 mod dump_chain; 2 + mod forget; 2 3 mod load_chain; 3 4 mod markov; 4 5 mod weights; ··· 16 17 use crate::{BotContext, prelude::*}; 17 18 18 19 use dump_chain::DumpChainCommand; 20 + use forget::ForgetCommand; 19 21 use load_chain::LoadChainCommand; 20 22 use markov::MarkovCommand; 21 23 use weights::WeightsCommand; ··· 66 68 DumpChainCommand::create_command().into(), 67 69 LoadChainCommand::create_command().into(), 68 70 MarkovCommand::create_command().into(), 71 + ForgetCommand::create_command().into(), 69 72 ]; 70 73 71 74 let client = ctx.http.interaction(ctx.app_id); ··· 88 91 "dump_chain" => DumpChainCommand::handle(inter, data, ctx).await, 89 92 "load_chain" => LoadChainCommand::handle(inter, data, ctx).await, 90 93 "markov" => MarkovCommand::handle(inter, data, ctx).await, 94 + "forget" => ForgetCommand::handle(inter, data, ctx).await, 91 95 other => { 92 96 warn!("Unknown command send: {other}"); 93 97 Ok(())