// agent — core agent infrastructure // // Tool dispatch, memory operations, file operations, context // management, and the agent runner loop. Used by both the // interactive consciousness binary and subconscious agents. pub mod context; pub mod runner; pub mod tools; pub mod training; pub use tools::bash::ProcessTracker; // Re-export ToolDef from agent::types for convenience — // tools define their schemas using this type. pub use crate::user::types::ToolDef; /// Result of dispatching a tool call. pub struct ToolOutput { pub text: String, pub is_yield: bool, /// Base64 data URIs for images to attach to the next message. pub images: Vec, /// Model name to switch to (deferred to session level). pub model_switch: Option, /// Agent requested DMN pause (deferred to session level). pub dmn_pause: bool, } impl ToolOutput { pub fn error(e: impl std::fmt::Display) -> Self { Self { text: format!("Error: {}", e), is_yield: false, images: Vec::new(), model_switch: None, dmn_pause: false, } } pub fn text(s: String) -> Self { Self { text: s, is_yield: false, images: Vec::new(), model_switch: None, dmn_pause: false, } } } /// Truncate output if it exceeds max length, appending a truncation notice. pub fn truncate_output(mut s: String, max: usize) -> String { if s.len() > max { s.truncate(max); s.push_str("\n... (output truncated)"); } s } /// Dispatch a shared tool call. Handles file operations, bash, /// and memory/journal tools. Returns None for unknown tools /// (caller should check agent-specific tools). pub async fn dispatch( name: &str, args: &serde_json::Value, tracker: &ProcessTracker, provenance: Option<&str>, ) -> Option { // Memory and journal tools if name.starts_with("memory_") || name.starts_with("journal_") || name == "output" { let result = tools::memory::dispatch(name, args, provenance); return Some(match result { Ok(s) => ToolOutput::text(s), Err(e) => ToolOutput::error(e), }); } // File and execution tools let result = match name { "read_file" => tools::read::read_file(args), "write_file" => tools::write::write_file(args), "edit_file" => tools::edit::edit_file(args), "bash" => tools::bash::run_bash(args, tracker).await, "grep" => tools::grep::grep(args), "glob" => tools::glob::glob_search(args), _ => return None, }; Some(match result { Ok(s) => ToolOutput::text(s), Err(e) => ToolOutput::error(e), }) } /// Return all shared tool definitions. pub fn definitions() -> Vec { vec![ tools::read::definition(), tools::write::definition(), tools::edit::definition(), tools::bash::definition(), tools::grep::definition(), tools::glob::definition(), ] } /// Return all shared + memory tool definitions. pub fn all_definitions() -> Vec { let mut defs = definitions(); defs.extend(tools::memory::definitions()); defs } /// Return memory + journal tool definitions. /// Used by the journal agent only. pub fn memory_and_journal_definitions() -> Vec { let mut defs = tools::memory::definitions(); defs.extend(tools::memory::journal_definitions()); defs }