diff --git a/api/streaming.py b/api/streaming.py index af38737e..e18c6aec 100644 --- a/api/streaming.py +++ b/api/streaming.py @@ -8106,7 +8106,7 @@ def _run_agent_streaming( _drop_replayed_assistant = ( _agent_result_terminal_failure(result) or bool(getattr(agent, '_last_error', None)) - or ('error' in result) + or ('error' in result and result.get('error') is not None) ) _saved_transcript_lacks_final_answer = _merged_transcript_lacks_final_assistant_answer( _previous_messages, diff --git a/tests/test_issue5121_provider_auth_terminal_error.py b/tests/test_issue5121_provider_auth_terminal_error.py index bb752426..a44ad0b9 100644 --- a/tests/test_issue5121_provider_auth_terminal_error.py +++ b/tests/test_issue5121_provider_auth_terminal_error.py @@ -377,6 +377,42 @@ def test_success_repeated_assistant_text_stays_successful_current_turn(tmp_path, assert not any(event == "apperror" for event, _ in events) +def test_success_repeated_assistant_text_ignores_empty_error_field(tmp_path, monkeypatch): + session = _prepare_session("repeat_success_empty_error", "stream_repeat_success_empty_error", pending_user_message="Please say it again") + _seed_prior_turn( + session, + prior_user="Earlier question", + prior_assistant="Same answer", + ) + + class RepeatedSuccessWithEmptyErrorAgent(MockAgent): + def run_conversation(self, **kwargs): + history = list(kwargs.get("conversation_history") or []) + return { + "messages": history + [{"role": "assistant", "content": "Same answer"}], + "error": None, + } + + fake_queue = _run_stream( + monkeypatch, + session, + "stream_repeat_success_empty_error", + RepeatedSuccessWithEmptyErrorAgent, + workspace=str(tmp_path), + ) + saved = Session.load("repeat_success_empty_error") + assert saved is not None + + assert any(msg.get("role") == "user" and msg.get("content") == "Please say it again" for msg in saved.messages) + assert saved.messages[-1]["role"] == "assistant" + assert saved.messages[-1]["content"] == "Same answer" + assert not any(msg.get("_error") for msg in saved.messages) + + events = _queue_events(fake_queue) + assert any(event == "done" for event, _ in events) + assert not any(event == "apperror" for event, _ in events) + + def test_non_auth_silent_failure_still_uses_no_response(tmp_path, monkeypatch): session = _prepare_session("silent_failure", "stream_silent_failure", pending_user_message="Please handle silence")