206 lines
7.0 KiB
Markdown
206 lines
7.0 KiB
Markdown
|
|
# Sub-Agent Orchestration System
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
Ajarbot now supports **dynamic sub-agent spawning** - the ability to create specialized agents on-demand for complex tasks. The main agent can delegate work to specialists with focused system prompts, reducing context window bloat and improving task efficiency.
|
||
|
|
|
||
|
|
## Architecture
|
||
|
|
|
||
|
|
```
|
||
|
|
Main Agent (Garvis)
|
||
|
|
├─> Handles general chat, memory, scheduling
|
||
|
|
├─> Can spawn sub-agents dynamically
|
||
|
|
└─> Sub-agents share tools and (optionally) memory
|
||
|
|
|
||
|
|
Sub-Agent (Specialist)
|
||
|
|
├─> Focused system prompt (no SOUL, user profile overhead)
|
||
|
|
├─> Own conversation history (isolated context)
|
||
|
|
├─> Can use all 24 tools
|
||
|
|
└─> Returns result to main agent
|
||
|
|
```
|
||
|
|
|
||
|
|
## Key Features
|
||
|
|
|
||
|
|
- **Dynamic spawning**: Create specialists at runtime, no hardcoded definitions
|
||
|
|
- **Caching**: Reuse specialists across multiple calls (agent_id parameter)
|
||
|
|
- **Memory sharing**: Sub-agents can share memory workspace with main agent
|
||
|
|
- **Tool access**: All tools available to sub-agents (file, web, zettelkasten, Google)
|
||
|
|
- **Isolation**: Each sub-agent has separate conversation history
|
||
|
|
|
||
|
|
## Usage
|
||
|
|
|
||
|
|
### Method 1: Manual Spawning
|
||
|
|
|
||
|
|
```python
|
||
|
|
# Spawn a specialist
|
||
|
|
specialist = agent.spawn_sub_agent(
|
||
|
|
specialist_prompt="You are a zettelkasten expert. Focus ONLY on note organization.",
|
||
|
|
agent_id="zettelkasten_processor" # Optional: cache for reuse
|
||
|
|
)
|
||
|
|
|
||
|
|
# Use the specialist
|
||
|
|
result = specialist.chat("Process my fleeting notes", username="jordan")
|
||
|
|
```
|
||
|
|
|
||
|
|
### Method 2: Delegation (Recommended)
|
||
|
|
|
||
|
|
```python
|
||
|
|
# One-off delegation (specialist not cached)
|
||
|
|
result = agent.delegate(
|
||
|
|
task="Analyze my emails and extract action items",
|
||
|
|
specialist_prompt="You are an email analyst. Extract action items and deadlines.",
|
||
|
|
username="jordan"
|
||
|
|
)
|
||
|
|
|
||
|
|
# Cached delegation (specialist reused)
|
||
|
|
result = agent.delegate(
|
||
|
|
task="Create permanent notes from my fleeting notes",
|
||
|
|
specialist_prompt="You are a zettelkasten specialist. Focus on note linking.",
|
||
|
|
username="jordan",
|
||
|
|
agent_id="zettelkasten_processor" # Cached for future use
|
||
|
|
)
|
||
|
|
```
|
||
|
|
|
||
|
|
### Method 3: LLM-Driven Orchestration (Future)
|
||
|
|
|
||
|
|
The main agent can analyze requests and decide when to delegate:
|
||
|
|
|
||
|
|
```python
|
||
|
|
def _should_delegate(self, user_message: str) -> Optional[str]:
|
||
|
|
"""Let LLM decide if delegation is needed."""
|
||
|
|
# Ask LLM: "Should this be delegated? If yes, generate specialist prompt"
|
||
|
|
# Return specialist_prompt if delegation needed, None otherwise
|
||
|
|
pass
|
||
|
|
```
|
||
|
|
|
||
|
|
## Use Cases
|
||
|
|
|
||
|
|
### Complex Zettelkasten Operations
|
||
|
|
```python
|
||
|
|
# Main agent detects: "This requires deep note processing"
|
||
|
|
specialist = agent.spawn_sub_agent(
|
||
|
|
specialist_prompt="""You are a zettelkasten expert. Your ONLY job is:
|
||
|
|
- Process fleeting notes into permanent notes
|
||
|
|
- Find semantic connections using hybrid search
|
||
|
|
- Create wiki-style links between related concepts
|
||
|
|
Stay focused on knowledge management.""",
|
||
|
|
agent_id="zettelkasten_processor"
|
||
|
|
)
|
||
|
|
```
|
||
|
|
|
||
|
|
### Email Intelligence
|
||
|
|
```python
|
||
|
|
specialist = agent.spawn_sub_agent(
|
||
|
|
specialist_prompt="""You are an email analyst. Your ONLY job is:
|
||
|
|
- Summarize email threads
|
||
|
|
- Extract action items and deadlines
|
||
|
|
- Identify patterns in communication
|
||
|
|
Stay focused on email analysis.""",
|
||
|
|
agent_id="email_analyst"
|
||
|
|
)
|
||
|
|
```
|
||
|
|
|
||
|
|
### Calendar Optimization
|
||
|
|
```python
|
||
|
|
specialist = agent.spawn_sub_agent(
|
||
|
|
specialist_prompt="""You are a calendar optimization expert. Your ONLY job is:
|
||
|
|
- Find scheduling conflicts
|
||
|
|
- Suggest optimal meeting times
|
||
|
|
- Identify time-blocking opportunities
|
||
|
|
Stay focused on schedule management.""",
|
||
|
|
agent_id="calendar_optimizer"
|
||
|
|
)
|
||
|
|
```
|
||
|
|
|
||
|
|
## Benefits
|
||
|
|
|
||
|
|
1. **Reduced Context Window**: Specialists don't load SOUL.md, user profiles, or irrelevant memory
|
||
|
|
2. **Focused Performance**: Specialists stay on-task without distractions
|
||
|
|
3. **Token Efficiency**: Smaller system prompts = lower token usage
|
||
|
|
4. **Parallel Execution**: Can spawn multiple specialists simultaneously (future)
|
||
|
|
5. **Learning Over Time**: Main agent learns when to delegate based on patterns
|
||
|
|
|
||
|
|
## Configuration
|
||
|
|
|
||
|
|
No configuration needed! The infrastructure is ready to use. You can:
|
||
|
|
|
||
|
|
1. **Add specialists later**: Define common specialists in a config file
|
||
|
|
2. **LLM-driven delegation**: Let the main agent decide when to delegate
|
||
|
|
3. **Parallel execution**: Spawn multiple specialists for complex workflows
|
||
|
|
4. **Custom workspaces**: Give specialists isolated memory (set `share_memory=False`)
|
||
|
|
|
||
|
|
## Implementation Details
|
||
|
|
|
||
|
|
### Code Location
|
||
|
|
- **agent.py**: Lines 25-90 (sub-agent infrastructure)
|
||
|
|
- `spawn_sub_agent()`: Create specialist with custom prompt
|
||
|
|
- `delegate()`: Convenience method for one-off delegation
|
||
|
|
- `is_sub_agent`, `specialist_prompt`: Instance variables
|
||
|
|
- `sub_agents`: Cache dictionary
|
||
|
|
|
||
|
|
### Thread Safety
|
||
|
|
- Sub-agents have their own `_chat_lock`
|
||
|
|
- Safe to spawn from multiple threads
|
||
|
|
- Cached specialists are reused (no duplicate spawning)
|
||
|
|
|
||
|
|
### Memory Sharing
|
||
|
|
- Default: Sub-agents share main memory workspace
|
||
|
|
- Optional: Isolated workspace at `memory_workspace/sub_agents/{agent_id}/`
|
||
|
|
- Shared memory = specialists can access/update zettelkasten vault
|
||
|
|
|
||
|
|
## Future Enhancements
|
||
|
|
|
||
|
|
1. **Specialist Registry**: Define common specialists in `config/specialists.yaml`
|
||
|
|
2. **Auto-Delegation**: Main agent auto-detects when to delegate
|
||
|
|
3. **Parallel Execution**: Run multiple specialists concurrently
|
||
|
|
4. **Result Synthesis**: Main agent combines outputs from multiple specialists
|
||
|
|
5. **Learning System**: Track which specialists work best for which tasks
|
||
|
|
|
||
|
|
## Example Workflows
|
||
|
|
|
||
|
|
### Workflow 1: Zettelkasten Processing with Delegation
|
||
|
|
```python
|
||
|
|
# User: "Process my fleeting notes about AI and machine learning"
|
||
|
|
# Main agent detects: complex zettelkasten task
|
||
|
|
|
||
|
|
result = agent.delegate(
|
||
|
|
task="Find all fleeting notes tagged 'AI' or 'machine-learning', process into permanent notes, and discover connections",
|
||
|
|
specialist_prompt="You are a zettelkasten expert. Use hybrid search to find semantic connections. Create permanent notes with smart links.",
|
||
|
|
username="jordan",
|
||
|
|
agent_id="zettelkasten_processor"
|
||
|
|
)
|
||
|
|
|
||
|
|
# Specialist:
|
||
|
|
# 1. search_by_tags(tags=["AI", "machine-learning", "fleeting"])
|
||
|
|
# 2. For each note: permanent_note() with auto-linking
|
||
|
|
# 3. Returns: "Created 5 permanent notes with 18 discovered connections"
|
||
|
|
|
||
|
|
# Main agent synthesizes:
|
||
|
|
# "Sir, I've processed your AI and ML notes. Five concepts emerged with particularly
|
||
|
|
# interesting connections to your existing work on neural architecture..."
|
||
|
|
```
|
||
|
|
|
||
|
|
### Workflow 2: Email + Calendar Coordination
|
||
|
|
```python
|
||
|
|
# User: "Find meetings next week and check if I have email threads about them"
|
||
|
|
|
||
|
|
# Spawn two specialists in parallel (future feature)
|
||
|
|
email_result = agent.delegate(
|
||
|
|
task="Search emails for threads about meetings",
|
||
|
|
specialist_prompt="Email analyst. Extract meeting context.",
|
||
|
|
agent_id="email_analyst"
|
||
|
|
)
|
||
|
|
|
||
|
|
calendar_result = agent.delegate(
|
||
|
|
task="List all meetings next week",
|
||
|
|
specialist_prompt="Calendar expert. Get meeting details.",
|
||
|
|
agent_id="calendar_optimizer"
|
||
|
|
)
|
||
|
|
|
||
|
|
# Main agent synthesizes both results
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
**Status**: Infrastructure complete, ready to use. Add specialists as patterns emerge!
|