Skip to content

feat: modal & ai actions#2860

Merged
abaicus merged 55 commits into
developmentfrom
feat/content-ai
Jul 2, 2026
Merged

feat: modal & ai actions#2860
abaicus merged 55 commits into
developmentfrom
feat/content-ai

Conversation

@Soare-Robert-Daniel

@Soare-Robert-Daniel Soare-Robert-Daniel commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Closes #2124
Closes https://github.com/Codeinwp/otter-internals/issues/280
Closes https://github.com/Codeinwp/otter-internals/issues/281
Closes https://github.com/Codeinwp/otter-internals/issues/285

Ref https://github.com/Codeinwp/otter-internals/issues/282

Summary

Reworks a bunch of the AI functionality:

  • AI Block is now out of beta and completely reworked;
  • We now have a separate tab for the AI settings in the Otter Blocks dashboard;
  • Users can edit and add actions to the AI toolbar with custom prompts;

Screenshots

image image image image

Test instructions:

Important

  • You have to enable and connect at least one AI provider in WordPress 7.0 for this to work.
  • Results vary, and sometimes the generation might fail for complex tasks. This is a limit that we're aware of but it should at least work as intended for base cases - generating sections, pages, translating, rewriting, etc.
  • The AI actions work a lot better with Atomic Wind blocks than other blocks, again, a known caveat, but still,

Custom Actions:

  • Test if the custom actions can be edited, added, removed, saved in the Otter Blocks dashboard > AI tab;
  • Test that these changes reflect in the block toolbar AI menu;

Editor AI integration:

  • Make sure that the quick actions from the block toolbar run fine when launched from there;
  • Selecting multiple blocks and running actions on them should work;
  • Make sure that generating a section works as expected when inserting the Otter Blocks AI Block;
  • Make sure that generating a whole page works as expected when inserting;
  • Applying edits on nested blocks should work (text editing works fine with blocks other than Atomic Wind ones - summarizing, rewording, translating, etc);

Checklist before the final review

  • Included E2E or unit tests for the changes in this PR.
  • Visual elements are not affected by independent changes.
  • It is at least compatible with the minimum WordPress version.
  • It loads additional script in frontend only if it is required.
  • Does not impact the Core Web Vitals.
  • In case of deprecation, old blocks are safely migrated.
  • It is usable in Widgets and FSE.
  • Copy/Paste is working if the attributes are modified.
  • PR is following the best practices

@Soare-Robert-Daniel Soare-Robert-Daniel self-assigned this Jun 11, 2026
@pirate-bot pirate-bot added pr-checklist-incomplete The Pull Request checklist is incomplete. (automatic label) pr-checklist-complete The Pull Request checklist is complete. (automatic label) and removed pr-checklist-incomplete The Pull Request checklist is incomplete. (automatic label) labels Jun 11, 2026
Comment thread src/blocks/plugins/ai-content/apply-content.ts Fixed
@@ -0,0 +1,64 @@
const stripTags = ( html ) => html.replace( /<[^>]+>/g, '' ).trim();
@pirate-bot

pirate-bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Bundle Size Diff

Package Old Size New Size Diff
Animations 178.27 KB 178.27 KB 0 B (0.00%)
Blocks 1.53 MB 1.65 MB 117.26 KB (7.47%)
CSS 7.87 KB 7.87 KB 0 B (0.00%)
Dashboard 111.06 KB 172.5 KB 61.44 KB (55.32%)
Onboarding 68.14 KB 68.14 KB 0 B (0.00%)
Export Import 4.7 KB 4.7 KB 0 B (0.00%)
Pro 436.25 KB 439.79 KB 3.54 KB (0.81%)

@pirate-bot

pirate-bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Plugin build for 35e74e3 is ready 🛎️!

@pirate-bot

pirate-bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

E2E Tests

Playwright Test Status: See serial and parallel matrix jobs

