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;
|
use crate::tools::ToolExecutor;
|
||||||
|
|
||||||
// ─── CLI color constants ──────────────────────────────────────────────
|
// ─── CLI color constants ──────────────────────────────────────────────
|
||||||
|
#[allow(dead_code)]
|
||||||
mod cli_color {
|
mod cli_color {
|
||||||
pub const RESET: &str = "\x1b[0m";
|
pub const RESET: &str = "\x1b[0m";
|
||||||
pub const BOLD: &str = "\x1b[1m";
|
pub const BOLD: &str = "\x1b[1m";
|
||||||
@@ -143,6 +144,7 @@ pub struct AgentLoop {
|
|||||||
sanitizer: Sanitizer,
|
sanitizer: Sanitizer,
|
||||||
status: Arc<Mutex<AgentStatus>>,
|
status: Arc<Mutex<AgentStatus>>,
|
||||||
retry_cfg: RetryConfig,
|
retry_cfg: RetryConfig,
|
||||||
|
#[allow(dead_code)]
|
||||||
browser_client: Option<BrowserClient>,
|
browser_client: Option<BrowserClient>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -204,7 +206,7 @@ impl AgentLoop {
|
|||||||
// ── Identity & memory injection on startup ─────────────────────
|
// ── Identity & memory injection on startup ─────────────────────
|
||||||
let (agent_name, agent_role, user_name, user_role) = {
|
let (agent_name, agent_role, user_name, user_role) = {
|
||||||
let memory = self.memory.lock().await;
|
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
|
// Priority: config identity > config.agent.name > defaults
|
||||||
let a_name = if !self.config.identity.agent_name.is_empty() {
|
let a_name = if !self.config.identity.agent_name.is_empty() {
|
||||||
@@ -267,7 +269,16 @@ impl AgentLoop {
|
|||||||
// 1. Read user input
|
// 1. Read user input
|
||||||
let user_input = self.read_input().await?;
|
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) {
|
if self.should_exit(&user_input) {
|
||||||
info!("User requested exit");
|
info!("User requested exit");
|
||||||
break;
|
break;
|
||||||
@@ -619,7 +630,49 @@ impl AgentLoop {
|
|||||||
|
|
||||||
/// Check if the user wants to exit.
|
/// Check if the user wants to exit.
|
||||||
fn should_exit(&self, input: &str) -> bool {
|
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).
|
//! Uses the camoufox-browser daemon protocol (Unix socket IPC).
|
||||||
|
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use tracing::{info, warn};
|
use tracing::info;
|
||||||
|
|
||||||
use gyandoot_browser::BrowserClient;
|
use gyandoot_browser::BrowserClient;
|
||||||
use gyandoot_core::ToolDefinition;
|
|
||||||
|
|
||||||
use crate::tools::Tool;
|
use crate::tools::Tool;
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ impl BuiltinTool {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
fn name(&self) -> &'static str {
|
fn name(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
BuiltinTool::Read => "read",
|
BuiltinTool::Read => "read",
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
|
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
|
||||||
use tokio::net::UnixStream;
|
use tokio::net::UnixStream;
|
||||||
use tracing::{debug, info, warn};
|
use tracing::{debug, warn};
|
||||||
|
|
||||||
// ─── Constants ──────────────────────────────────────────────────────────
|
// ─── Constants ──────────────────────────────────────────────────────────
|
||||||
|
|
||||||
@@ -101,6 +101,7 @@ struct DaemonCommand {
|
|||||||
/// A response from the daemon.
|
/// A response from the daemon.
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
struct DaemonResponse {
|
struct DaemonResponse {
|
||||||
|
#[allow(dead_code)]
|
||||||
id: String,
|
id: String,
|
||||||
success: bool,
|
success: bool,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
|||||||
@@ -649,6 +649,7 @@ impl ConfigLoader {
|
|||||||
/// - Provider-specific: `GYANDOOT_OPENAI_API_KEY`, `GYANDOOT_OPENAI_MODEL`,
|
/// - Provider-specific: `GYANDOOT_OPENAI_API_KEY`, `GYANDOOT_OPENAI_MODEL`,
|
||||||
/// `GYANDOOT_OPENAI_BASE_URL`, `GYANDOOT_ANTHROPIC_API_KEY`, etc.
|
/// `GYANDOOT_OPENAI_BASE_URL`, `GYANDOOT_ANTHROPIC_API_KEY`, etc.
|
||||||
pub fn from_env(&self, config: &mut GyandootConfig) {
|
pub fn from_env(&self, config: &mut GyandootConfig) {
|
||||||
|
#[allow(unused_macros)]
|
||||||
macro_rules! env_opt {
|
macro_rules! env_opt {
|
||||||
($key:literal, $target:expr) => {
|
($key:literal, $target:expr) => {
|
||||||
if let Ok(val) = std::env::var(concat!(env_prefix_str!(), $key)) {
|
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).
|
/// Convenience: load config from a single TOML file (legacy API).
|
||||||
pub fn load_config_from_file(path: &std::path::Path) -> anyhow::Result<AgentConfig> {
|
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)?;
|
let gyandoot = ConfigLoader::from_file(path)?;
|
||||||
Ok(AgentConfig::from(gyandoot))
|
Ok(AgentConfig::from(gyandoot))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,13 @@ pub mod config;
|
|||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod service;
|
pub mod service;
|
||||||
|
|
||||||
pub use types::*;
|
pub use config::{
|
||||||
pub use config::*;
|
AgentConfig, AgentSection, AnthropicConfig, BrowserSection, ConfigLoader,
|
||||||
pub use error::*;
|
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
|
//! Templates live in the resources/ directory of the repo and are rendered
|
||||||
//! at install time with the actual binary path and home directory.
|
//! at install time with the actual binary path and home directory.
|
||||||
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::PathBuf;
|
||||||
use tracing::{info, warn};
|
use tracing::info;
|
||||||
|
|
||||||
use crate::{AgentError, AgentResult};
|
use crate::{AgentError, AgentResult};
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
//! Task decomposition — breaks complex tasks into smaller subtasks.
|
//! Task decomposition — breaks complex tasks into smaller subtasks.
|
||||||
|
|
||||||
use gyandoot_core::{KanbanResult, Priority, Task, TaskStatus};
|
use gyandoot_core::{KanbanResult, Task, TaskStatus};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
/// Decomposes a complex task into smaller, actionable subtasks.
|
/// Decomposes a complex task into smaller, actionable subtasks.
|
||||||
pub struct Decomposer {
|
pub struct Decomposer {
|
||||||
/// Maximum depth of decomposition.
|
/// Maximum depth of decomposition.
|
||||||
|
#[allow(dead_code)]
|
||||||
max_depth: usize,
|
max_depth: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ pub struct Diagnostics {
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct TaskTiming {
|
struct TaskTiming {
|
||||||
|
#[allow(dead_code)]
|
||||||
created_at: DateTime<Utc>,
|
created_at: DateTime<Utc>,
|
||||||
started_at: Option<DateTime<Utc>>,
|
started_at: Option<DateTime<Utc>>,
|
||||||
completed_at: Option<DateTime<Utc>>,
|
completed_at: Option<DateTime<Utc>>,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use gyandoot_core::{KanbanResult, Task, TaskStatus};
|
use gyandoot_core::{KanbanResult, Task};
|
||||||
use tracing::{debug, info};
|
use tracing::{debug, info};
|
||||||
|
|
||||||
/// Manages parallel execution of tasks via a swarm of sub-agents.
|
/// Manages parallel execution of tasks via a swarm of sub-agents.
|
||||||
|
|||||||
@@ -441,7 +441,7 @@ impl ConfigResolver {
|
|||||||
let default_path = self.default_config_path();
|
let default_path = self.default_config_path();
|
||||||
if default_path.exists() {
|
if default_path.exists() {
|
||||||
match Self::load_profile_from_file(&default_path) {
|
match Self::load_profile_from_file(&default_path) {
|
||||||
Ok(mut profile) => {
|
Ok(profile) => {
|
||||||
if profile_name.is_empty() {
|
if profile_name.is_empty() {
|
||||||
profile_name = profile.name.clone();
|
profile_name = profile.name.clone();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,12 +29,11 @@
|
|||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::path::PathBuf;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use gyandoot_agent::agent_loop::{AgentLoop, ConversationOutput};
|
use gyandoot_agent::agent_loop::AgentLoop;
|
||||||
use gyandoot_core::{AgentConfig, AgentError, AgentStatus};
|
use gyandoot_core::AgentConfig;
|
||||||
use tokio::sync::{Mutex, Semaphore};
|
use tokio::sync::{Mutex, Semaphore};
|
||||||
use tracing::{error, info, span, warn, Level};
|
use tracing::{error, info, span, warn, Level};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
@@ -219,7 +218,7 @@ impl SubAgentWorker {
|
|||||||
/// The worker respects max_iterations by passing a capped max_tokens
|
/// The worker respects max_iterations by passing a capped max_tokens
|
||||||
/// and managing iteration count through the system prompt directive.
|
/// and managing iteration count through the system prompt directive.
|
||||||
pub async fn execute(&self) -> WorkerResult {
|
pub async fn execute(&self) -> WorkerResult {
|
||||||
let started_at = Utc::now();
|
let _started_at = Utc::now();
|
||||||
{
|
{
|
||||||
let mut s = self.status.lock().await;
|
let mut s = self.status.lock().await;
|
||||||
*s = WorkerStatus::Running;
|
*s = WorkerStatus::Running;
|
||||||
@@ -293,7 +292,7 @@ impl SubAgentWorker {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let completed_at = Utc::now();
|
let _completed_at = Utc::now();
|
||||||
info!(
|
info!(
|
||||||
worker_id = %self.config.id,
|
worker_id = %self.config.id,
|
||||||
success = %result.success,
|
success = %result.success,
|
||||||
@@ -325,8 +324,11 @@ impl SubAgentWorker {
|
|||||||
_config: &AgentConfig,
|
_config: &AgentConfig,
|
||||||
) -> WorkerResult {
|
) -> WorkerResult {
|
||||||
let started_at = Utc::now();
|
let started_at = Utc::now();
|
||||||
|
#[allow(unused_assignments)]
|
||||||
let mut summary = String::new();
|
let mut summary = String::new();
|
||||||
|
#[allow(unused_assignments)]
|
||||||
let mut error_msg = None;
|
let mut error_msg = None;
|
||||||
|
#[allow(unused_assignments)]
|
||||||
let mut iteration_count = 0;
|
let mut iteration_count = 0;
|
||||||
|
|
||||||
// Build a directive message for the sub-agent
|
// Build a directive message for the sub-agent
|
||||||
@@ -410,7 +412,7 @@ impl SubAgentWorker {
|
|||||||
|
|
||||||
// Build a simulated ToolExecutor with filtered tools
|
// Build a simulated ToolExecutor with filtered tools
|
||||||
let tool_executor = if let Some(allowed) = &self.config.allowed_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
|
// Remove tools not in the allowed list
|
||||||
let names: Vec<String> = allowed.clone();
|
let names: Vec<String> = allowed.clone();
|
||||||
// We can't easily unregister, so we build fresh
|
// We can't easily unregister, so we build fresh
|
||||||
@@ -653,7 +655,7 @@ impl SubAgentManager {
|
|||||||
let mut w = self.workers.lock().await;
|
let mut w = self.workers.lock().await;
|
||||||
w.retain(|_, worker| {
|
w.retain(|_, worker| {
|
||||||
// We can only check the current status synchronously
|
// 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!(
|
!matches!(
|
||||||
status,
|
status,
|
||||||
Some(WorkerStatus::Completed { .. }) | Some(WorkerStatus::Failed(_))
|
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,
|
model: String,
|
||||||
temperature: Option<f64>,
|
temperature: Option<f64>,
|
||||||
max_tokens: Option<u32>,
|
max_tokens: Option<u32>,
|
||||||
|
#[allow(dead_code)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
merge_system: bool,
|
merge_system: bool,
|
||||||
|
#[allow(dead_code)]
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
no_tools: bool,
|
no_tools: bool,
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user