PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 2.9.8
AI Engine – The Chatbot, AI Framework & MCP for WordPress v2.9.8
3.5.7 3.5.6 3.5.5 3.5.4 3.5.3 3.5.2 3.5.1 3.5.0 3.4.9 3.4.8 3.4.7 0.2.1 1.6.91 0.2.2 1.6.92 0.2.3 1.6.93 0.2.4 1.6.94 0.2.5 1.6.95 0.2.6 1.6.96 0.2.7 1.6.97 0.2.8 1.6.98 0.2.9 1.6.99 0.3.0 1.7.0 0.3.1 1.7.1 0.3.2 1.7.2 0.3.3 1.7.3 0.3.4 1.7.4 0.3.5 1.7.5 0.3.6 1.7.6 0.4.0 1.7.7 0.4.1 1.7.8 0.4.2 1.7.9 0.4.3 1.8.0 0.4.4 1.8.1 0.4.5 1.8.2 0.4.6 1.8.3 0.4.7 1.8.4 0.4.8 1.8.5 0.4.9 1.8.6 0.5.0 1.8.7 0.5.1 1.8.8 0.5.2 1.8.9 0.5.3 1.9.0 0.5.4 1.9.1 0.5.5 1.9.2 0.5.6 1.9.3 0.5.7 1.9.4 0.5.8 1.9.5 0.5.9 1.9.6 0.6.0 1.9.7 0.6.1 1.9.8 0.6.2 1.9.81 0.6.3 1.9.82 0.6.4 1.9.83 0.6.5 1.9.84 0.6.6 1.9.85 0.6.7 1.9.86 0.6.8 1.9.87 0.6.9 1.9.88 0.7.0 1.9.89 0.7.1 1.9.90 0.7.2 1.9.91 0.7.3 1.9.92 0.7.4 1.9.93 0.7.5 1.9.94 0.7.6 1.9.95 0.7.7 1.9.96 0.7.8 1.9.97 0.7.9 1.9.98 0.8.0 1.9.99 0.8.1 2.0.0 0.8.2 2.0.1 0.8.3 2.0.2 0.8.4 2.0.3 0.8.5 2.0.4 0.8.6 2.0.5 0.8.7 2.0.6 0.8.8 2.0.7 0.8.9 2.0.8 0.9.0 2.0.9 0.9.2 2.1.0 0.9.3 2.1.1 0.9.4 2.1.2 0.9.5 2.1.3 0.9.6 2.1.4 0.9.7 2.1.5 0.9.8 2.1.6 0.9.81 2.1.7 0.9.82 2.1.8 0.9.83 2.1.9 0.9.84 2.2.0 0.9.85 2.2.1 0.9.86 2.2.2 0.9.87 2.2.3 0.9.88 2.2.4 0.9.89 2.2.5 0.9.9 2.2.51 0.9.91 2.2.52 0.9.92 2.2.53 0.9.93 2.2.54 0.9.94 2.2.56 0.9.95 2.2.57 0.9.96 2.2.6 0.9.97 2.2.60 0.9.98 2.2.61 0.9.99 2.2.62 1.0.0 2.2.63 1.0.01 2.2.70 1.0.1 2.2.80 1.0.2 2.2.81 1.0.3 2.2.90 1.0.4 2.2.91 1.0.5 2.2.92 1.0.6 2.2.93 1.0.7 2.2.94 1.0.8 2.2.95 1.0.9 2.3.0 1.1.0 2.3.1 1.1.1 2.3.2 1.1.2 2.3.3 1.1.3 2.3.4 1.1.4 2.3.5 1.1.5 2.3.6 1.1.6 2.3.7 1.1.7 2.3.8 1.1.8 2.3.9 1.1.9 2.4.0 1.2.0 2.4.1 1.2.1 2.4.2 1.2.2 2.4.3 1.2.21 2.4.4 1.2.3 2.4.5 1.2.30 2.4.6 1.3.0 2.4.7 1.3.1 2.4.8 1.3.2 2.4.9 1.3.3 2.5.0 1.3.31 2.5.1 1.3.32 2.5.2 1.3.33 2.5.3 1.3.34 2.5.4 1.3.35 2.5.5 1.3.36 2.5.6 1.3.37 2.5.7 1.3.38 2.5.8 1.3.39 2.5.9 1.3.40 2.6.0 1.3.41 2.6.1 1.3.42 2.6.2 1.3.43 2.6.3 1.3.44 2.6.5 1.3.45 2.6.6 1.3.46 2.6.7 1.3.47 2.6.8 1.3.48 2.6.9 1.3.49 2.7.0 1.3.50 2.7.1 1.3.51 2.7.2 1.3.52 2.7.3 1.3.53 2.7.4 1.3.54 2.7.5 1.3.56 2.7.6 1.3.57 2.7.7 1.3.58 2.7.8 1.3.59 2.7.9 1.3.60 2.8.0 1.3.61 2.8.1 1.3.62 2.8.2 1.3.63 2.8.3 1.3.64 2.8.4 1.3.65 2.8.5 1.3.66 2.8.6 1.3.67 2.8.7 1.3.68 2.8.8 1.3.69 2.8.9 1.3.70 2.9.0 1.3.71 2.9.1 1.3.72 2.9.2 1.3.73 2.9.3 1.3.74 2.9.4 1.3.75 2.9.5 1.3.76 2.9.6 1.3.77 2.9.7 1.3.78 2.9.8 1.3.79 2.9.9 1.3.80 3.0.0 1.3.81 3.0.1 1.3.82 3.0.2 1.3.83 3.0.3 1.3.84 3.0.4 1.3.85 3.0.5 1.3.86 3.0.6 1.3.87 3.0.7 1.3.88 3.0.8 1.3.89 3.0.9 1.3.90 3.1.0 1.3.91 3.1.1 1.3.92 3.1.2 1.3.93 3.1.3 1.3.94 3.1.4 1.3.95 3.1.5 1.3.96 3.1.6 1.3.97 3.1.7 1.3.98 3.1.8 1.3.99 3.1.9 1.4.0 3.2.0 1.4.1 3.2.1 1.4.2 3.2.2 1.4.3 3.2.3 1.4.4 3.2.4 1.4.5 3.2.5 1.4.6 3.2.6 1.4.7 3.2.7 1.4.8 3.2.8 1.4.9 3.2.9 1.5.0 3.3.0 1.5.1 3.3.1 1.5.2 3.3.2 1.5.3 3.3.3 1.5.4 3.3.4 1.5.5 3.3.5 1.5.6 3.3.6 1.5.7 3.3.7 1.5.8 3.3.8 1.5.9 3.3.9 1.6.0 3.4.0 1.6.1 3.4.1 1.6.2 3.4.2 1.6.3 3.4.3 1.6.5 3.4.4 1.6.51 3.4.5 1.6.52 3.4.6 1.6.53 1.6.54 1.6.55 1.6.56 1.6.57 1.6.58 1.6.59 1.6.60 1.6.61 1.6.62 1.6.63 1.6.64 1.6.65 1.6.66 1.6.67 1.6.68 trunk 1.6.69 0.0.1 1.6.70 0.0.2 1.6.71 0.0.3 1.6.72 0.0.4 1.6.73 0.0.5 1.6.74 0.0.6 1.6.75 0.0.7 1.6.76 0.0.8 1.6.77 0.0.9 1.6.78 0.1.0 1.6.79 0.1.1 1.6.81 0.1.2 1.6.82 0.1.3 1.6.83 0.1.4 1.6.84 0.1.5 1.6.85 0.1.6 1.6.86 0.1.7 1.6.87 0.1.8 1.6.88 0.1.9 1.6.89 0.2.0 1.6.90
ai-engine / dev-notes.md
ai-engine Last commit date
app 11 months ago archives 11 months ago classes 11 months ago common 11 months ago constants 11 months ago images 11 months ago labs 11 months ago themes 11 months ago vendor 11 months ago ai-engine.php 11 months ago blueprint.json 2 years ago dev-notes.md 11 months ago readme.txt 11 months ago uninstall.php 11 months ago
dev-notes.md
1544 lines
1 # AI Engine - Developer Documentation
2
3 This documentation is for developers who want to extend AI Engine with custom functionality. AI Engine provides multiple extension points through filters and APIs that allow you to enhance chatbots, add custom AI tools, and integrate with WordPress in powerful ways.
4
5 ## Table of Contents
6 - [](#wordpress-hooks-referenceWordPress Hooks Reference](#wordpress-hooks-reference](#wordpress-hooks-reference) - Complete list of filters and actions
7 - [](#chatbot-actionsChatbot Actions](#chatbot-actions](#chatbot-actions) - Execute client-side functions from AI responses
8 - [](#chatbot-shortcutsChatbot Shortcuts](#chatbot-shortcuts](#chatbot-shortcuts) - Dynamic quick-action buttons in chatbots
9 - [](#chatbot-blocksChatbot Blocks](#chatbot-blocks](#chatbot-blocks) - Interactive HTML content in chat conversations
10 - [](#mcp-model-context-protocolMCP (Model Context Protocol)](#mcp-model-context-protocol](#mcp-model-context-protocol) - Enable AI agents to interact with WordPress
11 - [](#discussion-context-menuDiscussion Context Menu](#discussion-context-menu](#discussion-context-menu) - Customize the discussions interface
12
13 ---
14
15 # WordPress Hooks Reference
16
17 AI Engine provides numerous WordPress filters and actions that allow developers to customize and extend its functionality. This section documents the most useful hooks for developers.
18
19 ## Core AI Filters
20
21 ### Query and Reply Processing
22
23 ```php
24 // Modify AI query before it's sent
25 add_filter( 'mwai_ai_query', function( $query ) {
26 // Modify the query object
27 return $query;
28 });
29
30 // Modify AI reply after it's received
31 add_filter( 'mwai_ai_reply', function( $reply, $query ) {
32 // Process or modify the reply
33 return $reply;
34 }, 10, 2 );
35
36 // Control whether a query is allowed
37 add_filter( 'mwai_ai_allowed', function( $allowed, $query, $limits ) {
38 // Return true to allow, false to block, or a string error message
39 if ( /* some condition */ ) {
40 return 'Query blocked due to rate limits';
41 }
42 return $allowed;
43 }, 10, 3 );
44
45 // Modify AI instructions/context
46 add_filter( 'mwai_ai_instructions', function( $instructions, $query ) {
47 // Add or modify system instructions
48 $instructions .= "\nAlways be polite and helpful.";
49 return $instructions;
50 }, 10, 2 );
51 ```
52
53 ### Error Handling
54
55 ```php
56 // Customize error messages shown to users
57 add_filter( 'mwai_ai_exception', function( $message ) {
58 // Hide technical details from users
59 if ( strpos( $message, 'API' ) !== false ) {
60 return 'Service temporarily unavailable. Please try again.';
61 }
62 return $message;
63 });
64 ```
65
66 ## Chatbot Filters
67
68 ### Chatbot Parameters and Behavior
69
70 ```php
71 // Modify chatbot parameters
72 add_filter( 'mwai_chatbot_params', function( $params ) {
73 // Force specific settings
74 $params['temperature'] = 0.7;
75 $params['max_tokens'] = 500;
76 return $params;
77 });
78
79 // Takeover chatbot response (bypass AI)
80 add_filter( 'mwai_chatbot_takeover', function( $takeover, $query, $params ) {
81 // Check for specific triggers
82 if ( strpos( $query->get_message(), 'current time' ) !== false ) {
83 return 'The current time is ' . current_time( 'mysql' );
84 }
85 return $takeover;
86 }, 10, 3 );
87
88 // Modify chatbot query before processing
89 add_filter( 'mwai_chatbot_query', function( $query, $params ) {
90 // Add context or modify the query
91 return $query;
92 }, 10, 2 );
93
94 // Process chatbot reply before sending to user
95 add_filter( 'mwai_chatbot_reply', function( $reply, $query, $params, $extra ) {
96 // Add custom formatting or processing
97 return $reply;
98 }, 10, 4 );
99 ```
100
101 ### Dynamic UI Elements
102
103 ```php
104 // Add chatbot shortcuts dynamically
105 add_filter( 'mwai_chatbot_shortcuts', function( $shortcuts, $args ) {
106 $shortcuts[] = [
107 'type' => 'message',
108 'data' => [
109 'label' => 'Help',
110 'message' => 'I need help',
111 'variant' => 'info'
112 ]
113 ];
114 return $shortcuts;
115 }, 10, 2 );
116
117 // Add chatbot blocks (HTML content)
118 add_filter( 'mwai_chatbot_blocks', function( $blocks, $args ) {
119 $blocks[] = [
120 'type' => 'content',
121 'data' => [
122 'html' => '<div>Custom content</div>',
123 'script' => 'console.log("Block loaded");'
124 ]
125 ];
126 return $blocks;
127 }, 10, 2 );
128
129 // Add chatbot actions (function calls)
130 add_filter( 'mwai_chatbot_actions', function( $actions, $args ) {
131 $actions[] = [
132 'name' => 'custom_action',
133 'data' => ['param' => 'value']
134 ];
135 return $actions;
136 }, 10, 2 );
137 ```
138
139 ## Discussion Filters
140
141 ### Discussion Metadata Display
142
143 These filters allow you to customize how discussion metadata is displayed in the discussion list.
144
145 ```php
146 // Customize the start date display
147 add_filter( 'mwai_discussion_metadata_start_date', function( $formatted_date, $discussion ) {
148 // $formatted_date is already formatted (e.g., "5m ago", "Jan 20th")
149 // $discussion contains the full discussion data
150
151 // Example: Add emoji for recent discussions
152 $created_time = strtotime( $discussion['created'] );
153 $hours_ago = ( time() - $created_time ) / 3600;
154
155 if ( $hours_ago < 1 ) {
156 return '🔥 ' . $formatted_date;
157 } elseif ( $hours_ago < 24 ) {
158 return '' . $formatted_date;
159 }
160
161 return $formatted_date;
162 }, 10, 2 );
163
164 // Customize the last update display
165 add_filter( 'mwai_discussion_metadata_last_update', function( $formatted_date, $discussion ) {
166 // Example: Show activity status instead of time
167 $updated_time = strtotime( $discussion['updated'] );
168 $days_ago = ( time() - $updated_time ) / 86400;
169
170 if ( $days_ago < 1 ) {
171 return '🟢 Active today';
172 } elseif ( $days_ago < 7 ) {
173 return '🟡 This week';
174 } else {
175 return '' . $formatted_date;
176 }
177 }, 10, 2 );
178
179 // Customize the message count display
180 add_filter( 'mwai_discussion_metadata_message_count', function( $count, $discussion ) {
181 // Example: Format with descriptive text
182 if ( $count == 0 ) {
183 return 'No messages';
184 } elseif ( $count == 1 ) {
185 return '1 message';
186 } elseif ( $count > 50 ) {
187 return $count . ' messages 🔥';
188 }
189
190 return $count . ' messages';
191 }, 10, 2 );
192
193 // Complete example: Custom badges based on discussion data
194 add_filter( 'mwai_discussion_metadata_start_date', function( $formatted_date, $discussion ) {
195 // Access discussion properties
196 $message_count = count( json_decode( $discussion['messages'], true ) );
197 $has_title = !empty( $discussion['title'] );
198
199 // Add badges based on conditions
200 $badges = [];
201 if ( $message_count > 20 ) {
202 $badges[] = '💬';
203 }
204 if ( $has_title ) {
205 $badges[] = '📝';
206 }
207
208 $badge_string = !empty( $badges ) ? implode( '', $badges ) . ' ' : '';
209 return $badge_string . $formatted_date;
210 }, 10, 2 );
211 ```
212
213 ### Available Discussion Data
214
215 The `$discussion` parameter contains:
216 - `id` - Discussion ID
217 - `chatId` - Unique chat identifier
218 - `botId` - Associated bot ID
219 - `title` - Discussion title (may be empty)
220 - `created` - Creation timestamp
221 - `updated` - Last update timestamp
222 - `messages` - JSON string of messages (decode to access)
223 - `extra` - JSON string of extra data
224
225 ## Embeddings and Vector Database
226
227 ```php
228 // Add custom vector to database
229 add_filter( 'mwai_embeddings_add_vector', function( $success, $vector, $options ) {
230 // Implement custom vector storage
231 return $success;
232 }, 10, 3 );
233
234 // Query vectors from database
235 add_filter( 'mwai_embeddings_query_vectors', function( $results, $searchVectors, $options ) {
236 // Implement custom vector search
237 return $results;
238 }, 10, 3 );
239
240 // Delete vectors
241 add_filter( 'mwai_embeddings_delete_vectors', function( $vectorIds, $options ) {
242 // Handle vector deletion
243 return $vectorIds;
244 }, 10, 2 );
245
246 // Modify context search results
247 add_filter( 'mwai_context_search', function( $context, $query, $options ) {
248 // Add or modify context from embeddings
249 return $context;
250 }, 10, 3 );
251 ```
252
253 ## Content Processing
254
255 ```php
256 // Modify content before AI processing
257 add_filter( 'mwai_contentaware_content', function( $content, $post ) {
258 // Clean or enhance content
259 $content = strip_shortcodes( $content );
260 return $content;
261 }, 10, 2 );
262
263 // Customize prompt templates
264 add_filter( 'mwai_prompt_suggestTitles', function( $prompt, $args ) {
265 return "Generate 5 SEO-optimized titles for:\n\n";
266 }, 10, 2 );
267
268 add_filter( 'mwai_prompt_translateText', function( $prompt, $args ) {
269 return "Translate to {$args['language']} maintaining tone:\n\n";
270 }, 10, 2 );
271 ```
272
273 ## AI Forms
274
275 ```php
276 // Modify form parameters
277 add_filter( 'mwai_form_params', function( $params ) {
278 $params['submit_label'] = 'Generate Content';
279 return $params;
280 });
281
282 // Takeover form submission
283 add_filter( 'mwai_form_takeover', function( $takeover, $query, $params ) {
284 // Handle form submission custom logic
285 return $takeover;
286 }, 10, 3 );
287
288 // Process form reply
289 add_filter( 'mwai_form_reply', function( $reply, $query, $params, $extra ) {
290 // Format or process the reply
291 return $reply;
292 }, 10, 4 );
293
294 // Customize form field parameters
295 add_filter( 'mwai_forms_field_params', function( $params ) {
296 // Modify field settings
297 return $params;
298 });
299
300 // Add custom form styles
301 add_filter( 'mwai_forms_style', function( $styles, $formId ) {
302 $styles .= "\n.mwai-form-{$formId} { border: 2px solid blue; }";
303 return $styles;
304 }, 10, 2 );
305 ```
306
307 ## Function Calling
308
309 ```php
310 // Register custom functions for AI to call
311 add_filter( 'mwai_functions_list', function( $functions ) {
312 $functions[] = [
313 'name' => 'get_weather',
314 'description' => 'Get current weather',
315 'parameters' => [
316 'type' => 'object',
317 'properties' => [
318 'location' => [
319 'type' => 'string',
320 'description' => 'City name'
321 ]
322 ]
323 ]
324 ];
325 return $functions;
326 });
327
328 // Handle function execution
329 add_filter( 'mwai_ai_feedback', function( $result, $function, $args ) {
330 if ( $function['name'] === 'get_weather' ) {
331 // Execute function and return result
332 return "Sunny, 25°C in " . $args['location'];
333 }
334 return $result;
335 }, 10, 3 );
336 ```
337
338 ## Statistics and Usage
339
340 ```php
341 // Modify usage statistics
342 add_filter( 'mwai_stats_credits', function( $credits, $userId ) {
343 // Implement custom credit system
344 return $credits;
345 }, 10, 2 );
346
347 // Customize pricing calculations
348 add_filter( 'mwai_stats_coins', function( $price, $stats, $atts ) {
349 // Apply custom pricing logic
350 return $price;
351 }, 10, 3 );
352
353 // Access logs
354 add_filter( 'mwai_stats_logs_list', function( $logs, $offset, $limit, $filters, $sort ) {
355 // Filter or modify logs
356 return $logs;
357 }, 10, 5 );
358 ```
359
360 ## MCP (Model Context Protocol)
361
362 ```php
363 // Register MCP tools
364 add_filter( 'mwai_mcp_tools', function( $tools ) {
365 $tools[] = [
366 'name' => 'custom_tool',
367 'description' => 'My custom tool',
368 'inputSchema' => [/* ... */]
369 ];
370 return $tools;
371 });
372
373 // Handle MCP tool execution
374 add_filter( 'mwai_mcp_callback', function( $result, $tool, $args, $id ) {
375 if ( $tool === 'custom_tool' ) {
376 // Execute and return result
377 return ['success' => true, 'data' => 'result'];
378 }
379 return $result;
380 }, 10, 4 );
381
382 // Control MCP access
383 add_filter( 'mwai_allow_mcp', function( $allowed, $userId ) {
384 // Implement custom access control
385 return $allowed;
386 }, 10, 2 );
387 ```
388
389 ## Engine Configuration
390
391 ```php
392 // Customize AI engine initialization
393 add_filter( 'mwai_init_engine', function( $engine, $core, $env ) {
394 // Return custom engine implementation
395 return $engine;
396 }, 10, 3 );
397
398 // Modify model lists
399 add_filter( 'mwai_openai_models', function( $models ) {
400 // Add custom models
401 $models[] = 'custom-model-id';
402 return $models;
403 });
404
405 // Customize API endpoints
406 add_filter( 'mwai_openai_endpoint', function( $endpoint, $env ) {
407 // Use custom endpoint
408 return 'https://custom-api.example.com/v1';
409 }, 10, 2 );
410 ```
411
412 ## Actions
413
414 ```php
415 // Scheduled tasks
416 add_action( 'mwai_tasks_run', function() {
417 // Run scheduled maintenance tasks
418 // This runs on WP cron
419 });
420 ```
421
422 ## Best Practices
423
424 1. **Priority Matters**: Use appropriate priority values (default is 10) to control execution order
425 2. **Return Values**: Always return the filtered value, even if unchanged
426 3. **Error Handling**: Use try-catch blocks in your filters to prevent breaking the plugin
427 4. **Performance**: Keep filter callbacks lightweight, especially for frequently called filters
428 5. **Documentation**: Document your custom filters for other developers on your team
429
430 ---
431
432 # Chatbot Actions
433
434 Actions allow AI models to trigger client-side JavaScript functions during chat conversations. This enables dynamic interactions like form submissions, API calls, or UI updates directly from the AI's response.
435
436 ## How Actions Work
437
438 When the AI includes a specific action in its response, the chatbot automatically executes the corresponding JavaScript function on the client side. This is particularly useful for:
439 - Triggering form submissions
440 - Making API calls
441 - Updating UI elements
442 - Collecting user data
443 - Integrating with third-party services
444
445 ## Implementation
446
447 ### Step 1: Create a Callable Action in Code Engine
448
449 1. Go to **AI Engine → Code Engine**
450 2. Create a new snippet with:
451 - **Type**: Callable Action
452 - **Target**: JS
453 - **Name**: Your action name (e.g., `submit_form`)
454
455 ### Step 2: Write Your JavaScript Function
456
457 ```javascript
458 // This function will be called when the AI triggers the action
459 function submit_form(args) {
460 // Access chatbot context
461 const chatbot = args.chatbot;
462 const message = args.message;
463
464 // Your custom logic
465 const formData = {
466 name: args.name,
467 email: args.email,
468 message: args.userMessage
469 };
470
471 // Example: Submit to an API
472 fetch('/wp-json/custom/v1/submit', {
473 method: 'POST',
474 headers: { 'Content-Type': 'application/json' },
475 body: JSON.stringify(formData)
476 })
477 .then(response => response.json())
478 .then(data => {
479 // Send response back to chat
480 chatbot.addMessage({
481 role: 'assistant',
482 content: 'Form submitted successfully!'
483 });
484 });
485 }
486 ```
487
488 ### Step 3: Configure AI to Use the Action
489
490 In your AI assistant or system prompt, instruct the model to use the action:
491
492 ```
493 When the user wants to submit a contact form, use the submit_form action with their name, email, and message.
494
495 Example response format:
496 "I'll submit that form for you now."
497 [Action: submit_form, Args: {"name": "John", "email": "john@example.com", "userMessage": "Hello!"}]
498 ```
499
500 ## Action Response Format
501
502 The AI should include actions in this format:
503 ```json
504 {
505 "type": "function",
506 "data": {
507 "name": "action_name",
508 "args": {
509 "param1": "value1",
510 "param2": "value2"
511 }
512 }
513 }
514 ```
515
516 ## Complete Example: Calculator Action
517
518 ```javascript
519 // Code Engine Callable Action: "calculate"
520 function calculate(args) {
521 const { operation, a, b, chatbot } = args;
522 let result;
523
524 switch(operation) {
525 case 'add':
526 result = a + b;
527 break;
528 case 'multiply':
529 result = a * b;
530 break;
531 case 'divide':
532 result = b !== 0 ? a / b : 'Cannot divide by zero';
533 break;
534 }
535
536 // Display result in chat
537 chatbot.addMessage({
538 role: 'assistant',
539 content: `The result is: ${result}`
540 });
541 }
542 ```
543
544 AI Assistant instruction:
545 ```
546 When asked to perform calculations, use the calculate action.
547 Example: "What is 5 plus 3?"
548 Response: "Let me calculate that for you." [Action: calculate, Args: {"operation": "add", "a": 5, "b": 3}]
549 ```
550
551 ---
552
553 # Chatbot Shortcuts
554
555 Shortcuts are dynamic quick-action buttons that appear in the chatbot interface. They provide users with suggested actions or common questions, improving the chat experience by offering one-click interactions.
556
557 ## What Are Shortcuts?
558
559 Shortcuts appear as clickable buttons above the chat input. When clicked, they can:
560 - Send predefined messages to the chatbot
561 - Trigger specific conversations
562 - Guide users through common workflows
563 - Provide contextual suggestions based on the conversation
564
565 ## Adding Shortcuts via JavaScript
566
567 ### Basic Example
568
569 ```javascript
570 // Add shortcuts to all chatbots
571 MwaiAPI.chatbots.forEach(chatbot => {
572 chatbot.setShortcuts([
573 {
574 type: 'message',
575 data: {
576 label: 'Get Started',
577 message: 'Hello! What can you help me with?',
578 variant: 'success',
579 icon: '👋'
580 }
581 },
582 {
583 type: 'message',
584 data: {
585 label: 'Contact Support',
586 message: 'I need help with a technical issue',
587 variant: 'warning',
588 icon: '🛠️'
589 }
590 }
591 ]);
592 });
593 ```
594
595 ### Dynamic Shortcuts Based on Context
596
597 ```javascript
598 // Listen for messages and update shortcuts dynamically
599 MwaiAPI.chatbots.forEach(chatbot => {
600 chatbot.on('message', (message) => {
601 if (message.content.includes('products')) {
602 chatbot.setShortcuts([
603 {
604 type: 'message',
605 data: {
606 label: 'View Catalog',
607 message: 'Show me your product catalog',
608 variant: 'info'
609 }
610 },
611 {
612 type: 'message',
613 data: {
614 label: 'Best Sellers',
615 message: 'What are your best selling products?',
616 variant: 'success'
617 }
618 }
619 ]);
620 }
621 });
622 });
623 ```
624
625 ## Adding Shortcuts via PHP
626
627 ### Basic Implementation
628
629 ```php
630 add_filter( 'mwai_chatbot_shortcuts', function ( $shortcuts, $args ) {
631 // Add shortcuts for all chatbots
632 $shortcuts[] = [
633 'type' => 'message',
634 'data' => [
635 'label' => 'FAQ',
636 'message' => 'Show me frequently asked questions',
637 'variant' => 'info',
638 'icon' => ''
639 ]
640 ];
641
642 $shortcuts[] = [
643 'type' => 'message',
644 'data' => [
645 'label' => 'Pricing',
646 'message' => 'Tell me about your pricing plans',
647 'variant' => 'success',
648 'icon' => '💰'
649 ]
650 ];
651
652 return $shortcuts;
653 }, 10, 2);
654 ```
655
656 ### Conditional Shortcuts
657
658 ```php
659 add_filter( 'mwai_chatbot_shortcuts', function ( $shortcuts, $args ) {
660 // Show shortcuts based on conversation content
661 $hasQuery = isset($args['newMessage']) ? $args['newMessage'] : '';
662 $hasReply = isset($args['reply']) ? $args['reply'] : '';
663
664 // E-commerce shortcuts when products are mentioned
665 if (stripos($hasQuery . $hasReply, 'product') !== false) {
666 $shortcuts[] = [
667 'type' => 'message',
668 'data' => [
669 'label' => '🛒 Cart',
670 'message' => 'Show my shopping cart',
671 'variant' => 'info'
672 ]
673 ];
674
675 $shortcuts[] = [
676 'type' => 'message',
677 'data' => [
678 'label' => '📦 Track Order',
679 'message' => 'I want to track my order',
680 'variant' => 'warning'
681 ]
682 ];
683 }
684
685 // Support shortcuts when help is needed
686 if (stripos($hasQuery . $hasReply, 'help') !== false ||
687 stripos($hasQuery . $hasReply, 'support') !== false) {
688 $shortcuts[] = [
689 'type' => 'message',
690 'data' => [
691 'label' => '📧 Email Support',
692 'message' => 'I need to contact support via email',
693 'variant' => 'danger'
694 ]
695 ];
696
697 $shortcuts[] = [
698 'type' => 'message',
699 'data' => [
700 'label' => '📞 Call Us',
701 'message' => 'What is your support phone number?',
702 'variant' => 'success'
703 ]
704 ];
705 }
706
707 return $shortcuts;
708 }, 10, 2);
709 ```
710
711 ### User-Specific Shortcuts
712
713 ```php
714 add_filter( 'mwai_chatbot_shortcuts', function ( $shortcuts, $args ) {
715 // Show different shortcuts based on user role
716 if (is_user_logged_in()) {
717 $user = wp_get_current_user();
718
719 if (in_array('customer', $user->roles)) {
720 $shortcuts[] = [
721 'type' => 'message',
722 'data' => [
723 'label' => 'My Orders',
724 'message' => 'Show me my recent orders',
725 'variant' => 'info'
726 ]
727 ];
728 }
729
730 if (in_array('administrator', $user->roles)) {
731 $shortcuts[] = [
732 'type' => 'message',
733 'data' => [
734 'label' => 'Admin Stats',
735 'message' => 'Show me the site statistics',
736 'variant' => 'warning'
737 ]
738 ];
739 }
740 } else {
741 $shortcuts[] = [
742 'type' => 'message',
743 'data' => [
744 'label' => 'Sign Up',
745 'message' => 'How do I create an account?',
746 'variant' => 'success'
747 ]
748 ];
749 }
750
751 return $shortcuts;
752 }, 10, 2);
753 ```
754
755 ## Shortcut Properties
756
757 - **type**: Always 'message' for shortcuts
758 - **data.label**: Button text displayed to user
759 - **data.message**: Message sent when clicked
760 - **data.variant**: Button style ('success', 'warning', 'danger', 'info')
761 - **data.icon**: Optional emoji or icon
762
763 ---
764
765 # Chatbot Blocks
766
767 Blocks allow you to inject interactive HTML content directly into chat conversations. Unlike simple text responses, blocks can contain forms, buttons, custom UI elements, and even executable JavaScript.
768
769 ## What Are Blocks?
770
771 Blocks are custom HTML elements that can:
772 - Display forms for data collection
773 - Show interactive widgets
774 - Present rich media content
775 - Lock the chatbot until user interaction
776 - Execute custom JavaScript code
777
778 ## Adding Blocks via JavaScript
779
780 ### Simple Content Block
781
782 ```javascript
783 // Display a welcome message with custom styling
784 MwaiAPI.getChatbot().setBlocks([
785 {
786 type: 'content',
787 data: {
788 html: `
789 <div style="background: #f0f0f0; padding: 20px; border-radius: 10px;">
790 <h3>Welcome to Our Support Chat!</h3>
791 <p>How can we help you today?</p>
792 <ul>
793 <li>Technical Support</li>
794 <li>Billing Questions</li>
795 <li>Product Information</li>
796 </ul>
797 </div>
798 `
799 }
800 }
801 ]);
802 ```
803
804 ### Interactive Form Block
805
806 ```javascript
807 // Create a form that locks the chatbot until completed
808 MwaiAPI.getChatbot().setBlocks([
809 {
810 type: 'content',
811 data: {
812 html: `
813 <div class="custom-form-block">
814 <h4>Quick Survey</h4>
815 <p>Please help us improve by answering this question:</p>
816 <form id="surveyForm">
817 <label>How satisfied are you with our service?</label><br>
818 <select id="satisfaction" required>
819 <option value="">Choose...</option>
820 <option value="very-satisfied">Very Satisfied</option>
821 <option value="satisfied">Satisfied</option>
822 <option value="neutral">Neutral</option>
823 <option value="unsatisfied">Unsatisfied</option>
824 </select><br><br>
825 <button type="submit">Submit</button>
826 </form>
827 </div>
828 `,
829 script: `
830 const chatbot = MwaiAPI.getChatbot();
831 chatbot.lock(); // Prevent further messages
832
833 document.getElementById('surveyForm').addEventListener('submit', function(e) {
834 e.preventDefault();
835 const satisfaction = document.getElementById('satisfaction').value;
836
837 // Send the response as a message
838 chatbot.ask('My satisfaction level is: ' + satisfaction, true);
839
840 // Remove the block and unlock
841 chatbot.setBlocks([]);
842 chatbot.unlock();
843 });
844 `
845 }
846 }
847 ]);
848 ```
849
850 ## Adding Blocks via PHP
851
852 ### Conditional Block Display
853
854 ```php
855 add_filter( 'mwai_chatbot_blocks', function ( $blocks, $args ) {
856 // Show block when specific keywords are detected
857 $message = $args['newMessage'] ?? '';
858 $reply = $args['reply'] ?? '';
859
860 // Show appointment form when appointment is mentioned
861 if (stripos($message . $reply, 'appointment') !== false) {
862 $blocks[] = [
863 'type' => 'content',
864 'data' => [
865 'html' => '
866 <div class="appointment-block">
867 <h4>Book an Appointment</h4>
868 <form id="appointmentForm">
869 <label>Select Date:</label>
870 <input type="date" id="apptDate" required><br><br>
871
872 <label>Select Time:</label>
873 <select id="apptTime" required>
874 <option value="9:00">9:00 AM</option>
875 <option value="10:00">10:00 AM</option>
876 <option value="14:00">2:00 PM</option>
877 <option value="15:00">3:00 PM</option>
878 </select><br><br>
879
880 <label>Your Name:</label>
881 <input type="text" id="apptName" required><br><br>
882
883 <button type="submit">Book Now</button>
884 </form>
885 </div>
886 ',
887 'script' => '
888 const chatbot = MwaiAPI.getChatbot("' . $args['botId'] . '");
889 chatbot.lock();
890
891 document.getElementById("appointmentForm").addEventListener("submit", function(e) {
892 e.preventDefault();
893
894 const date = document.getElementById("apptDate").value;
895 const time = document.getElementById("apptTime").value;
896 const name = document.getElementById("apptName").value;
897
898 // Send appointment details
899 chatbot.ask(`Book appointment for ${name} on ${date} at ${time}`, true);
900
901 // Show confirmation
902 chatbot.setBlocks([{
903 type: "content",
904 data: {
905 html: "<div style=\"color: green; padding: 10px;\">�
906 Appointment request sent!</div>"
907 }
908 }]);
909
910 chatbot.unlock();
911
912 // Clear confirmation after 3 seconds
913 setTimeout(() => chatbot.setBlocks([]), 3000);
914 });
915 '
916 ]
917 ];
918 }
919
920 return $blocks;
921 }, 10, 2);
922 ```
923
924 ### Product Showcase Block
925
926 ```php
927 add_filter( 'mwai_chatbot_blocks', function ( $blocks, $args ) {
928 // Show products when requested
929 if (stripos($args['reply'], 'here are our products') !== false) {
930 $products = wc_get_products(['limit' => 3, 'status' => 'publish']);
931
932 $html = '<div class="products-showcase">';
933 $html .= '<h4>Featured Products</h4>';
934 $html .= '<div style="display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px;">';
935
936 foreach ($products as $product) {
937 $html .= sprintf(
938 '<div style="border: 1px solid #ddd; padding: 10px; text-align: center;">
939 <img src="%s" style="width: 100%%; height: 100px; object-fit: cover;">
940 <h5>%s</h5>
941 <p>%s</p>
942 <button onclick="MwaiAPI.getChatbot(\'%s\').ask(\'Tell me more about %s\', true)">Learn More</button>
943 </div>',
944 wp_get_attachment_url($product->get_image_id()),
945 esc_html($product->get_name()),
946 wc_price($product->get_price()),
947 $args['botId'],
948 esc_html($product->get_name())
949 );
950 }
951
952 $html .= '</div></div>';
953
954 $blocks[] = [
955 'type' => 'content',
956 'data' => ['html' => $html]
957 ];
958 }
959
960 return $blocks;
961 }, 10, 2);
962 ```
963
964 ### Data Collection Wizard
965
966 ```php
967 add_filter( 'mwai_chatbot_blocks', function ( $blocks, $args ) {
968 // Multi-step form wizard
969 if (stripos($args['newMessage'], 'start wizard') !== false) {
970 $blocks[] = [
971 'type' => 'content',
972 'data' => [
973 'html' => '
974 <div id="wizard" data-step="1">
975 <div class="step" id="step1">
976 <h4>Step 1: Your Information</h4>
977 <input type="text" id="userName" placeholder="Your name">
978 <button onclick="nextStep()">Next</button>
979 </div>
980
981 <div class="step" id="step2" style="display:none;">
982 <h4>Step 2: Your Interest</h4>
983 <select id="interest">
984 <option>Product Information</option>
985 <option>Technical Support</option>
986 <option>Pricing</option>
987 </select>
988 <button onclick="prevStep()">Back</button>
989 <button onclick="nextStep()">Next</button>
990 </div>
991
992 <div class="step" id="step3" style="display:none;">
993 <h4>Step 3: Summary</h4>
994 <div id="summary"></div>
995 <button onclick="prevStep()">Back</button>
996 <button onclick="submitWizard()">Submit</button>
997 </div>
998 </div>
999 ',
1000 'script' => '
1001 const chatbot = MwaiAPI.getChatbot("' . $args['botId'] . '");
1002 chatbot.lock();
1003
1004 window.nextStep = function() {
1005 const wizard = document.getElementById("wizard");
1006 const currentStep = parseInt(wizard.dataset.step);
1007
1008 // Hide current step
1009 document.getElementById("step" + currentStep).style.display = "none";
1010
1011 // Show next step
1012 const nextStep = currentStep + 1;
1013 document.getElementById("step" + nextStep).style.display = "block";
1014 wizard.dataset.step = nextStep;
1015
1016 // Update summary on last step
1017 if (nextStep === 3) {
1018 const name = document.getElementById("userName").value;
1019 const interest = document.getElementById("interest").value;
1020 document.getElementById("summary").innerHTML =
1021 `<p>Name: ${name}</p><p>Interest: ${interest}</p>`;
1022 }
1023 };
1024
1025 window.prevStep = function() {
1026 const wizard = document.getElementById("wizard");
1027 const currentStep = parseInt(wizard.dataset.step);
1028 document.getElementById("step" + currentStep).style.display = "none";
1029 const prevStep = currentStep - 1;
1030 document.getElementById("step" + prevStep).style.display = "block";
1031 wizard.dataset.step = prevStep;
1032 };
1033
1034 window.submitWizard = function() {
1035 const name = document.getElementById("userName").value;
1036 const interest = document.getElementById("interest").value;
1037
1038 chatbot.ask(`Wizard completed. Name: ${name}, Interest: ${interest}`, true);
1039 chatbot.setBlocks([]);
1040 chatbot.unlock();
1041 };
1042 '
1043 ]
1044 ];
1045 }
1046
1047 return $blocks;
1048 }, 10, 2);
1049 ```
1050
1051 ## Block Best Practices
1052
1053 1. **Always unlock the chatbot** when done with user interaction
1054 2. **Clean up blocks** after they're no longer needed
1055 3. **Use unique IDs** for form elements to avoid conflicts
1056 4. **Test across devices** - ensure blocks work on mobile
1057 5. **Provide fallbacks** for users who might have JavaScript disabled
1058 6. **Keep scripts focused** - each block should have a single purpose
1059
1060 ---
1061
1062 # MCP (Model Context Protocol)
1063
1064 The Model Context Protocol (MCP) enables AI agents like Claude to interact with WordPress sites through a standardized tool interface. AI Engine provides a comprehensive MCP implementation that allows developers to extend WordPress functionality accessible to AI.
1065
1066 ## Overview
1067
1068 MCP is a protocol that allows AI models to use tools (functions) to interact with external systems. In AI Engine, this means Claude can manage WordPress content, upload media, analyze images, and perform custom operations defined by developers.
1069
1070 ## Adding Custom MCP Functions
1071
1072 ### Basic Example
1073
1074 ```php
1075 // 1. Register your tool
1076 add_filter( 'mwai_mcp_tools', function( $tools ) {
1077 $tools[] = [
1078 'name' => 'get_weather',
1079 'description' => 'Get current weather for a city. Returns temperature and conditions.',
1080 'inputSchema' => [
1081 'type' => 'object',
1082 'properties' => [
1083 'city' => [
1084 'type' => 'string',
1085 'description' => 'City name (e.g., "New York", "London")'
1086 ],
1087 'units' => [
1088 'type' => 'string',
1089 'enum' => ['celsius', 'fahrenheit'],
1090 'default' => 'celsius',
1091 'description' => 'Temperature units'
1092 ]
1093 ],
1094 'required' => ['city']
1095 ]
1096 ];
1097 return $tools;
1098 });
1099
1100 // 2. Handle execution
1101 add_filter( 'mwai_mcp_callback', function( $result, $tool, $args, $id ) {
1102 if ( $tool !== 'get_weather' ) {
1103 return $result;
1104 }
1105
1106 // Your logic here
1107 $city = $args['city'];
1108 $units = $args['units'] ?? 'celsius';
1109
1110 // Simulated weather data
1111 $weather = [
1112 'city' => $city,
1113 'temperature' => rand(15, 30),
1114 'units' => $units,
1115 'conditions' => 'Partly cloudy'
1116 ];
1117
1118 return $weather; // AI Engine handles JSON-RPC wrapping
1119 }, 10, 4 );
1120 ```
1121
1122 ### WordPress Integration Example
1123
1124 ```php
1125 // Register a tool for custom post type management
1126 add_filter( 'mwai_mcp_tools', function( $tools ) {
1127 $tools[] = [
1128 'name' => 'manage_products',
1129 'description' => 'Create, update, or search WooCommerce products. Can handle inventory, pricing, and product details.',
1130 'inputSchema' => [
1131 'type' => 'object',
1132 'properties' => [
1133 'action' => [
1134 'type' => 'string',
1135 'enum' => ['create', 'update', 'search'],
1136 'description' => 'Action to perform'
1137 ],
1138 'title' => [
1139 'type' => 'string',
1140 'description' => 'Product title (for create/update)'
1141 ],
1142 'price' => [
1143 'type' => 'number',
1144 'description' => 'Product price'
1145 ],
1146 'sku' => [
1147 'type' => 'string',
1148 'description' => 'Product SKU'
1149 ],
1150 'stock' => [
1151 'type' => 'integer',
1152 'description' => 'Stock quantity'
1153 ],
1154 'search_term' => [
1155 'type' => 'string',
1156 'description' => 'Search term (for search action)'
1157 ],
1158 'product_id' => [
1159 'type' => 'integer',
1160 'description' => 'Product ID (for update action)'
1161 ]
1162 ],
1163 'required' => ['action']
1164 ]
1165 ];
1166 return $tools;
1167 });
1168
1169 add_filter( 'mwai_mcp_callback', function( $result, $tool, $args, $id ) {
1170 if ( $tool !== 'manage_products' ) return $result;
1171
1172 switch ( $args['action'] ) {
1173 case 'create':
1174 $product = new WC_Product_Simple();
1175 $product->set_name( $args['title'] );
1176 $product->set_regular_price( $args['price'] );
1177 if ( isset($args['sku']) ) $product->set_sku( $args['sku'] );
1178 if ( isset($args['stock']) ) {
1179 $product->set_manage_stock( true );
1180 $product->set_stock_quantity( $args['stock'] );
1181 }
1182 $product->save();
1183
1184 return [
1185 'success' => true,
1186 'product_id' => $product->get_id(),
1187 'message' => "Product '{$args['title']}' created successfully"
1188 ];
1189
1190 case 'search':
1191 $products = wc_get_products([
1192 's' => $args['search_term'],
1193 'limit' => 10
1194 ]);
1195
1196 return array_map( function($p) {
1197 return [
1198 'id' => $p->get_id(),
1199 'title' => $p->get_name(),
1200 'price' => $p->get_price(),
1201 'stock' => $p->get_stock_quantity()
1202 ];
1203 }, $products );
1204
1205 case 'update':
1206 // Update logic here
1207 break;
1208 }
1209 }, 10, 4 );
1210 ```
1211
1212 ## Best Practices for Tool Descriptions
1213
1214 **EXTREMELY IMPORTANT**: Write clear, detailed descriptions that help AI understand exactly what your tool does and when to use it.
1215
1216 ### Good Description Examples
1217
1218 ```php
1219 // �
1220 GOOD - Clear, specific, and actionable
1221 'description' => 'Search and filter WooCommerce products by name, SKU, or category. Returns product details including price, stock, and variations.'
1222
1223 // �
1224 GOOD - Explains capabilities and use cases
1225 'description' => 'Analyze website performance metrics including page load times, database queries, and memory usage. Useful for debugging slow pages.'
1226
1227 // ❌ BAD - Too vague
1228 'description' => 'Handle products'
1229
1230 // ❌ BAD - No context about what it returns
1231 'description' => 'Get data from API'
1232 ```
1233
1234 ### Parameter Descriptions
1235
1236 Always describe parameters clearly:
1237
1238 ```php
1239 'properties' => [
1240 'post_id' => [
1241 'type' => 'integer',
1242 'description' => 'WordPress post ID. Use 0 to get the current post.'
1243 ],
1244 'meta_key' => [
1245 'type' => 'string',
1246 'description' => 'Custom field name (e.g., "_price", "custom_color")'
1247 ],
1248 'format' => [
1249 'type' => 'string',
1250 'enum' => ['raw', 'formatted'],
1251 'default' => 'formatted',
1252 'description' => 'Output format. "raw" returns database value, "formatted" applies WordPress filters.'
1253 ]
1254 ]
1255 ```
1256
1257 ## Error Handling
1258
1259 ```php
1260 add_filter( 'mwai_mcp_callback', function( $result, $tool, $args, $id ) {
1261 if ( $tool !== 'your_tool' ) return $result;
1262
1263 try {
1264 // Validate inputs
1265 if ( empty($args['required_param']) ) {
1266 throw new Exception('Missing required parameter: required_param');
1267 }
1268
1269 // Check permissions
1270 if ( !current_user_can('edit_posts') ) {
1271 throw new Exception('Insufficient permissions to perform this action');
1272 }
1273
1274 // Your logic here
1275 $data = process_something($args);
1276
1277 if ( !$data ) {
1278 throw new Exception('Failed to process request: No data returned');
1279 }
1280
1281 return $data;
1282
1283 } catch ( Exception $e ) {
1284 // Exception message will be properly formatted as JSON-RPC error
1285 throw $e;
1286 }
1287 }, 10, 4 );
1288 ```
1289
1290 ## Built-in Tools Reference
1291
1292 AI Engine includes 40+ built-in tools. Key categories:
1293
1294 - **Posts**: create_post, read_post, update_post, delete_post, search_posts
1295 - **Media**: upload_media, get_media_url, delete_attachment
1296 - **Users**: create_user, update_user, get_current_user
1297 - **Options**: get_option, update_option
1298 - **AI Features**: vision (image analysis), imagine (image generation)
1299
1300 See implementation examples in:
1301 - `labs/mcp-core.php` - Core WordPress tools
1302 - `labs/mcp-rest.php` - REST API integration
1303 - `premium/mcp_plugin.php` - Plugin management
1304 - `premium/mcp_theme.php` - Theme management
1305
1306 ## Testing Your MCP Tools
1307
1308 1. **Enable MCP** in AI Engine settings
1309 2. **Get your Bearer token** from the MCP section
1310 3. **Add to Claude**: Use the MCP server URL with your token
1311 4. **Test with Claude**: Ask Claude to use your custom tool
1312
1313 Example Claude prompt:
1314 ```
1315 "Can you search for products with 'laptop' in the name and show me their prices?"
1316 ```
1317
1318 ## Advanced Features
1319
1320 ### Conditional Tool Registration
1321
1322 ```php
1323 add_filter( 'mwai_mcp_tools', function( $tools ) {
1324 // Only add tool if WooCommerce is active
1325 if ( class_exists('WooCommerce') ) {
1326 $tools[] = [
1327 'name' => 'woo_reports',
1328 'description' => 'Generate WooCommerce sales reports',
1329 // ... rest of tool definition
1330 ];
1331 }
1332
1333 // Add tool based on user capabilities
1334 if ( current_user_can('manage_options') ) {
1335 $tools[] = [
1336 'name' => 'admin_tasks',
1337 'description' => 'Perform administrative tasks',
1338 // ... rest of tool definition
1339 ];
1340 }
1341
1342 return $tools;
1343 });
1344 ```
1345
1346 ### Complex Return Values
1347
1348 ```php
1349 // Return structured data - AI Engine handles JSON encoding
1350 return [
1351 'status' => 'success',
1352 'data' => [
1353 'total' => 42,
1354 'items' => $items,
1355 'metadata' => [
1356 'generated_at' => current_time('mysql'),
1357 'cache_hit' => false
1358 ]
1359 ],
1360 'messages' => [
1361 'Found 42 matching items',
1362 'Results limited to first 20'
1363 ]
1364 ];
1365 ```
1366
1367 ### Access Control
1368
1369 ```php
1370 // Control MCP access
1371 add_filter( 'mwai_allow_mcp', function( $allow, $user_id ) {
1372 // Only allow specific users
1373 $allowed_users = [1, 42, 99];
1374 return in_array($user_id, $allowed_users);
1375 }, 10, 2 );
1376 ```
1377
1378 ## Tips for Success
1379
1380 1. **Start Simple**: Begin with read-only tools before adding write operations
1381 2. **Test Thoroughly**: Ensure your tools handle edge cases and invalid inputs
1382 3. **Document Well**: Good descriptions save time and improve AI accuracy
1383 4. **Security First**: Always validate inputs and check permissions
1384 5. **Return Useful Data**: Structure responses for easy AI interpretation
1385
1386 Remember: The MCP system automatically handles JSON-RPC protocol details, so focus on your business logic and return clean, structured data.
1387
1388 ---
1389
1390 # Discussion Context Menu
1391
1392 You can customize the context menu that appears when clicking the three-dot icon on discussions. The menu supports regular items, separators, and custom HTML content.
1393
1394 ## Menu Item Structure
1395
1396 Each menu item can have the following properties:
1397
1398 - `id`: Unique identifier for the item (required for regular items)
1399 - `type`: Item type - 'separator' or 'title' (optional, defaults to regular item)
1400 - `label`: Text to display (for regular items and titles)
1401 - `onClick`: Function called when item is clicked, receives the discussion object
1402 - `className`: CSS class names (defaults to 'mwai-menu-item')
1403 - `style`: Inline styles object (optional)
1404 - `html`: Custom HTML content (overrides label)
1405
1406 ## Examples
1407
1408 ### Add Custom Actions
1409
1410 ```javascript
1411 // Add a simple alert action
1412 MwaiAPI.addFilter('mwai_discussion_menu_items', (items, discussion) => {
1413 items.push({
1414 id: 'alert',
1415 label: 'Show Info',
1416 onClick: (discussion) => {
1417 alert(`Discussion ID: ${discussion.chatId}\nMessages: ${discussion.messages.length}`);
1418 }
1419 });
1420 return items;
1421 });
1422
1423
1424 // Add multiple items with separator
1425 MwaiAPI.addFilter('mwai_discussion_menu_items', (items, discussion) => {
1426 // Add separator before custom items
1427 items.push({ type: 'separator' });
1428
1429 // Add title
1430 items.push({
1431 type: 'title',
1432 label: 'Custom Actions'
1433 });
1434
1435 // Add export action
1436 items.push({
1437 id: 'export',
1438 label: 'Export JSON',
1439 onClick: (discussion) => {
1440 const json = JSON.stringify(discussion, null, 2);
1441 const blob = new Blob([json], { type: 'application/json' });
1442 const url = URL.createObjectURL(blob);
1443 const a = document.createElement('a');
1444 a.href = url;
1445 a.download = `discussion-${discussion.chatId}.json`;
1446 a.click();
1447 }
1448 });
1449
1450 // Add copy ID action
1451 items.push({
1452 id: 'copy-id',
1453 label: 'Copy Chat ID',
1454 onClick: (discussion) => {
1455 navigator.clipboard.writeText(discussion.chatId);
1456 alert('Chat ID copied to clipboard!');
1457 }
1458 });
1459
1460 return items;
1461 });
1462
1463 // Add item with custom HTML and styling
1464 MwaiAPI.addFilter('mwai_discussion_menu_items', (items, discussion) => {
1465 items.push({
1466 id: 'custom-html',
1467 html: `<div style="display: flex; align-items: center; gap: 8px;">
1468 <span style="font-size: 16px;">📊</span>
1469 <span>Stats: ${discussion.messages.length} msgs</span>
1470 </div>`,
1471 onClick: (discussion) => {
1472 console.log('Custom item clicked', discussion);
1473 }
1474 });
1475 return items;
1476 });
1477
1478 // Reorder or remove default items
1479 MwaiAPI.addFilter('mwai_discussion_menu_items', (items, discussion) => {
1480 // Move delete to top
1481 const deleteItem = items.find(item => item.id === 'delete');
1482 const otherItems = items.filter(item => item.id !== 'delete');
1483 return [deleteItem, ...otherItems];
1484 });
1485
1486 // Conditionally show items based on discussion
1487 MwaiAPI.addFilter('mwai_discussion_menu_items', (items, discussion) => {
1488 // Only show archive option for discussions with more than 10 messages
1489 if (discussion.messages.length > 10) {
1490 items.push({
1491 id: 'archive',
1492 label: 'Archive',
1493 className: 'mwai-menu-item',
1494 style: { color: '#0066cc' },
1495 onClick: (discussion) => {
1496 console.log('Archiving discussion:', discussion.chatId);
1497 // Your archive logic here
1498 }
1499 });
1500 }
1501 return items;
1502 });
1503 ```
1504
1505 ### Complete Example with All Features
1506
1507 ```javascript
1508 // Comprehensive context menu customization
1509 MwaiAPI.addFilter('mwai_discussion_menu_items', (items, discussion) => {
1510 // Keep default items
1511 const newItems = [...items];
1512
1513 // Add separator
1514 newItems.push({ type: 'separator' });
1515
1516 // Add section title
1517 newItems.push({
1518 type: 'title',
1519 label: 'Developer Tools'
1520 });
1521
1522 // Add debug info item
1523 newItems.push({
1524 id: 'debug',
1525 label: 'Debug Info',
1526 onClick: (discussion) => {
1527 console.log('Discussion Object:', discussion);
1528 alert(`Chat ID: ${discussion.chatId}\nTitle: ${discussion.title || 'Untitled'}\nMessages: ${discussion.messages.length}`);
1529 }
1530 });
1531
1532 // Add item with custom icon (using emoji as HTML)
1533 newItems.push({
1534 id: 'favorite',
1535 html: '<span>⭐ Add to Favorites</span>',
1536 onClick: (discussion) => {
1537 // Your favorite logic here
1538 console.log('Added to favorites:', discussion.chatId);
1539 }
1540 });
1541
1542 return newItems;
1543 }, 20); // Higher priority to run after other filters
1544 ```