Files
wp-agentic-writer/docs/guides/DEFECT_REPORT_IMAGE_GENERATION.md

469 lines
14 KiB
Markdown

# WP Agentic Writer - Defect Report
**Date:** January 29, 2026
**Reporter:** Development Team
**Testing Session:** Image Generation Feature Integration
---
## Executive Summary
After comprehensive flow tracing, **4 critical defects** and **multiple integration gaps** were identified. The image generation backend is functional, but frontend integration is incomplete.
---
## Defect #1: "Create Outline Now" Button - Mode Timing Issue
### Symptom
Clicking "Create Outline Now" only prefills English message and changes mode. User expects automatic outline generation.
### Root Cause Analysis
**File:** `@/Users/dwindown/Local Sites/bricks/app/public/wp-content/plugins/wp-agentic-writer/assets/js/sidebar.js:4432-4444`
```javascript
onClick: async () => {
setAgentMode('planning'); // Line 4434
const outlineMessage = 'Create an outline based on our discussion';
setInput(outlineMessage); // Line 4438
setTimeout(() => {
sendMessage(); // Line 4443
}, 100);
}
```
**Problem:** React's `setState` is asynchronous. When `sendMessage()` is called 100ms later:
1. `agentMode` state may not have updated yet in the closure
2. `input` state may not have updated yet
3. The `sendMessage()` function reads stale state values
**Flow Trace:**
```
User clicks "Create Outline Now"
setAgentMode('planning') called - state update QUEUED
setInput('Create an outline...') called - state update QUEUED
100ms timeout fires
sendMessage() runs with STALE state (agentMode might still be 'chat')
Line 3084: if (agentMode === 'chat' && !hasMentions) → TRUE (stale state!)
Chat API called instead of generate-plan
```
### Expected Behavior
Button should directly trigger planning flow with proper mode context, bypassing React state timing issues.
### Recommended Fix
Pass mode and message directly to sendMessage, not relying on state:
```javascript
onClick: async () => {
setAgentMode('planning');
const outlineMessage = 'Create an outline based on our discussion';
// Call API directly instead of relying on state
await triggerPlanGeneration(outlineMessage, {
mode: 'planning',
autoTrigger: true
});
}
```
Or use a dedicated function that doesn't depend on `agentMode` state.
---
## Defect #2: Clarity Check Not Triggered for Planning Mode
### Symptom
Cost tracking shows `clarity_check` was never called when using "Create Outline Now".
### Root Cause Analysis
**Flow Trace through `sendMessage()`:**
```
Line 3049: shouldShowPlan = (agentMode === 'planning')
If agentMode is still 'chat' (due to Defect #1):
Line 3084: if (agentMode === 'chat' && !hasMentions) → TRUE
→ Enters CHAT flow (NOT planning flow)
→ Calls /chat API
→ Clarity check is NOT in this branch
```
**If agentMode correctly updated to 'planning':**
```
Line 3077: if (agentMode === 'planning' && !hasMentions && currentPlanRef.current)
→ FALSE because currentPlanRef.current is null (no existing plan)
→ Falls through
Line 3084: if (agentMode === 'chat' && !hasMentions)
→ FALSE because agentMode is 'planning'
→ Falls through
Line 3225: if (!hasMentions && refineableBlocks.length > 0)
→ FALSE if no content exists yet
→ Falls through
Line 3262: if (!hasMentions)
→ TRUE
→ Enters clarity check + generate-plan flow ✓
```
**Conclusion:** The clarity check SHOULD work if agentMode is correctly set to 'planning'. The root cause is **Defect #1** - the timing issue with state updates.
### Recommended Fix
Fix Defect #1, which will automatically fix this defect.
---
## Defect #3: Numbered List with Bold Title + Bullets - Incorrect Conversion
### Symptom
Markdown like:
```markdown
1. **Jadikan AI sebagai Asisten**
- Gunakan untuk mempercepat pekerjaan
- Manfaatkan sebagai sumber referensi
1. **Terus Belajar dan Beradaptasi**
- Ikuti perkembangan teknologi AI
```
Renders as:
- Ordered list with item "1. **Jadikan AI sebagai Asisten**"
- Separate unordered list with bullets
- **New** ordered list restarting at "1." for next section
User sees "1. 1. 1." instead of "1. 2. 3."
### Root Cause Analysis
**File:** `@/Users/dwindown/Local Sites/bricks/app/public/wp-content/plugins/wp-agentic-writer/includes/class-markdown-parser.php:261-274`
```php
// Handle ordered lists.
if ( preg_match( '/^\d+\.\s+(.+)$/', $trimmed, $matches ) ) {
// ... creates ordered list item
$list_items[] = self::parse_inline_markdown( $matches[1] );
continue;
}
```
**Problem:** The parser correctly identifies numbered items, but when an empty line or different list type appears, it flushes the current list. Each section becomes a **separate** ordered list block, each starting at 1.
The `merge_consecutive_ordered_lists()` function at line 674 only merges **consecutive** ordered lists. But the structure has:
```
ordered list (1 item)
unordered list (bullets)
ordered list (1 item) ← NOT consecutive, won't merge
unordered list (bullets)
```
### Expected Behavior (per user request)
For numbered items with bold titles followed by bullet sub-content:
```
1. **Bold Title** → core/paragraph with "1. <strong>Bold Title</strong>"
- bullet item → core/list (unordered)
- bullet item
2. **Next Title** → core/paragraph with "2. <strong>Next Title</strong>"
- more bullets → core/list (unordered)
```
This structure:
- Prevents the "1. 1. 1." numbering issue
- Creates logical grouping
- Maintains proper section hierarchy
### Recommended Fix
**Option A:** Detect pattern `^\d+\.\s+\*\*(.+)\*\*$` (numbered + bold) and treat as paragraph:
```php
// Handle numbered items with bold title (treat as paragraph, not list)
if ( preg_match( '/^(\d+)\.\s+\*\*(.+)\*\*\s*$/', $trimmed, $matches ) ) {
// Create paragraph with manual numbering
$content = $matches[1] . '. <strong>' . self::parse_inline_markdown( $matches[2] ) . '</strong>';
$blocks[] = self::create_paragraph_block( $content );
continue;
}
```
**Option B:** Pre-process markdown to normalize this pattern before parsing.
---
## Defect #4: Image Blocks Missing `data-agent-image-id` Attribute
### Symptom
Generated image blocks have no way to:
1. Confirm agent assigned an image ID
2. View the recommended prompt/alt text
3. Trigger image generation modal
4. Connect to backend image recommendations
### Root Cause Analysis
**File:** `@/Users/dwindown/Local Sites/bricks/app/public/wp-content/plugins/wp-agentic-writer/includes/class-markdown-parser.php:644-664`
```php
private static function create_image_placeholder_block( $description ) {
$alt = trim( $description );
$attrs = array(
'id' => 0,
'url' => '',
'alt' => $alt,
'caption' => '',
'sizeSlug' => 'large',
'linkDestination' => 'none',
);
// ❌ MISSING: 'data-agent-image-id' => 'img_xxx'
```
**The `data-agent-image-id` attribute is documented in:**
- `IMAGE_GENERATION_IMPLEMENTATION_PLAN.md`
- `IMAGE_GENERATION_README.md`
- `image-gen-flow.md`
- `image-modal.js` (expects this attribute)
**But NEVER implemented in the actual code!**
### Missing Integration Points
1. **Markdown Parser:** Must generate unique `agent_image_id` and add to block attrs
2. **Backend Storage:** Must save recommendations with matching IDs to `wp_wpaw_images` table
3. **Block Toolbar:** Must add "Generate Image" button for image blocks with this attribute
4. **Modal Trigger:** Must open image modal after article generation or from toolbar
### Recommended Fix
**Step 1:** Update `create_image_placeholder_block()`:
```php
private static function create_image_placeholder_block( $description, $image_index = 0 ) {
$alt = trim( $description );
$agent_image_id = 'img_' . uniqid(); // Or use index-based ID
$attrs = array(
'id' => 0,
'url' => '',
'alt' => $alt,
'caption' => '',
'sizeSlug' => 'large',
'linkDestination' => 'none',
'data-agent-image-id' => $agent_image_id,
);
// ...
}
```
**Step 2:** Track and return image IDs during article generation
**Step 3:** Register toolbar button for image blocks (see below)
---
## Missing Integration #1: Image Block Toolbar Button
### Current State
No "Generate Image" button exists in image block toolbar.
### Required Implementation
**File to create:** Extend `block-refine.js` or create new `block-image-generate.js`
```javascript
// Add toolbar button to core/image blocks with data-agent-image-id
const withImageGenerateToolbar = createHigherOrderComponent((BlockEdit) => {
return (props) => {
const { clientId } = props;
const block = useSelect(
(select) => select('core/block-editor').getBlock(clientId),
[clientId]
);
if (!block || block.name !== 'core/image') {
return wp.element.createElement(BlockEdit, props);
}
const agentImageId = block.attributes['data-agent-image-id'];
if (!agentImageId) {
return wp.element.createElement(BlockEdit, props);
}
const openImageModal = () => {
window.dispatchEvent(
new CustomEvent('wpaw:open-image-modal', {
detail: { agentImageId, blockId: clientId }
})
);
};
return wp.element.createElement(
wp.element.Fragment,
null,
wp.element.createElement(BlockEdit, props),
wp.element.createElement(
BlockControls,
null,
wp.element.createElement(
ToolbarGroup,
null,
wp.element.createElement(ToolbarButton, {
icon: 'format-image',
label: 'Generate AI Image',
onClick: openImageModal,
})
)
)
);
};
}, 'withImageGenerateToolbar');
addFilter(
'editor.BlockEdit',
'wp-agentic-writer/image-generate-toolbar',
withImageGenerateToolbar
);
```
---
## Missing Integration #2: Image Modal Trigger After Article Generation
### Current State
`image-modal.js` component exists but is never rendered/triggered.
### Required Implementation
**In `sidebar.js`, after article execution completes:**
```javascript
// After all sections are written and blocks inserted:
const checkForImagePlaceholders = () => {
const blocks = wp.data.select('core/block-editor').getBlocks();
const imagePlaceholders = blocks.filter(
block => block.name === 'core/image' &&
block.attributes['data-agent-image-id']
);
if (imagePlaceholders.length > 0) {
// Open image review modal
window.dispatchEvent(
new CustomEvent('wpaw:open-image-review-modal', {
detail: {
postId: postId,
imageCount: imagePlaceholders.length
}
})
);
}
};
```
**In `image-modal.js`, listen for event:**
```javascript
useEffect(() => {
const handleOpenModal = (event) => {
setPostId(event.detail.postId);
setIsOpen(true);
loadRecommendations(event.detail.postId);
};
window.addEventListener('wpaw:open-image-review-modal', handleOpenModal);
return () => window.removeEventListener('wpaw:open-image-review-modal', handleOpenModal);
}, []);
```
---
## Missing Integration #3: Backend Image ID Generation
### Current State
`[IMAGE: description]` placeholders are converted to blocks, but:
- No unique ID generated
- No storage in `wp_wpaw_images` table during article generation
- No link between block and database record
### Required Implementation
**During article generation in `class-gutenberg-sidebar.php`:**
1. Parse `[IMAGE: ...]` placeholders before block conversion
2. Generate unique `agent_image_id` for each
3. Store in `wp_wpaw_images` table with post_id, prompt, alt_text
4. Pass image IDs to markdown parser for block attribute injection
```php
// In handle_generate_article or handle_execute_plan:
$image_placeholders = [];
preg_match_all('/\[IMAGE:\s*(.+?)\]/i', $markdown_content, $matches);
foreach ($matches[1] as $index => $description) {
$agent_image_id = 'img_' . $post_id . '_' . ($index + 1);
$image_placeholders[] = [
'agent_image_id' => $agent_image_id,
'description' => $description,
];
// Save to database
$image_manager = WP_Agentic_Writer_Image_Manager::get_instance();
// ... save recommendation
}
// Convert markdown with image IDs
$blocks = WP_Agentic_Writer_Markdown_Parser::to_blocks($markdown_content, $image_placeholders);
```
---
## Priority Matrix
| Defect | Severity | Impact | Fix Effort |
|--------|----------|--------|------------|
| #1 - Create Outline timing | **High** | Blocks main workflow | Low |
| #2 - Clarity check | **High** | Poor content quality | Depends on #1 |
| #3 - Numbered list | **Medium** | Visual formatting | Medium |
| #4 - Image IDs missing | **Critical** | Image feature broken | Medium |
| Toolbar button | **Critical** | No way to trigger images | Medium |
| Modal trigger | **Critical** | No user-facing image feature | Medium |
| Backend ID generation | **Critical** | No data persistence | Medium |
---
## Recommended Fix Order
1. **Defect #1** - Fix timing issue (enables #2)
2. **Defect #4 + Backend ID generation** - Core image functionality
3. **Toolbar button** - User can trigger image generation
4. **Modal trigger** - Automatic flow after article generation
5. **Defect #3** - Formatting improvement (lower priority)
---
## Testing Checklist After Fixes
- [ ] Click "Create Outline Now" → Clarity quiz appears (if needed)
- [ ] Click "Create Outline Now" → Plan generated automatically
- [ ] Cost tracking shows `clarity_check` action
- [ ] Numbered + bold items render as paragraphs with manual numbering
- [ ] Image blocks have `data-agent-image-id` attribute in inspector
- [ ] Image blocks show "Generate AI Image" in toolbar
- [ ] After article generation, image modal opens automatically
- [ ] Can generate variants for each image placeholder
- [ ] Can select and commit variant to Media Library
- [ ] Block updates with real image after commit
---
**Report Status:** Complete
**Next Steps:** Implement fixes in priority order