fix(streaming): surface provider auth failures in chat (#5121)

This commit is contained in:
Rod Boev 2026-06-28 13:18:32 -04:00
parent 6681bef796
commit 5f02189939
2 changed files with 32 additions and 13 deletions

View file

@ -8053,16 +8053,8 @@ def _run_agent_streaming(
_terminal_failure = (
_agent_result_terminal_failure(result)
or (
_is_auth
and _saved_transcript_lacks_final_answer
)
or (
_tool_limit_reached
and _session_lacks_final_assistant_answer(_all_result_messages)
)
or (
not _token_sent
and _session_lacks_final_assistant_answer(_all_result_messages)
_saved_transcript_lacks_final_answer
and _classification['type'] not in {'cancelled', 'interrupted'}
)
)
if _terminal_failure:

View file

@ -133,7 +133,7 @@ def _auth_failure_error_payload():
}
def _build_auth_failure_agent(*, token_text: str, success_text: str = "Recovered auth reply"):
def _build_auth_failure_agent(*, token_text: str | None, success_text: str = "Recovered auth reply"):
class AuthFailureAgent(MockAgent):
runs = 0
@ -141,7 +141,7 @@ def _build_auth_failure_agent(*, token_text: str, success_text: str = "Recovered
type(self).runs += 1
history = list(kwargs.get("conversation_history") or [])
if type(self).runs == 1:
if self.stream_delta_callback is not None:
if self.stream_delta_callback is not None and token_text is not None:
self.stream_delta_callback(token_text)
return {
"messages": history,
@ -178,7 +178,7 @@ def _run_stream(monkeypatch, session, stream_id, agent_cls, *, workspace):
def test_auth_401_without_delivery_persists_error_turn(tmp_path, monkeypatch):
session = _prepare_session("auth_no_delivery", "stream_auth_no_delivery", pending_user_message="Please respond")
agent_cls = _build_auth_failure_agent(token_text="")
agent_cls = _build_auth_failure_agent(token_text=None)
fake_queue = _run_stream(monkeypatch, session, "stream_auth_no_delivery", agent_cls, workspace=str(tmp_path))
saved = Session.load("auth_no_delivery")
@ -281,3 +281,30 @@ def test_non_auth_silent_failure_still_uses_no_response(tmp_path, monkeypatch):
assert apperrors[-1]["type"] == "no_response"
assert apperrors[-1]["type"] != "auth_mismatch"
assert saved.messages[-1]["_error"] is True
def test_non_auth_partial_delivery_persists_error_turn(tmp_path, monkeypatch):
session = _prepare_session("partial_escape", "stream_partial_escape", pending_user_message="Please handle partial silence")
class PartialSilentFailureAgent(MockAgent):
def run_conversation(self, **kwargs):
if self.stream_delta_callback is not None:
self.stream_delta_callback("Partial text before failure")
return {
"messages": list(kwargs.get("conversation_history") or []),
"error": "",
}
fake_queue = _run_stream(monkeypatch, session, "stream_partial_escape", PartialSilentFailureAgent, workspace=str(tmp_path))
saved = Session.load("partial_escape")
assert saved is not None
partial = next((msg for msg in saved.messages if msg.get("_partial")), None)
assert partial is not None
assert partial["content"] == "Partial text before failure"
events = _queue_events(fake_queue)
apperrors = [data for event, data in events if event == "apperror"]
assert apperrors, "expected apperror for partial silent failure"
assert apperrors[-1]["type"] == "no_response"
assert saved.messages[-1]["_error"] is True