name: ‘step-03-generate-tests’ description: ‘Orchestrate adaptive test generation (agent-team, subagent, or sequential)’
Select execution mode deterministically, then generate tests using agent-team, subagent, or sequential execution while preserving the same output contract. Worker selection depends on {detected_stack}.
{communication_language}tea_execution_mode, tea_capability_probe)CRITICAL: Follow this sequence exactly. Do not skip, reorder, or improvise.
Generate unique timestamp for temp file naming:
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
Prepare input context for subagents:
const parseBooleanFlag = (value, defaultValue = true) => {
if (typeof value === 'string') {
const normalized = value.trim().toLowerCase();
if (['false', '0', 'off', 'no'].includes(normalized)) return false;
if (['true', '1', 'on', 'yes'].includes(normalized)) return true;
}
if (value === undefined || value === null) return defaultValue;
return Boolean(value);
};
const subagentContext = {
features: /* from Step 2 coverage plan */,
knowledge_fragments_loaded: /* list of fragments */,
config: {
test_framework: config.test_framework,
use_playwright_utils: config.tea_use_playwright_utils,
use_pactjs_utils: config.tea_use_pactjs_utils,
pact_mcp: config.tea_pact_mcp, // "mcp" | "none"
browser_automation: config.tea_browser_automation, // "auto" | "cli" | "mcp" | "none"
detected_stack: '{detected_stack}', // "frontend" | "backend" | "fullstack"
execution_mode: config.tea_execution_mode || 'auto', // "auto" | "subagent" | "agent-team" | "sequential"
capability_probe: parseBooleanFlag(config.tea_capability_probe, true), // supports booleans and "false"/"true" strings
provider_endpoint_map: /* from Step 2 coverage plan, if use_pactjs_utils enabled */,
},
timestamp: timestamp
};
const normalizeUserExecutionMode = (mode) => {
if (typeof mode !== 'string') return null;
const normalized = mode.trim().toLowerCase().replace(/[-_]/g, ' ').replace(/\s+/g, ' ');
if (normalized === 'auto') return 'auto';
if (normalized === 'sequential') return 'sequential';
if (normalized === 'subagent' || normalized === 'sub agent' || normalized === 'subagents' || normalized === 'sub agents') {
return 'subagent';
}
if (normalized === 'agent team' || normalized === 'agent teams' || normalized === 'agentteam') {
return 'agent-team';
}
return null;
};
const normalizeConfigExecutionMode = (mode) => {
if (mode === 'subagent') return 'subagent';
if (mode === 'auto' || mode === 'sequential' || mode === 'subagent' || mode === 'agent-team') {
return mode;
}
return null;
};
// Explicit user instruction in the active run takes priority over config.
const explicitModeFromUser = normalizeUserExecutionMode(runtime.getExplicitExecutionModeHint?.() || null);
const requestedMode = explicitModeFromUser || normalizeConfigExecutionMode(subagentContext.config.execution_mode) || 'auto';
const probeEnabled = subagentContext.config.capability_probe;
const supports = {
subagent: false,
agentTeam: false,
};
if (probeEnabled) {
// Probe using runtime-native capability checks or a no-op launch test.
supports.subagent = runtime.canLaunchSubagents?.() === true;
supports.agentTeam = runtime.canLaunchAgentTeams?.() === true;
}
let resolvedMode = requestedMode;
if (requestedMode === 'auto') {
if (supports.agentTeam) resolvedMode = 'agent-team';
else if (supports.subagent) resolvedMode = 'subagent';
else resolvedMode = 'sequential';
} else if (probeEnabled && requestedMode === 'agent-team' && !supports.agentTeam) {
resolvedMode = supports.subagent ? 'subagent' : 'sequential';
} else if (probeEnabled && requestedMode === 'subagent' && !supports.subagent) {
resolvedMode = 'sequential';
}
subagentContext.execution = {
requestedMode,
resolvedMode,
probeEnabled,
supports,
};
Resolution precedence:
agent team => agent-team; subagent => subagent; sequential; auto)tea_execution_mode from configIf probing is disabled, honor the requested mode strictly. If that mode cannot be executed at runtime, fail with explicit error instead of silent fallback.
Report selected mode before dispatch:
⚙️ Execution Mode Resolution:
- Requested: {requestedMode}
- Probe Enabled: {probeEnabled}
- Supports agent-team: {supports.agentTeam}
- Supports subagent: {supports.subagent}
- Resolved: {resolvedMode}
Select subagents based on {detected_stack}:
{detected_stack} |
Subagent A (API) | Subagent B (E2E) | Subagent B-backend |
|---|---|---|---|
frontend |
Launch | Launch | Skip |
backend |
Launch | Skip | Launch |
fullstack |
Launch | Launch | Launch |
When resolvedMode is agent-team or subagent, let the runtime decide concurrency and scheduling. TEA does not impose an additional worker ceiling.
When use_pactjs_utils is enabled, the API test generation subagent (step-03a) also generates:
createProviderState for type-safe provider statesbuildVerifierOptions for one-call verifier setupbuildMessageVerifierOptions if async/Kafka patterns detectedcreateRequestFilter, shared state constantscontract-testing.md Provider Scrutiny Protocol)When pact_mcp is "mcp", the subagent can use SmartBear MCP tools to fetch existing provider states and generate tests informed by broker data.
Dispatch worker:
./step-03a-subagent-api.md/tmp/tea-automate-api-tests-${timestamp}.jsonsubagentContextagent-team or subagent: launch non-blockingsequential: run blocking and wait before next dispatchSystem Action:
🚀 Launching Subagent A: API Test Generation
📝 Output: /tmp/tea-automate-api-tests-${timestamp}.json
⚙️ Mode: ${resolvedMode}
⏳ Status: Running...
If {detected_stack} is frontend or fullstack:
Dispatch worker:
./step-03b-subagent-e2e.md/tmp/tea-automate-e2e-tests-${timestamp}.jsonsubagentContextagent-team or subagent: launch non-blockingsequential: run blocking and wait before next dispatchSystem Action:
🚀 Launching Subagent B: E2E Test Generation
📝 Output: /tmp/tea-automate-e2e-tests-${timestamp}.json
⚙️ Mode: ${resolvedMode}
⏳ Status: Running...
If {detected_stack} is backend: Skip this subagent.
If {detected_stack} is backend or fullstack:
Dispatch worker:
./step-03b-subagent-backend.md/tmp/tea-automate-backend-tests-${timestamp}.jsonsubagentContextagent-team or subagent: launch non-blockingsequential: run blocking and wait before next dispatchSystem Action:
🚀 Launching Subagent B-backend: Backend Test Generation
📝 Output: /tmp/tea-automate-backend-tests-${timestamp}.json
⚙️ Mode: ${resolvedMode}
⏳ Status: Running...
If {detected_stack} is frontend: Skip this subagent.
If resolvedMode is agent-team or subagent:
⏳ Waiting for subagents to complete...
├── Subagent A (API): Running... ⟳
├── Subagent B (E2E): Running... ⟳ [if frontend/fullstack]
└── Subagent B-backend: Running... ⟳ [if backend/fullstack]
[... time passes ...]
├── Subagent A (API): Complete ✅
├── Subagent B (E2E): Complete ✅ [if frontend/fullstack]
└── Subagent B-backend: Complete ✅ [if backend/fullstack]
✅ All subagents completed successfully!
If resolvedMode is sequential:
✅ Sequential mode: each worker already completed during dispatch.
Verify outputs exist (based on {detected_stack}):
const apiOutputExists = fs.existsSync(`/tmp/tea-automate-api-tests-${timestamp}.json`);
// Check based on detected_stack
if (detected_stack === 'frontend' || detected_stack === 'fullstack') {
const e2eOutputExists = fs.existsSync(`/tmp/tea-automate-e2e-tests-${timestamp}.json`);
if (!e2eOutputExists) throw new Error('E2E subagent output missing!');
}
if (detected_stack === 'backend' || detected_stack === 'fullstack') {
const backendOutputExists = fs.existsSync(`/tmp/tea-automate-backend-tests-${timestamp}.json`);
if (!backendOutputExists) throw new Error('Backend subagent output missing!');
}
if (!apiOutputExists) throw new Error('API subagent output missing!');
The aggregate step expects both outputs to include success, but the payload shapes are intentionally different:
step-03b-subagent-e2e.md output includes success, subagent, tests, fixture_needs, knowledge_fragments_used, test_count, and summary.step-03b-subagent-backend.md output includes success, subagent, subagentType, testsGenerated, coverageSummary (with fixtureNeeds), status, knowledge_fragments_used, and summary.The aggregate step reads whichever output file(s) exist based on {detected_stack} and must use the matching schema per subagent type.
Display performance metrics:
🚀 Performance Report:
- Execution Mode: {resolvedMode}
- Stack Type: {detected_stack}
- API Test Generation: ~X minutes
- E2E Test Generation: ~Y minutes [if frontend/fullstack]
- Backend Test Generation: ~Z minutes [if backend/fullstack]
- Total Elapsed: ~mode-dependent
- Parallel Gain: ~40-70% faster when mode is subagent/agent-team
Load aggregation step:
Load next step: {nextStepFile}
The aggregation step (3C) will:
{detected_stack})Proceed to Step 3C (Aggregation) when:
Do NOT proceed if:
{detected_stack})Master Rule: Deterministic mode selection + stable output contract. Use the best supported mode, then aggregate normally.