Repository navigation
test(harness): an OpenAI Agents SDK reference agent for the hosted path (TH-8800) - #301
khushalsonawat wants to merge 3 commits into
Conversation
…th (TH-8800) A small support agent on the OpenAI Agents SDK, written the way a customer would: three plain function tools, a module-level agent_callback for the kit's callback bridge, the model built per call as a chat-completions model object (the SDK's default provider refuses a gateway name such as vertex_ai/...), and the SDK's own trace export off. Offline tests pin what the hosted path does with it, with a stand-in for the SDK: it is detected as openai_agents; the build runs it through the callback bridge with the tool tracer bound to its three tools; the tracer records each tool as the SDK calls it (asyncio.to_thread on a request thread); and the callback sends the conversation once and replies with content only. Signed-off-by: khushalsonawat <khushalsonawat@gmail.com>
Signed-off-by: khushalsonawat <khushalsonawat@gmail.com>
| ''' | ||
|
|
||
|
|
||
| def _copy_example(destination: Path) -> Path: |
There was a problem hiding this comment.
P3. _copy_example, the stand-in writer, the fresh-import fixture, the three detection tests, the build test skeleton, the tracer subprocess driver and the pin tests are repeated nearly line for line in #304, #305, #306 and #311 (#304's test file shares 339 lines with this one). All five also import the private _authoring and _github_job from test_bundle_author_v2.
Fix: this is the first of the series, so land one tests/harness/reference_agents.py here with those helpers and a parametrised detection test, and have the others import it. The copied _ORDERS and tools inside each example folder are fine, since each folder has to stand alone.
| @@ -0,0 +1,2 @@ | |||
| openai-agents==0.24.0 | |||
| agent-simulate==0.1.3 | |||
There was a problem hiding this comment.
P3. Nothing in agent.py imports agent-simulate, so a reader will take this pin as unused. It's needed because the kit's callback bridge imports fi.simulate.AgentInput. One line in the README saying so would do.
… key with no base URL (TH-8800) Adds tests/harness/reference_agents.py: the example copy, stand-in writer, fresh import, detection cases, build, tracer driver and pin helpers the reference agent tests share, and the only module importing test_bundle_author_v2's private names. The OpenAI Agents SDK reference test moves onto it. The example refuses, before building a client, a key given without OPENAI_BASE_URL, and the README says why agent-simulate is pinned. Signed-off-by: khushalsonawat <khushalsonawat@gmail.com>
…s, and give the real reason for custom_openai (TH-8811) The test file uses tests/harness/reference_agents.py from #301 instead of its own copies. The agent's comment and the README say custom_openai stops CrewAI switching to the Responses API after a responses-only error, which the gateway can't serve; a plain openai/ model string with a base URL reaches the native client too. The README says agent-simulate is pinned for the kit's callback bridge. Signed-off-by: khushalsonawat <khushalsonawat@gmail.com>
…elpers, and refuse a key with no base URL (TH-8808) The test file uses tests/harness/reference_agents.py from #301; the tracer subprocess has a timeout, and the build test checks each tracer binding against the example's real functions. The example refuses, before building a client, a key given without OPENAI_BASE_URL, and the README says why agent-simulate is pinned. Signed-off-by: khushalsonawat <khushalsonawat@gmail.com>
…lpers, and check the tracer bindings against the real agent (TH-8809) The test file uses tests/harness/reference_agents.py from #301. The build test checks each tracer binding against support_agent.agent's real tools, so renaming a tool fails it, and the assert matching the model in the agent's source text is gone. Signed-off-by: khushalsonawat <khushalsonawat@gmail.com>
| expected = {"name": framework, "version": None} | ||
| if where == "run_folder": | ||
| run = copy_example(example, tmp_path / "run", ignore) | ||
| assert detect_framework(run) == expected |
There was a problem hiding this comment.
P3. pytest only rewrites asserts in files matching python_files = ["test_*.py"] and in conftests, and nothing registers this module, so a failing pin or detection check in any of the five reference test files prints a bare AssertionError with no values.
Repro: change one pin in requirements.txt and run test_requirements_and_python_version_are_pinned.
Fix: pytest.register_assert_rewrite("reference_agents") in tests/harness/conftest.py.
| (run / f"{names[0]}.py").write_text("def helper():\n return 1\n", encoding="utf-8") | ||
| found = detect_framework(run) | ||
| blockers = folder_findings(run).blockers | ||
| assert not (found == expected and blockers == frozenset()) |
There was a problem hiding this comment.
P3. This passes when detection still finds the framework but with a blocker, so it is looser than the test it replaced (#311's old check was detect_framework(run) != CREWAI). Today a shadowed import is skipped outright (framework_detection.py:486), so nothing hides yet, but a change that reports the framework with a blocker would stay green.
Fix: assert found != expected in the shadowed branch.
| from collections.abc import Callable, Iterator, Mapping, Sequence | ||
| from pathlib import Path | ||
|
|
||
| from test_bundle_author_v2 import ( |
There was a problem hiding this comment.
Summary
TH-8800 is a proof of concept: take one OpenAI Agents SDK agent through the hosted flow (reading, build, simulation, graded run) and list what breaks, before five more frameworks follow. This PR is the agent and the offline half. A local end-to-end run with a real reading and a real model is summarised under Verification.
examples/harness/openai_agents_support/is a small support agent, written the way a customer would:agent_callbackfor the kit's callback bridge;vertex_ai/....tests/harness/test_openai_agents_reference.pypins what the hosted path does with the agent. It uses a stand-in for the SDK, since the SDK isn't a kit dependency:openai_agents, including as a subfolder of a tree with a nestedagents/folder;asyncio.to_threadfrom a request thread), and nothing for a same-named function in another module;tests/harness/reference_agents.pyholds the helpers the reference agent tests share: copying an example, writing stand-ins, a fresh import, the detection cases (run folder, subfolder, in place, and a shadowing module), the build, the tracer driver and the pin check. It is the only module importingtest_bundle_author_v2's private names. The Pydantic AI, Google ADK, Deep Agents and CrewAI references (test(harness): a Pydantic AI reference agent for the hosted path (TH-8808) #304, test(harness): a Google ADK reference agent for the hosted path (TH-8809) #305, test(harness): a Deep Agents reference agent for the hosted path (TH-8810) #306, test(harness): a CrewAI reference agent for the hosted path (TH-8811) #311) stack on this PR and use it, so this PR merges first, with a merge commit.OPENAI_API_KEYis set andOPENAI_BASE_URLisn't, the callback raises before building a client, naming the missing setting.No kit code changes.
Verification
ruff checkon the new filestest_framework_detection.py,test_python_tool_trace_bootstrap.pyandtest_callback_http_adapter.py. 291 passed.uv run pytest -q: not run, because no shared runtime is touched.sdk-smokeruns a fixed list of test files, which didn't include this one. It now does (tests/harness/test_openai_agents_reference.py).vertex_ai/gemini-3.7-flashthrough the model gateway): the agent gave the right replies on chat completions. The reading saved its tools asunreachable, with the module from the repo root, so no calls were recorded. An earlier local run with a hand-writtenimportentry from moduleagentrecorded all 3.Review round 1 (Dileep)
tests/harness/reference_agents.py), with a parametrised detection test, and this file moved onto them.agent-simulateis pinned because the kit's callback bridge importsfi.simulate.AgentInput.clean-installfailed once ontests/harness/test_contract_model.py::test_a_crafted_file_of_block_comments_does_not_hold_up_the_check[a-file-of-openers], a timing test in a file this PR doesn't touch (0.525 s against 0.5 s): https://github.com/future-agi/agent-learning-kit/actions/runs/43196563653. The push run of the same commit is green (https://github.com/future-agi/agent-learning-kit/actions/runs/43196557257); the failed job was re-run.Known limits
@function_tooltools in a way the tracer can bind. It saves them asunreachable, with the module from the repo root, so a hosted run of this agent gets no tool evidence today. This is the reading's guidance, outside this PR, and it's a High row in the older-findings register.agentsdoesn't block detection; only a root-levelagents/oragents.pydoes. The test pins the folder name instead.Checklist
agent_learning.*,agent-learn, or@future-agi/agent-learning-kit