Skip to content

types.ts: SuccessfulInvocationResult.structuredOutput docstring says 'Present only when structured output was requested', but openai-sdk sets it for any non-string output #80

@joewalker

Description

@joewalker

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:

  1. Tighten the agents so structuredOutput is only populated when outputSchema was configured on the agent (matching the type's documented contract), or
  2. 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").

Metadata

Metadata

Assignees

No one assigned

    Labels

    S4Clean-ups or nits with low behavioral riskbugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions