tenseleyflow/loader / 1403a6a

Browse files

Persist TodoWrite resumes

Authored by mfwolffe <wolffemf@dukes.jmu.edu>
SHA
1403a6a1b81c3f2952cc48c1b44ba639e894d896
Parents
fa5d5a8
Tree
d76c856

2 changed files

StatusFile+-
M src/loader/runtime/tool_batches.py 3 3
M tests/test_tool_batches.py 38 25
src/loader/runtime/tool_batches.pymodified
@@ -1231,9 +1231,9 @@ class ToolBatchRunner:
12311231
                         "Perform the mutation now instead of spending another turn on "
12321232
                         "planning, rereads, or verification."
12331233
                     )
1234
-                    self.context.queue_ephemeral_steering_message(concrete_message)
1234
+                    self.context.queue_steering_message(concrete_message)
12351235
                     return
1236
-                self.context.queue_ephemeral_steering_message(
1236
+                self.context.queue_steering_message(
12371237
                     "Todo tracking is updated. Continue with the next pending item: "
12381238
                     f"`{next_pending}`. Use the current output files as the source of "
12391239
                     "truth, and do not reopen reference materials unless one specific "
@@ -1305,7 +1305,7 @@ class ToolBatchRunner:
13051305
             if next_pending
13061306
             else ""
13071307
         )
1308
-        self.context.queue_ephemeral_steering_message(
1308
+        self.context.queue_steering_message(
13091309
             "Todo tracking is updated. A declared output artifact is still missing."
13101310
             + next_pending_suffix
13111311
             + _missing_artifact_resume_suffix(
tests/test_tool_batches.pymodified
@@ -2288,8 +2288,10 @@ async def test_duplicate_observation_nudge_prioritizes_missing_artifact_over_rev
22882288
         verify_action=verify_action,
22892289
         auto_recover=False,
22902290
     )
2291
-    queued_messages: list[str] = []
2292
-    context.queue_steering_message_callback = queued_messages.append
2291
+    persistent_messages: list[str] = []
2292
+    ephemeral_messages: list[str] = []
2293
+    context.queue_steering_message_callback = persistent_messages.append
2294
+    context.queue_ephemeral_steering_message_callback = ephemeral_messages.append
22932295
     runner = ToolBatchRunner(context, DefinitionOfDoneStore(temp_dir))
22942296
     dod = create_definition_of_done("Create a multi-file nginx guide.")
22952297
     dod.implementation_plan = str(implementation_plan)
@@ -2322,8 +2324,8 @@ async def test_duplicate_observation_nudge_prioritizes_missing_artifact_over_rev
23222324
     )
23232325
     runner._queue_duplicate_observation_nudge(tool_call, dod=dod)  # type: ignore[attr-defined]
23242326
 
2325
-    assert queued_messages
2326
-    message = queued_messages[-1]
2327
+    assert persistent_messages
2328
+    message = persistent_messages[-1]
23272329
     assert "06-ssl-configuration.html" in message
23282330
     assert "Do not switch into review or consistency-check mode" in message
23292331
     assert (
@@ -2385,8 +2387,10 @@ async def test_tool_batch_runner_hands_off_to_verification_once_planned_artifact
23852387
         verify_action=verify_action,
23862388
         auto_recover=False,
23872389
     )
2388
-    queued_messages: list[str] = []
2389
-    context.queue_steering_message_callback = queued_messages.append
2390
+    persistent_messages: list[str] = []
2391
+    ephemeral_messages: list[str] = []
2392
+    context.queue_steering_message_callback = persistent_messages.append
2393
+    context.queue_ephemeral_steering_message_callback = ephemeral_messages.append
23902394
     runner = ToolBatchRunner(context, DefinitionOfDoneStore(temp_dir))
23912395
     dod = create_definition_of_done("Create a multi-file nginx guide.")
23922396
     dod.implementation_plan = str(implementation_plan)
@@ -2440,15 +2444,15 @@ async def test_tool_batch_runner_hands_off_to_verification_once_planned_artifact
24402444
 
24412445
     assert any(
24422446
         "All explicitly planned artifacts now exist." in message
2443
-        for message in queued_messages
2447
+        for message in persistent_messages
24442448
     )
24452449
     assert any(
24462450
         "Ensure all files are properly linked and formatted consistently" in message
2447
-        for message in queued_messages
2451
+        for message in persistent_messages
24482452
     )
24492453
     assert any(
24502454
         "Move to verification once no specific mismatch remains." in message
2451
-        for message in queued_messages
2455
+        for message in persistent_messages
24522456
     )
24532457
 
24542458
 
@@ -2503,8 +2507,10 @@ async def test_tool_batch_runner_mutation_handoff_points_at_next_missing_artifac
25032507
         verify_action=verify_action,
25042508
         auto_recover=False,
25052509
     )
2506
-    queued_messages: list[str] = []
2507
-    context.queue_steering_message_callback = queued_messages.append
2510
+    persistent_messages: list[str] = []
2511
+    ephemeral_messages: list[str] = []
2512
+    context.queue_steering_message_callback = persistent_messages.append
2513
+    context.queue_ephemeral_steering_message_callback = ephemeral_messages.append
25082514
     runner = ToolBatchRunner(context, DefinitionOfDoneStore(temp_dir))
25092515
     dod = create_definition_of_done("Create a multi-file nginx guide.")
25102516
     dod.implementation_plan = str(implementation_plan)
@@ -2552,8 +2558,8 @@ async def test_tool_batch_runner_mutation_handoff_points_at_next_missing_artifac
25522558
         consecutive_errors=0,
25532559
     )
