tenseleyflow/loader / ede0506

Browse files

Compact concrete write retries

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
ede0506dbe0434405ceb3b19c94f4420e17e744d
Parents
44ab5d8
Tree
1b3c2e8

2 changed files

StatusFile+-
M src/loader/runtime/repair.py 16 12
M tests/test_repair.py 92 0
src/loader/runtime/repair.pymodified
@@ -420,6 +420,7 @@ class ResponseRepairer:
420420
             )
421421
         else:
422422
             first_line = f"Create `{concrete_target.name}` now."
423
+        compact_retry = retry_number >= 4
423424
 
424425
         lines = [
425426
             first_line,
@@ -429,25 +430,25 @@ class ResponseRepairer:
429430
             lines.append(
430431
                 f"Use the existing outline label `{outline_label}` for that file so it matches the current guide structure."
431432
             )
433
+        html_scaffold_line = self._known_existing_html_scaffold_line(
434
+            concrete_target,
435
+            require_first_substantive_output=True,
436
+        )
437
+        if html_scaffold_line:
438
+            lines.append(html_scaffold_line)
432439
         reference_line = self._known_reference_structure_line(
433440
             concrete_target,
434441
             require_first_substantive_output=True,
435442
         )
436
-        if reference_line:
443
+        if reference_line and not compact_retry:
437444
             lines.append(reference_line)
438445
         reference_cues_line = self._known_reference_cues_line(
439446
             concrete_target,
440447
             require_first_substantive_output=True,
441448
             retry_number=retry_number,
442449
         )
443
-        if reference_cues_line:
450
+        if reference_cues_line and not compact_retry:
444451
             lines.append(reference_cues_line)
445
-        html_scaffold_line = self._known_existing_html_scaffold_line(
446
-            concrete_target,
447
-            require_first_substantive_output=True,
448
-        )
449
-        if html_scaffold_line:
450
-            lines.append(html_scaffold_line)
451452
         html_starter_line = self._known_html_starter_shape_line(
452453
             concrete_target,
453454
             require_first_substantive_output=True,
@@ -456,10 +457,13 @@ class ResponseRepairer:
456457
         )
457458
         if html_starter_line:
458459
             lines.append(html_starter_line)
459
-        if _should_encourage_initial_version(
460
-            target=concrete_target,
461
-            has_confirmed_output_file_progress=True,
462
-            has_confirmed_substantive_output_file_progress=False,
460
+        if (
461
+            not compact_retry
462
+            and _should_encourage_initial_version(
463
+                target=concrete_target,
464
+                has_confirmed_output_file_progress=True,
465
+                has_confirmed_substantive_output_file_progress=False,
466
+            )
463467
         ):
464468
             lines.append(
465469
                 "Write a compact but real initial version of this file now, then refine or expand it in later edits."
tests/test_repair.pymodified
@@ -1362,6 +1362,98 @@ def test_compact_first_substantive_retry_reuses_known_reference_structure(
13621362
     )
13631363
 
13641364
 
1365
+def test_late_first_substantive_retry_trims_context_to_core_write_cues(
1366
+    temp_dir: Path,
1367
+) -> None:
1368
+    context = build_context(
1369
+        temp_dir=temp_dir,
1370
+        use_react=False,
1371
+    )
1372
+    repairer = ResponseRepairer(context)
1373
+
1374
+    guide_root = temp_dir / "guides" / "nginx"
1375
+    chapters = guide_root / "chapters"
1376
+    chapters.mkdir(parents=True)
1377
+    index_path = guide_root / "index.html"
1378
+    reference_chapter = temp_dir / "guides" / "fortran" / "chapters" / "01-introduction.html"
1379
+    reference_chapter.parent.mkdir(parents=True)
1380
+    reference_chapter.write_text("<h1>Chapter 1: Introduction to Fortran</h1>\n")
1381
+    index_path.write_text(
1382
+        "\n".join(
1383
+            [
1384
+                "<html>",
1385
+                '<a href="chapters/01-introduction.html">Chapter 1: Introduction to Nginx</a>',
1386
+                "</html>",
1387
+            ]
1388
+        )
1389
+        + "\n"
1390
+    )
1391
+    context.session.append(
1392
+        Message(
1393
+            role=Role.ASSISTANT,
1394
+            content="",
1395
+            tool_calls=[
1396
+                ToolCall(
1397
+                    id="call_ref",
1398
+                    name="read",
1399
+                    arguments={"file_path": str(reference_chapter)},
1400
+                )
1401
+            ],
1402
+        )
1403
+    )
1404
+
1405
+    implementation_plan = temp_dir / "implementation.md"
1406
+    implementation_plan.write_text(
1407
+        "\n".join(
1408
+            [
1409
+                "# Implementation Plan",
1410
+                "",
1411
+                "## File Changes",
1412
+                f"- `{guide_root}/`",
1413
+                f"- `{chapters}/`",
1414
+                f"- `{index_path}`",
1415
+                "",
1416
+            ]
1417
+        )
1418
+    )
1419
+
1420
+    dod = create_definition_of_done("Create a multi-file nginx guide.")
1421
+    dod.implementation_plan = str(implementation_plan)
1422
+    dod.touched_files.append(str(index_path))
1423
+    dod.completed_items.append("Develop the main index.html file with proper structure")
1424
+    dod.pending_items.append("Create chapter files following the established pattern")
1425
+
1426
+    decision = repairer.handle_empty_response(
1427
+        task="Create a multi-file nginx guide.",
1428
+        original_task=None,
1429
+        empty_retry_count=6,
1430
+        max_empty_retries=6,
1431
+        dod=dod,
1432
+    )
1433
+
1434
+    assert decision.should_continue is True
1435
+    assert decision.retry_message is not None
1436
+    assert (
1437
+        f"Reuse the existing `{display_runtime_path(index_path)}` head/style/container pattern "
1438
+        "for this chapter so the guide stays visually consistent; only adapt the title, heading, "
1439
+        "and chapter body content."
1440
+        in decision.retry_message
1441
+    )
1442
+    assert (
1443
+        "If you get stuck, start with `<title>Chapter 1: Introduction to Nginx</title>`, "
1444
+        "`<h1>Chapter 1: Introduction to Nginx</h1>`, one introductory paragraph, a couple "
1445
+        "of `<h2>` sections with short body text, and a back link to `../index.html`."
1446
+        in decision.retry_message
1447
+    )
1448
+    assert (
1449
+        f"You already read `{display_runtime_path(reference_chapter)}`; reuse its overall structure "
1450
+        "as the starting pattern for this new file, then adapt the content to the current target."
1451
+        not in decision.retry_message
1452
+    )
1453
+    assert "Reference cues from" not in decision.retry_message
1454
+    assert "Write a compact but real initial version of this file now" not in decision.retry_message
1455
+
1456
+
13651457
 def test_empty_response_retry_prefers_output_index_over_reference_index_with_same_name(
13661458
     temp_dir: Path,
13671459
 ) -> None: