# 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.