130 lines
4.0 KiB
Python
130 lines
4.0 KiB
Python
"""
|
|
End-to-end smoke test for image upload + multimodal inference (mock LLM).
|
|
|
|
Registers an openai-agents agent, creates a runner-bound session, uploads
|
|
an image via the session-scoped files API, posts a user message with an
|
|
``input_image`` content block referencing the file, and verifies the
|
|
agent produces non-empty text. The mock LLM returns a canned response
|
|
describing the image colors.
|
|
|
|
Usage::
|
|
|
|
pytest tests/e2e/test_image_upload_e2e.py -v
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import uuid
|
|
from pathlib import Path
|
|
|
|
import httpx
|
|
|
|
from tests.e2e.conftest import (
|
|
configure_mock_llm,
|
|
create_runner_bound_session,
|
|
poll_session_until_terminal,
|
|
register_inline_agent,
|
|
reset_mock_llm,
|
|
send_user_message_to_session,
|
|
)
|
|
from tests.e2e.helpers import final_assistant_text
|
|
|
|
_REPO_ROOT = Path(__file__).resolve().parents[2]
|
|
|
|
# Checked-in test image: 100x100 red square with a blue center.
|
|
_TEST_IMAGE_PATH = _REPO_ROOT / "tests" / "resources" / "test_image.png"
|
|
|
|
|
|
def test_image_upload_reaches_llm(
|
|
http_client: httpx.Client,
|
|
live_runner_id: str,
|
|
mock_llm_server_url: str,
|
|
) -> None:
|
|
"""
|
|
Upload an image, send it to an agent, verify the agent produces
|
|
non-empty text describing the image.
|
|
|
|
Full AP-side e2e:
|
|
|
|
1. Register an openai-agents agent pointing at the mock LLM.
|
|
2. Create a runner-bound session and upload a test PNG via the
|
|
session-scoped files API.
|
|
3. Post a user message (text + ``input_image``) asking the model
|
|
to identify the dominant color; poll the snapshot until terminal.
|
|
4. Assert the mock response text appears in the output (proving
|
|
the image upload pipeline didn't drop content before reaching
|
|
the executor).
|
|
"""
|
|
model = f"mock-image-{uuid.uuid4().hex[:6]}"
|
|
reset_mock_llm(mock_llm_server_url)
|
|
|
|
agent_name = register_inline_agent(
|
|
http_client,
|
|
name=f"image-e2e-{uuid.uuid4().hex[:6]}",
|
|
harness="openai-agents",
|
|
model=model,
|
|
profile="",
|
|
prompt=(
|
|
"You are a vision assistant. When the user sends an "
|
|
"image, describe what you see. Be specific about "
|
|
"colors, shapes, and content."
|
|
),
|
|
mock_llm_base_url=f"{mock_llm_server_url}/v1",
|
|
)
|
|
|
|
# The mock returns a canned description mentioning the test image colors.
|
|
configure_mock_llm(
|
|
mock_llm_server_url,
|
|
[{"text": "The image shows a red square with a blue center."}],
|
|
key=model,
|
|
)
|
|
|
|
session_id = create_runner_bound_session(
|
|
http_client,
|
|
agent_name=agent_name,
|
|
runner_id=live_runner_id,
|
|
)
|
|
|
|
assert _TEST_IMAGE_PATH.exists(), (
|
|
f"Test image missing at {_TEST_IMAGE_PATH}. Run the generate script or restore from git."
|
|
)
|
|
image_bytes = _TEST_IMAGE_PATH.read_bytes()
|
|
file_resp = http_client.post(
|
|
f"/v1/sessions/{session_id}/resources/files",
|
|
files={"file": ("test_image.png", image_bytes, "image/png")},
|
|
)
|
|
file_resp.raise_for_status()
|
|
file_id = file_resp.json()["id"]
|
|
|
|
response_id = send_user_message_to_session(
|
|
http_client,
|
|
session_id=session_id,
|
|
content=[
|
|
{
|
|
"type": "input_text",
|
|
"text": (
|
|
"What is the dominant color of this image? Reply with just the color name."
|
|
),
|
|
},
|
|
{"type": "input_image", "file_id": file_id},
|
|
],
|
|
)
|
|
body = poll_session_until_terminal(
|
|
http_client,
|
|
session_id=session_id,
|
|
response_id=response_id,
|
|
timeout=120,
|
|
)
|
|
|
|
assert body["status"] == "completed", f"response failed: {body.get('error', 'unknown')}"
|
|
|
|
text = final_assistant_text(body).lower().strip()
|
|
assert text, "no assistant output text in response"
|
|
|
|
# The mock returns "red" and "blue" — verify it came through.
|
|
assert "red" in text or "blue" in text, (
|
|
f"LLM did not identify any color in the image — "
|
|
f"multimodal content likely dropped before reaching "
|
|
f"the model. Full response:\n{text}"
|
|
)
|