feat: Add connection test caching and reasoning content support

Backend improvements:
- Add cache auto-clear on settings save (class-settings-v2.php)
  - Hooks updated_option action
  - Clears connection test transients when local backend settings change
- Add reasoning_content streaming support (class-local-backend-provider.php)
  - Handles thinking models like Claude extended thinking
  - Captures chunk['choices'][0]['delta']['reasoning_content']

Documentation:
- Add FRONTEND_AND_CHAT_FIX_SUMMARY.md with all fixes
- Add FRONTEND-REFACTOR-PHASE2.md with modularization plan

Note: Splitting effort deferred - will continue iterating on monolith
Next: Fix session history not appearing bug
This commit is contained in:
Dwindi Ramadhana
2026-06-17 05:26:12 +07:00
parent f55acd7d26
commit d3f142222c
4 changed files with 1765 additions and 516 deletions

302
FRONTEND-REFACTOR-PHASE2.md Normal file
View File

@@ -0,0 +1,302 @@
# Frontend Refactor Phase 2: Modularization Plan
**Date**: 2026-06-17
**Status**: 📋 IN PROGRESS
**Author**: Agent
**Reference**: `FRONTEND_AND_CHAT_FIX_SUMMARY.md`
---
## Session Summary (2026-06-17)
### Completed Backend Improvements
| Task | File | Status |
|------|------|--------|
| Connection test caching | `class-provider-manager.php` | ✅ Already existed |
| Cache auto-clear on settings save | `class-settings-v2.php` | ✅ Added |
| Reasoning content parsing | `class-local-backend-provider.php` | ✅ Added |
### Files Modified This Session
1. **`includes/class-settings-v2.php`**
- Added `clear_local_backend_cache_on_settings_change()` method
- Hooked to `updated_option` action
- Clears connection test transients when local backend settings change
2. **`includes/class-local-backend-provider.php`**
- Added `reasoning_content` streaming support (lines ~494-520)
- Handles thinking models like Claude extended thinking
- Debug logging included
### Validation Results
| Check | Result |
|-------|--------|
| `npm run build` | ✅ Passes |
| PHP syntax (all modified files) | ✅ Passes |
| Build output | `dist/sidebar.js` (169 KB) |
---
## Overview
This document outlines the approach for splitting the monolithic `assets/js/src/index.jsx` (11,793 lines) into modular React components, hooks, and utilities while maintaining the existing build pipeline.
### Key Principle
> The build pipeline (`scripts/build.js` → `assets/js/dist/sidebar.js`) **already works correctly**. We are refactoring the source for maintainability, NOT fixing a broken build.
### Important: Two sidebar.js Files
| File | Source of Truth? | Loaded by PHP? |
|------|------------------|---------------|
| `assets/js/sidebar.js` | ❌ Legacy (webpack, 438KB) | ❌ No |
| `assets/js/dist/sidebar.js` | ✅ Current (esbuild, 169KB) | ✅ Yes |
> **Do NOT confuse the two files.** The legacy `sidebar.js` (438KB) is the original monolithic file that was never modularized. The `dist/sidebar.js` (169KB) is the esbuild-compiled output from `src/index.jsx`.
---
## Current State
### Build Pipeline (Working ✅)
```
assets/js/src/index.jsx
│ esbuild (bundle: true)
│ format: "iife"
│ globalName: undefined (anonymous IIFE)
assets/js/dist/sidebar.js (compiled, served to WordPress) ✅
```
### Source & Output Files
| Path | Lines/Size | Purpose | Status |
|------|------------|---------|--------|
| `src/index.jsx` | 11,793 | React source (to be split) | ✅ Active |
| `dist/sidebar.js` | 169 KB | Compiled output (loaded by PHP) | ✅ Active |
| `sidebar.js` | 438 KB | **Legacy file** (NOT loaded) | ⚠️ Archived |
### Build Validation (2026-06-17) ✅
| Check | Result |
|-------|--------|
| `npm run build` | ✅ Passes (165.8kb output) |
| PHP syntax (settings) | ✅ Passes |
| PHP syntax (provider) | ✅ Passes |
| PHP syntax (provider manager) | ✅ Passes |
| PHP syntax (local backend) | ✅ Passes |
| PHP loads `dist/sidebar.js` | ✅ Confirmed in `class-gutenberg-sidebar.php:217` |
### esbuild Configuration
The `scripts/build.js` uses `bundle: true`, which means:
- All local imports are resolved automatically
- No need for separate bundler config
- Extracted files will compile seamlessly
---
## Proposed Directory Structure
```
assets/js/
├── src/
│ ├── index.jsx # Main entry, imports all modules
│ ├── components/
│ │ ├── ChatTab.jsx # Chat tab content
│ │ ├── ConfigTab.jsx # Configuration tab
│ │ ├── CostTab.jsx # Cost tracking tab
│ │ ├── WelcomeScreen.jsx # Welcome/home screen
│ │ ├── Clarification.jsx # Clarification quiz UI
│ │ ├── AgentWorkspaceCard.jsx
│ │ ├── ContextualAction.jsx
│ │ ├── FocusKeywordBar.jsx
│ │ ├── Messages.jsx # Message rendering
│ │ ├── GlobalStatusBar.jsx
│ │ └── RefineAllModal.jsx
│ ├── hooks/
│ │ ├── useChatHistory.js
│ │ ├── useSessionLock.js
│ │ ├── usePostConfig.js
│ │ ├── useWritingState.js
│ │ └── useStreaming.js
│ ├── utils/
│ │ ├── api.js # REST API helpers
│ │ ├── blockUtils.js # Block manipulation
│ │ ├── planUtils.js # Plan parsing/building
│ │ ├── streamUtils.js # Streaming utilities
│ │ ├── markdownUtils.js # Markdown rendering
│ │ └── formatUtils.js # Formatting helpers
│ └── styles/
│ └── components.css # Component-specific styles
└── dist/
└── sidebar.js # Compiled output (auto-generated)
```
---
## Extraction Strategy
### Phase 1: Extract Utilities (Low Risk)
Begin with pure functions that have no React dependencies:
1. **`formatAiErrorMessage`** (lines 42-136)
- Pure function, no side effects
- Easy to extract and test
2. **`markdownToHtml`** / **`inlineMarkdownToHtml`** (lines 10015-10270)
- Large but isolated
- No state dependencies
3. **Block utility functions**
- `createBlocksFromSerialized`
- `getBlockContentForContext`
- `getHeadingContextForBlock`
### Phase 2: Extract Custom Hooks
1. **`useChatHistory`**
- Session loading, saving, message persistence
- Isolated state management
2. **`useSessionLock`**
- Tab locking mechanism
- Heartbeat management
3. **`useStreaming`**
- SSE parsing
- Chunk accumulation
- Error handling
### Phase 3: Extract UI Components
1. **Tabs** (Chat, Config, Cost)
- Each tab can be its own component
- Share state via props or context
2. **WelcomeScreen**
- Self-contained, minimal dependencies
3. **Clarification Quiz**
- Complex but isolated UI
### Phase 4: Extract Editor Integration
The most complex part - interactions with WordPress block editor:
- Block mutation observation
- Input blocking
- Undo/redo integration
---
## Migration Pattern
### Before (in index.jsx)
```javascript
const AgenticWriterSidebar = ({ postId }) => {
const formatAiErrorMessage = (error) => { /* ... */ };
const sendMessage = async (msg) => { /* ... */ };
return <div>...</div>;
};
```
### After (modular)
**`src/utils/formatUtils.js`**
```javascript
export const formatAiErrorMessage = (error, fallback, settings) => {
// ...
};
```
**`src/hooks/useChatApi.js`**
```javascript
export const useChatApi = () => {
const sendMessage = async (msg) => { /* ... */ };
return { sendMessage };
};
```
**`src/index.jsx`**
```javascript
import { formatAiErrorMessage } from './utils/formatUtils';
import { useChatApi } from './hooks/useChatApi';
import { ChatTab } from './components/ChatTab';
const AgenticWriterSidebar = ({ postId }) => {
const { sendMessage } = useChatApi();
return <ChatTab onSend={sendMessage} />;
};
```
---
## Verification Checklist
After each extraction:
- [ ] `npm run build` completes without errors
- [ ] Compiled `sidebar.js` matches expected size (±5%)
- [ ] Chat functionality works (send message, receive response)
- [ ] Planning functionality works (generate plan)
- [ ] Refinement works (refine blocks)
- [ ] Tab switching works
- [ ] Session persistence works
- [ ] No console errors in browser
---
## Rollback Plan
If extraction causes issues:
1. Revert the specific extracted file
2. Keep extracted utilities (safe to keep)
3. Re-run `npm run build`
4. Verify functionality
---
## Next Action
1. **Create `src/utils/` directory**
2. **Extract `formatAiErrorMessage`** as the first migration
3. **Verify build and functionality**
4. **Iterate with next extraction**
---
## Dependencies
| Tool | Status |
|------|--------|
| esbuild | ✅ Configured |
| npm | ✅ Available |
| WordPress environment | ✅ Local by Flywheel |
---
## Questions to Resolve Before Starting
1. Should extracted components use TypeScript or remain JSX?
2. Should we add PropTypes for component prop validation?
3. Should we maintain backward compatibility with `wpAgenticWriter` global?
---
## References
- `FRONTEND_AND_CHAT_FIX_SUMMARY.md` - Original fix documentation
- `scripts/build.js` - Current esbuild configuration
- `assets/js/dist/sidebar.js` - **Compiled output** (loaded by PHP, 169KB)
- `assets/js/sidebar.js` - **Legacy file** (archived, 438KB, NOT loaded)
- `assets/js/src/index.jsx` - Current source (to be split, 11,793 lines)