Skip to content

[Platform] Add PartialJsonParser for streaming structured output#2113

Open
wachterjohannes wants to merge 5 commits into
symfony:mainfrom
wachterjohannes:feature/partial-json-parser
Open

[Platform] Add PartialJsonParser for streaming structured output#2113
wachterjohannes wants to merge 5 commits into
symfony:mainfrom
wachterjohannes:feature/partial-json-parser

Conversation

@wachterjohannes

@wachterjohannes wachterjohannes commented May 23, 2026

Copy link
Copy Markdown
Contributor
Q A
Bug fix? no
New feature? yes
Docs? yes
Issues -
License MIT

This PR adds Symfony\AI\Platform\StructuredOutput\Streaming\PartialJsonParser, 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.

Algorithm

PartialJsonParser::parse() attempts a strict json_decode first; on failure it applies best-effort fixes in order and tries again:

  1. Strip trailing commas before ] / }.
  2. Close unclosed strings by tracking " and \ byte-wise (UTF-8 safe because both are single-byte).
  3. Fix incomplete values at the tail:
    • dangling colon → append null
    • partial literals (tru, fals, nul, ...) → complete them
    • trailing comma at EOF → strip it
  4. Close unclosed { / [ by walking the string with a stack that ignores chars inside strings.

If still invalid, returns null and populates the &$errorMessage reference with json_last_error_msg().

Usage

use Symfony\AI\Platform\StructuredOutput\Streaming\PartialJsonParser;

$buffer = '';
foreach ($chunks as $chunk) {
    $buffer .= $chunk;
    $partial = PartialJsonParser::parse($buffer);

    if (null !== $partial) {
        // render the partial structure
    }
}

Notes

  • Ported from ModelflowAi\Chat\Util\Json\OptimisticJsonParser
  • No platform wiring changes — follow-up PRs can wire it into StreamResult / structured-output streaming.
  • composer test, vendor/bin/phpstan analyse, and php-cs-fixer pass cleanly on the new files.

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.
@wachterjohannes wachterjohannes force-pushed the feature/partial-json-parser branch from 4e4507c to 36b812d Compare May 27, 2026 07:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Feature New feature Platform Issues & PRs about the AI Platform component Status: Needs Review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants