@@ -1206,6 +1206,60 @@ Respond with ONLY the JSON:
12061206 coverageSummary = getCoverageSummary ( coverageTargets ) ;
12071207 }
12081208
1209+ // Third chance: one more pass if coverage is still below 70%
1210+ if ( ! skipHeavyPasses && shouldRunLowCoverageSecondChance ( coverageSummary ) ) {
1211+ logger . warn ( {
1212+ message : `[AGENT-COVERAGE-THIRD-CHANCE] Coverage still low after second chance (${ coverageSummary . touchedTargets } /${ coverageSummary . totalTargets } ). Running final inspection pass.` ,
1213+ context : 'AgentLoop' ,
1214+ metadata : {
1215+ coverage : coverageSummary ,
1216+ } ,
1217+ } ) ;
1218+
1219+ const coverageThirdChance = await runLowCoverageSecondChance ( {
1220+ input,
1221+ byokConfig : secrets . byokConfig ,
1222+ tools,
1223+ coverageTargets,
1224+ allToolCalls,
1225+ totalInputTokens,
1226+ totalOutputTokens,
1227+ totalReasoningTokens,
1228+ } ) ;
1229+
1230+ totalInputTokens = coverageThirdChance . totalInputTokens ;
1231+ totalOutputTokens = coverageThirdChance . totalOutputTokens ;
1232+ totalReasoningTokens = coverageThirdChance . totalReasoningTokens ;
1233+
1234+ if ( coverageThirdChance . text ) {
1235+ let extraFindings = tryParseFindings ( coverageThirdChance . text ) ;
1236+
1237+ if ( ! extraFindings && coverageThirdChance . text . length > 50 ) {
1238+ const fallbackResult = await structureWithFallbackModel (
1239+ coverageThirdChance . text ,
1240+ secrets . byokConfig ,
1241+ input . telemetryMetadata ?. organizationId ,
1242+ ) ;
1243+ if ( fallbackResult ) {
1244+ extraFindings = fallbackResult . findings ;
1245+ totalInputTokens += fallbackResult . usage . inputTokens ;
1246+ totalOutputTokens += fallbackResult . usage . outputTokens ;
1247+ totalReasoningTokens +=
1248+ fallbackResult . usage . reasoningTokens ;
1249+ }
1250+ }
1251+
1252+ if ( extraFindings ) {
1253+ findings = mergeFindings ( findings , extraFindings ) ;
1254+ if ( source === 'empty' ) {
1255+ source = 'json-parse' ;
1256+ }
1257+ }
1258+ }
1259+
1260+ coverageSummary = getCoverageSummary ( coverageTargets ) ;
1261+ }
1262+
12091263 if ( ! skipHeavyPasses ) {
12101264 const synthesisRescue = await runSynthesisRescuePass ( {
12111265 input,
@@ -1462,10 +1516,10 @@ Investigate the remaining changed files now.
14621516- If no new findings appear, return an empty suggestions array.
14631517` ,
14641518 tools,
1465- stopWhen : stepCountIs ( 6 ) ,
1519+ stopWhen : stepCountIs ( MAX_STEPS_NORMAL ) ,
14661520 prepareStep : ( { stepNumber } : any ) => {
14671521 recoveryStep = stepNumber ;
1468- if ( stepNumber >= 5 ) {
1522+ if ( stepNumber >= MAX_STEPS_NORMAL - 1 ) {
14691523 return {
14701524 toolChoice : 'none' as const ,
14711525 activeTools : [ ] ,
@@ -1644,10 +1698,10 @@ Instructions:
16441698- Be surgical: inspect remaining files, then return ONLY JSON with ADDITIONAL findings.
16451699- If the remaining files are safe, return an empty suggestions array.` ,
16461700 tools,
1647- stopWhen : stepCountIs ( 5 ) ,
1701+ stopWhen : stepCountIs ( MAX_STEPS_NORMAL ) ,
16481702 prepareStep : ( { stepNumber } : any ) => {
16491703 secondChanceStep = stepNumber ;
1650- if ( stepNumber >= 4 ) {
1704+ if ( stepNumber >= MAX_STEPS_NORMAL - 1 ) {
16511705 return {
16521706 toolChoice : 'none' as const ,
16531707 activeTools : [ ] ,
0 commit comments