Materialize remote images before model requests

This commit is contained in:
Rohit Arunachalam
2026-06-09 13:24:12 -07:00
parent 472619f9fc
commit fdf73292be
8 changed files with 249 additions and 22 deletions
+19
View File
@@ -106,6 +106,7 @@ class MockResponsesServer:
self._responses: queue.Queue[MockSseResponse] = queue.Queue()
self._requests: list[CapturedResponsesRequest] = []
self._requests_lock = threading.Lock()
self._get_responses: dict[str, tuple[bytes, str]] = {}
self._server = _ResponsesHttpServer(("127.0.0.1", 0), _ResponsesHandler, self)
self._thread = threading.Thread(
target=self._server.serve_forever,
@@ -158,6 +159,13 @@ class MockResponsesServer:
)
)
def serve_bytes(self, path: str, body: bytes, *, content_type: str) -> str:
"""Serve bytes from a GET path and return its absolute URL."""
if not path.startswith("/"):
raise ValueError("GET response path must start with '/'")
self._get_responses[path] = (body, content_type)
return f"{self.url}{path}"
def requests(self) -> list[CapturedResponsesRequest]:
"""Return all recorded Responses API requests."""
with self._requests_lock:
@@ -202,6 +210,9 @@ class MockResponsesServer:
"""Return the next queued SSE response or fail the HTTP request."""
return self._responses.get_nowait()
def _get_response(self, path: str) -> tuple[bytes, str] | None:
return self._get_responses.get(path)
class AppServerHarness:
"""Test fixture that points a pinned runtime app-server at MockResponsesServer."""
@@ -283,6 +294,14 @@ class _ResponsesHandler(BaseHTTPRequestHandler):
def do_GET(self) -> None:
"""Serve a minimal `/v1/models` response if app-server asks for models."""
if response := self.server.mock._get_response(self.path):
body, content_type = response
self.send_response(200)
self.send_header("content-type", content_type)
self.send_header("content-length", str(len(body)))
self.end_headers()
self.wfile.write(body)
return
if self.path.endswith("/v1/models") or self.path.endswith("/models"):
self._send_json(
{
+10 -4
View File
@@ -1,18 +1,24 @@
from __future__ import annotations
import base64
from app_server_harness import AppServerHarness
from app_server_helpers import TINY_PNG_BYTES
from openai_codex import Codex, ImageInput, LocalImageInput, SkillInput, TextInput
def test_remote_image_input_reaches_responses_api(
def test_remote_image_input_is_materialized_before_responses_api(
tmp_path,
) -> None:
"""Remote image inputs should survive the SDK and app-server boundary."""
remote_image_url = "https://example.com/codex.png"
"""Remote image inputs should be inlined by the app-server."""
with AppServerHarness(tmp_path) as harness:
remote_image_url = harness.responses.serve_bytes(
"/codex.png",
TINY_PNG_BYTES,
content_type="image/png",
)
harness.responses.enqueue_assistant_message(
"remote image received",
response_id="remote-image",
@@ -34,7 +40,7 @@ def test_remote_image_input_reaches_responses_api(
} == {
"final_response": "remote image received",
"contains_user_prompt": True,
"image_urls": [remote_image_url],
"image_urls": [f"data:image/png;base64,{base64.b64encode(TINY_PNG_BYTES).decode('ascii')}"],
}