# Excerpt Generation Prototype — Implementation Plan

## Context

The AI Agent Hub plugin has an existing `awfah-content/generate-excerpt` ability, but it currently does **NOT use AI** — it just calls `wp_trim_words($content, 40)`. We need to:

1. **Upgrade the PHP ability** to use `AI_Provider_Manager::generate_text()` with a real AI prompt
2. **Build a Gutenberg editor UI** that integrates into the post excerpt panel
3. **Add advanced features** beyond the reference AI Experiments plugin: editable prompts, prompt saving (global/per-post), AI provider/model selection, Apply/Regenerate/Modify Prompt buttons, generation history, tone chips, and quality score

This serves as the **prototype pattern** — once approved, we replicate for Title Gen, Summarization, Image Gen, and Alt-Text Gen.

---

## Critical Discovery: Build System

The plugin has **two build systems**:
- **Laravel Mix** — for `admin-app.js` and `post-meta-box.js` (NO WordPress dependency extraction)
- **wp-scripts** — for `assets/mcp/` settings app (WITH auto dependency extraction via `@wordpress/dependency-extraction-webpack-plugin`)

**Decision:** Use `wp-scripts` for editor experiment scripts. It auto-extracts `@wordpress/*` imports into an `.asset.php` file, which WordPress uses to enqueue the correct dependencies. This is the same proven pattern already used for the MCP settings app.

---

## Files to Create/Modify

### New Files (8)

| # | File | Purpose |
|---|------|---------|
| 1 | `assets/js/experiments/excerpt-generation/index.js` | JS entry point — registers Gutenberg plugin |
| 2 | `assets/js/experiments/excerpt-generation/components/ExcerptPanel.js` | Main panel component (settings popup + generate button + results) |
| 3 | `assets/js/experiments/excerpt-generation/components/SettingsPopover.js` | Popover with prompt editor, provider/model dropdowns, tone chips, save toggles |
| 4 | `assets/js/experiments/excerpt-generation/components/ResultPanel.js` | Post-generation UI: result display + Apply/Regenerate/Modify buttons + quality score |
| 5 | `assets/js/experiments/excerpt-generation/components/GenerationHistory.js` | Collapsible history of last 5 generations |
| 6 | `assets/js/experiments/excerpt-generation/hooks/useExcerptGeneration.js` | Core hook: state management, API calls, generation logic |
| 7 | `src/Admin/Editor_Experiments.php` | PHP class: enqueue scripts, register post meta, localize data |
| 8 | `src/REST/Prompts_Controller.php` | REST endpoint: save/load global & per-post prompts |

### Existing Files to Modify (3)

| # | File | Change |
|---|------|--------|
| 1 | `src/Abilities/Content_Steward_Abilities.php` | Upgrade `execute_generate_excerpt()` to use AI + accept `prompt`, `content`, `provider`, `tone` params |
| 2 | `src/Plugin.php` | Initialize `Editor_Experiments` in `init_admin()`, register `Prompts_Controller` routes |
| 3 | `package.json` | Add `build:experiments` and `start:experiments` wp-scripts commands |

---

## Step-by-Step Implementation

### Step 1: Update `package.json` Build Scripts

Add wp-scripts build commands for experiments:

```json
"build:experiments": "wp-scripts build --webpack-src-dir=assets/js/experiments --output-path=assets/js/experiments-build",
"start:experiments": "wp-scripts start --webpack-src-dir=assets/js/experiments --output-path=assets/js/experiments-build"
```

This auto-discovers entry points from `assets/js/experiments/*/index.js` and outputs to `assets/js/experiments-build/excerpt-generation/index.js` + `index.asset.php`.

### Step 2: Upgrade `execute_generate_excerpt()` in `Content_Steward_Abilities.php`

**Current code (broken — not using AI):**
```php
public static function execute_generate_excerpt( array $input ): array {
    // Just calls wp_trim_words() — NOT AI!
    $content = wp_strip_all_tags( $post->post_content );
    $excerpt = wp_trim_words( $content, 40, '...' );
    return [ 'excerpt' => $excerpt ];
}
```

