[STG-2515] feat(evals): openai_agents_sdk harness adapter#2340
Open
shrey150 wants to merge 5 commits into
Open
[STG-2515] feat(evals): openai_agents_sdk harness adapter#2340shrey150 wants to merge 5 commits into
shrey150 wants to merge 5 commits into
Conversation
This was referenced Jul 9, 2026
a7e0668 to
e48ccaa
Compare
9eb922a to
a9faa18
Compare
e48ccaa to
e3cab93
Compare
a9faa18 to
c9e254d
Compare
|
e3cab93 to
f41f73f
Compare
c9e254d to
0255867
Compare
Contributor
There was a problem hiding this comment.
All reported issues were addressed across 7 files
Confidence score: 5/5
- Safe to merge after the addressed issues were fixed.
Architecture diagram
sequenceDiagram
participant CLI as Evals CLI
participant Registry as Harness Registry
participant Runner as openaiAgentsSdkRunner
participant AgentSDK as @openai/agents SDK
participant Browse as Browse Binary
participant Verifier as Verifier
Note over CLI,Verifier: OPENAI AGENTS SDK HARNESS FLOW
CLI->>Registry: registerHarness("openai_agents_sdk")
Registry->>Registry: buildAdapterBackedHarness("openai_agents_sdk", runOpenAiAgentsSdkAgent)
CLI->>Runner: runOpenAiAgentsSdkAgent({ plan, model, toolAdapter, logger })
Note over Runner: normalizeOpenAiAgentsModel(model)
alt Non-OpenAI provider
Note over Runner: throws EvalsError("only accepts openai models")
else OpenAI model
Runner->>Runner: stripProviderPrefix("openai/...") → "gpt-5.4-mini"
end
Runner->>Runner: readBareLoopMaxSteps("EVAL_OPENAI_AGENTS_SDK_MAX_TURNS")
Runner->>Runner: createBareLoopToolRecorder(toolAdapter, logger, "openai_agents_sdk")
Runner->>Runner: sdk.tool({ name: "browse", parameters: { type: "object", properties: { args } }, execute: async (params) => ... })
Runner->>AgentSDK: new Agent({ name, instructions: systemPromptAddendum, model, tools: [browseTool] })
Runner->>AgentSDK: run(agent, buildBareLoopUserPrompt(plan), { maxTurns, signal })
alt Run succeeds normally
AgentSDK-->>Runner: result { finalOutput, rawResponses }
Runner->>Runner: sumAgentsUsage(result.rawResponses)
Note over Runner: Sums inputTokens/outputTokens from each rawResponse
Runner-->>Verifier: finalizeBareLoopResult({ status: "complete", stopReason: undefined, usage, toolCalls })
Verifier-->>CLI: TaskResult with graded metrics
else SDK throws MaxTurnsExceededError
AgentSDK--xRunner: Error("Max turns (N) exceeded") with name "MaxTurnsExceededError"
Runner->>Runner: isMaxTurnsExceededError(error)
Note over Runner: Checks error.name === "MaxTurnsExceededError" OR message matches /^Max turns \(\d+\) exceeded$/
Runner->>Runner: cappedOut = true, logger.warn("hit max-turns cap")
Runner-->>Verifier: finalizeBareLoopResult({ status: "complete", stopReason: "step cap reached (N)", usage: {0,0} })
Verifier-->>CLI: TaskResult with capped-out completion
else SDK throws other error
AgentSDK--xRunner: Error("network error talking to the model provider")
Runner->>Runner: loopError = error, stringifyLoopError(error)
Runner-->>Verifier: finalizeBareLoopResult({ status: "error", stopReason: "network error...", usage: {0,0} })
Verifier-->>CLI: TaskResult with failed status
end
Note over Runner,Browse: Tool Execution (during SDK run loop)
AgentSDK->>+Runner: execute({ args: "open https://example.com" })
Runner->>Runner: recorder.execute(args)
Runner->>Browse: browse "open https://example.com"
Browse-->>Runner: stdout output
Runner-->>-AgentSDK: execution result string
Note over Runner,AgentSDK: SDK manages its own turn loop, tool dispatch, and tracing
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
f41f73f to
ecb6e11
Compare
0255867 to
69033b7
Compare
ecb6e11 to
ad0a3c3
Compare
69033b7 to
64633ae
Compare
ad0a3c3 to
b87d6b6
Compare
64633ae to
e4f238c
Compare
Registers --harness openai_agents_sdk via @openai/agents. Classification: bare-ISH — the SDK runs its own agent loop (turn management, tool dispatch, tracing) but ships no behavioral scaffolding; everything the agent knows comes from the dev-supplied instructions string, which carries only the configured skill-arm prompt. SDK defaults untouched except maxTurns (shared 40 default, EVAL_OPENAI_AGENTS_SDK_MAX_TURNS override). Tool parameters use a plain JSON schema instead of a zod schema to sidestep the SDK's zod version coupling (packages/evals pins zod v4). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… as a runner error
@openai/agents-core throws MaxTurnsExceededError ("Max turns (N)
exceeded", name "MaxTurnsExceededError" per AgentsError's `this.name =
new.target.name`) instead of returning a truncated result like
vercel_ai_sdk/anthropic_sdk do, so the generic catch was reporting the
step cap as a harness/SDK failure (status "error") instead of the shared
step-cap outcome. Detect it by error name or by the SDK's own message
shape and report status "complete" + the same `step cap reached (N)`
stopReason anthropic_sdk uses.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…teps rawResponses is one entry per model turn; counting browse tool calls undercounts runs that end with a text-only turn (a run with zero tool calls reported 0 steps). Falls back to the tool-call count when the SDK returns no result. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
b87d6b6 to
7d73972
Compare
e4f238c to
1fbd7c2
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Part 4 of 5 — stacked on #2339 (
anthropic_sdk) (base:shrey/evals-harness-anthropic-sdk; GitHub shows only this PR's delta). When the parent merges, retarget this PR's base and rebase.Registers
--harness openai_agents_sdkvia@openai/agents(6.8M PyPI dl/wk for the Python twin). Classification: bare-ish — one notch above the raw provider loops. The SDK runs its own agent loop (turn management, tool dispatch, tracing) but ships no behavioral scaffolding: everything the agent knows comes from the dev-suppliedinstructionsstring, which carries only the configured skill-arm prompt. SDK defaults untouched exceptmaxTurns(the SDK's own default of 10 is far too low for a browse task; shared 40 default,EVAL_OPENAI_AGENTS_SDK_MAX_TURNSoverride).openai/prefix stripped; other providers rejected loudly).result.rawResponses.@openai/agentsdependency (pinned 0.13.0) — this PR carries its own lockfile delta.sdkinjection seam ({ Agent, run, tool } mock).External harnesses design + usage:
packages/evals/README.md#external-harnesses(in #2337). Linear: STG-2515.Comparability fix (2026-07-09 audit)
@openai/agents-corethrowsMaxTurnsExceededError("Max turns (N) exceeded",error.name === "MaxTurnsExceededError"perAgentsError'sthis.name = new.target.name) instead of returning a truncated result the way vercel_ai_sdk/anthropic_sdk do — the generic catch was folding that intoopenaiAgentsSdkStatus: "error", reporting the shared step cap as a harness/SDK failure. Now detects it (by error name, with a message-shape regex fallback for robustness) and reportsstatus: "complete"+ the samestep cap reached (N)stopReasonanthropic_sdk(#2339) uses. The previous single "SDK errors" test (which happened to throw exactly this message and was silently exercising the bug) is now three tests: a genuine unrelated SDK error (still "error"), the realMaxTurnsExceededError-shaped throw hitting the cap, and the bare message-shape fallback without the SDK's error name.E2E Test Matrix
Live smoke ran on the pre-split combined branch (content identical to this stack's tip — verified by diff); results transplanted, not rerun.
evals run b:webtailbench --harness openai_agents_sdk -m openai/gpt-5.4-mini -l 1 -t 1 -c 1(local build, real OPENAI + GEMINI keys, local Chrome via browse CLI)browsetool calls recorded; trajectory persisted; verifier graded:outcomeSuccess=false,processScore=1.0, 5 rubric criteria, no verifierError. Clean final answer: "No reliable flight availability/pricing could be retrieved for United direct flights ..." Usage: 24k in / 0.5k out tokenspnpm exec vitest run(this branch)Test Files 52 passed, Tests 380 passed— addsopenaiAgentsSdkRunner.test.ts(instructions === verbatim arm prompt only, maxTurns passthrough, JSON-schema tool execution against a real temp binary, usage summing, model-prefix validation, MaxTurnsExceeded folding)tsc --noEmit+ prettier + eslintpnpm exec vitest run(this branch, post-fix)Test Files 52 passed, Tests 385 passed— MaxTurnsExceeded now correctly reported asstatus: "completed"+step cap reached (N)(2 new dedicated tests: real error-name shape, message-shape fallback); the pre-existing "SDK errors" test now throws a genuinely unrelated error to keep testing the generic-error pathpnpm -w exec tsc --noEmit+ prettier + eslint (post-fix)No changeset:
packages/evalsis private.🤖 Generated with Claude Code