From d9ff12929fe804603a512107529a9032172176c9 Mon Sep 17 00:00:00 2001 From: markstuart-oai <323302876+markstuart-oai@users.noreply.github.com> Date: Sun, 1 Nov 2026 23:51:31 +0000 Subject: [PATCH 1/2] test(realtime): cover mixed reference input serialization --- tests/lib/test_realtime_reference_inputs.py | 99 +++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 tests/lib/test_realtime_reference_inputs.py diff --git a/tests/lib/test_realtime_reference_inputs.py b/tests/lib/test_realtime_reference_inputs.py new file mode 100644 index 0000000000..dcf8969b37 --- /dev/null +++ b/tests/lib/test_realtime_reference_inputs.py @@ -0,0 +1,99 @@ +from __future__ import annotations + +import json +import asyncio + +import httpx2 +import pytest +from websockets.sync.server import ServerConnection + +from openai import OpenAI, AsyncOpenAI +from openai.types.realtime.conversation_item_param import ConversationItemParam +from openai.types.realtime.response_item_reference_param import ResponseItemReferenceParam +from openai.types.realtime.response_create_event_with_references_param import ResponseCreateEventWithReferencesParam +from openai.types.realtime.realtime_response_create_params_with_references_param import ( + RealtimeResponseCreateParamsWithReferencesParam, +) + +from .responses.test_websocket_session import script_server + + +@pytest.fixture +def reference_response() -> RealtimeResponseCreateParamsWithReferencesParam: + reference: ResponseItemReferenceParam = {"id": "item_existing", "type": "item_reference"} + message: ConversationItemParam = { + "type": "message", + "role": "user", + "content": [{"type": "input_text", "text": "new input 東京"}], + } + return { + "conversation": "none", + "input": [reference, message], + "instructions": "Use both inputs.", + "metadata": {"case": "reference-input"}, + "output_modalities": ["text"], + } + + +@pytest.mark.parametrize("mode", ["sync", "async"]) +@pytest.mark.parametrize("operation", ["create", "send"]) +async def test_realtime_reference_inputs_preserve_mixed_wire_payload( + mode: str, + operation: str, + reference_response: RealtimeResponseCreateParamsWithReferencesParam, + monkeypatch: pytest.MonkeyPatch, +) -> None: + monkeypatch.setenv("NO_PROXY", "127.0.0.1") + monkeypatch.setenv("no_proxy", "127.0.0.1") + event: ResponseCreateEventWithReferencesParam = { + "type": "response.create", + "event_id": "fake-reference-request", + "response": reference_response, + } + + def script(socket: ServerConnection) -> None: + wire = socket.recv(timeout=5) + assert isinstance(wire, str) + assert json.loads(wire) == { + "type": "response.create", + "event_id": "fake-reference-request", + "response": { + "conversation": "none", + "input": [ + {"id": "item_existing", "type": "item_reference"}, + { + "type": "message", + "role": "user", + "content": [{"type": "input_text", "text": "new input 東京"}], + }, + ], + "instructions": "Use both inputs.", + "metadata": {"case": "reference-input"}, + "output_modalities": ["text"], + }, + } + + with script_server(script) as url: + if mode == "sync": + with OpenAI( + api_key="fake-reference-key", base_url=url, http_client=httpx2.Client(trust_env=False) + ) as client: + with client.realtime.connect(model="gpt-realtime") as connection: + if operation == "create": + connection.response.create(event_id="fake-reference-request", response=reference_response) + else: + connection.send(event) + else: + async with AsyncOpenAI( + api_key="fake-reference-key", base_url=url, http_client=httpx2.AsyncClient(trust_env=False) + ) as async_client: + async with async_client.realtime.connect(model="gpt-realtime") as async_connection: + if operation == "create": + await asyncio.wait_for( + async_connection.response.create( + event_id="fake-reference-request", response=reference_response + ), + timeout=5, + ) + else: + await asyncio.wait_for(async_connection.send(event), timeout=5) From 4680764d3187118c02da0d79dc209c505a79755c Mon Sep 17 00:00:00 2001 From: markstuart-oai <323302876+markstuart-oai@users.noreply.github.com> Date: Mon, 2 Nov 2026 00:03:42 +0000 Subject: [PATCH 2/2] test(realtime): wait for peer payload validation --- tests/lib/test_realtime_reference_inputs.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/lib/test_realtime_reference_inputs.py b/tests/lib/test_realtime_reference_inputs.py index dcf8969b37..3fa2abc6ef 100644 --- a/tests/lib/test_realtime_reference_inputs.py +++ b/tests/lib/test_realtime_reference_inputs.py @@ -2,6 +2,7 @@ import json import asyncio +import threading import httpx2 import pytest @@ -51,6 +52,8 @@ async def test_realtime_reference_inputs_preserve_mixed_wire_payload( "response": reference_response, } + validated = threading.Event() + def script(socket: ServerConnection) -> None: wire = socket.recv(timeout=5) assert isinstance(wire, str) @@ -72,6 +75,7 @@ def script(socket: ServerConnection) -> None: "output_modalities": ["text"], }, } + validated.set() with script_server(script) as url: if mode == "sync": @@ -83,6 +87,7 @@ def script(socket: ServerConnection) -> None: connection.response.create(event_id="fake-reference-request", response=reference_response) else: connection.send(event) + assert validated.wait(5), "Peer did not validate the request" else: async with AsyncOpenAI( api_key="fake-reference-key", base_url=url, http_client=httpx2.AsyncClient(trust_env=False) @@ -97,3 +102,4 @@ def script(socket: ServerConnection) -> None: ) else: await asyncio.wait_for(async_connection.send(event), timeout=5) + assert await asyncio.to_thread(validated.wait, 5), "Peer did not validate the request"