**New implementation:**
- Accept expanded input: `post_id`, `content` (optional override), `prompt` (custom system instruction), `provider`, `tone`
- Update input_schema to add optional `content`, `prompt`, `provider`, `tone` fields
- Build prompt with tone modifier if provided
- Call `AI_Provider_Manager::generate_text()` with proper temperature (0.7) and model preferences
- Return `{ excerpt: string }` on success, error message on failure
- Fall back to `wp_trim_words()` if AI credentials are not configured

### Step 3: Create `src/REST/Prompts_Controller.php`

New REST controller for prompt persistence:

```
GET  /awfah/v1/prompts/{tool_slug}              → Get global prompt for tool
POST /awfah/v1/prompts/{tool_slug}              → Save global prompt for tool
GET  /awfah/v1/prompts/{tool_slug}/{post_id}    → Get per-post prompt
POST /awfah/v1/prompts/{tool_slug}/{post_id}    → Save per-post prompt
```

**Storage:**
- Global: `wp_options` → `awfah_prompt_{tool_slug}` (e.g., `awfah_prompt_generate-excerpt`)
- Per-post: `wp_postmeta` → `_awfah_prompt_{tool_slug}` (underscore prefix = hidden from custom fields UI)
- Generation history: `wp_postmeta` → `_awfah_history_{tool_slug}` (JSON array, max 5 entries)

**Permission:** `edit_posts` (same as abilities)

### Step 4: Create `src/Admin/Editor_Experiments.php`

PHP class registered in `Plugin::init_admin()`:

```php
class Editor_Experiments {
    public function __construct() {
        add_action( 'enqueue_block_editor_assets', [ $this, 'enqueue_excerpt_generation' ] );
        add_action( 'init', [ $this, 'register_meta' ] );
    }
}
```

**Script Enqueue:**
- Hook: `enqueue_block_editor_assets` (fires on both post.php and post-new.php in block editor)
- Guard: Check `content_steward` module is enabled + post type supports `excerpt` + not `attachment`
- Load: `assets/js/experiments-build/excerpt-generation/index.js`
- Dependencies: auto-loaded from `index.asset.php` (generated by wp-scripts)
- Localize as `aahExcerptGeneration`:
  ```php
  [
      'enabled'      => true,
      'abilitySlug'  => 'awfah-content/generate-excerpt',
      'restUrl'      => rest_url('awfah/v1'),
      'promptsUrl'   => rest_url('awfah/v1/prompts/generate-excerpt'),
      'providersUrl' => rest_url('awfah/v1/providers'),
      'wpNonce'      => wp_create_nonce('wp_rest'),
      'postId'       => get_the_ID(),
      'defaultPrompt'=> 'Generate a concise, SEO-friendly excerpt...',
      'tones'        => ['professional', 'casual', 'friendly', 'academic'],
  ]
  ```

**Post Meta Registration:**
```php
register_post_meta('', '_awfah_prompt_generate-excerpt', [...]);
register_post_meta('', '_awfah_history_generate-excerpt', [...]);
```

### Step 5: Create JS Entry Point `index.js`

```javascript
import { registerPlugin } from '@wordpress/plugins';
import { PluginPostExcerpt } from '@wordpress/edit-post'; // or __experimentalPluginPostExcerpt
import ExcerptPanel from './components/ExcerptPanel';

registerPlugin('aah-excerpt-generation', {
    render: () => {
        // Use __experimentalPluginPostExcerpt slot to inject into excerpt panel
        const Slot = PluginPostExcerpt?.();
        if (!Slot) return null;
        return <Slot><ExcerptPanel /></Slot>;
    },
});
```

### Step 6: Create `ExcerptPanel.js` Component

Main orchestrator component. Renders inside the excerpt panel.

