first commit all files
This commit is contained in:
384
REMAINING_IMPLEMENTATION.md
Normal file
384
REMAINING_IMPLEMENTATION.md
Normal 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.
|
||||
Reference in New Issue
Block a user