PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 3.4.9
AI Engine – The Chatbot, AI Framework & MCP for WordPress v3.4.9
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 / classes / modules / tasks-examples.php
ai-engine / classes / modules Last commit date
advisor.php 3 months ago chatbot.php 2 months ago discussions.php 2 months ago editor-assistant.php 3 months ago files.php 3 months ago forms-manager.php 3 months ago gdpr.php 4 months ago search.php 3 months ago security.php 1 year ago tasks-examples.php 6 months ago tasks.php 1 month ago wand.php 3 months ago
tasks-examples.php
413 lines
1 <?php
2
3 /**
4 * AI Engine Tasks Examples
5 *
6 * This class demonstrates how to use the AI Engine Tasks system programmatically.
7 * It includes examples of:
8 * - Simple recurring tasks (Ping Example)
9 * - Multi-step tasks (Chatbot Test)
10 * - Task data persistence across runs
11 * - Error handling and retry logic
12 *
13 * TUTORIAL: How to Create Your Own Tasks
14 *
15 * 1. Register your task handler:
16 * add_filter( 'mwai_task_your_task_name', [ $this, 'your_handler' ], 10, 2 );
17 *
18 * 2. Create or ensure your task exists:
19 * $this->core->tasks->ensure( [
20 * 'name' => 'your_task_name',
21 * 'description' => 'What your task does.',
22 * 'schedule' => '0 2 * * *', // Cron expression or 'once'
23 * 'next_run' => '2024-12-25 14:00:00', // Optional: specific time for one-time tasks
24 * ] );
25 *
26 * 3. Implement your handler:
27 * public function your_handler( $result, $job ) {
28 * // $job contains: task_name, task_id, data (persistent), step, step_name
29 * // Return: [ 'ok' => true/false, 'message' => 'Status', 'data' => [] ]
30 * }
31 *
32 * 4. For multi-step tasks:
33 * - Return 'step' => N to move to next step
34 * - Return 'done' => true when complete
35 * - Data persists across steps automatically
36 */
37 class Meow_MWAI_Modules_Tasks_Examples {
38 private $core;
39 private $tasks;
40
41 public function __construct( $core ) {
42 $this->core = $core;
43 // Don't set $this->tasks here as $core->tasks might not be initialized yet
44
45 // Always register the test task handlers and REST endpoint
46 // These are needed for the test task feature which is now available to all users
47 add_filter( 'mwai_task_run', [ $this, 'handle_dynamic_tasks' ], 10, 2 );
48 add_action( 'rest_api_init', [ $this, 'register_rest_routes' ] );
49
50 // Only initialize example tasks if Dev Mode is enabled
51 if ( $this->core->get_option( 'dev_mode' ) ) {
52 // Simple recurring task example
53 add_action( 'init', [ $this, 'ensure_ping_task' ], 20 );
54 add_filter( 'mwai_task_ping_example', [ $this, 'run_ping_task' ], 10, 2 );
55 }
56 }
57
58 /**
59 * Ensure the Ping Task exists when Dev Mode is enabled
60 */
61 public function ensure_ping_task() {
62 if ( !$this->core->tasks ) {
63 return;
64 }
65
66 // Check if ping task already exists
67 $existing_task = $this->core->tasks->get_task( 'ping_example' );
68
69 if ( !$existing_task ) {
70 // Create the ping task with 5-minute schedule and 6-hour expiry
71 $task_data = [
72 'task_name' => 'ping_example',
73 'category' => 'test',
74 'schedule' => '*/5 * * * *', // Every 5 minutes
75 'next_run' => date( 'Y-m-d H:i:s', time() + 60 ), // Start in 1 minute (proper format)
76 'status' => 'pending', // Changed from 'active' to 'pending' so it can be executed
77 'description' => 'Example ping task that runs every 5 minutes (Dev Mode only).',
78 'expires_at' => date( 'Y-m-d H:i:s', time() + 6 * 3600 ), // Expires in 6 hours
79 'step' => 0,
80 'step_name' => null,
81 'step_data' => null,
82 'error_count' => 0,
83 'max_retries' => 3
84 ];
85
86 $this->core->tasks->create_task( $task_data );
87 } else {
88 // Update expiry if task exists but Dev Mode was re-enabled
89 $new_expiry = date( 'Y-m-d H:i:s', time() + 6 * 3600 );
90 if ( $existing_task->expires_at < $new_expiry ) {
91 $this->core->tasks->update_task( 'ping_example', [
92 'expires_at' => $new_expiry,
93 'status' => 'pending' // Changed from 'active' to 'pending'
94 ] );
95 }
96 }
97 }
98
99 /**
100 * Register REST routes for task examples
101 */
102 public function register_rest_routes() {
103 register_rest_route( 'mwai/v1', '/helpers/task_create_test', [
104 'methods' => 'POST',
105 'callback' => [ $this, 'rest_create_test_task' ],
106 'permission_callback' => [ $this->core, 'can_access_settings' ],
107 ] );
108 }
109
110 /**
111 * REST: Create a test task for chatbot testing
112 *
113 * This creates a multi-step task that:
114 * 1. Queries the specified chatbot with a question
115 * 2. Stores the response
116 * 3. Generates a summary using the default AI
117 */
118 public function rest_create_test_task( $request ) {
119 $chatbot_ids = $request->get_param( 'chatbot_ids' );
120 $question = $request->get_param( 'question' );
121
122 if ( !$chatbot_ids || empty( $chatbot_ids ) || !$question ) {
123 return new WP_REST_Response( [
124 'success' => false,
125 'message' => 'Chatbot IDs and question are required'
126 ], 400 );
127 }
128
129 // Create a unique task name
130 $task_name = 'chatbot_test_' . uniqid();
131
132 // Schedule for 1 minute from now
133 $next_run = gmdate( 'Y-m-d H:i:s', time() + 60 );
134
135 // Create the task
136 $chatbot_count = count( $chatbot_ids );
137 $created = $this->core->tasks->create_task( [
138 'task_name' => $task_name,
139 'description' => "Test {$chatbot_count} chatbots: " . substr( $question, 0, 40 ) . '...',
140 'category' => 'test',
141 'schedule' => 'once',
142 'next_run' => $next_run,
143 'expires_at' => gmdate( 'Y-m-d H:i:s', time() + 3600 ), // Expire after 1 hour
144 'is_multistep' => 1,
145 'step' => 0,
146 'step_name' => 'Initializing',
147 'data' => [
148 'chatbot_ids' => $chatbot_ids,
149 'current_chatbot_index' => 0,
150 'question' => $question,
151 'responses' => [],
152 'created_at' => gmdate( 'Y-m-d H:i:s' ),
153 ],
154 ] );
155
156 if ( !$created ) {
157 return new WP_REST_Response( [
158 'success' => false,
159 'message' => 'Failed to create test task'
160 ], 500 );
161 }
162
163 return new WP_REST_Response( [
164 'success' => true,
165 'message' => 'Test task created successfully',
166 'task_name' => $task_name,
167 'next_run' => $next_run
168 ] );
169 }
170
171 /**
172 * Handle dynamic tasks (like chatbot_test_*)
173 */
174 public function handle_dynamic_tasks( $result, $job ) {
175 // Check if this is a chatbot test task
176 // Note: The job array uses 'name' not 'task_name'
177 if ( strpos( $job['name'], 'chatbot_test_' ) === 0 ) {
178 return $this->run_chatbot_test( $result, $job );
179 }
180
181 // Return null to let other handlers process
182 return $result;
183 }
184
185 /**
186 * Execute the multi-step chatbot test task
187 *
188 * Step 0: Initialize and prepare
189 * Step 1-N: Query each chatbot (one step per chatbot)
190 * Final Step: Generate comparison summary
191 */
192 public function run_chatbot_test( $result, $job ) {
193 $data = $job['data'];
194 $step = $job['step'];
195
196 try {
197 $chatbot_ids = $data['chatbot_ids'];
198 $chatbot_count = count( $chatbot_ids );
199
200 if ( $step == 0 ) {
201 // Step 0: Initialize
202 return [
203 'ok' => true,
204 'done' => false, // Important: Not done yet!
205 'message' => "Starting test of {$chatbot_count} chatbots",
206 'step' => 1,
207 'step_name' => 'Querying chatbot 1 of ' . $chatbot_count,
208 'data' => $data
209 ];
210 }
211 else if ( $step <= $chatbot_count ) {
212 // Steps 1-N: Query each chatbot
213 $chatbot_index = $step - 1;
214 $chatbot_id = $chatbot_ids[$chatbot_index];
215 $question = $data['question'];
216
217 // Use the Simple API to query the chatbot
218 // This handles all the chatbot configuration and environment setup automatically
219 try {
220 // Use the global $mwai object
221 global $mwai;
222
223 // Use simpleChatbotQuery which handles everything for us
224 // Parameters: $botId, $message, $params = [], $onlyReply = true
225 $response = $mwai->simpleChatbotQuery( $chatbot_id, $question, [], true );
226
227 // Get chatbot name for display
228 $chatbots = get_option( 'mwai_chatbots', [] );
229 $chatbot_name = 'Chatbot ' . $chatbot_id;
230 foreach ( $chatbots as $bot ) {
231 $bot_id = isset( $bot['botId'] ) ? $bot['botId'] : ( isset( $bot['id'] ) ? $bot['id'] : null );
232 if ( $bot_id === $chatbot_id && isset( $bot['name'] ) ) {
233 $chatbot_name = $bot['name'];
234 break;
235 }
236 }
237
238 // Store the response
239 $data['responses'][] = [
240 'chatbot_id' => $chatbot_id,
241 'chatbot_name' => $chatbot_name,
242 'question' => $question,
243 'response' => $response,
244 'timestamp' => gmdate( 'Y-m-d H:i:s' ),
245 'tokens_used' => 0, // Token usage not available with simple API
246 ];
247 } catch ( Exception $e ) {
248 // If this chatbot fails, log the error but continue with others
249 $data['responses'][] = [
250 'chatbot_id' => $chatbot_id,
251 'chatbot_name' => 'Chatbot ' . $chatbot_id,
252 'question' => $question,
253 'response' => 'Error: ' . $e->getMessage(),
254 'timestamp' => gmdate( 'Y-m-d H:i:s' ),
255 'tokens_used' => 0,
256 ];
257 }
258
259 // Move to next chatbot or summary
260 $next_step = $step + 1;
261 if ( $next_step <= $chatbot_count ) {
262 // More chatbots to test
263 return [
264 'ok' => true,
265 'done' => false, // Important: Not done yet!
266 'message' => "Chatbot {$step} of {$chatbot_count} queried",
267 'step' => $next_step,
268 'step_name' => "Querying chatbot {$next_step} of {$chatbot_count}",
269 'data' => $data
270 ];
271 } else {
272 // All chatbots tested, move to summary
273 return [
274 'ok' => true,
275 'done' => false, // Important: Not done yet!
276 'message' => 'All chatbots queried',
277 'step' => $next_step,
278 'step_name' => 'Generating comparison summary',
279 'data' => $data
280 ];
281 }
282 }
283 else if ( $step == $chatbot_count + 1 ) {
284 // Final Step: Generate comparison summary
285 $responses = $data['responses'];
286
287 // Build summary prompt
288 $summary_prompt = "Compare and analyze these chatbot responses to the same question:\n\n";
289 $summary_prompt .= "Question asked: {$responses[0]['question']}\n\n";
290
291 foreach ( $responses as $index => $resp ) {
292 $num = $index + 1;
293 $summary_prompt .= "Chatbot {$num} ({$resp['chatbot_name']}):\n";
294 $summary_prompt .= "{$resp['response']}\n\n";
295 }
296
297 $summary_prompt .= "Provide a brief comparison (3-4 sentences) analyzing:\n";
298 $summary_prompt .= "1. Response quality and accuracy\n";
299 $summary_prompt .= "2. Tone and style differences\n";
300 $summary_prompt .= "3. Which chatbot(s) provided the best response and why";
301
302 // Generate summary using default AI
303 $summary_query = new Meow_MWAI_Query_Text( $summary_prompt );
304 $summary_reply = $this->core->run_query( $summary_query );
305
306 $data['summary'] = [
307 'analysis' => $summary_reply->result,
308 'generated_at' => gmdate( 'Y-m-d H:i:s' ),
309 ];
310
311 return [
312 'ok' => true,
313 'message' => 'Test completed successfully',
314 'done' => true,
315 'data' => $data
316 ];
317 }
318 else {
319 return [
320 'ok' => false,
321 'message' => 'Unknown step: ' . $step
322 ];
323 }
324 } catch ( Exception $e ) {
325 return [
326 'ok' => false,
327 'message' => 'Test failed: ' . $e->getMessage()
328 ];
329 }
330 }
331
332 /**
333 * Execute the ping task
334 *
335 * This is a simple example of a recurring task that:
336 * - Pings a host (google.com)
337 * - Tracks response times
338 * - Maintains history across runs
339 */
340 public function run_ping_task( $result, $job ) {
341 // Get current data (persisted across runs)
342 $data = isset( $job['data'] ) ? $job['data'] : [];
343
344 // Initialize or increment run count
345 $run_count = isset( $data['run_count'] ) ? $data['run_count'] + 1 : 1;
346
347 // Track last 5 ping results
348 $ping_history = isset( $data['ping_history'] ) ? $data['ping_history'] : [];
349
350 // Perform actual ping to google.com
351 $host = 'google.com';
352 $start_time = microtime( true );
353
354 // Use wp_remote_get with a short timeout to simulate a ping
355 $response = wp_remote_get( "https://{$host}", [
356 'timeout' => 5,
357 'redirection' => 0,
358 'sslverify' => MWAI_SSL_VERIFY,
359 ] );
360
361 $end_time = microtime( true );
362 $response_time = round( ( $end_time - $start_time ) * 1000, 2 ); // Convert to ms
363
364 $ping_result = [
365 'timestamp' => date( 'Y-m-d H:i:s' ),
366 'host' => $host,
367 'response_time_ms' => $response_time,
368 'status' => is_wp_error( $response ) ? 'failed' : 'success',
369 ];
370
371 if ( is_wp_error( $response ) ) {
372 $ping_result['error'] = $response->get_error_message();
373 } else {
374 $ping_result['http_code'] = wp_remote_retrieve_response_code( $response );
375 }
376
377 // Add to history (keep last 5)
378 $ping_history[] = $ping_result;
379 if ( count( $ping_history ) > 5 ) {
380 array_shift( $ping_history );
381 }
382
383 // Calculate average response time
384 $total_time = 0;
385 $success_count = 0;
386 foreach ( $ping_history as $ping ) {
387 if ( $ping['status'] === 'success' ) {
388 $total_time += $ping['response_time_ms'];
389 $success_count++;
390 }
391 }
392 $avg_response_time = $success_count > 0 ? round( $total_time / $success_count, 2 ) : 0;
393
394 $message = "Ping #{$run_count} to {$host}: {$response_time}ms";
395
396 // Log to PHP error log if server debug is enabled
397 if ( $this->core->get_option( 'server_debug_mode' ) ) {
398 error_log( "[AI Engine] Ping Task: {$message}" );
399 }
400
401 // Return success result with updated data
402 return [
403 'ok' => !is_wp_error( $response ),
404 'message' => $message,
405 'data' => [
406 'run_count' => $run_count,
407 'ping_history' => $ping_history,
408 'avg_response_time_ms' => $avg_response_time,
409 'last_ping' => $ping_result,
410 ]
411 ];
412 }
413 }