Skip to content

Explore having the LLM return content in JSON schema instead of WordPress block markup#1119

Open
dkotter wants to merge 11 commits into
developfrom
update/block-renderer
Open

Explore having the LLM return content in JSON schema instead of WordPress block markup#1119
dkotter wants to merge 11 commits into
developfrom
update/block-renderer

Conversation

@dkotter

@dkotter dkotter commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

Description of the Change

For the Content Generation Feature, we specify in our prompt that the content returned should follow the WordPress block markup (with some examples). This seems to work but is fairly fragile as it relies on the LLM knowing what this block markup should look like.

There's a few alternatives to that approach and this PR is exploring one of those: having the LLM return content formatted as JSON and then having us parse that into valid block markup. In theory this should be more reliable and does open up a path where we could support a wider-range of block types (for example, blocks specific to a site or that come from a plugin that some sites may be using).

Some of the work here comes from the @10up/block-renderer-core package (I was wanting to use the full suite but ran into issues getting that working in the block editor cc / @fabiankaegy). Our prompt is still static so won't include custom blocks but we now ask for things formatted as JSON and then parse that on the client-side to create our blocks.

How to test the Change

  1. Checkout this branch and run npm i && npm run build
  2. Turn on the Content Generation Feature and configure it correctly
  3. Create a new post and then click on the sparkle icon in the lower right corner of the editor
  4. In the box that opens up, add your article summary you want to generate (i.e. brief history of WordPress)
  5. Send that request off and ensure you see valid results rendered
  6. Ensure you can insert that content into the editor and it renders properly there

Changelog Entry

Changed - For our Content Generation Feature, have the LLM return JSON data instead of block markup and then parse that out ourselves

Credits

Props @fabiankaegy, @dkotter

Checklist:

Open WordPress Playground Preview

@dkotter dkotter added this to the Future Release milestone Jun 16, 2026
@dkotter dkotter self-assigned this Jun 16, 2026
@dkotter dkotter requested review from a team and jeffpaul as code owners June 16, 2026 19:43
@github-actions github-actions Bot added the needs:code-review This requires code review. label Jun 16, 2026
@github-actions

github-actions Bot commented Jun 16, 2026

Copy link
Copy Markdown

✅ WordPress Plugin Check Report

✅ Status: Passed

📊 Report

All checks passed! No errors or warnings found.


🤖 Generated by WordPress Plugin Check Action • Learn more about Plugin Check

@github-actions github-actions Bot added the needs:refresh This requires a refreshed PR to resolve. label Jun 18, 2026
@github-actions github-actions Bot added needs:refresh This requires a refreshed PR to resolve. and removed needs:refresh This requires a refreshed PR to resolve. labels Jun 18, 2026
@github-actions github-actions Bot removed the needs:refresh This requires a refreshed PR to resolve. label Jun 25, 2026

@peterwilsoncc peterwilsoncc left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added some notes inline re validation and handling the old format in the event the filters are used.

The backcompat would need to be handled in the JS too, so if it's all a bit messy then maybe the filters can be renamed to include _json or similar so out of date plugins don't trigger errors and the use the engine instead.

* @param mixed $value Decoded block tree, or a nested value within it.
* @return mixed Sanitized value.
*/
function sanitize_generated_block_tree( $value ) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to ensure that blocks with specific parent requirements are enforced, eg column is a child of columns? It's in the instructions but it would be good to remove the element of trust.

'temperature' => 0.9,
'messages' => $messages,
'temperature' => 0.9,
'response_format' => array( 'type' => 'json_object' ),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Document introduction of response_format in X.X.X and that prior versions require block formatted code.

🔢 Applies to other providers too.

// preserved when re-encoded rather than becoming "props":[].
$decoded = json_decode( $content );
if ( null === $decoded || JSON_ERROR_NONE !== json_last_error() ) {
return new WP_Error( 'invalid_content_response', esc_html__( 'The generated content was not in the expected format. Please try again.', 'classifai' ) );

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For developers using the filter and returning block formatted code, a check here for <!-- wp: and gracefully falling back to the older format would be lovely.

🔢 Applies to other providers too.

@github-actions github-actions Bot added the needs:refresh This requires a refreshed PR to resolve. label Jul 9, 2026
@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown

@dkotter thanks for the PR! Could you please rebase your PR on top of the latest changes in the base branch?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs:code-review This requires code review. needs:refresh This requires a refreshed PR to resolve.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants