Skip to content

Build streamed OpenAI events before serializing them#1586

Open
brianstrauch wants to merge 3 commits into
mainfrom
fix-openai-payload-serialization-1585
Open

Build streamed OpenAI events before serializing them#1586
brianstrauch wants to merge 3 commits into
mainfrom
fix-openai-payload-serialization-1585

Conversation

@brianstrauch
Copy link
Copy Markdown
Member

@brianstrauch brianstrauch commented Jun 5, 2026

What

Force pydantic's deferred schema build on each streamed OpenAI event in invoke_model_activity_streaming, before the event is published to the workflow stream or returned as the activity result.

Why

OpenAI's BaseModel sets defer_build=True (since openai-python v1.16.1, April 2024) — a model's serializer stays a MockValSer placeholder until pydantic's lazy build is triggered through the model's own machinery (validation, model_dump*, etc.). The payload converter serializes with a type-agnostic serializer that reaches for that placeholder directly without triggering the build, so an un-built event raises:

PydanticSerializationError: Unable to serialize unknown type: ResponseOutputTextAnnotationAddedEvent
  During handling: TypeError: 'MockValSer' object cannot be converted to 'SchemaSerializer'

This surfaced once events were streamed via WorkflowStreamClient (#1497): streamed events are serialized without first crossing a validation/deserialization boundary that would have built their schema. It's masked on newer pydantic (instance creation triggers the build) but fails on the reporter's older pydantic.

model_rebuild() completes the deferred build and is a cheap no-op once built. Doing it at the source fixes serialization on both streaming paths — the per-event publish and the list[event] activity return value (a list the converter serializes generically and can't build on its own).

Fixes #1585

🤖 Generated with Claude Code

OpenAI response and stream event types whose pydantic serializer is a
lazily-built MockValSer cannot be serialized by the generic any-schema
serializer, raising PydanticSerializationError (e.g. when streaming via
WorkflowStreamClient). The model's own model_dump_json() handles them.

Fixes #1585
@brianstrauch brianstrauch requested review from a team as code owners June 5, 2026 20:24
OpenAI's BaseModel sets defer_build=True, so a model's serializer is a
MockValSer placeholder until pydantic's lazy build runs. The generic any-schema
serializer reaches for that placeholder directly without triggering the build
and raises PydanticSerializationError. Route pydantic models through their own
model_dump_json (which triggers the build) by type instead of catching the
error; non-model values continue through the generic serializer unchanged.
Force the deferred pydantic build on each streamed event before it is published
or returned, so it serializes regardless of build state. This also covers the
activity's list return value, which the payload converter serializes generically
and cannot build on its own. Drop the now-redundant to_payload override.
@brianstrauch brianstrauch changed the title Fall back to model_dump_json for OpenAI payload serialization Build streamed OpenAI events before serializing them Jun 5, 2026
@brianstrauch brianstrauch enabled auto-merge (squash) June 5, 2026 22:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PydanticSerializationError when streaming OpenAI agent events via WorkflowStreamClient

1 participant