Performance Results serverResponse: {"q25":463.8,"q50":487.4,"q75":500,"cnt":10}, firstPaint: {"q25":1353.8,"q50":1439.9,"q75":1703.9,"cnt":10}, domContentLoaded: {"q25":3815.9,"q50":3846.15,"q75":3877.6,"cnt":10}, loaded: {"q25":3817.7,"q50":3848,"q75":3879.2,"cnt":10}, firstContentfulPaint: {"q25":4333.8,"q50":4362.4,"q75":4395.9,"cnt":10}, firstBlock: {"q25":14839.6,"q50":14875.55,"q75":14963.4,"cnt":10}, type: {"q25":27.33,"q50":28.41,"q75":31.33,"cnt":10}, typeWithoutInspector: {"q25":24.62,"q50":25.38,"q75":28.51,"cnt":10}, typeWithTopToolbar: {"q25":37.19,"q50":39.56,"q75":40.47,"cnt":10}, typeContainer: {"q25":17.12,"q50":18.91,"q75":19.61,"cnt":10}, focus: {"q25":138.15,"q50":147.64,"q75":154.61,"cnt":10}, inserterOpen: {"q25":43.33,"q50":45.92,"q75":47.25,"cnt":10}, inserterSearch: {"q25":17.21,"q50":19.01,"q75":21.19,"cnt":10}, inserterHover: {"q25":5.63,"q50":5.86,"q75":6.34,"cnt":20}, loadPatterns: {"q25":1846.68,"q50":1888.34,"q75":1912.95,"cnt":10}, listViewOpen: {"q25":248.09,"q50":260.08,"q75":270.25,"cnt":10}

Soare-Robert-Daniel and others added 6 commits June 16, 2026 18:44
Resolve conflicts integrating the multi-backend AI work (WP AI Client /
Connectors) with the content-ai toolbar/modal refactor:

- AI settings stay in the dedicated AI dashboard tab; ported the
  multi-backend "WordPress AI"/Connectors panel, provider-status notices,
  and legacy OpenAI-key fallback into AI.js.
- Editor toolbar gate now uses isAIBackendConfigured().
- Adapt prompt response consumers (modal, content-generator, block
  generation) to the normalized {ok, content, usedTokens} contract; drop
  the deleted ChatResponse type.
- Merge e2e specs/config and keep both server-side AI and captcha HTTP
  stubs; dashboard specs cover the multi-backend states on the AI tab.
- Guard rest_sanitize_boolean inputs in toolbar-action sanitization.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
# Conflicts:
#	packages/e2e-tests/mu-plugins/otter-e2e-bootstrap.php
The content-generator refactor stopped passing the `resultHistory`
attribute into PromptPlaceholder, so the component's restore-last-prompt
effect bailed out (`! props.resultHistory`) and the prompt field came up
empty for blocks that carry history. Re-wire the prop.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ve across reset

Two pre-existing e2e failures on this branch:

- The AI mocks returned HTML, but the new `generateBlocksFromTask`
  pipeline JSON.parses the reply expecting `{ rationale, roots }`, so no
  blocks were produced. Make both the legacy /chat/completions and the WP
  AI Client /responses mocks emit phase-aware block-generation JSON.

- `reset()` deleted PRO_LICENSE_OPTION, which global-setup activates only
  once for the whole run. ai-toolbar's reset() therefore deactivated Pro
  for every later spec, failing the Pro-gated Form tests. Restore the stub
  license in reset() instead of deleting it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the separate "Replace" and "Insert below" buttons in the AI
content generator with one primary "Done" button that applies the
generated blocks in place (the former Replace behavior). Drop the
now-unused insert-below handler/import and update the e2e specs to the
new label.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The content generator labelled every generation request as an
"OpenAI request (gpt-5-mini)", but the backend is resolved server-side:
on the WP AI Client connector path the model pin is dropped and the
configured provider/model is used. Make the debug labels backend-agnostic.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Soare-Robert-Daniel and others added 5 commits June 17, 2026 15:16
…orm submit

Add two instructions to the block-generation prompt:
- system prompt: for design requests, produce a clean, well-structured,
  visually appealing layout.
- structure prompt: when using a form block, don't add a separate submit
  button — the Otter Form already renders its own.

Also document the missing @param tags on buildStructureCatalog,
buildAttributeSchema and validateStructure, which were failing
`npm run lint` (jsdoc/require-param).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drop the aiDebug step logger that was on by default during the beta:
delete debug.ts, its call sites in the block-generation pipeline and the
content generator, and the test mock that silenced it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The block-generation rewrite hardcoded the "content" placeholder and
title, so inserting the block with promptID 'form' no longer showed
"Start describing what form you need…". Restore a small preset lookup
keyed by promptID (form vs textTransformation) while keeping the single
Done action. Fixes the ai-block-wp-client form e2e test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The content generator rewrite routed every prompt through the block
generation pipeline, so promptID 'form' stopped producing Form field
blocks. Send the form prompt through the embedded-prompt path again
(onPreview → parseFormPromptResponseToBlocks → Form block), keeping the
new pipeline for content prompts. Fixes the ai-block-wp-client form e2e.