**Layout:**
```
┌─────────────────────────────────────────┐
│ [⚙ Settings]              [tone chips] │
│                                         │
│ [ Generate Excerpt ]  (or Re-generate)  │
│                                         │
│ ┌─ Result ────────────────────────────┐ │
│ │ Generated excerpt text here...      │ │
│ │                                     │ │
│ │ Quality: ██████░░ 78% (SEO: Good)   │ │
│ │                                     │ │
│ │ [Apply] [Regenerate] [Modify Prompt]│ │
│ └─────────────────────────────────────┘ │
│                                         │
│ ▸ Generation History (3)                │
└─────────────────────────────────────────┘
```

**Imports:**
- `@wordpress/components`: `Button`, `Flex`, `FlexItem`, `Popover`, `Spinner`
- `@wordpress/icons`: `update`, `settings`
- `@wordpress/i18n`: `__`
- Internal: `SettingsPopover`, `ResultPanel`, `GenerationHistory`, `useExcerptGeneration`

### Step 7: Create `SettingsPopover.js` Component

Opens as a Popover when Settings icon clicked.

**Contains:**
1. **Prompt Editor** — `TextareaControl` showing the current system prompt. User can edit.
2. **Save Prompt Toggles:**
   - `CheckboxControl` — "Save as global default" (saves to `wp_options`)
   - `CheckboxControl` — "Save for this post only" (saves to `wp_postmeta`)
3. **Provider Dropdown** — `SelectControl` populated from `/awfah/v1/providers`. Shows only `supported: true` providers + "Auto" option.
4. **Tone Quick Selector** — `ButtonGroup` with chips: Professional, Casual, Friendly, Academic. Selecting a tone auto-appends a modifier to the prompt.

**Data Flow:**
- On mount: Fetch global prompt from `/awfah/v1/prompts/generate-excerpt`
- If per-post prompt exists, use that instead (priority: per-post > global > default)
- On save: POST to prompts endpoint based on which checkbox is checked

### Step 8: Create `ResultPanel.js` Component

Shown after generation completes.

**Contains:**
1. **Excerpt Display** — `TextareaControl` (readonly) showing the generated excerpt
2. **Quality Score** — Simple word count indicator + character count vs recommended (150-160 chars for SEO)
3. **Action Buttons:**
   - **Apply** — Calls `editPost({ excerpt })` + updates DOM textarea (same pattern as AI Experiments)
   - **Regenerate** — Triggers generation again with same settings
   - **Modify Prompt** — Opens SettingsPopover focused on prompt editor

### Step 9: Create `GenerationHistory.js` Component

Collapsible panel showing last 5 generations.

**Contains:**
- Stored in post meta `_awfah_history_generate-excerpt` as JSON array
- Each entry: `{ excerpt, prompt, tone, provider, timestamp }`
- `PanelBody` with `PanelRow` items
- Click on history item → loads it into result panel
- "Apply" button on each history item

**Save Strategy: Immediate (via REST API)**
- Each generation triggers a direct `apiFetch` POST to `/awfah/v1/prompts/generate-excerpt/{postId}/history`
- History persists even if user navigates away without saving the post
- On mount: history loaded from post meta via REST
- Max 5 entries — oldest removed when 6th added

### Step 10: Create `useExcerptGeneration.js` Hook

Core state management hook.

**State:**
```javascript
{
    isGenerating: false,
    generatedExcerpt: '',
    currentPrompt: '',       // editable prompt text
    currentTone: '',         // selected tone
    currentProvider: 'auto', // selected provider
    history: [],             // last 5 generations
    error: null,
}
```

**API Calls:**
1. **Generate:** `POST /wp-abilities/v1/abilities/awfah-content/generate-excerpt/run`
   - Input: `{ post_id, content, prompt, provider, tone }`
   - Uses `apiFetch` with nonce from localized data
2. **Load prompts:** `GET /awfah/v1/prompts/generate-excerpt` and `GET /awfah/v1/prompts/generate-excerpt/{postId}`
3. **Save prompts:** `POST /awfah/v1/prompts/generate-excerpt` (global) or `POST /awfah/v1/prompts/generate-excerpt/{postId}` (per-post)
4. **Load providers:** `GET /awfah/v1/providers`

