feat(tui): implement status bar with connection and turn state indicators feat(tui): create workflow panel for agent status and progress visualization feat(web): introduce web frontend interface with static file serving feat(ws): add WebSocket interface for real-time communication and session management
139 lines
5.1 KiB
Rust
139 lines
5.1 KiB
Rust
//! 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<String>,
|
|
/// Optional tool allowlist. `None` means role-based defaults.
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub allowed_tools: Option<Vec<String>>,
|
|
/// Optional step budget. `None` means no limit.
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub max_steps: Option<usize>,
|
|
/// Optional temperature override.
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub temperature: Option<f32>,
|
|
}
|
|
|
|
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<String>) -> 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<AgentDefinition> {
|
|
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),
|
|
]
|
|
}
|