@@ -450,6 +450,52 @@ def test_empty_response_retry_budget_extends_for_late_stage_multi_artifact_progr |
| 450 | 450 | assert "Follow the same one-file-at-a-time mutation pattern" in decision.retry_message |
| 451 | 451 | |
| 452 | 452 | |
| 453 | +def test_empty_response_retry_budget_extends_when_concrete_next_output_is_known( |
| 454 | + temp_dir: Path, |
| 455 | +) -> None: |
| 456 | + context = build_context( |
| 457 | + temp_dir=temp_dir, |
| 458 | + use_react=False, |
| 459 | + ) |
| 460 | + repairer = ResponseRepairer(context) |
| 461 | + |
| 462 | + implementation_plan = temp_dir / "implementation.md" |
| 463 | + implementation_plan.write_text( |
| 464 | + "\n".join( |
| 465 | + [ |
| 466 | + "# Implementation Plan", |
| 467 | + "", |
| 468 | + "## File Changes", |
| 469 | + f"- `{temp_dir / 'guides' / 'nginx' / 'index.html'}`", |
| 470 | + f"- `{temp_dir / 'guides' / 'nginx' / 'chapters'}`", |
| 471 | + "", |
| 472 | + ] |
| 473 | + ) |
| 474 | + ) |
| 475 | + |
| 476 | + dod = create_definition_of_done("Create a multi-file nginx guide.") |
| 477 | + dod.implementation_plan = str(implementation_plan) |
| 478 | + dod.pending_items.append("Develop the main index.html file for the nginx guide") |
| 479 | + |
| 480 | + decision = repairer.handle_empty_response( |
| 481 | + task="Create a multi-file nginx guide.", |
| 482 | + original_task=None, |
| 483 | + empty_retry_count=3, |
| 484 | + max_empty_retries=2, |
| 485 | + dod=dod, |
| 486 | + ) |
| 487 | + |
| 488 | + assert decision.should_continue is True |
| 489 | + assert decision.retry_message is not None |
| 490 | + assert "retry 3/4" in decision.retry_message |
| 491 | + assert "Next missing planned artifact: `index.html`" in decision.retry_message |
| 492 | + assert ( |
| 493 | + "Resume with this exact next step: continue `Develop the main index.html file for the nginx guide` " |
| 494 | + "by creating `index.html`." |
| 495 | + in decision.retry_message |
| 496 | + ) |
| 497 | + |
| 498 | + |
| 453 | 499 | def test_empty_response_retry_uses_compact_prompt_after_substantial_progress( |
| 454 | 500 | temp_dir: Path, |
| 455 | 501 | ) -> None: |