fix(streaming): surface provider auth failures in chat (#5121)
This commit is contained in:
parent
6681bef796
commit
5f02189939
2 changed files with 32 additions and 13 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue