Files
owlen/crates/tools/task/SUBAGENT_ORCHESTRATION.md

304 lines
8.6 KiB
Markdown

# Subagent Orchestration Enhancement
This document describes the enhanced Task tool with proper subagent orchestration support using plugin agents.
## Overview
The Task tool has been enhanced to support a new architecture for spawning and managing specialized subagents. The system now integrates with the plugin system's `AgentDefinition` type, allowing both built-in and plugin-provided agents to be orchestrated.
## Key Components
### 1. SubagentConfig
Configuration structure for spawning subagents:
```rust
pub struct SubagentConfig {
/// Agent type/name (e.g., "code-reviewer", "explore")
pub agent_type: String,
/// Task prompt for the agent
pub prompt: String,
/// Optional model override
pub model: Option<String>,
/// Tool whitelist (if None, uses agent's default)
pub tools: Option<Vec<String>>,
/// Parsed agent definition (if from plugin)
pub definition: Option<AgentDefinition>,
}
```
**Builder Pattern:**
```rust
let config = SubagentConfig::new("explore".to_string(), "Find all Rust files".to_string())
.with_model("claude-3-opus".to_string())
.with_tools(vec!["read".to_string(), "glob".to_string()]);
```
### 2. SubagentRegistry
Thread-safe registry for tracking available agents:
```rust
pub struct SubagentRegistry {
agents: Arc<RwLock<HashMap<String, AgentDefinition>>>,
}
```
**Key Methods:**
- `new()` - Create empty registry
- `register_builtin()` - Register built-in agents
- `register_from_plugins(Vec<AgentDefinition>)` - Register plugin agents
- `get(name: &str)` - Get agent by name
- `list()` - List all agents with descriptions
- `contains(name: &str)` - Check if agent exists
- `agent_names()` - Get all agent names
**Usage:**
```rust
let registry = SubagentRegistry::new();
registry.register_builtin();
// Load plugin agents
let plugin_manager = PluginManager::new();
plugin_manager.load_all()?;
let plugin_agents = plugin_manager.load_all_agents();
registry.register_from_plugins(plugin_agents);
// Use registry
if let Some(agent) = registry.get("explore") {
println!("Agent: {} - {}", agent.name, agent.description);
}
```
### 3. Built-in Agents
The system includes six specialized built-in agents:
#### explore
- **Purpose:** Codebase exploration
- **Tools:** read, glob, grep, ls
- **Color:** blue
- **Use Cases:** Finding files, understanding structure
#### plan
- **Purpose:** Implementation planning
- **Tools:** read, glob, grep
- **Color:** green
- **Use Cases:** Designing architectures, creating strategies
#### code-reviewer
- **Purpose:** Code analysis
- **Tools:** read, grep, glob (read-only)
- **Color:** yellow
- **Use Cases:** Quality review, bug detection
#### test-writer
- **Purpose:** Test creation
- **Tools:** read, write, edit, grep, glob
- **Color:** cyan
- **Use Cases:** Writing unit tests, integration tests
#### doc-writer
- **Purpose:** Documentation
- **Tools:** read, write, edit, grep, glob
- **Color:** magenta
- **Use Cases:** Writing READMEs, API docs
#### refactorer
- **Purpose:** Code refactoring
- **Tools:** read, write, edit, grep, glob (no bash)
- **Color:** red
- **Use Cases:** Improving structure, applying patterns
## Future Implementation
The following functions will be implemented to complete the orchestration system:
### spawn_subagent
```rust
/// Spawn a subagent with the given configuration
pub async fn spawn_subagent<P: LlmProvider>(
provider: &P,
registry: &SubagentRegistry,
config: SubagentConfig,
perms: &PermissionManager,
) -> Result<String>
```
**Behavior:**
1. Look up agent definition from registry or config
2. Extract system prompt and tool whitelist from definition
3. Build full prompt combining system prompt + task
4. Create filtered permission manager if tool whitelist specified
5. Run agent loop with system prompt
6. Return result string
### spawn_parallel
```rust
/// Spawn multiple subagents in parallel and collect results
pub async fn spawn_parallel<P: LlmProvider + Clone>(
provider: &P,
registry: &SubagentRegistry,
configs: Vec<SubagentConfig>,
perms: &PermissionManager,
) -> Vec<Result<String>>
```
**Behavior:**
1. Create futures for each config
2. Execute all in parallel using `join_all`
3. Return vector of results
**Note:** Requires `PermissionManager` to implement `Clone`. This may need to be added to the permissions crate.
## Integration Points
### With Plugin System
```rust
use plugins::PluginManager;
use tools_task::SubagentRegistry;
let mut plugin_manager = PluginManager::new();
plugin_manager.load_all()?;
let registry = SubagentRegistry::new();
registry.register_builtin();
registry.register_from_plugins(plugin_manager.load_all_agents());
```
### With Agent Core
The subagent execution will integrate with `agent-core` by:
1. Calling the same `run_agent_loop` function used by main agent
2. Passing filtered tool definitions based on agent's tool whitelist
3. Using agent-specific system prompts
4. Inheriting parent's permission manager (or creating restricted copy)
### With Permission System
Subagents respect the permission system:
- Tool whitelist from agent definition restricts available tools
- Permission manager checks are still applied
- Parent's mode (plan/acceptEdits/code) is inherited
## Example Usage Patterns
### Basic Exploration
```rust
let registry = SubagentRegistry::new();
registry.register_builtin();
let config = SubagentConfig::new(
"explore".to_string(),
"Find all test files in the codebase".to_string()
);
let result = spawn_subagent(&provider, &registry, config, &perms).await?;
println!("Found files:\n{}", result);
```
### Parallel Analysis
```rust
let configs = vec![
SubagentConfig::new("explore".to_string(), "Find all Rust files".to_string()),
SubagentConfig::new("code-reviewer".to_string(), "Review auth module".to_string()),
SubagentConfig::new("test-writer".to_string(), "Check test coverage".to_string()),
];
let results = spawn_parallel(&provider, &registry, configs, &perms).await;
for (i, result) in results.iter().enumerate() {
match result {
Ok(output) => println!("Agent {} completed:\n{}", i, output),
Err(e) => eprintln!("Agent {} failed: {}", i, e),
}
}
```
### Custom Plugin Agent
```rust
// Plugin provides custom-analyzer agent
let config = SubagentConfig::new(
"custom-analyzer".to_string(),
"Analyze security vulnerabilities".to_string()
);
if registry.contains("custom-analyzer") {
let result = spawn_subagent(&provider, &registry, config, &perms).await?;
} else {
eprintln!("Agent not found. Available: {:?}", registry.agent_names());
}
```
## Migration Guide
### From Legacy Subagent API
The legacy `Subagent` struct and keyword-based matching is still available for backward compatibility:
```rust
// Legacy API (still works)
let agent = Subagent::new(
"reader".to_string(),
"Read-only agent".to_string(),
vec!["read".to_string()],
vec![Tool::Read, Tool::Grep],
);
```
**Migrate to new API:**
1. Use `SubagentRegistry` instead of custom keyword matching
2. Use `SubagentConfig` instead of direct agent instantiation
3. Use `spawn_subagent` instead of manual tool execution
## Testing
Run tests:
```bash
cargo test -p tools-task
```
All tests pass, including:
- Registry builtin registration
- Plugin agent registration
- Config builder pattern
- Legacy API backward compatibility
## Dependencies
- `plugins` - For `AgentDefinition` type
- `parking_lot` - For `RwLock` in thread-safe registry
- `permissions` - For tool permission checks
- `color-eyre` - For error handling
- `serde` / `serde_json` - For serialization
## Future Work
1. **Implement spawn_subagent:** Complete the actual subagent spawning logic
2. **Add Clone to PermissionManager:** Required for parallel execution
3. **System Prompt Support:** Ensure agent loop respects system prompts
4. **Tool Filtering:** Implement filtered tool definitions based on whitelist
5. **Progress Tracking:** Add hooks for monitoring subagent progress
6. **Error Recovery:** Handle subagent failures gracefully
7. **Resource Limits:** Add timeout and resource constraints
8. **Inter-Agent Communication:** Allow agents to share context
## Related Files
- `/home/cnachtigall/data/git/projects/Owlibou/owlen/crates/tools/task/src/lib.rs` - Main implementation
- `/home/cnachtigall/data/git/projects/Owlibou/owlen/crates/tools/task/Cargo.toml` - Dependencies
- `/home/cnachtigall/data/git/projects/Owlibou/owlen/crates/platform/plugins/src/lib.rs` - AgentDefinition type
- `/home/cnachtigall/data/git/projects/Owlibou/owlen/crates/core/agent/src/lib.rs` - Agent execution loop
- `/home/cnachtigall/data/git/projects/Owlibou/owlen/crates/platform/permissions/src/lib.rs` - Permission system