diff --git a/crates/gyandoot-agent/src/agent_loop.rs b/crates/gyandoot-agent/src/agent_loop.rs index 97f7b7d..f6651ab 100644 --- a/crates/gyandoot-agent/src/agent_loop.rs +++ b/crates/gyandoot-agent/src/agent_loop.rs @@ -25,6 +25,7 @@ use crate::context::ContextCompressor; use crate::tools::ToolExecutor; // ─── CLI color constants ────────────────────────────────────────────── +#[allow(dead_code)] mod cli_color { pub const RESET: &str = "\x1b[0m"; pub const BOLD: &str = "\x1b[1m"; @@ -143,6 +144,7 @@ pub struct AgentLoop { sanitizer: Sanitizer, status: Arc>, retry_cfg: RetryConfig, + #[allow(dead_code)] browser_client: Option, } @@ -204,7 +206,7 @@ impl AgentLoop { // ── Identity & memory injection on startup ───────────────────── let (agent_name, agent_role, user_name, user_role) = { let memory = self.memory.lock().await; - let (l0, _) = memory.identity_get().unwrap_or_default(); + let (_l0, _) = memory.identity_get().unwrap_or_default(); // Priority: config identity > config.agent.name > defaults let a_name = if !self.config.identity.agent_name.is_empty() { @@ -267,7 +269,16 @@ impl AgentLoop { // 1. Read user input let user_input = self.read_input().await?; - // 2. Check exit conditions + // 2. Handle built-in slash commands + if user_input.starts_with('/') { + let should_quit = self.handle_command(&user_input).await; + if should_quit { + break; + } + continue; + } + + // 3. Check exit conditions if self.should_exit(&user_input) { info!("User requested exit"); break; @@ -619,7 +630,49 @@ impl AgentLoop { /// Check if the user wants to exit. fn should_exit(&self, input: &str) -> bool { - matches!(input.to_lowercase().as_str(), "exit" | "quit" | "bye") + matches!(input.to_lowercase().as_str(), "exit" | "quit" | "bye" | "/quit") + } + + /// Handle a slash command. Returns true if the user wants to exit. + async fn handle_command(&self, cmd: &str) -> bool { + match cmd.to_lowercase().as_str() { + "/quit" | "/exit" => { + info!("User requested exit via slash command"); + true + } + "/help" => { + println!( + "\n{bold}{cyan}╔════════════════════════════════════╗\ + \n║ GyanDoot — Help ║\ + \n╚════════════════════════════════════╝{reset}\n\ + \n{bold}Commands:{reset}\ + \n {green}»{reset} Type anything to chat with the AI\ + \n {green}/quit{reset} Exit GyanDoot\ + \n {green}/help{reset} Show this help message\n\ + \n{bold}Tips:{reset}\ + \n • Use {cyan}web_search{reset} for online queries\ + \n • Use {cyan}web_browse{reset} to visit websites\ + \n • Type {yellow}exit{reset}, {yellow}quit{reset}, or {yellow}bye{reset} to exit\n", + bold = cli_color::BOLD, + cyan = cli_color::BRIGHT_CYAN, + green = cli_color::GREEN, + yellow = cli_color::YELLOW, + reset = cli_color::RESET, + ); + false + } + _ => { + println!( + "\n{yellow}Unknown command:{reset} {cmd}\n\ + Type {green}/help{reset} for available commands.\n", + yellow = cli_color::YELLOW, + reset = cli_color::RESET, + cmd = cmd, + green = cli_color::GREEN, + ); + false + } + } } } diff --git a/crates/gyandoot-agent/src/browser_tools.rs b/crates/gyandoot-agent/src/browser_tools.rs index e147eca..d9f3ab9 100644 --- a/crates/gyandoot-agent/src/browser_tools.rs +++ b/crates/gyandoot-agent/src/browser_tools.rs @@ -7,10 +7,9 @@ //! Uses the camoufox-browser daemon protocol (Unix socket IPC). use serde_json; -use tracing::{info, warn}; +use tracing::info; use gyandoot_browser::BrowserClient; -use gyandoot_core::ToolDefinition; use crate::tools::Tool; diff --git a/crates/gyandoot-agent/src/tools.rs b/crates/gyandoot-agent/src/tools.rs index bede79b..894690a 100644 --- a/crates/gyandoot-agent/src/tools.rs +++ b/crates/gyandoot-agent/src/tools.rs @@ -58,6 +58,7 @@ impl BuiltinTool { ] } + #[allow(dead_code)] fn name(&self) -> &'static str { match self { BuiltinTool::Read => "read", diff --git a/crates/gyandoot-browser/src/client.rs b/crates/gyandoot-browser/src/client.rs index eff7856..40f65c2 100644 --- a/crates/gyandoot-browser/src/client.rs +++ b/crates/gyandoot-browser/src/client.rs @@ -14,7 +14,7 @@ use serde::{Deserialize, Serialize}; use serde_json::Value; use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader}; use tokio::net::UnixStream; -use tracing::{debug, info, warn}; +use tracing::{debug, warn}; // ─── Constants ────────────────────────────────────────────────────────── @@ -101,6 +101,7 @@ struct DaemonCommand { /// A response from the daemon. #[derive(Debug, Deserialize)] struct DaemonResponse { + #[allow(dead_code)] id: String, success: bool, #[serde(default)] diff --git a/crates/gyandoot-core/src/config.rs b/crates/gyandoot-core/src/config.rs index 367599f..6d34ae0 100644 --- a/crates/gyandoot-core/src/config.rs +++ b/crates/gyandoot-core/src/config.rs @@ -649,6 +649,7 @@ impl ConfigLoader { /// - Provider-specific: `GYANDOOT_OPENAI_API_KEY`, `GYANDOOT_OPENAI_MODEL`, /// `GYANDOOT_OPENAI_BASE_URL`, `GYANDOOT_ANTHROPIC_API_KEY`, etc. pub fn from_env(&self, config: &mut GyandootConfig) { + #[allow(unused_macros)] macro_rules! env_opt { ($key:literal, $target:expr) => { if let Ok(val) = std::env::var(concat!(env_prefix_str!(), $key)) { @@ -785,7 +786,7 @@ impl ConfigLoader { /// Convenience: load config from a single TOML file (legacy API). pub fn load_config_from_file(path: &std::path::Path) -> anyhow::Result { - let loader = ConfigLoader::new(); + let _loader = ConfigLoader::new(); let gyandoot = ConfigLoader::from_file(path)?; Ok(AgentConfig::from(gyandoot)) } diff --git a/crates/gyandoot-core/src/lib.rs b/crates/gyandoot-core/src/lib.rs index c629eb6..f6e5bb2 100644 --- a/crates/gyandoot-core/src/lib.rs +++ b/crates/gyandoot-core/src/lib.rs @@ -9,6 +9,13 @@ pub mod config; pub mod error; pub mod service; -pub use types::*; -pub use config::*; -pub use error::*; \ No newline at end of file +pub use config::{ + AgentConfig, AgentSection, AnthropicConfig, BrowserSection, ConfigLoader, + GatewaySection, GyandootConfig, IdentitySection, + KanbanRootConfig, MemoryRootConfig, MemorySection, OllamaConfig, + OpenAIConfig, PlatformRootConfig, PlatformSection, ProviderRootConfig, + ProvidersSection, SecurityRootConfig, SkillsRootConfig, TelegramConfig, + WebhookConfig, DiscordConfig, load_config_from_file, +}; +pub use error::*; +pub use types::*; \ No newline at end of file diff --git a/crates/gyandoot-core/src/service.rs b/crates/gyandoot-core/src/service.rs index eb9bb57..1da243a 100644 --- a/crates/gyandoot-core/src/service.rs +++ b/crates/gyandoot-core/src/service.rs @@ -7,8 +7,8 @@ //! Templates live in the resources/ directory of the repo and are rendered //! at install time with the actual binary path and home directory. -use std::path::{Path, PathBuf}; -use tracing::{info, warn}; +use std::path::PathBuf; +use tracing::info; use crate::{AgentError, AgentResult}; diff --git a/crates/gyandoot-kanban/src/decompose.rs b/crates/gyandoot-kanban/src/decompose.rs index 4ecc69e..1a7bfbd 100644 --- a/crates/gyandoot-kanban/src/decompose.rs +++ b/crates/gyandoot-kanban/src/decompose.rs @@ -1,11 +1,12 @@ //! Task decomposition — breaks complex tasks into smaller subtasks. -use gyandoot_core::{KanbanResult, Priority, Task, TaskStatus}; +use gyandoot_core::{KanbanResult, Task, TaskStatus}; use uuid::Uuid; /// Decomposes a complex task into smaller, actionable subtasks. pub struct Decomposer { /// Maximum depth of decomposition. + #[allow(dead_code)] max_depth: usize, } diff --git a/crates/gyandoot-kanban/src/diagnostics.rs b/crates/gyandoot-kanban/src/diagnostics.rs index 3ceef9e..ab48cc2 100644 --- a/crates/gyandoot-kanban/src/diagnostics.rs +++ b/crates/gyandoot-kanban/src/diagnostics.rs @@ -27,6 +27,7 @@ pub struct Diagnostics { #[derive(Debug, Clone)] struct TaskTiming { + #[allow(dead_code)] created_at: DateTime, started_at: Option>, completed_at: Option>, diff --git a/crates/gyandoot-kanban/src/swarm.rs b/crates/gyandoot-kanban/src/swarm.rs index fc803ca..f3d1775 100644 --- a/crates/gyandoot-kanban/src/swarm.rs +++ b/crates/gyandoot-kanban/src/swarm.rs @@ -2,7 +2,7 @@ use std::collections::HashMap; -use gyandoot_core::{KanbanResult, Task, TaskStatus}; +use gyandoot_core::{KanbanResult, Task}; use tracing::{debug, info}; /// Manages parallel execution of tasks via a swarm of sub-agents. diff --git a/crates/gyandoot-profile/src/lib.rs b/crates/gyandoot-profile/src/lib.rs index 1783f61..e613a7a 100644 --- a/crates/gyandoot-profile/src/lib.rs +++ b/crates/gyandoot-profile/src/lib.rs @@ -441,7 +441,7 @@ impl ConfigResolver { let default_path = self.default_config_path(); if default_path.exists() { match Self::load_profile_from_file(&default_path) { - Ok(mut profile) => { + Ok(profile) => { if profile_name.is_empty() { profile_name = profile.name.clone(); } diff --git a/crates/gyandoot-subagents/src/lib.rs b/crates/gyandoot-subagents/src/lib.rs index f90e82e..d12d343 100644 --- a/crates/gyandoot-subagents/src/lib.rs +++ b/crates/gyandoot-subagents/src/lib.rs @@ -29,12 +29,11 @@ //! ``` use std::collections::HashMap; -use std::path::PathBuf; use std::sync::Arc; use chrono::{DateTime, Utc}; -use gyandoot_agent::agent_loop::{AgentLoop, ConversationOutput}; -use gyandoot_core::{AgentConfig, AgentError, AgentStatus}; +use gyandoot_agent::agent_loop::AgentLoop; +use gyandoot_core::AgentConfig; use tokio::sync::{Mutex, Semaphore}; use tracing::{error, info, span, warn, Level}; use uuid::Uuid; @@ -219,7 +218,7 @@ impl SubAgentWorker { /// The worker respects max_iterations by passing a capped max_tokens /// and managing iteration count through the system prompt directive. pub async fn execute(&self) -> WorkerResult { - let started_at = Utc::now(); + let _started_at = Utc::now(); { let mut s = self.status.lock().await; *s = WorkerStatus::Running; @@ -293,7 +292,7 @@ impl SubAgentWorker { }; } - let completed_at = Utc::now(); + let _completed_at = Utc::now(); info!( worker_id = %self.config.id, success = %result.success, @@ -325,8 +324,11 @@ impl SubAgentWorker { _config: &AgentConfig, ) -> WorkerResult { let started_at = Utc::now(); + #[allow(unused_assignments)] let mut summary = String::new(); + #[allow(unused_assignments)] let mut error_msg = None; + #[allow(unused_assignments)] let mut iteration_count = 0; // Build a directive message for the sub-agent @@ -410,7 +412,7 @@ impl SubAgentWorker { // Build a simulated ToolExecutor with filtered tools let tool_executor = if let Some(allowed) = &self.config.allowed_tools { - let mut exec = gyandoot_agent::tools::ToolExecutor::with_defaults(); + let _exec = gyandoot_agent::tools::ToolExecutor::with_defaults(); // Remove tools not in the allowed list let names: Vec = allowed.clone(); // We can't easily unregister, so we build fresh @@ -653,7 +655,7 @@ impl SubAgentManager { let mut w = self.workers.lock().await; w.retain(|_, worker| { // We can only check the current status synchronously - let status = worker.status.try_lock().map(|mut s| s.clone()).ok(); + let status = worker.status.try_lock().map(|s| s.clone()).ok(); !matches!( status, Some(WorkerStatus::Completed { .. }) | Some(WorkerStatus::Failed(_)) diff --git a/src/main.rs b/src/main.rs index c587a83..a87c594 100644 --- a/src/main.rs +++ b/src/main.rs @@ -303,8 +303,10 @@ fn load_and_convert_config(path: &std::path::Path) -> Result, max_tokens: Option, + #[allow(dead_code)] #[serde(default)] merge_system: bool, + #[allow(dead_code)] #[serde(default)] no_tools: bool, }