|
9 | 9 | from openai import APIConnectionError, BadRequestError |
10 | 10 | from openai.types.responses import ( |
11 | 11 | ResponseCompletedEvent, |
| 12 | + ResponseErrorEvent, |
12 | 13 | ResponseFailedEvent, |
13 | 14 | ResponseFunctionToolCall, |
14 | 15 | ResponseIncompleteEvent, |
|
42 | 43 | from agents.run import RunConfig |
43 | 44 | from agents.run_internal import run_loop |
44 | 45 | from agents.run_internal.run_loop import QueueCompleteSentinel |
45 | | -from agents.stream_events import AgentUpdatedStreamEvent, StreamEvent |
| 46 | +from agents.stream_events import AgentUpdatedStreamEvent, RawResponsesStreamEvent, StreamEvent |
46 | 47 | from agents.usage import Usage |
47 | 48 |
|
48 | 49 | from .fake_model import FakeModel, get_response_obj |
@@ -188,10 +189,71 @@ async def stream_response( |
188 | 189 | agent = Agent(name="test", model=model) |
189 | 190 |
|
190 | 191 | result = Runner.run_streamed(agent, input="test") |
| 192 | + stream_events: list[StreamEvent] = [] |
191 | 193 | with pytest.raises(ModelBehaviorError, match=terminal_event_type): |
192 | | - async for _ in result.stream_events(): |
193 | | - pass |
| 194 | + async for event in result.stream_events(): |
| 195 | + stream_events.append(event) |
| 196 | + |
| 197 | + assert len(stream_events) == 2 |
| 198 | + assert isinstance(stream_events[0], AgentUpdatedStreamEvent) |
| 199 | + assert isinstance(stream_events[1], RawResponsesStreamEvent) |
| 200 | + assert stream_events[1].data.type == terminal_event_type |
| 201 | + assert result.final_output is None |
| 202 | + assert result.raw_responses == [] |
| 203 | + |
| 204 | + |
| 205 | +@pytest.mark.asyncio |
| 206 | +async def test_streamed_run_rejects_response_error_terminal_event() -> None: |
| 207 | + class TerminalErrorFakeModel(FakeModel): |
| 208 | + async def stream_response( |
| 209 | + self, |
| 210 | + system_instructions, |
| 211 | + input, |
| 212 | + model_settings, |
| 213 | + tools, |
| 214 | + output_schema, |
| 215 | + handoffs, |
| 216 | + tracing, |
| 217 | + *, |
| 218 | + previous_response_id=None, |
| 219 | + conversation_id=None, |
| 220 | + prompt=None, |
| 221 | + ): |
| 222 | + self.last_turn_args = { |
| 223 | + "system_instructions": system_instructions, |
| 224 | + "input": input, |
| 225 | + "model_settings": model_settings, |
| 226 | + "tools": tools, |
| 227 | + "output_schema": output_schema, |
| 228 | + "previous_response_id": previous_response_id, |
| 229 | + "conversation_id": conversation_id, |
| 230 | + } |
| 231 | + if self.first_turn_args is None: |
| 232 | + self.first_turn_args = self.last_turn_args.copy() |
| 233 | + |
| 234 | + yield ResponseErrorEvent( |
| 235 | + type="error", |
| 236 | + code="invalid_request_error", |
| 237 | + message="bad request", |
| 238 | + param=None, |
| 239 | + sequence_number=0, |
| 240 | + ) |
| 241 | + |
| 242 | + model = TerminalErrorFakeModel() |
| 243 | + agent = Agent(name="test", model=model) |
194 | 244 |
|
| 245 | + result = Runner.run_streamed(agent, input="test") |
| 246 | + stream_events: list[StreamEvent] = [] |
| 247 | + with pytest.raises(ModelBehaviorError, match="error"): |
| 248 | + async for event in result.stream_events(): |
| 249 | + stream_events.append(event) |
| 250 | + |
| 251 | + assert len(stream_events) == 2 |
| 252 | + assert isinstance(stream_events[0], AgentUpdatedStreamEvent) |
| 253 | + assert isinstance(stream_events[1], RawResponsesStreamEvent) |
| 254 | + assert stream_events[1].data.type == "error" |
| 255 | + assert stream_events[1].data.code == "invalid_request_error" |
| 256 | + assert stream_events[1].data.message == "bad request" |
195 | 257 | assert result.final_output is None |
196 | 258 | assert result.raw_responses == [] |
197 | 259 |
|
@@ -373,10 +435,15 @@ async def fake_open( |
373 | 435 |
|
374 | 436 | agent = Agent(name="test", model=model) |
375 | 437 | result = Runner.run_streamed(agent, input="test") |
| 438 | + stream_events: list[StreamEvent] = [] |
376 | 439 | with pytest.raises(ModelBehaviorError, match=terminal_event_type): |
377 | | - async for _ in result.stream_events(): |
378 | | - pass |
| 440 | + async for event in result.stream_events(): |
| 441 | + stream_events.append(event) |
379 | 442 |
|
| 443 | + assert len(stream_events) == 2 |
| 444 | + assert isinstance(stream_events[0], AgentUpdatedStreamEvent) |
| 445 | + assert isinstance(stream_events[1], RawResponsesStreamEvent) |
| 446 | + assert stream_events[1].data.type == terminal_event_type |
380 | 447 | assert result.final_output is None |
381 | 448 | assert result.raw_responses == [] |
382 | 449 |
|
|
0 commit comments