summaryrefslogtreecommitdiff
path: root/Omni/Agent/Subagent/DESIGN.md
diff options
context:
space:
mode:
Diffstat (limited to 'Omni/Agent/Subagent/DESIGN.md')
-rw-r--r--Omni/Agent/Subagent/DESIGN.md352
1 files changed, 352 insertions, 0 deletions
diff --git a/Omni/Agent/Subagent/DESIGN.md b/Omni/Agent/Subagent/DESIGN.md
new file mode 100644
index 0000000..9fd20d1
--- /dev/null
+++ b/Omni/Agent/Subagent/DESIGN.md
@@ -0,0 +1,352 @@
+# Subagent System Design
+
+**Status:** Draft
+**Goal:** Enable Ava (orchestrator) to spawn specialized subagents for parallel, token-intensive tasks.
+
+## 1. Architecture Overview
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ Ava (Orchestrator) │
+│ Model: claude-sonnet-4.5 (via OpenRouter) │
+│ Role: Task decomposition, delegation, synthesis │
+│ Memory: Read/Write access │
+├─────────────────────────────────────────────────────────────┤
+│ Tools: spawn_subagent, all existing Ava tools │
+└───────────────┬───────────────────────────────────────┬─────┘
+ │ │
+ ▼ ▼
+┌───────────────────────────┐ ┌───────────────────────────┐
+│ Subagent: WebCrawler │ │ Subagent: CodeReviewer │
+│ Model: claude-haiku │ │ Model: claude-opus │
+│ Tools: web_search, │ │ Tools: read_file, │
+│ http_get, │ │ search_codebase, │
+│ python_exec │ │ run_bash │
+│ Memory: Read-only │ │ Memory: Read-only │
+│ Limits: 600s, $0.50 │ │ Limits: 300s, $1.00 │
+└───────────────────────────┘ └───────────────────────────┘
+```
+
+## 2. Key Design Decisions
+
+### 2.1 Hierarchical (No Sub-Subagents)
+- Subagents cannot spawn their own subagents
+- Prevents runaway token consumption
+- Keeps orchestrator in control
+
+### 2.2 Memory Access
+- **Orchestrator (Ava):** Full read/write to Memory system
+- **Subagents:** Read-only access to memories
+- Prevents conflicting memory writes from parallel agents
+
+### 2.3 Model Selection by Role
+| Role | Model | Rationale |
+|------|-------|-----------|
+| Orchestrator | claude-sonnet-4.5 | Balance of capability/cost |
+| Deep reasoning | claude-opus | Complex analysis, architecture |
+| Quick tasks | claude-haiku | Fast, cheap for simple lookups |
+| Code tasks | claude-sonnet | Good code understanding |
+
+### 2.4 Resource Limits (Guardrails)
+Each subagent has strict limits:
+- **Timeout:** Max wall-clock time (default: 600s)
+- **Cost cap:** Max spend in cents (default: 50c)
+- **Token cap:** Max total tokens (default: 100k)
+- **Iteration cap:** Max agent loop iterations (default: 20)
+
+### 2.5 Extended Thinking
+- Configurable per-subagent
+- Enabled for deep research tasks
+- Disabled for quick lookups
+
+## 3. Data Types
+
+```haskell
+-- | Subagent role determines toolset and model
+data SubagentRole
+ = WebCrawler -- Deep web research
+ | CodeReviewer -- Code analysis, PR review
+ | DataExtractor -- Structured data extraction
+ | Researcher -- General research with web+docs
+ | CustomRole Text -- User-defined role
+ deriving (Show, Eq, Generic)
+
+-- | Configuration for spawning a subagent
+data SubagentConfig = SubagentConfig
+ { subagentRole :: SubagentRole
+ , subagentTask :: Text -- What to accomplish
+ , subagentModel :: Maybe Text -- Override default model
+ , subagentTimeout :: Int -- Seconds (default: 600)
+ , subagentMaxCost :: Double -- Cents (default: 50.0)
+ , subagentMaxTokens :: Int -- Default: 100000
+ , subagentMaxIterations :: Int -- Default: 20
+ , subagentExtendedThinking :: Bool
+ , subagentContext :: Maybe Text -- Additional context from orchestrator
+ } deriving (Show, Eq, Generic)
+
+-- | Result returned by subagent to orchestrator
+data SubagentResult = SubagentResult
+ { subagentOutput :: Aeson.Value -- Structured result
+ , subagentSummary :: Text -- Human-readable summary
+ , subagentConfidence :: Double -- 0.0-1.0 confidence score
+ , subagentTokensUsed :: Int
+ , subagentCostCents :: Double
+ , subagentDuration :: Int -- Seconds
+ , subagentIterations :: Int
+ , subagentStatus :: SubagentStatus
+ } deriving (Show, Eq, Generic)
+
+data SubagentStatus
+ = SubagentSuccess
+ | SubagentTimeout
+ | SubagentCostExceeded
+ | SubagentError Text
+ deriving (Show, Eq, Generic)
+```
+
+## 4. Tool: spawn_subagent
+
+This is the main interface for the orchestrator to spawn subagents.
+
+```haskell
+spawnSubagentTool :: Engine.Tool
+spawnSubagentTool = Engine.Tool
+ { toolName = "spawn_subagent"
+ , toolDescription =
+ "Spawn a specialized subagent for a focused task. "
+ <> "Use for tasks that benefit from deep exploration, parallel execution, "
+ <> "or specialized tools. The subagent will iterate until task completion "
+ <> "or resource limits are reached."
+ , toolJsonSchema = ...
+ , toolExecute = executeSpawnSubagent
+ }
+```
+
+**Parameters:**
+```json
+{
+ "role": "web_crawler | code_reviewer | data_extractor | researcher | custom",
+ "task": "Research competitor pricing for podcast transcription services",
+ "context": "We're building a pricing page and need market data",
+ "model": "claude-haiku",
+ "timeout": 600,
+ "max_cost_cents": 50,
+ "extended_thinking": false
+}
+```
+
+**Response:**
+```json
+{
+ "status": "success",
+ "summary": "Found 5 competitors with pricing ranging from $0.10-$0.25/min",
+ "output": {
+ "competitors": [
+ {"name": "Otter.ai", "pricing": "$0.12/min", "features": ["..."]},
+ ...
+ ]
+ },
+ "confidence": 0.85,
+ "tokens_used": 45000,
+ "cost_cents": 23.5,
+ "duration_seconds": 180,
+ "iterations": 8
+}
+```
+
+## 5. Role-Specific Tool Sets
+
+### 5.1 WebCrawler
+```haskell
+webCrawlerTools :: [Engine.Tool]
+webCrawlerTools =
+ [ webSearchTool -- Search the web
+ , webReaderTool -- Fetch and parse web pages
+ , pythonExecTool -- Execute Python for data processing
+ ]
+```
+**Use case:** Deep market research, competitive analysis, documentation gathering
+
+### 5.2 CodeReviewer
+```haskell
+codeReviewerTools :: [Engine.Tool]
+codeReviewerTools =
+ [ readFileTool
+ , searchCodebaseTool
+ , searchAndReadTool
+ , runBashTool -- For running tests, linters
+ ]
+```
+**Use case:** PR review, architecture analysis, test verification
+
+### 5.3 DataExtractor
+```haskell
+dataExtractorTools :: [Engine.Tool]
+dataExtractorTools =
+ [ webReaderTool
+ , pythonExecTool
+ ]
+```
+**Use case:** Scraping structured data, parsing PDFs, extracting metrics
+
+### 5.4 Researcher
+```haskell
+researcherTools :: [Engine.Tool]
+researcherTools =
+ [ webSearchTool
+ , webReaderTool
+ , readFileTool
+ , searchCodebaseTool
+ ]
+```
+**Use case:** General research combining web and local codebase
+
+## 6. Subagent System Prompt Template
+
+```
+You are a specialized {ROLE} subagent working on a focused task.
+
+## Your Task
+{TASK}
+
+## Context from Orchestrator
+{CONTEXT}
+
+## Your Capabilities
+{TOOL_DESCRIPTIONS}
+
+## Guidelines
+1. Work iteratively: search → evaluate → refine → verify
+2. Return structured data when possible (JSON objects)
+3. Include confidence scores for your findings
+4. If stuck, explain what you tried and what didn't work
+5. Stop when you have sufficient information OR hit resource limits
+
+## Output Format
+When complete, provide:
+1. A structured result (JSON) with the requested data
+2. A brief summary of findings
+3. Confidence score (0.0-1.0) indicating reliability
+4. Any caveats or limitations
+```
+
+## 7. Orchestrator Delegation Logic
+
+The orchestrator (Ava) should spawn subagents when:
+
+1. **Deep research needed:** "Research all competitors in X market"
+2. **Parallel tasks:** Multiple independent subtasks that can run concurrently
+3. **Specialized tools:** Task requires tools the orchestrator shouldn't use directly
+4. **Token-intensive:** Task would consume excessive tokens in main context
+
+The orchestrator should NOT spawn subagents for:
+
+1. **Simple queries:** Quick lookups, single tool calls
+2. **Conversation continuation:** Multi-turn dialogue with user
+3. **Memory writes:** Tasks that need to update Ava's memory
+
+## 8. Execution Flow
+
+```
+1. Orchestrator calls spawn_subagent tool
+2. Subagent module:
+ a. Creates fresh agent config from SubagentConfig
+ b. Selects model based on role (or override)
+ c. Builds tool list for role
+ d. Constructs system prompt
+ e. Calls Engine.runAgentWithProvider
+ f. Monitors resource usage
+ g. Returns SubagentResult
+3. Orchestrator receives structured result
+4. Orchestrator synthesizes into response
+```
+
+## 9. Concurrency Model
+
+Initial implementation: **Sequential** (one subagent at a time)
+
+Future enhancement: **Parallel** spawning with:
+- `async` library for concurrent execution
+- Aggregate cost tracking across all subagents
+- Combined timeout for parallel group
+
+```haskell
+-- Future: Parallel spawning
+spawnParallel :: [SubagentConfig] -> IO [SubagentResult]
+spawnParallel configs = mapConcurrently runSubagent configs
+```
+
+## 10. Status Reporting
+
+Subagents report status back to the orchestrator via callbacks:
+
+```haskell
+data SubagentCallbacks = SubagentCallbacks
+ { onSubagentStart :: Text -> IO () -- "Starting web research..."
+ , onSubagentActivity :: Text -> IO () -- "Searching for X..."
+ , onSubagentToolCall :: Text -> Text -> IO () -- Tool name, args
+ , onSubagentComplete :: SubagentResult -> IO ()
+ }
+```
+
+For Telegram, this appears as:
+```
+🔍 Subagent [WebCrawler]: Starting research...
+🔍 Subagent [WebCrawler]: Searching "podcast transcription pricing"...
+🔍 Subagent [WebCrawler]: Reading otter.ai/pricing...
+✅ Subagent [WebCrawler]: Complete (180s, $0.24)
+```
+
+## 11. Implementation Plan
+
+### Phase 1: Core Infrastructure
+1. Create `Omni/Agent/Subagent.hs` with data types
+2. Implement `runSubagent` function using existing Engine
+3. Add `spawn_subagent` tool
+4. Basic WebCrawler role with existing web tools
+
+### Phase 2: Role Expansion
+1. Add CodeReviewer role
+2. Add DataExtractor role
+3. Add Researcher role
+4. Custom role support
+
+### Phase 3: Advanced Features
+1. Parallel subagent execution
+2. Extended thinking integration
+3. Cross-subagent context sharing
+4. Cost aggregation and budgeting
+
+## 12. Testing Strategy
+
+```haskell
+test :: Test.Tree
+test = Test.group "Omni.Agent.Subagent"
+ [ Test.unit "SubagentConfig JSON roundtrip" <| ...
+ , Test.unit "role selects correct tools" <| ...
+ , Test.unit "timeout terminates subagent" <| ...
+ , Test.unit "cost limit stops execution" <| ...
+ , Test.unit "WebCrawler role has web tools" <| ...
+ ]
+```
+
+## 13. Cost Analysis
+
+Based on Anthropic's research findings:
+- Subagents use ~15× more tokens than single-agent
+- But provide better results for complex tasks
+- 80% of performance variance from token budget
+
+**Budget recommendations:**
+| Task Type | Subagent Budget | Expected Tokens |
+|-----------|-----------------|-----------------|
+| Quick lookup | $0.10 | ~10k |
+| Standard research | $0.50 | ~50k |
+| Deep analysis | $2.00 | ~200k |
+
+## 14. References
+
+- [Claude Agent SDK - Subagents](https://platform.claude.com/docs/en/agent-sdk/subagents)
+- [Multi-Agent Research System](https://www.anthropic.com/engineering/multi-agent-research-system)
+- [OpenAI Agents Python](https://openai.github.io/openai-agents-python/agents/)
+- Existing: `Omni/Agent/Engine.hs`, `Omni/Agent/Provider.hs`, `Omni/Agent/Tools.hs`