**Apply Logic (from AI Experiments reference):**
```javascript
// 1. Update editor store
editPost({ excerpt: generatedExcerpt });

// 2. Update DOM textarea (React doesn't control it)
const textarea = document.querySelector(
    '.editor-post-excerpt .editor-post-excerpt__textarea textarea'
);
if (textarea) {
    const setter = Object.getOwnPropertyDescriptor(
        HTMLTextAreaElement.prototype, 'value'
    )?.set;
    setter?.call(textarea, generatedExcerpt);
    textarea.dispatchEvent(new Event('change', { bubbles: true }));
}
```

### Step 11: Wire Up in `Plugin.php`

In `init_admin()`:
```php
$this->editor_experiments = new Editor_Experiments();
```

In `init_rest()`:
```php
$this->prompts_controller = new Prompts_Controller();
// Add to rest_api_init callback:
$this->prompts_controller->register_routes();
```

---

## Verification Plan

### Build Test
```bash
cd D:\xampp\htdocs\azizulhasan\tts\wp-content\plugins\ai-workflow-automation-ai-agent-hub
npm run build:experiments
```
Verify output: `assets/js/experiments-build/excerpt-generation/index.js` + `index.asset.php`

### PHP Test
1. Visit any post in block editor
2. Check browser console for JS errors
3. Verify excerpt panel shows the new AI generate button
4. Verify Settings popover opens with prompt editor, provider dropdown, tone chips

### Generation Test
1. Create a post with content
2. Click "Generate Excerpt"
3. Verify loading state (spinner, button disabled)
4. Verify generated excerpt appears in result panel
5. Verify quality score shows correct metrics

### Apply Test
1. Click "Apply" on generated excerpt
2. Verify excerpt appears in the WordPress excerpt textarea
3. Verify excerpt persists when saving the post

### Prompt Persistence Test
1. Edit the prompt in settings
2. Check "Save as global default" → Save
3. Reload the page → verify global prompt loaded
4. Edit prompt, check "Save for this post only" → Save
5. Reload → verify per-post prompt takes priority
6. Go to different post → verify global prompt is used (not per-post from other post)

### History Test
1. Generate 3 different excerpts
2. Expand "Generation History"
3. Verify 3 entries shown with timestamps
4. Click on history item → verify it loads in result panel
5. Click "Apply" on history item → verify it applies

### Provider Test
1. Open Settings popover
2. Verify only configured providers show as enabled
3. Select a different provider
4. Generate → verify it uses the selected provider

### Tone Test
1. Select "Casual" tone chip
2. Generate → verify excerpt has casual tone
3. Select "Academic" tone → generate → verify academic tone

### Regenerate/Modify Test
1. Generate an excerpt
2. Click "Regenerate" → verify new generation with same settings
3. Click "Modify Prompt" → verify settings popover opens with prompt focused

### MCP Compatibility Test
1. Verify `awfah-content/generate-excerpt` still works via MCP tools/call
2. Verify resources/read still works for the excerpt resource

---

## Implementation Order

1. `package.json` — Add build scripts (1 min)
2. `Content_Steward_Abilities.php` — Upgrade excerpt ability with AI (15 min)
3. `Prompts_Controller.php` — New REST controller (15 min)
4. `Editor_Experiments.php` — Script enqueuing + meta registration (10 min)
5. `Plugin.php` — Wire up new classes (2 min)
6. `useExcerptGeneration.js` — Core hook (20 min)
7. `SettingsPopover.js` — Settings UI (15 min)
8. `ResultPanel.js` — Result display + actions (10 min)
9. `GenerationHistory.js` — History panel (10 min)
10. `ExcerptPanel.js` — Main orchestrator (10 min)
11. `index.js` — Plugin registration entry point (5 min)
12. Build + test (10 min)
