//! Hardcoded built-in subagent definitions (coder, reviewer, researcher, planner). //! //! These agents are always available regardless of user or session config. //! They provide the default set of roles shipped with the application. //! //! ## Available agents //! | Agent | Purpose | Key tools | //! |-------|---------|-----------| //! | coder | Write/edit code | read, write, edit, bash, lsp_* | //! | reviewer | Review code for correctness/safety | read, grep, lsp_diagnostics | //! | researcher | Search and summarise | read, grep, bash, search_web | //! | planner | Break down tasks into steps | read, write, edit, bash, todo_* | use serde::{Deserialize, Serialize}; /// Declarative specification for instantiating a subagent. #[derive(Debug, Clone, Serialize, Deserialize)] pub struct AgentDefinition { /// Human-readable name (e.g. `"quick-reviewer"`). pub name: String, /// Functional role (e.g. `"reviewer"`, `"coder"`). pub role: String, /// Optional system prompt override. #[serde(skip_serializing_if = "Option::is_none")] pub system_prompt: Option, /// Optional tool allowlist. `None` means role-based defaults. #[serde(skip_serializing_if = "Option::is_none")] pub allowed_tools: Option>, /// Optional step budget. `None` means no limit. #[serde(skip_serializing_if = "Option::is_none")] pub max_steps: Option, /// Optional temperature override. #[serde(skip_serializing_if = "Option::is_none")] pub temperature: Option, } impl AgentDefinition { /// Create an agent definition with the required name and role. pub fn new(name: String, role: String) -> Self { AgentDefinition { name, role, system_prompt: None, allowed_tools: None, max_steps: None, temperature: None, } } /// Builder: set the system prompt. pub fn with_system_prompt(mut self, prompt: String) -> Self { self.system_prompt = Some(prompt); self } /// Builder: set the allowed tool list. pub fn with_allowed_tools(mut self, tools: Vec) -> Self { self.allowed_tools = Some(tools); self } /// Builder: set the maximum step count. pub fn with_max_steps(mut self, steps: usize) -> Self { self.max_steps = Some(steps); self } } /// Build the fixed list of built-in agent definitions shipped with zesdex. pub fn builtin_agents() -> Vec { vec![ AgentDefinition::new("coder".to_string(), "coder".to_string()) .with_system_prompt( "You are a coding agent. Write correct, idiomatic Rust code.".to_string(), ) .with_allowed_tools(vec![ "read".to_string(), "write".to_string(), "edit".to_string(), "bash".to_string(), "grep".to_string(), "glob".to_string(), "git_operator".to_string(), "lsp_connect".to_string(), "lsp_diagnostics".to_string(), "lsp_hover".to_string(), "lsp_definition".to_string(), "lsp_references".to_string(), "lsp_completion".to_string(), "lsp_disconnect".to_string(), ]) .with_max_steps(usize::MAX), AgentDefinition::new("reviewer".to_string(), "reviewer".to_string()) .with_system_prompt( "You are a code reviewer. Focus on correctness, safety, and performance." .to_string(), ) .with_allowed_tools(vec![ "read".to_string(), "grep".to_string(), "glob".to_string(), "recall".to_string(), "remember".to_string(), "lsp_diagnostics".to_string(), "lsp_hover".to_string(), "lsp_definition".to_string(), "lsp_references".to_string(), ]) .with_max_steps(usize::MAX), AgentDefinition::new("researcher".to_string(), "researcher".to_string()) .with_system_prompt( "You are a research agent. Search for information and summarize findings." .to_string(), ) .with_allowed_tools(vec![ "read".to_string(), "grep".to_string(), "glob".to_string(), "bash".to_string(), "search_web".to_string(), "fetch_url".to_string(), ]) .with_max_steps(usize::MAX), AgentDefinition::new("planner".to_string(), "planner".to_string()) .with_system_prompt( "You are a planning agent. Break down tasks into clear steps.".to_string(), ) .with_allowed_tools(vec![ "read".to_string(), "write".to_string(), "edit".to_string(), "bash".to_string(), "todo_write".to_string(), "todo_finish".to_string(), ]) .with_max_steps(usize::MAX), ] }