From e9b8b08109b9caca8c71c8809702772c7035fffd Mon Sep 17 00:00:00 2001 From: Gautam Mehta Date: Fri, 1 May 2026 09:57:47 +0530 Subject: [PATCH 1/7] feat: enhance summarization by minimum content length filter and disable button --- .../Summarization/Summarization.php | 12 ++++- .../components/SummarizationBlockControls.tsx | 4 +- .../components/SummarizationPlugin.tsx | 45 ++++++++++++++----- .../functions/useSummaryGeneration.ts | 12 +++++ 4 files changed, 58 insertions(+), 15 deletions(-) diff --git a/includes/Experiments/Summarization/Summarization.php b/includes/Experiments/Summarization/Summarization.php index a12f569cc..f65a5ef8e 100644 --- a/includes/Experiments/Summarization/Summarization.php +++ b/includes/Experiments/Summarization/Summarization.php @@ -101,11 +101,21 @@ public function enqueue_assets( string $hook_suffix ): void { Asset_Loader::enqueue_script( 'summarization', 'experiments/summarization' ); Asset_Loader::enqueue_style( 'summarization', 'experiments/summarization' ); + /** + * Filters the minimum content length required to enable summarization. + * + * @since 0.9.0 + * + * @param int $min_content_length The minimum number of characters required. Default 100. + */ + $min_content_length = (int) apply_filters( 'ai_summarization_min_content_length', 100 ); + Asset_Loader::localize_script( 'summarization', 'SummarizationData', array( - 'enabled' => $this->is_enabled(), + 'enabled' => $this->is_enabled(), + 'minContentLength' => $min_content_length, ) ); } diff --git a/src/experiments/summarization/components/SummarizationBlockControls.tsx b/src/experiments/summarization/components/SummarizationBlockControls.tsx index f044300a6..2966f7454 100644 --- a/src/experiments/summarization/components/SummarizationBlockControls.tsx +++ b/src/experiments/summarization/components/SummarizationBlockControls.tsx @@ -23,7 +23,7 @@ const { aiSummarizationData } = window as any; * Block controls component. */ const Controls = () => { - const { isSummarizing, hasSummary, handleSummarize } = + const { isSummarizing, hasSummary, handleSummarize, isContentTooShort } = useSummaryGeneration(); let buttonLabel: string = __( 'Generate Summary', 'ai' ); @@ -46,7 +46,7 @@ const Controls = () => { icon={ update } className="ai-summarization-block-controls-button" onClick={ handleSummarize } - disabled={ isSummarizing } + disabled={ isSummarizing || isContentTooShort } isBusy={ isSummarizing } /> diff --git a/src/experiments/summarization/components/SummarizationPlugin.tsx b/src/experiments/summarization/components/SummarizationPlugin.tsx index 30df5c422..9f74003f3 100644 --- a/src/experiments/summarization/components/SummarizationPlugin.tsx +++ b/src/experiments/summarization/components/SummarizationPlugin.tsx @@ -7,7 +7,7 @@ */ import { Button, Flex, FlexItem } from '@wordpress/components'; import { PluginPostStatusInfo } from '@wordpress/editor'; -import { __ } from '@wordpress/i18n'; +import { __, sprintf } from '@wordpress/i18n'; import { update } from '@wordpress/icons'; /** @@ -21,8 +21,13 @@ const { aiSummarizationData } = window as any; * Summarization plugin component. */ export default function SummarizationPlugin() { - const { isSummarizing, hasSummary, handleSummarize } = - useSummaryGeneration(); + const { + isSummarizing, + hasSummary, + handleSummarize, + isContentTooShort, + minContentLength, + } = useSummaryGeneration(); let buttonLabel: string = __( 'Generate Summary', 'ai' ); @@ -31,15 +36,31 @@ export default function SummarizationPlugin() { } else if ( hasSummary ) { buttonLabel = __( 'Regenerate Summary', 'ai' ); } - const buttonDescription = hasSummary - ? __( - 'This will update the AI generated summary block with a new summary of the content of this post.', - 'ai' - ) - : __( - 'This will create a block that is a summary of the content of this post.', + + const isDisabled = isSummarizing || isContentTooShort; + + let buttonDescription: string; + + if ( isContentTooShort ) { + buttonDescription = sprintf( + /* translators: %d: minimum number of characters required */ + __( + 'The summarization experiment will be enabled when the post content has at least %d characters.', 'ai' - ); + ), + minContentLength + ); + } else if ( hasSummary ) { + buttonDescription = __( + 'This will update the AI generated summary block with a new summary of the content of this post.', + 'ai' + ); + } else { + buttonDescription = __( + 'This will create a block that is a summary of the content of this post.', + 'ai' + ); + } // Don't render if disabled. if ( ! aiSummarizationData?.enabled ) { @@ -60,7 +81,7 @@ export default function SummarizationPlugin() { label={ buttonLabel } icon={ update } onClick={ handleSummarize } - disabled={ isSummarizing } + disabled={ isDisabled } isBusy={ isSummarizing } __next40pxDefaultSize > diff --git a/src/experiments/summarization/functions/useSummaryGeneration.ts b/src/experiments/summarization/functions/useSummaryGeneration.ts index 0ecf70acf..76756a2c5 100644 --- a/src/experiments/summarization/functions/useSummaryGeneration.ts +++ b/src/experiments/summarization/functions/useSummaryGeneration.ts @@ -17,6 +17,8 @@ import { store as noticesStore } from '@wordpress/notices'; */ import { generateSummary } from './generate-summary'; +const { aiSummarizationData } = window as any; + /** * Summary generation hook. */ @@ -110,10 +112,20 @@ export function useSummaryGeneration() { } }; + // Minimum content length required for summarization. + const minContentLength: number = + aiSummarizationData?.minContentLength ?? 100; + const strippedContent = content + ? content.replace( /<[^>]+>/g, '' ).trim() + : ''; + const isContentTooShort = strippedContent.length < minContentLength; + return { isSummarizing, hasSummary: summary && summary.trim().length > 0, summary, handleSummarize, + isContentTooShort, + minContentLength, }; } From ed065964934ce8cd78599d0371634c08530e2e69 Mon Sep 17 00:00:00 2001 From: Gautam Mehta Date: Fri, 1 May 2026 10:38:27 +0530 Subject: [PATCH 2/7] fix: filter name for minimum content length in summarization --- includes/Experiments/Summarization/Summarization.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/Experiments/Summarization/Summarization.php b/includes/Experiments/Summarization/Summarization.php index f65a5ef8e..6f6edd9e7 100644 --- a/includes/Experiments/Summarization/Summarization.php +++ b/includes/Experiments/Summarization/Summarization.php @@ -108,7 +108,7 @@ public function enqueue_assets( string $hook_suffix ): void { * * @param int $min_content_length The minimum number of characters required. Default 100. */ - $min_content_length = (int) apply_filters( 'ai_summarization_min_content_length', 100 ); + $min_content_length = (int) apply_filters( 'wpai_summarization_min_content_length', 100 ); Asset_Loader::localize_script( 'summarization', From 514b8664639c8ca517840ffe1bcf4de5bda2c4ae Mon Sep 17 00:00:00 2001 From: Gautam Mehta <66418526+coderGtm@users.noreply.github.com> Date: Tue, 5 May 2026 17:48:50 +0530 Subject: [PATCH 3/7] fix: since version number Co-authored-by: Darin Kotter --- includes/Experiments/Summarization/Summarization.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/Experiments/Summarization/Summarization.php b/includes/Experiments/Summarization/Summarization.php index 6f6edd9e7..28347f758 100644 --- a/includes/Experiments/Summarization/Summarization.php +++ b/includes/Experiments/Summarization/Summarization.php @@ -104,7 +104,7 @@ public function enqueue_assets( string $hook_suffix ): void { /** * Filters the minimum content length required to enable summarization. * - * @since 0.9.0 + * @since x.x.x * * @param int $min_content_length The minimum number of characters required. Default 100. */ From d81b0cb682ee3bbfbbfc7e2d1d05ebb542962b24 Mon Sep 17 00:00:00 2001 From: Gautam Mehta <66418526+coderGtm@users.noreply.github.com> Date: Tue, 5 May 2026 17:49:24 +0530 Subject: [PATCH 4/7] feat: update description text Co-authored-by: Darin Kotter --- .../summarization/components/SummarizationPlugin.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/experiments/summarization/components/SummarizationPlugin.tsx b/src/experiments/summarization/components/SummarizationPlugin.tsx index 9f74003f3..31459ea26 100644 --- a/src/experiments/summarization/components/SummarizationPlugin.tsx +++ b/src/experiments/summarization/components/SummarizationPlugin.tsx @@ -45,7 +45,7 @@ export default function SummarizationPlugin() { buttonDescription = sprintf( /* translators: %d: minimum number of characters required */ __( - 'The summarization experiment will be enabled when the post content has at least %d characters.', + 'Summarization will be available when the post content has at least %d characters.', 'ai' ), minContentLength From 14f7fa7485c40488bfa72ae5a5ae072c300764ac Mon Sep 17 00:00:00 2001 From: Gautam Mehta Date: Thu, 7 May 2026 19:15:53 +0530 Subject: [PATCH 5/7] test: modify existing test and add new for summarization char limit --- .../experiments/content-summarization.spec.js | 81 ++++++++++++++++++- 1 file changed, 79 insertions(+), 2 deletions(-) diff --git a/tests/e2e/specs/experiments/content-summarization.spec.js b/tests/e2e/specs/experiments/content-summarization.spec.js index de94da456..db40bee21 100644 --- a/tests/e2e/specs/experiments/content-summarization.spec.js +++ b/tests/e2e/specs/experiments/content-summarization.spec.js @@ -36,12 +36,12 @@ test.describe( 'Content Summarization Experiment', () => { // Enable the Content Summarization Experiment. await enableExperiment( admin, page, 'Content Summarization' ); - // Create a new post. + // Create a new post with content that meets the minimum length requirement (>= 100 chars). await admin.createNewPost( { postType: 'post', title: 'Test Content Summarization Experiment', content: - 'This is some test content for the Content Summarization Experiment.', + 'This is some test content for the Content Summarization Experiment. It needs to be at least one hundred characters long.', } ); // Save the post. @@ -113,6 +113,83 @@ test.describe( 'Content Summarization Experiment', () => { ).not.toBeVisible(); } ); + test( 'Summarize button is disabled when content is shorter than the minimum length', async ( { + admin, + editor, + page, + } ) => { + // Globally turn on Experiments. + await enableExperiments( admin, page ); + + // Enable the Content Summarization Experiment. + await enableExperiment( admin, page, 'Content Summarization' ); + + // Create a new post with content shorter than 100 characters. + await admin.createNewPost( { + postType: 'post', + title: 'Test Short Content', + content: 'Too short.', + } ); + + // Save the post. + await editor.saveDraft(); + + // Ensure the sidebar is visible. + await editor.openDocumentSettingsSidebar(); + + const generateButton = page.locator( + '.ai-summarization-plugin-container button' + ); + + // Button should be visible but disabled. + await expect( generateButton ).toBeVisible(); + await expect( generateButton ).toBeDisabled(); + + // The descriptive text should explain when the button will be enabled. + await expect( + page.locator( '.ai-summarization-plugin-container .description' ) + ).toContainText( '100 characters' ); + } ); + + test( 'Summarize button is enabled when content meets the minimum length', async ( { + admin, + editor, + page, + } ) => { + // Globally turn on Experiments. + await enableExperiments( admin, page ); + + // Enable the Content Summarization Experiment. + await enableExperiment( admin, page, 'Content Summarization' ); + + // Create a new post with content that is at least 100 characters. + await admin.createNewPost( { + postType: 'post', + title: 'Test Sufficient Content', + content: + 'This post has enough content to meet the minimum character requirement for the summarization feature to be enabled.', + } ); + + // Save the post. + await editor.saveDraft(); + + // Ensure the sidebar is visible. + await editor.openDocumentSettingsSidebar(); + + const generateButton = page.locator( + '.ai-summarization-plugin-container button' + ); + + // Button should be visible and enabled. + await expect( generateButton ).toBeVisible(); + await expect( generateButton ).toBeEnabled(); + + // The descriptive text should NOT mention the minimum character requirement. + await expect( + page.locator( '.ai-summarization-plugin-container .description' ) + ).not.toContainText( 'characters' ); + } ); + test( 'Ensure the Content Summarization Experiment UI is not visible when the experiment is disabled', async ( { admin, editor, From 6fb7bef8ffb0c5bb79b6a9698a75660237b70603 Mon Sep 17 00:00:00 2001 From: Gautam Mehta Date: Thu, 7 May 2026 19:31:34 +0530 Subject: [PATCH 6/7] refactor: update content length check for summarization using word count utility --- .../summarization/functions/useSummaryGeneration.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/experiments/summarization/functions/useSummaryGeneration.ts b/src/experiments/summarization/functions/useSummaryGeneration.ts index 76756a2c5..d56501419 100644 --- a/src/experiments/summarization/functions/useSummaryGeneration.ts +++ b/src/experiments/summarization/functions/useSummaryGeneration.ts @@ -16,6 +16,7 @@ import { store as noticesStore } from '@wordpress/notices'; * Internal dependencies */ import { generateSummary } from './generate-summary'; +import { count } from '@wordpress/wordcount'; const { aiSummarizationData } = window as any; @@ -115,10 +116,8 @@ export function useSummaryGeneration() { // Minimum content length required for summarization. const minContentLength: number = aiSummarizationData?.minContentLength ?? 100; - const strippedContent = content - ? content.replace( /<[^>]+>/g, '' ).trim() - : ''; - const isContentTooShort = strippedContent.length < minContentLength; + const isContentTooShort = + count( content, 'characters_including_spaces' ) < minContentLength; return { isSummarizing, From a81bf79c733bccf41ce7b7f906cbb0d1e8b3e355 Mon Sep 17 00:00:00 2001 From: Darin Kotter Date: Mon, 11 May 2026 09:06:51 -0600 Subject: [PATCH 7/7] Add line break. Update button description a bit --- includes/Experiments/Summarization/Summarization.php | 1 + .../summarization/components/SummarizationPlugin.tsx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/includes/Experiments/Summarization/Summarization.php b/includes/Experiments/Summarization/Summarization.php index 4dfcb99a9..063537c3c 100644 --- a/includes/Experiments/Summarization/Summarization.php +++ b/includes/Experiments/Summarization/Summarization.php @@ -101,6 +101,7 @@ public function enqueue_assets( string $hook_suffix ): void { } Asset_Loader::enqueue_script( 'summarization', 'experiments/summarization' ); + /** * Filters the minimum content length required to enable summarization. * diff --git a/src/experiments/summarization/components/SummarizationPlugin.tsx b/src/experiments/summarization/components/SummarizationPlugin.tsx index 31459ea26..b5d8d1148 100644 --- a/src/experiments/summarization/components/SummarizationPlugin.tsx +++ b/src/experiments/summarization/components/SummarizationPlugin.tsx @@ -52,7 +52,7 @@ export default function SummarizationPlugin() { ); } else if ( hasSummary ) { buttonDescription = __( - 'This will update the AI generated summary block with a new summary of the content of this post.', + 'This will update the generated summary block with a new summary of the content of this post.', 'ai' ); } else {