Also poll for the inserted item in the accordion "add new item" e2e
instead of snapshotting immediately after the click, which raced the
async store update and flaked under parallel load.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
In the WP 7.0 iframe editor, a button rendered through InnerBlocks'
renderAppender prop does not fire its React onClick when clicked, so
"Add Accordion Item" did nothing (the e2e add-item test caught this).
Render the appender as block content with renderAppender={false},
matching the working Tabs block, so the click reaches the handler.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Soare-Robert-Daniel Soare-Robert-Daniel linked an issue Jun 18, 2026 that may be closed by this pull request
Soare-Robert-Daniel and others added 3 commits June 18, 2026 17:00
The toolbar filter only returned actions whose availability matched
'richtext' when every selected block was rich text, which dropped
"Any block" actions from text. Allow 'any' actions everywhere and
restrict 'richtext' actions to all-rich-text selections, which also
fixes mixed selections showing no actions.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Update the attribute-fill prompt to set tasteful, coherent colors when
a block exposes color attributes, keeping text readable, so generated
layouts look polished instead of bland.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Phase 1 now produces a plan (mission, design direction, and a section
outline with per-section notes) instead of a bare slug tree. The mission,
design direction and each section's notes are trickled into every per-root
attribute call so the page builds toward one coherent vision.

generateBlocksFromTask gains onPlanReady/onRootComplete callbacks; the AI
block renders the plan (mission, palette, outline checklist) and inserts
each section as it completes, with a staleness guard and undo-safe previews.
Verbose design chips stay internal (prompt context only).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
abaicus and others added 16 commits June 26, 2026 15:49
Route follow-up turns in create mode to the edit path (they were re-running generation and ignoring the instruction), and fix a ReferenceError that broke every text-only edit. Send the selection's block schema on edit, add meaningful error states with an inline Retry, cap the preview height with internal scroll, lock the prompt while generating with a red Stop, and switch accents to the WP admin color.
…gateway 502 pages

Cap block-generation output tokens and enforce JSON mode from response_format so a whole-markup rewrite no longer truncates into unparseable JSON. Classify provider gateway/timeout failures into clean, retryable errors instead of passing raw nginx 502 HTML through as the message, and retry HTML error pages the client can't parse.
…-markup rewrite

A style-only edit now sends just each block's className (the text-edit pattern, for classes) and splices the transformed classes back into a clone, so the response is bounded by class count rather than the full serialized tree. This keeps recolor/restyle off the oversized REWRITE path that truncated and timed out, and makes structural/text drift impossible. Falls back to the full style rewrite when nothing carries a className.
… overlays

Generalize the style-edit splice from className to any block's style attributes (the style object, color/spacing/font attrs), so recolor/restyle stays off the whole-markup rewrite for classic and core blocks too (class-nodes -> style-nodes). Classify 'add an overlay / new layer' as a structural redesign rather than a style tweak, and teach the atomic-wind rewrite the overlay idiom (an empty, absolutely-positioned box with a translucent background). Also make 'Edit with AI' the topmost toolbar-menu action and tidy the editor.scss comments.
const content = block.attributes?.content;

if ( 'string' === typeof tagName && HEADING_TAGS.has( tagName ) && 'string' === typeof content ) {
const text = content.replace( /<[^>]+>/g, '' ).trim();
Copilot stopped work on behalf of abaicus due to an error July 1, 2026 16:28
Copilot AI requested a review from abaicus July 1, 2026 16:28
@abaicus abaicus removed their request for review July 1, 2026 16:29
@poonam279

Copy link
Copy Markdown

@Soare-Robert-Daniel, The Go to AI Settings link under the Integration tab redirects to an invalid URL (https://retrievebag.s3-tastewp.com/wp-admin/undefined#ai).

image

Also, the AI Provider text is not showing in one line

image

Soare-Robert-Daniel and others added 3 commits July 2, 2026 14:13
The Integrations tab link built its URL from optionsPath, which is not
localized on the dashboard page, producing wp-admin/undefined#ai. Switch
tabs in place via setTab instead. Also opt SelectControl out of the flex
row layout forced on base-control fields so its stacked label no longer
wraps.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@abaicus abaicus merged commit 8be769a into development Jul 2, 2026
15 of 17 checks passed
@abaicus abaicus deleted the feat/content-ai branch July 2, 2026 14:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr-checklist-complete The Pull Request checklist is complete. (automatic label)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Custom AI action

5 participants