Delete synthetic prefill and empty-response puppeting
- SHA
f211d61fdc12a9bc6d733d19657e4a8652916f01- Parents
-
4effa19 - Tree
e578103
f211d61
f211d61fdc12a9bc6d733d19657e4a8652916f014effa19
e578103| Status | File | + | - |
|---|---|---|---|
| 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: | ||
| 13 | 13 | """Decision for an empty assistant response.""" |
| 14 | 14 | |
| 15 | 15 | should_continue: bool |
| 16 | - retry_prompt: str | None = None | |
| 16 | + retry_message: str | None = None | |
| 17 | 17 | final_response: str | None = None |
| 18 | 18 | failure: str | None = None |
| 19 | 19 | |
@@ -50,34 +50,22 @@ class ResponseRepairer: | ||
| 50 | 50 | ) -> EmptyResponseDecision: |
| 51 | 51 | """Return the next action when the assistant responds with empty content.""" |
| 52 | 52 | |
| 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: | |
| 71 | 55 | return EmptyResponseDecision( |
| 72 | 56 | 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 | + ), | |
| 74 | 62 | ) |
| 75 | 63 | |
| 76 | 64 | return EmptyResponseDecision( |
| 77 | 65 | should_continue=False, |
| 78 | 66 | 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." | |
| 81 | 69 | ), |
| 82 | 70 | failure="assistant returned empty output repeatedly", |
| 83 | 71 | ) |
src/loader/runtime/turn_iteration.pymodified@@ -266,11 +266,11 @@ class TurnIterationController: | ||
| 266 | 266 | empty_retry_count=next_empty_retry_count, |
| 267 | 267 | max_empty_retries=max_empty_retries, |
| 268 | 268 | ) |
| 269 | - if empty_decision.should_continue and empty_decision.retry_prompt: | |
| 269 | + if empty_decision.should_continue and empty_decision.retry_message: | |
| 270 | 270 | self.agent.session.append( |
| 271 | 271 | Message( |
| 272 | - role=Role.ASSISTANT, | |
| 273 | - content=empty_decision.retry_prompt, | |
| 272 | + role=Role.USER, | |
| 273 | + content=empty_decision.retry_message, | |
| 274 | 274 | ) |
| 275 | 275 | ) |
| 276 | 276 | return TurnIterationDecision( |
src/loader/runtime/turn_preamble.pymodified@@ -14,23 +14,6 @@ from .workflow_recovery import WorkflowRecoveryController | ||
| 14 | 14 | EventSink = Callable[[AgentEvent], Awaitable[None]] |
| 15 | 15 | UserQuestionHandler = Callable[[str, list[str] | None], Awaitable[str]] | None |
| 16 | 16 | |
| 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 | - | |
| 34 | 17 | |
| 35 | 18 | @dataclass(slots=True) |
| 36 | 19 | class TurnPreludeDecision: |
@@ -70,9 +53,6 @@ class TurnPreludeController: | ||
| 70 | 53 | summary.iterations = iterations |
| 71 | 54 | self.tracer.record("turn.iteration_started", iteration=iterations) |
| 72 | 55 | |
| 73 | - if self._should_seed_action_bracket(task=task, iterations=iterations): | |
| 74 | - self.agent.session.append(Message(role=Role.ASSISTANT, content="[")) | |
| 75 | - | |
| 76 | 56 | steering_messages = self.agent._drain_steering_queue() |
| 77 | 57 | for steering_message in steering_messages: |
| 78 | 58 | await emit(AgentEvent(type="steering", content=steering_message)) |
@@ -94,11 +74,3 @@ class TurnPreludeController: | ||
| 94 | 74 | return TurnPreludeDecision(should_continue=True) |
| 95 | 75 | |
| 96 | 76 | 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) | |