feat: Opus escalation for INCONCLUSIVE issues

Sonnet tries first. If INCONCLUSIVE, automatically retries with
claude-opus-4-6 (30 turns). Disable with QA_OPUS_ESCALATION=0.
Also: model param added to ResearchOptions for flexibility.
This commit is contained in:
snomiao
2026-04-14 13:14:33 +00:00
parent 3154865ce2
commit a2da58eb0f
2 changed files with 25 additions and 2 deletions

View File

@@ -35,6 +35,7 @@ interface ResearchOptions {
anthropicApiKey?: string
maxTurns?: number
timeBudgetMs?: number
model?: string
}
export type ReproMethod = 'e2e_test' | 'video' | 'both' | 'none'
@@ -602,7 +603,7 @@ ${issueContext}`
prompt:
'Write a Playwright E2E test that reproduces the reported bug. Use inspect() to discover selectors, readFixture() or readTest() if you need to understand the fixture API or see existing test patterns, writeTest() to write the test, runTest() to execute it. Iterate until it works or you determine the bug cannot be reproduced.',
options: {
model: 'claude-sonnet-4-6',
model: opts.model ?? 'claude-sonnet-4-6',
systemPrompt,
...(anthropicApiKey ? { apiKey: anthropicApiKey } : {}),
maxTurns,

View File

@@ -1952,7 +1952,7 @@ async function main() {
// QA guide not available
}
}
const research = await runResearchPhase({
let research = await runResearchPhase({
page,
issueContext: issueCtx,
qaGuide: qaGuideText,
@@ -1963,6 +1963,28 @@ async function main() {
console.warn(
`Research complete: ${research.verdict}${research.summary.slice(0, 100)}`
)
// Opus escalation: if Sonnet couldn't reproduce, try Opus
if (
research.verdict === 'INCONCLUSIVE' &&
anthropicKey &&
process.env.QA_OPUS_ESCALATION !== '0'
) {
console.warn('Escalating to claude-opus-4-6 for complex issue...')
research = await runResearchPhase({
page,
issueContext: issueCtx,
qaGuide: qaGuideText,
outputDir: opts.outputDir,
serverUrl: opts.serverUrl,
anthropicApiKey: anthropicKey,
model: 'claude-opus-4-6',
maxTurns: 30
})
console.warn(
`Opus result: ${research.verdict}${research.summary.slice(0, 100)}`
)
}
console.warn(`Evidence: ${research.evidence.slice(0, 200)}`)
// ═══ Phase 2: Record demo video with demowright ═══