Observed behavior
The docstring on SuccessfulInvocationResult.structuredOutput in src/types.ts reads:
/**
* When an ` + "`outputSchema`" + ` was provided, the SDK returns the parsed object
* that conforms to the schema. Present only when structured output was
* requested and the agent supports it.
*/
readonly structuredOutput?: unknown;
This describes a contract: structuredOutput is only set when the caller provided an outputSchema on the agent config.
The openai-sdk agent does not honour that contract. normalizeFinalOutput in src/agents/openai-sdk.ts sets structuredOutput unconditionally whenever the SDK's finalOutput is non-string:
if (typeof finalOutput === 'string') {
return { status: 'success', output: finalOutput };
}
return {
status: 'success',
output: stringifyStructuredOutput(finalOutput),
structuredOutput: finalOutput,
};
There is no check against this.#config.outputSchema. In normal use the OpenAI Agents SDK only returns non-string output when outputType is configured (which Loop derives from outputSchema), so the two paths usually agree in practice. But it is not guaranteed: a future SDK change, a different output type, or a non-default modelSettings could yield a non-string finalOutput with no outputSchema configured, at which point a downstream reporter would persist a structuredOutput block that the type's documented contract says could not exist.
claude-sdk is stricter: it only assigns structuredOutput when the result message has a structured_output field, which the Claude SDK only emits when an outputSchema was requested.
Expected behavior
Either:
- Tighten the agents so
structuredOutput is only populated when outputSchema was configured on the agent (matching the type's documented contract), or
- Loosen the docstring to acknowledge that any agent may populate
structuredOutput when the underlying SDK returns a non-string final output (so reporters and downstream consumers cannot assume "no outputSchema configured" implies "no structuredOutput").
Option 1 is more defensive; option 2 is a documentation-only change.
Minimal reproduction
Inspect normalizeFinalOutput in src/agents/openai-sdk.ts (around line 218) and compare with the docstring on SuccessfulInvocationResult.structuredOutput in src/types.ts (around line 17).
Suggested fix
Pick one of the two options above. The least invasive fix is to update the docstring to drop the "Present only when structured output was requested" guarantee, replacing it with a description that matches the agents' actual behaviour ("Present when the agent returned a structured value alongside the textual output").
Observed behavior
The docstring on
SuccessfulInvocationResult.structuredOutputinsrc/types.tsreads:This describes a contract:
structuredOutputis only set when the caller provided anoutputSchemaon the agent config.The
openai-sdkagent does not honour that contract.normalizeFinalOutputinsrc/agents/openai-sdk.tssetsstructuredOutputunconditionally whenever the SDK'sfinalOutputis non-string:There is no check against
this.#config.outputSchema. In normal use the OpenAI Agents SDK only returns non-string output whenoutputTypeis configured (which Loop derives fromoutputSchema), so the two paths usually agree in practice. But it is not guaranteed: a future SDK change, a different output type, or a non-defaultmodelSettingscould yield a non-stringfinalOutputwith nooutputSchemaconfigured, at which point a downstream reporter would persist astructuredOutputblock that the type's documented contract says could not exist.claude-sdkis stricter: it only assignsstructuredOutputwhen the result message has astructured_outputfield, which the Claude SDK only emits when anoutputSchemawas requested.Expected behavior
Either:
structuredOutputis only populated whenoutputSchemawas configured on the agent (matching the type's documented contract), orstructuredOutputwhen the underlying SDK returns a non-string final output (so reporters and downstream consumers cannot assume "no outputSchema configured" implies "no structuredOutput").Option 1 is more defensive; option 2 is a documentation-only change.
Minimal reproduction
Inspect
normalizeFinalOutputinsrc/agents/openai-sdk.ts(around line 218) and compare with the docstring onSuccessfulInvocationResult.structuredOutputinsrc/types.ts(around line 17).Suggested fix
Pick one of the two options above. The least invasive fix is to update the docstring to drop the "Present only when structured output was requested" guarantee, replacing it with a description that matches the agents' actual behaviour ("Present when the agent returned a structured value alongside the textual output").