Build streamed OpenAI events before serializing them#1586
Open
brianstrauch wants to merge 3 commits into
Open
Conversation
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
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.
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
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
BaseModelsetsdefer_build=True(since openai-python v1.16.1, April 2024) — a model's serializer stays aMockValSerplaceholder 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: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 thelist[event]activity return value (a list the converter serializes generically and can't build on its own).Fixes #1585
🤖 Generated with Claude Code