diff --git a/src/mcprobe/agents/adk.py b/src/mcprobe/agents/adk.py index b4da9d4..f3ac55e 100644 --- a/src/mcprobe/agents/adk.py +++ b/src/mcprobe/agents/adk.py @@ -134,8 +134,9 @@ async def send_message(self, message: str) -> AgentResponse: self._process_function_responses(responses, pending_calls) ) - # Get final response text - if event.is_final_response() and event.content and event.content.parts: + # Capture text from any event with text content + # (not just final response - text may come in earlier events when tools are used) + if event.content and event.content.parts: for part in event.content.parts: if hasattr(part, "text") and part.text: response_text += part.text diff --git a/src/mcprobe/synthetic_user/user.py b/src/mcprobe/synthetic_user/user.py index 2985d18..08452ce 100644 --- a/src/mcprobe/synthetic_user/user.py +++ b/src/mcprobe/synthetic_user/user.py @@ -62,6 +62,13 @@ async def respond(self, assistant_message: str) -> UserResponse: Raises: OrchestrationError: If the LLM call fails. """ + # Handle empty agent responses - ask for clarification instead of confusing the LLM + if not assistant_message.strip(): + response = "I didn't receive a response. Could you try again?" + self._conversation_history.append(Message(role="assistant", content=assistant_message)) + self._conversation_history.append(Message(role="user", content=response)) + return UserResponse(message=response, tokens_used=0) + # Add assistant message to history self._conversation_history.append(Message(role="assistant", content=assistant_message)) diff --git a/tests/unit/test_synthetic_user.py b/tests/unit/test_synthetic_user.py index f12124f..4d5d728 100644 --- a/tests/unit/test_synthetic_user.py +++ b/tests/unit/test_synthetic_user.py @@ -129,3 +129,39 @@ async def test_tokens_default_to_zero_on_missing_usage( response = await user.respond("Hello") assert response.tokens_used == 0 + + @pytest.mark.asyncio + async def test_empty_agent_response_asks_for_retry( + self, + mock_provider: LLMProvider, + user_config: SyntheticUserConfig, + ) -> None: + """Test that empty agent responses result in clarification request.""" + user = SyntheticUserLLM(mock_provider, user_config) + + # Agent sends empty response + response = await user.respond("") + + # Synthetic user asks for retry instead of calling LLM + assert response.message == "I didn't receive a response. Could you try again?" + assert response.tokens_used == 0 + + # LLM should NOT have been called + mock_provider.generate.assert_not_called() + + @pytest.mark.asyncio + async def test_whitespace_only_agent_response_asks_for_retry( + self, + mock_provider: LLMProvider, + user_config: SyntheticUserConfig, + ) -> None: + """Test that whitespace-only agent responses result in clarification request.""" + user = SyntheticUserLLM(mock_provider, user_config) + + # Agent sends whitespace-only response + response = await user.respond(" \n\t ") + + # Synthetic user asks for retry + assert response.message == "I didn't receive a response. Could you try again?" + assert response.tokens_used == 0 + mock_provider.generate.assert_not_called()