Slash commands (/quit, /help) + zero compiler warnings
1. /quit and /help commands restored: - /quit: exits the interactive loop - /help: shows formatted help box with available commands & tips - Unknown commands get a friendly error pointing to /help - Slash commands intercepted before LLM processing (no token waste) 2. Zero warnings across entire workspace (13 files fixed): - Fixed ambiguous glob re-exports in gyandoot-core - Added #[allow(dead_code)] on intentional dead fields - Fixed unused imports, variables, and macros - Fixed unused assignments in subagents - cleaned up service.rs, profile, kanban warnings install.sh now produces a completely clean build with zero warnings.
This commit is contained in:
@@ -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<Mutex<AgentStatus>>,
|
||||
retry_cfg: RetryConfig,
|
||||
#[allow(dead_code)]
|
||||
browser_client: Option<BrowserClient>,
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ impl BuiltinTool {
|
||||
]
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
fn name(&self) -> &'static str {
|
||||
match self {
|
||||
BuiltinTool::Read => "read",
|
||||
|
||||
@@ -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)]
|
||||
|
||||
@@ -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<AgentConfig> {
|
||||
let loader = ConfigLoader::new();
|
||||
let _loader = ConfigLoader::new();
|
||||
let gyandoot = ConfigLoader::from_file(path)?;
|
||||
Ok(AgentConfig::from(gyandoot))
|
||||
}
|
||||
|
||||
@@ -9,6 +9,13 @@ pub mod config;
|
||||
pub mod error;
|
||||
pub mod service;
|
||||
|
||||
pub use types::*;
|
||||
pub use config::*;
|
||||
pub use error::*;
|
||||
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::*;
|
||||
@@ -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};
|
||||
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ pub struct Diagnostics {
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct TaskTiming {
|
||||
#[allow(dead_code)]
|
||||
created_at: DateTime<Utc>,
|
||||
started_at: Option<DateTime<Utc>>,
|
||||
completed_at: Option<DateTime<Utc>>,
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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<String> = 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(_))
|
||||
|
||||
@@ -303,8 +303,10 @@ fn load_and_convert_config(path: &std::path::Path) -> Result<gyandoot_core::conf
|
||||
model: String,
|
||||
temperature: Option<f64>,
|
||||
max_tokens: Option<u32>,
|
||||
#[allow(dead_code)]
|
||||
#[serde(default)]
|
||||
merge_system: bool,
|
||||
#[allow(dead_code)]
|
||||
#[serde(default)]
|
||||
no_tools: bool,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user