[Platform] Add DeferredResult::asPartialJsonStream() for streaming structured output#2115
Draft
wachterjohannes wants to merge 6 commits into
Draft
Conversation
Adds a static, dependency-free utility that recovers the largest valid structure from an incomplete JSON string. This unblocks rendering partial objects from streamed structured output before the model finishes emitting them. The implementation handles trailing commas, unclosed strings, dangling colons, partial true/false/null literals, and unclosed object/array structures. Ported from modelflow-ai's OptimisticJsonParser. Includes example, documentation under Structured Output, and an entry in the platform CHANGELOG.
…ructured output Wires the new PartialJsonParser to the text-delta stream of a DeferredResult so consumers can render partial JSON snapshots without rebuilding the buffer themselves. The generator skips deltas that leave the recovered structure unchanged and silently swallows unrecoverable buffers, so each iteration is a denser snapshot of the same logical value. Includes an example that prompts a model for a structured book object via streaming output and renders snapshots progressively, an entry in the platform CHANGELOG, and a docs section under the Partial JSON parsing chapter.
662f286 to
70370de
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.
Note
Depends on #2113. Merge after that one or rebase this PR once it lands.
Follow-up to #2113. The
PartialJsonParserintroduced there is a static utility — useful, but it leaves consumers to wire up the streaming buffer themselves. This PR addsDeferredResult::asPartialJsonStream(), which feeds the running text buffer into the parser and yields each new partial value, so the caller doesn't have to touchObjectdenormalization or build their own listener.Behavior
TextDeltas fromasTextStream()into a single buffer.PartialJsonParserafter every delta.\$errorMessage).Usage
The return type is intentionally
mixed(matches the parser) — this PR stays at the "raw JSON" layer. Typed object denormalization on top of the partial stream is a separate follow-up.Notes
examples/platform/partial-json-stream.phpprompts a model for a structured book object via streaming output and renders each snapshot as it grows.composer testandvendor/bin/phpstan analyseon the platform component pass (the existing unmatched-ignore inSchema.phpis unrelated and tracked in [Platform] Remove unmatched PHPStan ignore in JsonSchema Schema attribute #2110).