mirror of
https://github.com/hanzoai/agent.git
synced 2026-09-11 21:08:51 +00:00
An OpenAI-compatible server can answer HTTP 200 with {"error": {...}}.
The openai client parses that as a result with no choices or output, and
the run died in a TypeError. Both model classes now raise
openai.APIError with the server's message and body, as the client does
for an error object inside a stream.
The test drives both routes through a local server. conftest imports
the Responses resource before swapping two of its classes for
factories; imported after, it subclasses a function and fails.
Co-authored-by: Hanzo Dev <[email protected]>
34 lines
1.2 KiB
Python
34 lines
1.2 KiB
Python
"""An OpenAI-compatible server can answer HTTP 200 with an error object in place of a result."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
from openai import APIError, AsyncOpenAI
|
|
|
|
from agents import Agent, OpenAIChatCompletionsModel, OpenAIResponsesModel, Runner
|
|
|
|
from .server import Server
|
|
|
|
|
|
@pytest.mark.allow_call_model_methods
|
|
@pytest.mark.asyncio
|
|
@pytest.mark.parametrize(
|
|
("model_class", "path"),
|
|
[
|
|
(OpenAIChatCompletionsModel, "/v1/chat/completions"),
|
|
(OpenAIResponsesModel, "/v1/responses"),
|
|
],
|
|
ids=["chat_completions", "responses"],
|
|
)
|
|
async def test_error_body_with_status_200_raises_api_error(model_class: type, path: str) -> None:
|
|
error = {"message": "upstream failed", "type": "server_error"}
|
|
with Server({path: {"error": error}}) as server:
|
|
async with AsyncOpenAI(base_url=f"{server.url}/v1", api_key="k", max_retries=0) as client:
|
|
agent = Agent(name="test", model=model_class(model="m", openai_client=client))
|
|
with pytest.raises(APIError, match="upstream failed") as raised:
|
|
await Runner.run(agent, input="hi")
|
|
|
|
assert raised.value.body == error
|
|
assert str(raised.value.request.url) == f"{server.url}{path}"
|
|
assert server.requests == [("POST", path)]
|