# Testing Subagents - Step-by-Step Guide

**Purpose**: How to test subagents in standalone mode

**Last Updated**: 2026-01-09

---

## ⚠️ CRITICAL: Adding New Subagent to Framework

**Before testing**, you MUST update THREE locations in framework code:

### 1. `evals/framework/src/sdk/run-sdk-tests.ts` (~line 336)
Add to `subagentParentMap`:
```typescript
'contextscout': 'openagent',  // Maps subagent → parent
```

### 2. `evals/framework/src/sdk/run-sdk-tests.ts` (~line 414)
Add to `subagentPathMap`:
```typescript
'contextscout': 'ContextScout',  // Maps name → path
```

### 3. `evals/framework/src/sdk/test-runner.ts` (~line 238)
Add to `agentMap`:
```typescript
'contextscout': 'ContextScout.md',  // Maps name → file
```

**If missing from ANY map**: Tests will fail with "No test files found" or "Unknown subagent"

---

## Quick Start

```bash
# Test subagent directly (standalone mode)
cd evals/framework
npm run eval:sdk -- --subagent=contextscout --pattern="01-test.yaml"

# Test via delegation (integration mode)
npm run eval:sdk -- --subagent=contextscout --delegate --pattern="01-test.yaml"

# Debug mode
npm run eval:sdk -- --subagent=contextscout --pattern="01-test.yaml" --debug
```

---

## Step 1: Verify Agent File

**Check agent exists and has correct structure**:

```bash
# Check agent file
cat .opencode/agent/ContextScout.md | head -20

# Verify frontmatter
grep -A 5 "^id:" .opencode/agent/ContextScout.md
```

**Expected**:
```yaml
id: contextscout
name: ContextScout
category: subagents/core
type: subagent
mode: subagent  # ← Will be forced to 'primary' in standalone tests
```

---

## Step 2: Verify Test Configuration

**Check test config points to correct agent**:

```bash
cat evals/agents/ContextScout/config/config.yaml
```

**Expected**:
```yaml
agent: ContextScout  # ← Full path
model: anthropic/claude-sonnet-4-5
timeout: 60000
```

---

## Step 3: Run Standalone Test

**Use `--subagent` flag** (not `--agent`):

```bash
cd evals/framework
npm run eval:sdk -- --subagent=ContextScout --pattern="standalone/01-simple-discovery.yaml"
```

**What to Look For**:
```
⚡ Standalone Test Mode
   Subagent: contextscout
   Mode: Forced to 'primary' for direct testing
   
Testing agent: contextscout  # ← Should show subagent name
```

---

## Step 4: Verify Agent Loaded Correctly

**Check test results**:

```bash
# View latest results
cat evals/results/latest.json | jq '.meta'
```

**Expected**:
```json
{
  "agent": "ContextScout",  // ← Correct agent
  "model": "opencode/grok-code-fast",
  "timestamp": "2026-01-07T..."
}
```

**Red Flags**:
- `"agent": "core/openagent"` ← Wrong! OpenAgent is running instead
- `"agent": "contextscout"` ← Missing category prefix

---

## Step 5: Check Tool Usage

**Verify subagent used tools**:

```bash
# Check tool calls in output
cat evals/results/latest.json | jq '.tests[0]' | grep -A 5 "Tool Calls"
```

**Expected** (for ContextScout):
```
Tool Calls: 1
Tools Used: glob

Tool Call Details:
  1. glob: {"pattern":"*.md","path":".opencode/context/core"}
```

**Red Flags**:
- `Tool Calls: 0` ← Agent didn't use any tools
- `Tools Used: task` ← Parent agent delegating (wrong mode)

---

## Step 6: Analyze Failures

**If test fails, check violations**:

```bash
cat evals/results/latest.json | jq '.tests[0].violations'
```

**Common Issues**:

### Issue 1: No Tool Calls
```json
{
  "type": "missing-required-tool",
  "message": "Required tool 'glob' was not used"
}
```

**Cause**: Agent prompt doesn't emphasize tool usage  
**Fix**: Add critical rules section emphasizing tools (see `examples/subagent-prompt-structure.md`)

### Issue 2: Wrong Agent Running
```
Agent: OpenAgent
```

**Cause**: Used `--agent` instead of `--subagent`  
**Fix**: Use `--subagent=ContextScout`

### Issue 3: Tool Permission Denied
```json
{
  "type": "missing-approval",
  "message": "Execution tool 'bash' called without requesting approval"
}
```

**Cause**: Agent tried to use restricted tool  
**Fix**: See `errors/tool-permission-errors.md`

---

## Step 7: Validate Results

**Check test passed**:

```bash
# View summary
cat evals/results/latest.json | jq '.summary'
```

**Expected**:
```json
{
  "total": 1,
  "passed": 1,  // ← Should be 1
  "failed": 0,
  "pass_rate": 1.0
}
```

---

## Test File Organization

**Best Practice**: Organize by mode

```
evals/agents/ContextScout/tests/
├── standalone/           # Unit tests (--subagent flag)
│   ├── 01-simple-discovery.yaml
│   ├── 02-search-test.yaml
│   └── 03-extraction-test.yaml
└── delegation/           # Integration tests (--agent flag)
    ├── 01-openagent-delegates.yaml
    └── 02-context-loading.yaml
```

---

## Writing Good Test Prompts

**Be explicit about tool usage**:

❌ **Vague** (may not work):
```yaml
prompts:
  - text: |
      List all markdown files in .opencode/context/core/
```

✅ **Explicit** (works):
```yaml
prompts:
  - text: |
      Use the glob tool to find all markdown files in .opencode/context/core/
      
      You MUST use the glob tool like this:
      glob(pattern="*.md", path=".opencode/context/core")
      
      Then list the files you found.
```

---

## Quick Troubleshooting

| Symptom | Cause | Fix |
|---------|-------|-----|
| OpenAgent runs instead | Used `--agent` flag | Use `--subagent` flag |
| Tool calls: 0 | Prompt doesn't emphasize tools | Add critical rules section |
| Permission denied | Tool restricted in frontmatter | Check `tools:` and `permissions:` |
| Test timeout | Agent stuck/looping | Check prompt logic, add timeout |

---

## Related

- `concepts/subagent-testing-modes.md` - Understand standalone vs delegation
- `lookup/subagent-test-commands.md` - Quick command reference
- `errors/tool-permission-errors.md` - Common permission issues
- `examples/subagent-prompt-structure.md` - Optimized prompt structure

**Reference**: `evals/framework/src/sdk/run-sdk-tests.ts`
