Skip to content

Commit 82d513f

Browse files
committed
Merge latest develop and resolve conflicts
2 parents ee862bb + 4fb4234 commit 82d513f

40 files changed

+34743
-34491
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ This [Canonical Plugin](https://make.wordpress.org/core/2022/09/11/canonical-plu
3939
* **[Content Summarization](docs/experiments/summarization.md)** - Summarizes long-form content into digestible overviews.
4040
* **[Excerpt Generation](docs/experiments/excerpt-generation.md)** - Generates excerpt suggestions from content.
4141
* **Experiment Framework** - Opt-in system that lets you enable only the AI features you want to use.
42-
* **[Image Generation and Editing](docs/experiments/image-generation.md)** - Create and edit images from post content in the editor, also via the Media Library.
42+
* **[Image Generation and Editing](docs/features/image-generation.md)** - Create and edit images from post content in the editor, also via the Media Library.
4343
* **[Meta Description Generation](docs/experiments/meta-description.md)** - Generates meta description suggestions and integrates those with various SEO plugins.
4444
* **Multi-Provider Support** - Works with popular AI providers like OpenAI, Google, and Anthropic.
4545
* **[Review Notes](docs/experiments/review-notes.md)** - Reviews post content block-by-block and adds Notes with suggestions for Accessibility, Readability, Grammar, and SEO.
45.8 KB
Loading
Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
## Summary
44

5-
The Image Generation experiment adds AI-powered image generation to the WordPress post editor in two ways: **featured images** (from the featured image panel) and **inline images** (from supported blocks). It provides a "Generate featured image" button in the featured image panel and a "Generate Image" buttons on Image, Cover, Media & Text, and Gallery blocks. The experiment registers three WordPress Abilities (`ai/image-generation`, `ai/image-import`, `ai/image-prompt-generation`) that can be used both through the admin UI and directly via REST API requests.
5+
The Image Generation feature adds AI-powered image generation to the WordPress post editor in two ways: **featured images** (from the featured image panel) and **inline images** (from supported blocks). It provides a "Generate featured image" button in the featured image panel and a "Generate Image" buttons on Image, Cover, Media & Text, and Gallery blocks. The feature registers three WordPress Abilities (`ai/image-generation`, `ai/image-import`, `ai/image-prompt-generation`) that can be used both through the admin UI and directly via REST API requests.
66

77
## Overview
88

99
### For End Users
1010

11-
When enabled, the Image Generation experiment adds:
11+
When enabled, the Image Generation feature adds:
1212

1313
- **Featured image panel:** A "Generate featured image" button that creates AI images from post content. The image is imported into the media library and set as the featured image. Images are marked with an "AI Generated Featured Image" label.
1414
- **Block buttons:** A "Generate Image" inline and toolbar button on Image, Cover, Media & Text, and Gallery blocks. Clicking it opens a modal where you describe the image, generate it, preview it, optionally refine it (edit with follow-up prompts using the current image as reference), and insert it into the block.
@@ -29,9 +29,9 @@ When enabled, the Image Generation experiment adds:
2929

3030
### For Developers
3131

32-
The experiment consists of four main components:
32+
The feature consists of four main components:
3333

34-
1. **Experiment Class** (`WordPress\AI\Experiments\Image_Generation\Image_Generation`): Handles registration, asset enqueuing, featured image and inline block editor UI integration, and post meta registration
34+
1. **Feature Class** (`WordPress\AI\Features\Image_Generation\Image_Generation`): Handles registration, asset enqueuing, featured image and inline block editor UI integration, and post meta registration
3535
2. **Generate Image Prompt Ability** (`WordPress\AI\Abilities\Image\Generate_Image_Prompt`): Generates optimized image generation prompts from post content and context
3636
3. **Generate Image Ability** (`WordPress\AI\Abilities\Image\Generate_Image`): Generates base64-encoded images from prompts (and optionally from a reference image for refining) using AI models
3737
4. **Import Image Ability** (`WordPress\AI\Abilities\Image\Import_Base64_Image`): Imports base64-encoded images into the WordPress media library
@@ -42,7 +42,7 @@ All three abilities can be called directly via REST API, making them useful for
4242

4343
### Key Hooks & Entry Points
4444

45-
- `WordPress\AI\Experiments\Image_Generation\Image_Generation::register()` wires everything once the experiment is enabled:
45+
- `WordPress\AI\Features\Image_Generation\Image_Generation::register()` wires everything once the feature is enabled:
4646
- `register_post_meta()` → registers `ai_generated` post meta for attachment post type
4747
- `wp_abilities_api_init` → registers the `ai/image-generation`, `ai/image-import`, and `ai/image-prompt-generation` abilities
4848
- `admin_enqueue_scripts``enqueue_assets()` loads assets on `post.php` and `post-new.php` screens for post types that support featured images
@@ -51,8 +51,8 @@ All three abilities can be called directly via REST API, making them useful for
5151
### Assets & Data Flow
5252

5353
1. **PHP Side:**
54-
- `enqueue_shared_assets()` (called from `enqueue_assets()` and `enqueue_inline_assets()`) loads `experiments/image-generation` (`src/experiments/image-generation/index.ts`) and localizes `window.aiImageGenerationData` with:
55-
- `enabled`: Whether the experiment is enabled
54+
- `enqueue_shared_assets()` (called from `enqueue_assets()` and `enqueue_inline_assets()`) loads `features/image-generation` (`src/features/image-generation/index.ts`) and localizes `window.aiImageGenerationData` with:
55+
- `enabled`: Whether the feature is enabled
5656
- `altTextEnabled`: Whether the alt text generation experiment is enabled
5757

5858
2. **React Side (Featured Image):**
@@ -675,7 +675,7 @@ Example error response:
675675
}
676676
```
677677
678-
## Extending the Experiment
678+
## Extending the Feature
679679
680680
### Customizing the Image Prompt Generation System Instruction
681681
@@ -706,7 +706,7 @@ add_filter( 'wpai_preferred_image_models', function( $models ) {
706706
You can customize what metadata is saved when importing images by modifying the `uploadImage` function in:
707707
708708
```typescript
709-
src/experiments/image-generation/functions/upload-image.ts
709+
src/features/image-generation/functions/upload-image.ts
710710
```
711711
712712
`uploadImage( imageData, options? )` accepts generated image data and an optional `options` object with `onProgress?: ( message: string ) => void` for progress callbacks. When the Alt Text Generation experiment is enabled, it generates alt text via `generateAltText()` before importing; otherwise it uses the image prompt as alt text.
@@ -715,45 +715,45 @@ You can also filter the input before calling the import ability via REST API.
715715
716716
### Customizing Post Context
717717
718-
The experiment uses `getContext()` to fetch post details (title, type). You can extend this to include additional context by modifying:
718+
The feature uses `getContext()` to fetch post details (title, type). You can extend this to include additional context by modifying:
719719
720720
```typescript
721-
src/experiments/image-generation/functions/get-context.ts
721+
src/features/image-generation/functions/get-context.ts
722722
```
723723
724724
The context is formatted using `formatContext()` which converts key-value pairs into a string format. You can customize this formatting by modifying:
725725
726726
```typescript
727-
src/experiments/image-generation/functions/format-context.ts
727+
src/features/image-generation/functions/format-context.ts
728728
```
729729
730730
### Adding Custom UI Elements
731731
732732
You can extend the React components to add custom UI elements:
733733
734734
1. **Modify the featured image button and progress UI:**
735-
- Edit `src/experiments/image-generation/components/GenerateFeaturedImage.tsx`
735+
- Edit `src/features/image-generation/components/GenerateFeaturedImage.tsx`
736736
- The component renders a button and, while generating, a progress container (`.ai-featured-image__progress`) that displays the current step and a spinner; progress is driven by the `onProgress` callbacks passed to `generateImage()` and `uploadImage()`
737737
738738
2. **Modify the inline generation modal:**
739-
- Edit `src/experiments/image-generation/components/GenerateImageInlineModal.tsx`
739+
- Edit `src/features/image-generation/components/GenerateImageInlineModal.tsx`
740740
- The modal supports idle (prompt input), generating, preview (keep/refine/start over) states
741741
- Customize the flow, UI copy, or add new actions
742742
743743
3. **Add or change supported blocks for inline generation:**
744744
- Edit `inline.tsx` and modify the `TARGET_BLOCKS` array (`core/image`, `core/cover`, `core/media-text`, `core/gallery`)
745-
- To support a new block type, update `insertIntoBlock()` in `src/experiments/image-generation/functions/insert-into-block.ts` with the correct attribute mapping
745+
- To support a new block type, update `insertIntoBlock()` in `src/features/image-generation/functions/insert-into-block.ts` with the correct attribute mapping
746746
747747
4. **Customize the AI label:**
748-
- Edit `src/experiments/image-generation/components/AILabel.tsx`
748+
- Edit `src/features/image-generation/components/AILabel.tsx`
749749
750750
5. **Add custom functions:**
751-
- Create new functions in `src/experiments/image-generation/functions/`
751+
- Create new functions in `src/features/image-generation/functions/`
752752
- Import and use them in the components
753753
754754
6. **Customize the featured image panel:**
755-
- The experiment uses the `editor.PostFeaturedImage` filter to inject into the featured image panel
756-
- You can modify `src/experiments/image-generation/featured-image.tsx` to add additional UI
755+
- The feature uses the `editor.PostFeaturedImage` filter to inject into the featured image panel
756+
- You can modify `src/features/image-generation/featured-image.tsx` to add additional UI
757757
758758
### Customizing Image Processing
759759
@@ -777,7 +777,7 @@ add_filter( 'wp_generate_attachment_metadata', function( $metadata, $attachment_
777777
778778
### Manual Testing
779779
780-
1. **Enable the experiment:**
780+
1. **Enable the feature:**
781781
- Go to `Settings → AI`
782782
- Toggle **Image Generation** to enabled
783783
- Ensure you have valid AI credentials configured
@@ -801,7 +801,7 @@ add_filter( 'wp_generate_attachment_metadata', function( $metadata, $attachment_
801801
- Test with each supported block type to ensure correct attribute mapping
802802
803803
4. **Test with different post types:**
804-
- The experiment only loads for post types that support featured images (`post_type_supports( $post_type, 'thumbnail' )`)
804+
- The feature only loads for post types that support featured images (`post_type_supports( $post_type, 'thumbnail' )`)
805805
- Test with posts, pages, and custom post types that have featured image support
806806
807807
5. **Test REST API:**
@@ -817,7 +817,7 @@ add_filter( 'wp_generate_attachment_metadata', function( $metadata, $attachment_
817817
Unit tests are located in:
818818
819819
- `tests/Integration/Includes/Abilities/Image_GenerationTest.php`
820-
- `tests/Integration/Includes/Experiments/Image_Generation/Image_GenerationTest.php`
820+
- `tests/Integration/Includes/Features/Image_Generation/Image_GenerationTest.php`
821821
822822
Run tests with:
823823
@@ -829,10 +829,10 @@ npm run test:php
829829
830830
### Requirements
831831
832-
- The experiment requires valid AI credentials to be configured
833-
- The experiment only works for post types that support featured images (`post_type_supports( $post_type, 'thumbnail' )`)
832+
- The feature requires valid AI credentials to be configured
833+
- The feature only works for post types that support featured images (`post_type_supports( $post_type, 'thumbnail' )`)
834834
- Users must have `upload_files` capability
835-
- The experiment requires image generation models to be available (configured via `get_preferred_image_models()`)
835+
- The feature requires image generation models to be available (configured via `get_preferred_image_models()`)
836836
837837
### Performance
838838
@@ -858,7 +858,7 @@ npm run test:php
858858
859859
### Prompt Generation
860860
861-
- The experiment uses a three-step process:
861+
- The feature uses a three-step process:
862862
1. First, it gets post context (title, type) using the `ai/get-post-details` ability
863863
2. Then, it generates an optimized image generation prompt from post content and context using the `ai/image-prompt-generation` ability
864864
3. Finally, it uses that prompt to generate the actual image
@@ -883,7 +883,7 @@ npm run test:php
883883
- Images are generated in real-time and not cached
884884
- The ability does not support batch processing (one image per request)
885885
- Generated images are suggestions and should be reviewed before publishing
886-
- The experiment requires JavaScript to be enabled in the admin
886+
- The feature requires JavaScript to be enabled in the admin
887887
- Image generation may fail if AI models are unavailable or rate-limited
888888
- Base64 image data can be very large; ensure adequate server resources
889889

includes/Abstracts/Abstract_Feature.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@ abstract class Abstract_Feature implements Feature {
6868
*/
6969
private string $stability;
7070

71+
/**
72+
* The image URL for feature showcase display.
73+
*
74+
* @since x.x.x
75+
* @var string
76+
*/
77+
protected string $image;
78+
7179
/**
7280
* Constructor.
7381
*
@@ -106,6 +114,7 @@ final public function __construct() {
106114
$this->description = $metadata['description'];
107115
$this->category = $metadata['category'];
108116
$this->stability = $metadata['stability'] ?? 'experimental';
117+
$this->image = $metadata['image'] ?? '';
109118
}
110119

111120
/**
@@ -121,6 +130,7 @@ final public function __construct() {
121130
* description: string,
122131
* category?: string,
123132
* stability?: 'deprecated'|'experimental'|'stable',
133+
* image?: string,
124134
* } Feature metadata.
125135
*/
126136
abstract protected function load_metadata(): array;
@@ -201,6 +211,17 @@ final public function get_stability(): string {
201211
return $this->stability;
202212
}
203213

214+
/**
215+
* Gets the image URL for feature showcase display.
216+
*
217+
* @since x.x.x
218+
*
219+
* @return string The image URL, or empty string if not set.
220+
*/
221+
public function get_image(): string {
222+
return $this->image;
223+
}
224+
204225
/**
205226
* Registers feature-specific settings.
206227
*

includes/Contracts/Feature.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,4 +106,13 @@ public function is_enabled(): bool;
106106
* }> Array of field definitions with full option names.
107107
*/
108108
public function get_settings_fields_metadata(): array;
109+
110+
/**
111+
* Gets the image URL for feature showcase display.
112+
*
113+
* @since x.x.x
114+
*
115+
* @return string The image URL, or empty string if not set.
116+
*/
117+
public function get_image(): string;
109118
}

includes/Experiments/Experiments.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ final class Experiments {
3232
\WordPress\AI\Experiments\Content_Classification\Content_Classification::class,
3333
\WordPress\AI\Experiments\Excerpt_Generation\Excerpt_Generation::class,
3434
\WordPress\AI\Experiments\Alt_Text_Generation\Alt_Text_Generation::class,
35-
\WordPress\AI\Experiments\Image_Generation\Image_Generation::class,
3635
\WordPress\AI\Experiments\Meta_Description\Meta_Description::class,
3736
\WordPress\AI\Experiments\Review_Notes\Review_Notes::class,
3837
\WordPress\AI\Experiments\Summarization\Summarization::class,

includes/Experiments/Image_Generation/Image_Generation.php renamed to includes/Features/Image_Generation/Image_Generation.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
11
<?php
22
/**
3-
* Image generation experiment implementation.
3+
* Image generation feature implementation.
44
*
55
* @package WordPress\AI
66
*/
77

88
declare( strict_types=1 );
99

10-
namespace WordPress\AI\Experiments\Image_Generation;
10+
namespace WordPress\AI\Features\Image_Generation;
1111

1212
use WordPress\AI\Abilities\Image\Generate_Image as Image_Generation_Ability;
1313
use WordPress\AI\Abilities\Image\Generate_Image_Prompt as Generate_Image_Prompt_Ability;
1414
use WordPress\AI\Abilities\Image\Import_Base64_Image as Image_Import_Ability;
1515
use WordPress\AI\Abstracts\Abstract_Feature;
1616
use WordPress\AI\Asset_Loader;
1717
use WordPress\AI\Experiments\Alt_Text_Generation\Alt_Text_Generation;
18-
use WordPress\AI\Experiments\Experiment_Category;
1918

2019
if ( ! defined( 'ABSPATH' ) ) {
2120
exit;
2221
}
2322

2423
/**
25-
* Image generation experiment.
24+
* Image generation feature.
2625
*
2726
* @since 0.2.0
2827
*/
@@ -42,7 +41,8 @@ protected function load_metadata(): array {
4241
return array(
4342
'label' => __( 'Image Generation and Editing', 'ai' ),
4443
'description' => __( 'Generate and edit images using AI. Requires an AI connector that includes support for image generation models.', 'ai' ),
45-
'category' => Experiment_Category::EDITOR,
44+
'stability' => 'stable',
45+
'image' => WPAI_PLUGIN_URL . 'assets/images/showcase-image-generation.webp',
4646
);
4747
}
4848

@@ -219,8 +219,8 @@ public function enqueue_inline_assets(): void {
219219
* @since 0.4.0
220220
*/
221221
private function enqueue_shared_assets(): void {
222-
Asset_Loader::enqueue_script( 'image_generation', 'experiments/image-generation' );
223-
Asset_Loader::enqueue_style( 'image_generation', 'experiments/image-generation' );
222+
Asset_Loader::enqueue_script( 'image_generation', 'features/image-generation' );
223+
Asset_Loader::enqueue_style( 'image_generation', 'features/image-generation' );
224224
Asset_Loader::localize_script(
225225
'image_generation',
226226
'ImageGenerationData',

includes/Features/Loader.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ private function register_features(): void {
105105
*/
106106
private function get_default_features(): array {
107107
$feature_classes = array(
108-
// Features start off as experiments until they pass the requirements to graduate to full features.
108+
\WordPress\AI\Features\Image_Generation\Image_Generation::get_id() => \WordPress\AI\Features\Image_Generation\Image_Generation::class,
109109
);
110110

111111
/**
@@ -115,7 +115,7 @@ private function get_default_features(): array {
115115
*
116116
* @since 0.6.0
117117
*
118-
* @param array<string, \WordPress\AI\Contracts\Feature|class-string<\WordPress\AI\Contracts\Feature>> $feature_classes Array of feature class names, keyed by ID.
118+
* @param array<string, class-string<\WordPress\AI\Contracts\Feature>> $feature_classes Array of feature class names, keyed by ID.
119119
*/
120120
$items = apply_filters( 'wpai_default_feature_classes', $feature_classes );
121121

includes/Settings/Settings_Page.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@ private static function get_settings_feature_metadata( Registry $registry ): arr
238238
'description' => wp_strip_all_tags( $feature->get_description() ),
239239
'category' => $category,
240240
'settingsFields' => $feature->get_settings_fields_metadata(),
241+
'stability' => $feature->get_stability(),
242+
'image' => esc_url( $feature->get_image() ),
241243
);
242244
}
243245

0 commit comments

Comments
 (0)