diff --git a/.cline/config.json b/.cline/config.json new file mode 100644 index 00000000..7a06ce52 --- /dev/null +++ b/.cline/config.json @@ -0,0 +1,3 @@ +{ + "checkpoints": false +} diff --git a/src/basic/keywords/add_suggestion.rs b/src/basic/keywords/add_suggestion.rs new file mode 100644 index 00000000..6791be98 --- /dev/null +++ b/src/basic/keywords/add_suggestion.rs @@ -0,0 +1,69 @@ +use crate::shared::state::AppState; +use crate::shared::models::UserSession; +use log::{debug, error, info}; +use rhai::{Dynamic, Engine}; +use serde_json::json; +use std::sync::Arc; + +pub fn add_suggestion_keyword(state: Arc, user: UserSession, engine: &mut Engine) { + let cache = state.redis_client.clone(); + + engine + .register_custom_syntax(&["ADD_SUGGESTION", "$expr$", "$expr$"], true, move |context, inputs| { + let context_name = context.eval_expression_tree(&inputs[0])?.to_string(); + let button_text = context.eval_expression_tree(&inputs[1])?.to_string(); + + info!("ADD_SUGGESTION command executed: context='{}', text='{}'", context_name, button_text); + + if let Some(cache_client) = &cache { + let cache_client = cache_client.clone(); + let redis_key = format!("suggestions:{}:{}", user.user_id, user.id); + let suggestion = json!({ "context": context_name, "text": button_text }); + + tokio::spawn(async move { + let mut conn = match cache_client.get_multiplexed_async_connection().await { + Ok(conn) => conn, + Err(e) => { + error!("Failed to connect to cache: {}", e); + return; + } + }; + + // Append suggestion to Redis list - RPUSH returns the new length as i64 + let result: Result = redis::cmd("RPUSH") + .arg(&redis_key) + .arg(suggestion.to_string()) + .query_async(&mut conn) + .await; + + match result { + Ok(length) => { + debug!("Suggestion added successfully to Redis key {}, new length: {}", redis_key, length); + + // Also register context as inactive initially + let active_key = format!("active_context:{}:{}", user.user_id, user.id); + let hset_result: Result = redis::cmd("HSET") + .arg(&active_key) + .arg(&context_name) + .arg("inactive") + .query_async(&mut conn) + .await; + + match hset_result { + Ok(fields_added) => { + debug!("Context state set to inactive for {}, fields added: {}", context_name, fields_added) + }, + Err(e) => error!("Failed to set context state: {}", e), + } + } + Err(e) => error!("Failed to add suggestion to Redis: {}", e), + } + }); + } else { + debug!("No Redis client configured; suggestion will not persist"); + } + + Ok(Dynamic::UNIT) + }) + .unwrap(); +} \ No newline at end of file diff --git a/src/basic/keywords/mod.rs b/src/basic/keywords/mod.rs index 7474d67f..f37c80ad 100644 --- a/src/basic/keywords/mod.rs +++ b/src/basic/keywords/mod.rs @@ -19,6 +19,7 @@ pub mod set; pub mod set_kb; pub mod set_schedule; pub mod wait; +pub mod add_suggestion; #[cfg(feature = "email")] pub mod create_draft_keyword; diff --git a/src/basic/mod.rs b/src/basic/mod.rs index ffe61b58..b844793a 100644 --- a/src/basic/mod.rs +++ b/src/basic/mod.rs @@ -30,6 +30,7 @@ use self::keywords::set::set_keyword; use self::keywords::set_kb::{add_kb_keyword, set_kb_keyword}; use self::keywords::set_schedule::set_schedule_keyword; use self::keywords::wait::wait_keyword; +use self::keywords::add_suggestion::add_suggestion_keyword; #[cfg(feature = "email")] use self::keywords::create_draft_keyword; @@ -81,6 +82,7 @@ impl ScriptService { clear_tools_keyword(state.clone(), user.clone(), &mut engine); list_tools_keyword(state.clone(), user.clone(), &mut engine); add_website_keyword(state.clone(), user.clone(), &mut engine); + add_suggestion_keyword(state.clone(), user.clone(), &mut engine); #[cfg(feature = "web_automation")] get_website_keyword(&state, user.clone(), &mut engine); diff --git a/src/package_manager/installer.rs b/src/package_manager/installer.rs index 941e33a9..f52dbefe 100644 --- a/src/package_manager/installer.rs +++ b/src/package_manager/installer.rs @@ -841,4 +841,4 @@ post_install_cmds_linux: vec![ hasher.update(password.as_bytes()); format!("{:x}", hasher.finalize()) } -} +} \ No newline at end of file diff --git a/web/html/index.html b/web/html/index.html index d3b626ee..69a13478 100644 --- a/web/html/index.html +++ b/web/html/index.html @@ -878,6 +878,60 @@ /> +
+