Spaces:
Running
Running
File size: 1,543 Bytes
e16f16c | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | """tests/unit/test_loop_errors.py — loop error handling (SC-015).
If the LLM client fails, the loop must yield an ``ErrorEvent`` and finish
gracefully — never raise through the async generator (which in the UI would be a
silent hang). No real network is used: the client is replaced with a fake.
"""
import pytest
from agent.events import AgentStartEvent, ErrorEvent
from agent.loop import AgentLoop
class _RaisingClient:
async def chat(self, *args, **kwargs):
raise RuntimeError("connection refused")
class _RaisingMidStreamClient:
async def chat(self, *args, **kwargs):
async def _gen():
raise RuntimeError("stream died")
yield # pragma: no cover - makes this an async generator
return _gen()
@pytest.mark.asyncio
async def test_error_before_stream_becomes_error_event():
loop = AgentLoop()
loop._client = _RaisingClient() # bypass lazy real client
events = [ev async for ev in loop.run("hi", session=None, system_prompt="x")]
assert isinstance(events[0], AgentStartEvent)
assert isinstance(events[-1], ErrorEvent)
assert "connection refused" in events[-1].message
@pytest.mark.asyncio
async def test_error_mid_stream_becomes_error_event():
loop = AgentLoop()
loop._client = _RaisingMidStreamClient()
events = [ev async for ev in loop.run("hi", session=None, system_prompt="x")]
types = [e.type for e in events]
assert types[0] == "agent_start"
assert types[-1] == "error"
assert "stream died" in events[-1].message
|