tenseleyflow/loader / f211d61

Browse files

Delete synthetic prefill and empty-response puppeting

Authored by espadonne
SHA
f211d61fdc12a9bc6d733d19657e4a8652916f01
Parents
4effa19
Tree
e578103

3 changed files

StatusFile+-
M src/loader/runtime/repair.py 10 22
M src/loader/runtime/turn_iteration.py 3 3
M src/loader/runtime/turn_preamble.py 0 28
src/loader/runtime/repair.pymodified
@@ -13,7 +13,7 @@ class EmptyResponseDecision:
1313
     """Decision for an empty assistant response."""
1414
 
1515
     should_continue: bool
16
-    retry_prompt: str | None = None
16
+    retry_message: str | None = None
1717
     final_response: str | None = None
1818
     failure: str | None = None
1919
 
@@ -50,34 +50,22 @@ class ResponseRepairer:
5050
     ) -> EmptyResponseDecision:
5151
         """Return the next action when the assistant responds with empty content."""
5252
 
53
-        if empty_retry_count <= max_empty_retries:
54
-            task_context = original_task or task
55
-            retry_prompts = [
56
-                "Great! Now let me proceed with the task. I'll start by using my tools.",
57
-                "I understand. Let me create that now using my tools (write, bash, etc.).",
58
-                (
59
-                    f"Proceeding with: {task_context[:80]}. "
60
-                    "I'll use the write tool to create the files."
61
-                ),
62
-                "Starting now. First step: create the necessary files and directories.",
63
-                (
64
-                    "Let me complete this task step by step. "
65
-                    f"The goal is: {task_context[:100]}"
66
-                ),
67
-            ]
68
-            retry_prompt = retry_prompts[
69
-                min(empty_retry_count - 1, len(retry_prompts) - 1)
70
-            ]
53
+        _ = task, original_task, max_empty_retries
54
+        if empty_retry_count == 1:
7155
             return EmptyResponseDecision(
7256
                 should_continue=True,
73
-                retry_prompt=retry_prompt,
57
+                retry_message=(
58
+                    "[EMPTY ASSISTANT RESPONSE]\n"
59
+                    "Your last response was empty. Respond directly to the task "
60
+                    "or call tools if needed. Do not return an empty response."
61
+                ),
7462
             )
7563
 
7664
         return EmptyResponseDecision(
7765
             should_continue=False,
7866
             final_response=(
79
-                "I need a bit more direction. "
80
-                "What specifically would you like me to create or do?"
67
+                "I didn't get a usable response from the model after retrying once. "
68
+                "Please try again or switch to a different backend/model."
8169
             ),
8270
             failure="assistant returned empty output repeatedly",
8371
         )
src/loader/runtime/turn_iteration.pymodified
@@ -266,11 +266,11 @@ class TurnIterationController:
266266
             empty_retry_count=next_empty_retry_count,
267267
             max_empty_retries=max_empty_retries,
268268
         )
269
-        if empty_decision.should_continue and empty_decision.retry_prompt:
269
+        if empty_decision.should_continue and empty_decision.retry_message:
270270
             self.agent.session.append(
271271
                 Message(
272
-                    role=Role.ASSISTANT,
273
-                    content=empty_decision.retry_prompt,
272
+                    role=Role.USER,
273
+                    content=empty_decision.retry_message,
274274
                 )
275275
             )
276276
             return TurnIterationDecision(
src/loader/runtime/turn_preamble.pymodified
@@ -14,23 +14,6 @@ from .workflow_recovery import WorkflowRecoveryController
1414
 EventSink = Callable[[AgentEvent], Awaitable[None]]
1515
 UserQuestionHandler = Callable[[str, list[str] | None], Awaitable[str]] | None
1616
 
17
-_ACTION_KEYWORDS = (
18
-    "create",
19
-    "write",
20
-    "make",
21
-    "run",
22
-    "execute",
23
-    "build",
24
-    "install",
25
-    "delete",
26
-    "remove",
27
-    "add",
28
-    "edit",
29
-    "modify",
30
-    "update",
31
-    "fix",
32
-)
33
-
3417
 
3518
 @dataclass(slots=True)
3619
 class TurnPreludeDecision:
@@ -70,9 +53,6 @@ class TurnPreludeController:
7053
         summary.iterations = iterations
7154
         self.tracer.record("turn.iteration_started", iteration=iterations)
7255
 
73
-        if self._should_seed_action_bracket(task=task, iterations=iterations):
74
-            self.agent.session.append(Message(role=Role.ASSISTANT, content="["))
75
-
7656
         steering_messages = self.agent._drain_steering_queue()
7757
         for steering_message in steering_messages:
7858
             await emit(AgentEvent(type="steering", content=steering_message))
@@ -94,11 +74,3 @@ class TurnPreludeController:
9474
             return TurnPreludeDecision(should_continue=True)
9575
 
9676
         return TurnPreludeDecision()
97
-
98
-    def _should_seed_action_bracket(self, *, task: str, iterations: int) -> bool:
99
-        """Return whether to preserve the legacy action-seed hint."""
100
-
101
-        if iterations != 1 or len(self.agent.messages) != 1:
102
-            return False
103
-        task_lower = task.lower()
104
-        return any(keyword in task_lower for keyword in _ACTION_KEYWORDS)