first commit all files

This commit is contained in:
dwindown
2026-01-28 00:26:00 +07:00
parent 65dd207a74
commit 97426d5ab1
72 changed files with 91484 additions and 0 deletions

384
REMAINING_IMPLEMENTATION.md Normal file
View File

@@ -0,0 +1,384 @@
# Remaining Implementation Code
This document contains all code snippets that need to be implemented for Phases 1.2, 1.3, 2, and 3.
---
## Phase 1.2: Writing Mode Empty State (Frontend - sidebar.js)
**Location:** Add before the main render return statement
```javascript
// Check if Writing mode needs empty state
const shouldShowWritingEmptyState = () => {
return agentMode === 'writing' && !currentPlanRef.current;
};
// Render Writing mode empty state
const renderWritingEmptyState = () => {
return wp.element.createElement('div', { className: 'wpaw-writing-empty-state' },
wp.element.createElement('div', { className: 'wpaw-empty-state-content' },
wp.element.createElement('span', { className: 'wpaw-empty-state-icon' }, '📝'),
wp.element.createElement('h3', null, 'No Outline Yet'),
wp.element.createElement('p', null, 'Writing mode requires an outline to structure your article.'),
wp.element.createElement(Button, {
isPrimary: true,
onClick: () => setAgentMode('planning'),
className: 'wpaw-empty-state-button'
}, '📝 Create Outline First'),
wp.element.createElement('p', { className: 'wpaw-empty-state-hint' },
'Or switch to ',
wp.element.createElement('button', {
onClick: () => setAgentMode('chat'),
className: 'wpaw-link-button'
}, 'Chat mode'),
' to discuss your ideas.'
)
)
);
};
```
**Location:** In handleExecuteArticle function, add at the beginning:
```javascript
// Check if plan exists
if (!currentPlanRef.current) {
setMessages(prev => [...prev, {
role: 'system',
type: 'error',
content: 'Please create an outline first. Switch to Planning mode to get started.'
}]);
setIsLoading(false);
return;
}
```
---
## Phase 1.2: CSS for Empty State (sidebar.css)
```css
.wpaw-writing-empty-state {
display: flex;
align-items: center;
justify-content: center;
min-height: 300px;
padding: 2rem;
}
.wpaw-empty-state-content {
text-align: center;
max-width: 400px;
}
.wpaw-empty-state-icon {
font-size: 3rem;
display: block;
margin-bottom: 1rem;
}
.wpaw-empty-state-content h3 {
margin: 0 0 0.5rem 0;
font-size: 1.5rem;
color: #1e1e1e;
}
.wpaw-empty-state-content p {
color: #666;
margin: 0.5rem 0;
line-height: 1.5;
}
.wpaw-empty-state-button {
margin: 1.5rem 0 1rem 0 !important;
}
.wpaw-empty-state-hint {
font-size: 0.9rem;
margin-top: 1rem !important;
}
.wpaw-link-button {
background: none;
border: none;
color: #2271b1;
text-decoration: underline;
cursor: pointer;
padding: 0;
font: inherit;
}
.wpaw-link-button:hover {
color: #135e96;
}
```
---
## Phase 1.3: Writing Mode Notes Warning (sidebar.js)
**Location:** In the message sending logic, add check for Writing mode:
```javascript
// Add this check before sending message
if (agentMode === 'writing' && currentPlanRef.current) {
// Show info about notes in writing mode
setMessages(prev => [...prev,
{ role: 'user', content: userMessage },
{
role: 'system',
type: 'info',
content: '💡 Note: To modify the outline, switch to Planning mode. Writing mode messages are for discussion only.'
}
]);
}
```
---
## Phase 2.1: Summarize-Context Endpoint (class-gutenberg-sidebar.php)
**Location:** In register_routes() method, add:
```php
register_rest_route(
'wp-agentic-writer/v1',
'/summarize-context',
array(
'methods' => 'POST',
'callback' => array( $this, 'handle_summarize_context' ),
'permission_callback' => array( $this, 'check_permissions' ),
)
);
```
**Location:** Add new method:
```php
/**
* Handle context summarization request.
*
* @param WP_REST_Request $request REST request.
* @return WP_REST_Response|WP_Error Response.
*/
public function handle_summarize_context( $request ) {
$params = $request->get_json_params();
$chat_history = $params['chatHistory'] ?? array();
$post_id = $params['postId'] ?? 0;
// Short history doesn't need summarization
if ( empty( $chat_history ) || count( $chat_history ) < 4 ) {
return new WP_REST_Response(
array(
'summary' => '',
'use_full_history' => true,
'cost' => 0,
'tokens_saved' => 0,
),
200
);
}
// Build history text
$history_text = '';
foreach ( $chat_history as $msg ) {
$role = ucfirst( $msg['role'] ?? 'Unknown' );
$content = $msg['content'] ?? '';
if ( ! empty( $content ) ) {
$history_text .= "{$role}: {$content}\n\n";
}
}
// Build summarization prompt
$prompt = "Summarize this conversation into key points that capture the user's intent and requirements.
Focus on:
- Main topic
- Specific focus areas
- Rejected/excluded topics
- User preferences (tone, audience, etc.)
Keep the summary concise (max 200 words) but preserve critical context.
Write in the same language as the conversation.
Output format:
TOPIC: [main topic]
FOCUS: [what to include]
EXCLUDE: [what to avoid]
PREFERENCES: [any specific requirements]
Conversation:
{$history_text}";
// Call AI with cheap model
$provider = WP_Agentic_Writer_OpenRouter_Provider::get_instance();
$messages = array(
array(
'role' => 'user',
'content' => $prompt,
),
);
$response = $provider->chat( $messages, array(), 'summarize' );
if ( is_wp_error( $response ) ) {
return $response;
}
// Calculate tokens saved
$original_tokens = count( $chat_history ) * 500; // Rough estimate
$summary_tokens = $response['output_tokens'] ?? 100;
$tokens_saved = $original_tokens - $summary_tokens;
// Track cost
do_action(
'wp_aw_after_api_request',
$post_id,
$response['model'] ?? '',
'summarize_context',
$response['input_tokens'] ?? 0,
$response['output_tokens'] ?? 0,
$response['cost'] ?? 0
);
return new WP_REST_Response(
array(
'summary' => $response['content'] ?? '',
'use_full_history' => false,
'cost' => $response['cost'] ?? 0,
'tokens_saved' => $tokens_saved,
),
200
);
}
```
---
## Phase 2.2: Detect-Intent Endpoint (class-gutenberg-sidebar.php)
**Location:** In register_routes() method, add:
```php
register_rest_route(
'wp-agentic-writer/v1',
'/detect-intent',
array(
'methods' => 'POST',
'callback' => array( $this, 'handle_detect_intent' ),
'permission_callback' => array( $this, 'check_permissions' ),
)
);
```
**Location:** Add new method:
```php
/**
* Handle intent detection request.
*
* @param WP_REST_Request $request REST request.
* @return WP_REST_Response|WP_Error Response.
*/
public function handle_detect_intent( $request ) {
$params = $request->get_json_params();
$last_message = $params['lastMessage'] ?? '';
$has_plan = $params['hasPlan'] ?? false;
$current_mode = $params['currentMode'] ?? 'chat';
$post_id = $params['postId'] ?? 0;
if ( empty( $last_message ) ) {
return new WP_REST_Response(
array( 'intent' => 'continue_chat' ),
200
);
}
// Build intent detection prompt
$prompt = "Based on the user's message, determine their intent. Choose ONE:
1. \"create_outline\" - User wants to create an article outline/structure
2. \"start_writing\" - User wants to write the full article
3. \"refine_content\" - User wants to improve existing content
4. \"continue_chat\" - User wants to continue discussing/exploring
5. \"clarify\" - User is asking questions or needs clarification
Consider:
- The user's explicit request
- Whether they have an outline already (has_plan: " . ( $has_plan ? 'true' : 'false' ) . ")
- Current mode (current_mode: {$current_mode})
User's message: \"{$last_message}\"
Respond with ONLY the intent code (e.g., \"create_outline\"). No explanation.";
// Call AI with cheap model
$provider = WP_Agentic_Writer_OpenRouter_Provider::get_instance();
$messages = array(
array(
'role' => 'user',
'content' => $prompt,
),
);
$response = $provider->chat( $messages, array(), 'intent_detection' );
if ( is_wp_error( $response ) ) {
return $response;
}
// Track cost
do_action(
'wp_aw_after_api_request',
$post_id,
$response['model'] ?? '',
'detect_intent',
$response['input_tokens'] ?? 0,
$response['output_tokens'] ?? 0,
$response['cost'] ?? 0
);
// Clean up response
$intent = trim( strtolower( $response['content'] ?? 'continue_chat' ) );
$intent = str_replace( '"', '', $intent );
// Validate intent
$valid_intents = array( 'create_outline', 'start_writing', 'refine_content', 'continue_chat', 'clarify' );
if ( ! in_array( $intent, $valid_intents ) ) {
$intent = 'continue_chat';
}
return new WP_REST_Response(
array(
'intent' => $intent,
'cost' => $response['cost'] ?? 0,
),
200
);
}
```
---
## Phase 2.3: Update Cost Tracking (class-cost-tracker.php)
**Location:** In get_operation_label() method, update the labels array:
```php
$labels = array(
'chat' => 'Chat',
'planning' => 'Planning',
'execution' => 'Article Writing',
'refinement' => 'Block Refinement',
'meta_description' => 'Meta Description',
'keyword_suggestion' => 'Keyword Suggestion',
'web_search' => 'Web Search',
'summarize_context' => 'Context Summarization', // NEW
'detect_intent' => 'Intent Detection', // NEW
);
```
---
This document contains the core implementation code. The actual integration requires careful placement in the existing codebase structure.