@@ -245,3 +245,63 @@ async def test_turn_completion_handles_deflection_text_without_repair_prompt( |
| 245 | 245 | for message in agent.session.messages |
| 246 | 246 | ) |
| 247 | 247 | assert any(event.type == "response" and event.content == deflection for event in events) |
| 248 | + |
| 249 | + |
| 250 | +@pytest.mark.asyncio |
| 251 | +async def test_turn_completion_skips_self_critique_reroute( |
| 252 | + temp_dir: Path, |
| 253 | +) -> None: |
| 254 | + backend = ScriptedBackend() |
| 255 | + config = non_streaming_config() |
| 256 | + config.reasoning.completion_check = False |
| 257 | + config.reasoning.self_critique = True |
| 258 | + agent = Agent( |
| 259 | + backend=backend, |
| 260 | + config=config, |
| 261 | + project_root=temp_dir, |
| 262 | + ) |
| 263 | + runtime = ConversationRuntime(agent) |
| 264 | + events = [] |
| 265 | + |
| 266 | + async def capture(event) -> None: |
| 267 | + events.append(event) |
| 268 | + |
| 269 | + prepared = await runtime.turn_preparation.prepare( |
| 270 | + task="Explain Loader's clarify loop.", |
| 271 | + emit=capture, |
| 272 | + requested_mode="execute", |
| 273 | + original_task=None, |
| 274 | + on_user_question=None, |
| 275 | + ) |
| 276 | + await runtime.phase_tracker.enter( |
| 277 | + TurnPhase.ASSISTANT, |
| 278 | + capture, |
| 279 | + detail="Requesting assistant response", |
| 280 | + reason_code="request_assistant_response", |
| 281 | + ) |
| 282 | + |
| 283 | + detailed = ( |
| 284 | + "Loader might begin with a bounded clarify pass, perhaps asking follow-up " |
| 285 | + "questions when the task leaves touchpoints or decision boundaries unclear. " |
| 286 | + "It then shifts into execution once the workflow policy is satisfied." |
| 287 | + ) |
| 288 | + decision = await runtime.turn_completion.handle_text_response( |
| 289 | + content=detailed, |
| 290 | + response_content=detailed, |
| 291 | + task=prepared.task, |
| 292 | + effective_task=prepared.effective_task, |
| 293 | + iterations=1, |
| 294 | + max_iterations=agent.config.max_iterations, |
| 295 | + actions_taken=[], |
| 296 | + continuation_count=0, |
| 297 | + dod=prepared.definition_of_done, |
| 298 | + emit=capture, |
| 299 | + summary=prepared.summary, |
| 300 | + executor=prepared.executor, |
| 301 | + rollback_plan=prepared.rollback_plan, |
| 302 | + ) |
| 303 | + |
| 304 | + assert decision.action == TurnCompletionAction.COMPLETE |
| 305 | + assert prepared.summary.final_response == detailed |
| 306 | + assert not any("[SELF-CRITIQUE]" in message.content for message in agent.session.messages) |
| 307 | + assert not any(event.type == "critique" for event in events) |