25542560
 
2555
-    assert queued_messages
2556
-    message = queued_messages[-1]
2561
+    assert persistent_messages
2562
+    message = persistent_messages[-1]
25572563
     assert "Next step: create `01-getting-started.html`." in message
25582564
     assert (
25592565
         f"Prefer one `write(file_path=..., content=...)` call for `{chapter_one.resolve(strict=False)}` now."
@@ -2626,8 +2632,10 @@ async def test_tool_batch_runner_large_plan_does_not_claim_completion_early(
26262632
         verify_action=verify_action,
26272633
         auto_recover=False,
26282634
     )
2629
-    queued_messages: list[str] = []
2630
-    context.queue_steering_message_callback = queued_messages.append
2635
+    persistent_messages: list[str] = []
2636
+    ephemeral_messages: list[str] = []
2637
+    context.queue_steering_message_callback = persistent_messages.append
2638
+    context.queue_ephemeral_steering_message_callback = ephemeral_messages.append
26312639
     runner = ToolBatchRunner(context, DefinitionOfDoneStore(temp_dir))
26322640
     dod = create_definition_of_done("Create a thorough nginx guide.")
26332641
     dod.implementation_plan = str(implementation_plan)
@@ -2681,11 +2689,11 @@ async def test_tool_batch_runner_large_plan_does_not_claim_completion_early(
26812689
 
26822690
     assert any(
26832691
         "Resume by creating `06-performance-tuning.html` now." in message
2684
-        for message in queued_messages
2692
+        for message in ephemeral_messages
26852693
     )
26862694
     assert not any(
26872695
         "All explicitly planned artifacts now exist." in message
2688
-        for message in queued_messages
2696
+        for message in ephemeral_messages
26892697
     )
26902698
 
26912699
 
@@ -2747,8 +2755,10 @@ async def test_tool_batch_runner_uses_compact_missing_artifact_nudge_after_subst
27472755
         verify_action=verify_action,
27482756
         auto_recover=False,
27492757
     )
2750
-    queued_messages: list[str] = []
2751
-    context.queue_steering_message_callback = queued_messages.append
2758
+    persistent_messages: list[str] = []
2759
+    ephemeral_messages: list[str] = []
2760
+    context.queue_steering_message_callback = persistent_messages.append
2761
+    context.queue_ephemeral_steering_message_callback = ephemeral_messages.append
27522762
     runner = ToolBatchRunner(context, DefinitionOfDoneStore(temp_dir))
27532763
     dod = create_definition_of_done("Create a thorough nginx guide.")
27542764
     dod.implementation_plan = str(implementation_plan)
@@ -2802,8 +2812,8 @@ async def test_tool_batch_runner_uses_compact_missing_artifact_nudge_after_subst
28022812
         consecutive_errors=0,
28032813
     )
28042814
 
2805
-    assert queued_messages
2806
-    message = queued_messages[-1]
2815
+    assert ephemeral_messages
2816
+    message = ephemeral_messages[-1]
28072817
     assert "Resume by creating `05-advanced-features.html` now." in message
28082818
     assert "No TodoWrite, no verification, no rereads until that artifact exists." in message
28092819
     assert "refresh `TodoWrite`" not in message
@@ -2863,8 +2873,10 @@ async def test_tool_batch_runner_todowrite_with_missing_artifact_requeues_exact_
28632873
         verify_action=verify_action,
28642874
         auto_recover=False,
28652875
     )
2866
-    queued_messages: list[str] = []
2867
-    context.queue_steering_message_callback = queued_messages.append
2876
+    persistent_messages: list[str] = []
2877
+    ephemeral_messages: list[str] = []
2878
+    context.queue_steering_message_callback = persistent_messages.append
2879
+    context.queue_ephemeral_steering_message_callback = ephemeral_messages.append
28682880
     runner = ToolBatchRunner(context, DefinitionOfDoneStore(temp_dir))
28692881
     dod = create_definition_of_done("Create a multi-file nginx guide.")
28702882
     dod.implementation_plan = str(implementation_plan)
@@ -2942,12 +2954,13 @@ async def test_tool_batch_runner_todowrite_with_missing_artifact_requeues_exact_
29422954
         consecutive_errors=0,
29432955
     )
29442956
 
2945
-    assert queued_messages
2946
-    message = queued_messages[-1]
2957
+    assert persistent_messages
2958
+    message = persistent_messages[-1]
29472959
     assert "Todo tracking is updated. A declared output artifact is still missing." in message
29482960
     assert "Resume by creating `02-installation.html` now." in message
29492961
     assert "refresh `TodoWrite`" in message
29502962
     assert "Do not spend the next turn on TodoWrite alone" in message
2963
+    assert ephemeral_messages == []
29512964
 
29522965
 
29532966
 @pytest.mark.asyncio