feat: modal & ai actions#2860
Open
Soare-Robert-Daniel wants to merge 23 commits into
Open
Conversation
| generatedHtml: string, | ||
| sourceBlocks: BlockProps<unknown>[] | ||
| ) => { | ||
| const plainText = generatedHtml.replace( /<[^>]+>/g, '' ).trim(); |
| @@ -0,0 +1,64 @@ | |||
| const stripTags = ( html ) => html.replace( /<[^>]+>/g, '' ).trim(); | |||
Contributor
Bundle Size Diff
|
Contributor
|
Plugin build for 17705d5 is ready 🛎️!
|
Contributor
E2E TestsPlaywright Test Status: See serial and parallel matrix jobs Performance ResultsserverResponse: {"q25":493.3,"q50":505.55,"q75":521.5,"cnt":10}, firstPaint: {"q25":557.8,"q50":700.3,"q75":750.3,"cnt":10}, domContentLoaded: {"q25":3629.3,"q50":3653.85,"q75":3663.1,"cnt":10}, loaded: {"q25":3631.4,"q50":3656.2,"q75":3665.1,"cnt":10}, firstContentfulPaint: {"q25":4215.3,"q50":4227.4,"q75":4260.5,"cnt":10}, firstBlock: {"q25":14953.7,"q50":14984.35,"q75":15092.1,"cnt":10}, type: {"q25":27.6,"q50":28.03,"q75":31.08,"cnt":10}, typeWithoutInspector: {"q25":25.11,"q50":26.4,"q75":28.43,"cnt":10}, typeWithTopToolbar: {"q25":31.93,"q50":32.96,"q75":47.45,"cnt":10}, typeContainer: {"q25":14.64,"q50":15.48,"q75":15.82,"cnt":10}, focus: {"q25":115.27,"q50":117.62,"q75":123.01,"cnt":10}, inserterOpen: {"q25":40.25,"q50":40.86,"q75":42.61,"cnt":10}, inserterSearch: {"q25":14.75,"q50":15.05,"q75":16.04,"cnt":10}, inserterHover: {"q25":5.71,"q50":5.96,"q75":6.27,"cnt":20}, loadPatterns: {"q25":1692.31,"q50":1714.15,"q75":1734.41,"cnt":10}, listViewOpen: {"q25":235.12,"q50":240.21,"q75":251.19,"cnt":10} |
d2fa71f to
d3b83d6
Compare
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>
f1d49d4 to
9c74c9e
Compare
…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>
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>
The WP AI Client sends provider requests with a 30s timeout, which reasoning models on OpenAI's /v1/responses endpoint regularly exceed (cURL error 28 -> 502). Raise the timeout for the generation request to 120s via http_request_args (filterable through otter_ai_request_timeout), and retry transient backend failures (timeouts, 5xx, network errors) with exponential backoff via withPromptRetry, leaving permanent errors alone. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Route AI block + toolbar generation through the AIContentModal: a version-based flow with a sparkle prompt row, live BlockPreview at Desktop/Mobile widths, an animated phase-aware generating state (planning → per-section), and Done/Regenerate with token + version nav. - Fix block generation to use the strict-JSON endpoint instead of the HTML-forcing textTransformation template, so the plan parses. - Move scope (Section/Full page) + starter prompt chips into the AI block (the first interaction); the modal auto-generates on open. - Lock the modal while generating so click-outside/Esc can't lose work. - Fixed-height modal with header/scroll/footer layout: the footer stays pinned at the bottom and the content scrolls between header and footer. - Stabilize useSelect in the AI toolbar HOC and useResponsiveAttributes (return store-memoized/primitive values, derive the rest with useMemo) to stop the "useSelect returns different values" warning storm that the modal's BlockPreview surfaced across every block. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
# Conflicts: # src/blocks/test/unit/utils.test.ts
…on + e2e - Modal: redesign the create/section experience (branded header, framed preview stage, status pill, bottom bar that generates then refines, footer with version stepper + Discard/Insert section). - Generation: feed the resolved theme palette into both prompt phases so generated colors reference real theme slugs instead of invented ones. - Insertion: clone generated blocks with fresh clientIds before replaceBlocks so they no longer share identity with the live BlockPreview tree. - e2e: add ai-block-section-insert spec reproducing the insertion path, plus a setAtomicWindBlocks fixture (and whitelist entry) to register atomic-wind/*. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- e2e: drive the real AI toolbar → Generate → Insert section flow (replaces the selected block while the modal + live BlockPreview unmount), the one path the store-only cases can't cover. Self-skips where Atomic Wind can't register. - bootstrap: emit a real atomic-wind/* features tree from the OpenAI stub when the Atomic Wind option is on, and fix block-generation phase detection (the plan-prompt wording no longer matched is_block_generation_request). Confirms the cloneBlock insertion fix: generating + inserting an Atomic Wind section on WP 7.0 (with the 404-ing icon slugs) no longer crashes the editor. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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.
Closes https://github.com/Codeinwp/otter-internals/issues/280
Summary
Screenshots
Test instructions
Checklist before the final review