PluginProbe ʕ •ᴥ•ʔ
AI Engine – The Chatbot, AI Framework & MCP for WordPress / 1.8.9
AI Engine – The Chatbot, AI Framework & MCP for WordPress v1.8.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 / rest.php
ai-engine / classes Last commit date
engines 2 years ago modules 3 years ago queries 2 years ago admin.php 2 years ago api.php 2 years ago core.php 2 years ago init.php 3 years ago reply.php 2 years ago rest.php 3 years ago
rest.php
916 lines
1 <?php
2
3 class Meow_MWAI_Rest
4 {
5 private $core = null;
6 private $namespace = 'mwai/v1';
7
8 public function __construct( $core ) {
9 $this->core = $core;
10 add_action( 'rest_api_init', array( $this, 'rest_init' ) );
11 }
12
13 function rest_init() {
14 try {
15 // Settings Endpoints
16 register_rest_route( $this->namespace, '/settings/update', array(
17 'methods' => 'POST',
18 'permission_callback' => array( $this->core, 'can_access_settings' ),
19 'callback' => array( $this, 'rest_settings_update' )
20 ) );
21 register_rest_route( $this->namespace, '/settings/list', array(
22 'methods' => 'GET',
23 'permission_callback' => array( $this->core, 'can_access_settings' ),
24 'callback' => array( $this, 'rest_settings_list' ),
25 ) );
26 register_rest_route( $this->namespace, '/settings/reset', array(
27 'methods' => 'POST',
28 'permission_callback' => array( $this->core, 'can_access_settings' ),
29 'callback' => array( $this, 'rest_settings_reset' ),
30 ) );
31 register_rest_route( $this->namespace, '/settings/chatbots', array(
32 'methods' => ['GET', 'POST'],
33 'permission_callback' => array( $this->core, 'can_access_settings' ),
34 'callback' => array( $this, 'rest_settings_chatbots' ),
35 ) );
36 register_rest_route( $this->namespace, '/settings/themes', array(
37 'methods' => ['GET', 'POST'],
38 'permission_callback' => array( $this->core, 'can_access_settings' ),
39 'callback' => array( $this, 'rest_settings_themes' ),
40 ) );
41
42 // System Endpoints
43 register_rest_route( $this->namespace, '/system/logs/list', array(
44 'methods' => 'POST',
45 'permission_callback' => array( $this->core, 'can_access_settings' ),
46 'callback' => array( $this, 'rest_system_logs_list' ),
47 ) );
48 register_rest_route( $this->namespace, '/system/logs/delete', array(
49 'methods' => 'POST',
50 'permission_callback' => array( $this->core, 'can_access_settings' ),
51 'callback' => array( $this, 'rest_system_logs_delete' ),
52 ) );
53 register_rest_route( $this->namespace, '/system/logs/meta', array(
54 'methods' => 'POST',
55 'permission_callback' => array( $this->core, 'can_access_settings' ),
56 'callback' => array( $this, 'rest_system_logs_meta_get' ),
57 ) );
58 register_rest_route( $this->namespace, '/system/templates', array(
59 'methods' => 'POST',
60 'permission_callback' => array( $this->core, 'can_access_features' ),
61 'callback' => array( $this, 'rest_system_templates_save' ),
62 ) );
63 register_rest_route( $this->namespace, '/system/templates', array(
64 'methods' => 'GET',
65 'permission_callback' => array( $this->core, 'can_access_features' ),
66 'callback' => array( $this, 'rest_system_templates_get' ),
67 ) );
68
69 // AI Endpoints
70 register_rest_route( $this->namespace, '/ai/completions', array(
71 'methods' => 'POST',
72 'permission_callback' => array( $this->core, 'can_access_features' ),
73 'callback' => array( $this, 'rest_ai_completions' ),
74 ) );
75 register_rest_route( $this->namespace, '/ai/images', array(
76 'methods' => 'POST',
77 'permission_callback' => array( $this->core, 'can_access_features' ),
78 'callback' => array( $this, 'rest_ai_images' ),
79 ) );
80 register_rest_route( $this->namespace, '/ai/copilot', array(
81 'methods' => 'POST',
82 'permission_callback' => array( $this->core, 'can_access_features' ),
83 'callback' => array( $this, 'rest_ai_copilot' ),
84 ) );
85
86 register_rest_route( $this->namespace, '/ai/magic_wand', array(
87 'methods' => 'POST',
88 'callback' => array( $this, 'rest_ai_magic_wand' ),
89 'permission_callback' => array( $this->core, 'can_access_features' ),
90 ) );
91 register_rest_route( $this->namespace, '/ai/moderate', array(
92 'methods' => 'POST',
93 'permission_callback' => array( $this->core, 'can_access_settings' ),
94 'callback' => array( $this, 'rest_ai_moderate' ),
95 ) );
96 register_rest_route( $this->namespace, '/ai/transcribe', array(
97 'methods' => 'POST',
98 'permission_callback' => array( $this->core, 'can_access_settings' ),
99 'callback' => array( $this, 'rest_ai_transcribe' ),
100 ) );
101
102 // Helpers Endpoints
103 register_rest_route( $this->namespace, '/helpers/update_post_title', array(
104 'methods' => 'POST',
105 'permission_callback' => array( $this->core, 'can_access_features' ),
106 'callback' => array( $this, 'rest_helpers_update_title' ),
107 ) );
108 register_rest_route( $this->namespace, '/helpers/update_post_excerpt', array(
109 'methods' => 'POST',
110 'permission_callback' => array( $this->core, 'can_access_features' ),
111 'callback' => array( $this, 'rest_helpers_update_excerpt' ),
112 ) );
113 register_rest_route( $this->namespace, '/helpers/create_post', array(
114 'methods' => 'POST',
115 'permission_callback' => array( $this->core, 'can_access_features' ),
116 'callback' => array( $this, 'rest_helpers_create_post' ),
117 ) );
118 register_rest_route( $this->namespace, '/helpers/create_image', array(
119 'methods' => 'POST',
120 'permission_callback' => array( $this->core, 'can_access_features' ),
121 'callback' => array( $this, 'rest_helpers_create_images' ),
122 ) );
123 register_rest_route( $this->namespace, '/helpers/count_posts', array(
124 'methods' => 'GET',
125 'permission_callback' => array( $this->core, 'can_access_features' ),
126 'callback' => array( $this, 'rest_helpers_count_posts' ),
127 ) );
128 register_rest_route( $this->namespace, '/helpers/post_types', array(
129 'methods' => 'GET',
130 'permission_callback' => array( $this->core, 'can_access_features' ),
131 'callback' => array( $this, 'rest_helpers_post_types' ),
132 ) );
133 register_rest_route( $this->namespace, '/helpers/post_content', array(
134 'methods' => 'GET',
135 'permission_callback' => array( $this->core, 'can_access_features' ),
136 'callback' => array( $this, 'rest_helpers_post_content' ),
137 ) );
138
139 // OpenAI Endpoints
140 register_rest_route( $this->namespace, '/openai/files/list', array(
141 'methods' => 'GET',
142 'permission_callback' => array( $this->core, 'can_access_settings' ),
143 'callback' => array( $this, 'rest_openai_files_get' ),
144 ) );
145 register_rest_route( $this->namespace, '/openai/files/upload', array(
146 'methods' => 'POST',
147 'permission_callback' => array( $this->core, 'can_access_settings' ),
148 'callback' => array( $this, 'rest_openai_files_upload' ),
149 ) );
150 register_rest_route( $this->namespace, '/openai/files/delete', array(
151 'methods' => 'POST',
152 'permission_callback' => array( $this->core, 'can_access_settings' ),
153 'callback' => array( $this, 'rest_openai_files_delete' ),
154 ) );
155 register_rest_route( $this->namespace, '/openai/files/download', array(
156 'methods' => 'POST',
157 'permission_callback' => array( $this->core, 'can_access_settings' ),
158 'callback' => array( $this, 'rest_openai_files_download' ),
159 ) );
160 register_rest_route( $this->namespace, '/openai/files/finetune', array(
161 'methods' => 'POST',
162 'permission_callback' => array( $this->core, 'can_access_settings' ),
163 'callback' => array( $this, 'rest_openai_files_finetune' ),
164 ) );
165 register_rest_route( $this->namespace, '/openai/finetunes/list_deleted', array(
166 'methods' => 'GET',
167 'permission_callback' => array( $this->core, 'can_access_settings' ),
168 'callback' => array( $this, 'rest_openai_deleted_finetunes_get' ),
169 ) );
170 register_rest_route( $this->namespace, '/openai/finetunes/list', array(
171 'methods' => 'GET',
172 'permission_callback' => array( $this->core, 'can_access_settings' ),
173 'callback' => array( $this, 'rest_openai_finetunes_get' ),
174 ) );
175 register_rest_route( $this->namespace, '/openai/finetunes/delete', array(
176 'methods' => 'POST',
177 'permission_callback' => array( $this->core, 'can_access_settings' ),
178 'callback' => array( $this, 'rest_openai_finetunes_delete' ),
179 ) );
180 register_rest_route( $this->namespace, '/openai/finetunes/cancel', array(
181 'methods' => 'POST',
182 'permission_callback' => array( $this->core, 'can_access_settings' ),
183 'callback' => array( $this, 'rest_openai_finetunes_cancel' ),
184 ) );
185 register_rest_route( $this->namespace, '/openai/incidents', array(
186 'methods' => 'GET',
187 'permission_callback' => array( $this->core, 'can_access_settings' ),
188 'callback' => array( $this, 'rest_openai_incidents' ),
189 ) );
190 }
191 catch ( Exception $e ) {
192 var_dump( $e );
193 }
194 }
195
196 function rest_settings_list() {
197 return new WP_REST_Response( [
198 'success' => true,
199 'options' => $this->core->get_all_options()
200 ], 200 );
201 }
202
203 function rest_settings_update( $request ) {
204 try {
205 $params = $request->get_json_params();
206 $value = $params['options'];
207 $options = $this->core->update_options( $value );
208 $success = !!$options;
209 $message = __( $success ? 'OK' : "Could not update options.", 'ai-engine' );
210 return new WP_REST_Response([ 'success' => $success, 'message' => $message, 'options' => $options ], 200 );
211 }
212 catch ( Exception $e ) {
213 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
214 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
215 }
216 }
217
218 function rest_settings_reset() {
219 try {
220 $options = $this->core->reset_options();
221 $success = !!$options;
222 $message = __( $success ? 'OK' : "Could not reset options.", 'ai-engine' );
223 return new WP_REST_Response([ 'success' => $success, 'message' => $message, 'options' => $options ], 200 );
224 }
225 catch ( Exception $e ) {
226 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
227 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
228 }
229 }
230
231 function createValidationResult( $result = true, $message = null) {
232 $message = $message ? $message : __( 'OK', 'ai-engine' );
233 return [ 'result' => $result, 'message' => $message ];
234 }
235
236 function validate_updated_option( $option_name ) {
237 $option_checkbox = get_option( 'mwai_option_checkbox', false );
238 $option_text = get_option( 'mwai_option_text', 'Default' );
239 if ( $option_checkbox === '' )
240 update_option( 'mwai_option_checkbox', false );
241 if ( $option_text === '' )
242 update_option( 'mwai_option_text', 'Default' );
243 return $this->createValidationResult();
244 }
245
246 function rest_ai_completions( $request ) {
247 try {
248 $params = $request->get_json_params();
249 $prompt = $params['prompt'];
250 $query = new Meow_MWAI_Query_Text( $prompt );
251 $query->injectParams( $params );
252
253 // Handle streaming
254 $stream = $params['stream'] ?? false;
255 $streamCallback = null;
256 if ( $stream ) {
257 $streamCallback = function( $reply ) {
258 //$raw = _wp_specialchars( $reply, ENT_NOQUOTES, 'UTF-8', true );
259 $raw = $reply;
260 $this->core->stream_push( [ 'type' => 'live', 'data' => $raw ] );
261 if ( ob_get_level() > 0 ) {
262 ob_flush();
263 }
264 flush();
265 };
266 header( 'Cache-Control: no-cache' );
267 header( 'Content-Type: text/event-stream' );
268 header( 'X-Accel-Buffering: no' ); // This is useful to disable buffering in nginx through headers.
269 ob_implicit_flush( true );
270 ob_end_flush();
271 }
272
273 // Process Reply
274 $reply = $this->core->ai->run( $query, $streamCallback );
275 $restRes = [
276 'success' => true,
277 'data' => $reply->result,
278 'usage' => $reply->usage
279 ];
280 if ( $stream ) {
281 $this->core->stream_push( [ 'type' => 'end', 'data' => json_encode( $restRes ) ] );
282 die();
283 }
284 return new WP_REST_Response( $restRes, 200 );
285 }
286 catch ( Exception $e ) {
287 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
288 if ( $stream ) {
289 $this->core->stream_push( [ 'type' => 'error', 'data' => $message ] );
290 }
291 else {
292 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
293 }
294 }
295 }
296
297 function rest_ai_images( $request ) {
298 try {
299 $params = $request->get_json_params();
300 $prompt = $params['prompt'];
301 $query = new Meow_MWAI_Query_Image( $prompt );
302 $query->injectParams( $params );
303 $reply = $this->core->ai->run( $query );
304 return new WP_REST_Response([ 'success' => true, 'data' => $reply->results, 'usage' => $reply->usage ], 200 );
305 }
306 catch ( Exception $e ) {
307 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
308 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
309 }
310 }
311
312 function rest_ai_magic_wand( $request ) {
313 try {
314 $params = $request->get_json_params();
315 $action = isset( $params['action'] ) ? $params['action'] : null;
316 $data = isset( $params['data'] ) ? $params['data'] : null;
317 if ( empty( $data ) || empty( $action ) ) {
318 return new WP_REST_Response([ 'success' => false, 'message' => "An action and some data are required." ], 500 );
319 }
320 $postId = isset( $data['postId'] ) ? $data['postId'] : null;
321 $text = isset( $data['text'] ) ? $data['text'] : null;
322 $selectedText = isset( $data['selectedText'] ) ? $data['selectedText'] : null;
323
324 // NOTE: As soon as we have a wide range of usages and possibilities,
325 // let's refactor this into a nice and extensible UI/API.
326 $query = new Meow_MWAI_Query_Text( "", 1024 );
327 $query->setEnv( 'admin-tools' );
328 $model = $this->core->get_option( 'assistants_model' );
329 if ( !empty( $model ) ) {
330 $query->setModel( $model );
331 }
332 $mode = 'replace';
333
334 $language = "";
335 $keepLanguage = "";
336 if ( !empty( $postId ) ) {
337 $language = $this->core->get_post_language( $postId );
338 $keepLanguage = " Ensure the reply is in the same language as the original text ({$language}).";
339 }
340
341 if ( $action === 'correctText' ) {
342 $query->setPrompt( "Correct the typos and grammar mistakes in this text without altering its content. Return only the corrected text, without explanations or additional content.{$keepLanguage}\n\n" . $text );
343 }
344 else if ( $action === 'enhanceText' ) {
345 $query->setPrompt( "Enhance this text by eliminating redundancies, utilizing a more suitable vocabulary, and refining its structure. Provide only the revised text, without explanations or any additional content.{$keepLanguage}\n\n" . $text );
346 }
347 else if ( $action === 'longerText' ) {
348 $query->setPrompt( "Expand the subsequent text to a minimum of three times its original length, integrating relevant and accurate information to enrich its content. If the text is a story, amplify its charm by elaborating on essential aspects, enhancing readability, and creating a sense of engagement for the reader. Maintain consistency in tone and vocabulary throughout the expansion process.{$keepLanguage}\n\n" . $text );
349 }
350 else if ( $action === 'shorterText' ) {
351 $query->setPrompt( "Condense the following text by reducing its length to half, while retaining the core elements of the original narrative. Focus on maintaining the essence of the story and its key details.{$keepLanguage}\n\n" . $text );
352 }
353 else if ( $action === 'suggestSynonyms' ) {
354 $mode = 'suggest';
355 $query->setPrompt( "Provide a synonym or rephrase the given word or sentence while retaining the original meaning and preserving the initial and final punctuation. Offer only the resulting word or expression, without additional context. If a suitable synonym or alternative cannot be identified, ensure that a creative response is still provided.{$keepLanguage}\n\n" . $selectedText );
356 $query->setTemperature( 1 );
357 $query->setMaxResults( 5 );
358 }
359 else if ( $action === 'translateText' ) {
360 $query->setPrompt( "Translate the text into {$language}, preserving the tone, mood, and nuance, while staying as true as possible to the original meaning. Provide only the translated text, without any additional content.\n\n" . $text );
361 }
362 else if ( $action === 'suggestExcerpts' ) {
363 $text = $this->core->getCleanPostContent( $postId );
364 $query->setPrompt( "Craft a clear, SEO-optimized introduction for the following text, using 120 to 170 characters. Ensure the introduction is concise and relevant, without including any URLs.{$keepLanguage}\n\n" . $text );
365 $query->setMaxResults( 5 );
366 }
367 else if ( $action === 'suggestTitles' ) {
368 $text = $this->core->getCleanPostContent( $postId );
369 $query->setPrompt( "Generate a concise, SEO-optimized title for the following text, without using quotes or any other formatting. Focus on clarity and relevance to the content.{$keepLanguage}\n\n" . $text );
370 $query->setMaxResults( 5 );
371 }
372 $reply = $this->core->ai->run( $query );
373 return new WP_REST_Response([ 'success' => true, 'data' => [
374 'mode' => $mode,
375 'result' => $reply->result,
376 'results' => $reply->results
377 ] ], 200 );
378 }
379 catch ( Exception $e ) {
380 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
381 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
382 }
383 }
384
385 function rest_ai_copilot( $request ) {
386 try {
387 $params = $request->get_json_params();
388 $action = sanitize_text_field( $params['action'] );
389 $prompt = sanitize_text_field( $params['prompt'] );
390 if ( empty( $action ) || empty( $prompt ) ) {
391 return new WP_REST_Response([ 'success' => false, 'message' => "Copilot needs an action and a prompt." ], 500 );
392 }
393 $query = new Meow_MWAI_Query_Text( $prompt, 2048 );
394 $query->setEnv( 'admin-tools' );
395 $model = $this->core->get_option( 'assistants_model' );
396 if ( !empty( $model ) ) {
397 $query->setModel( $model );
398 }
399 $reply = $this->core->ai->run( $query );
400 return new WP_REST_Response([ 'success' => true, 'data' => $reply->result ], 200 );
401 }
402 catch ( Exception $e ) {
403 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
404 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
405 }
406 }
407
408 function rest_helpers_update_title( $request ) {
409 try {
410 $params = $request->get_json_params();
411 $title = sanitize_text_field( $params['title'] );
412 $postId = intval( $params['postId'] );
413 $post = get_post( $postId );
414 if ( !$post ) {
415 throw new Exception( 'There is no post with this ID.' );
416 }
417 $post->post_title = $title;
418 //$post->post_name = sanitize_title( $title );
419 wp_update_post( $post );
420 return new WP_REST_Response([ 'success' => true, 'message' => "Title updated." ], 200 );
421 }
422 catch ( Exception $e ) {
423 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
424 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
425 }
426 }
427
428 function rest_helpers_update_excerpt( $request ) {
429 try {
430 $params = $request->get_json_params();
431 $excerpt = sanitize_text_field( $params['excerpt'] );
432 $postId = intval( $params['postId'] );
433 $post = get_post( $postId );
434 if ( !$post ) {
435 throw new Exception( 'There is no post with this ID.' );
436 }
437 $post->post_excerpt = $excerpt;
438 wp_update_post( $post );
439 return new WP_REST_Response([ 'success' => true, 'message' => "Excerpt updated." ], 200 );
440 }
441 catch ( Exception $e ) {
442 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
443 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
444 }
445 }
446
447 function rest_helpers_create_post( $request ) {
448 try {
449 $params = $request->get_json_params();
450 $title = sanitize_text_field( $params['title'] );
451 $content = sanitize_textarea_field( $params['content'] );
452 $excerpt = sanitize_text_field( $params['excerpt'] );
453 $postType = sanitize_text_field( $params['postType'] );
454 $post = new stdClass();
455 $post->post_title = $title;
456 $post->post_excerpt = $excerpt;
457 $post->post_content = $content;
458 $post->post_status = 'draft';
459 $post->post_type = isset( $postType ) ? $postType : 'post';
460 $post->post_content = $this->core->markdown_to_html( $post->post_content );
461 $postId = wp_insert_post( $post );
462 return new WP_REST_Response([ 'success' => true, 'postId' => $postId ], 200 );
463 }
464 catch ( Exception $e ) {
465 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
466 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
467 }
468 }
469
470 function image_download( $url ) {
471 $args = array( 'timeout' => 60, );
472 $response = wp_remote_get( $url, $args );
473 if ( is_wp_error( $response ) ) {
474 throw new Exception( $response->get_error_message() );
475 }
476 $output = wp_remote_retrieve_body( $response );
477 if ( is_wp_error( $output ) ) {
478 throw new Exception( $output->get_error_message() );
479 }
480 return $output;
481 }
482
483 function rest_helpers_create_images( $request ) {
484 try {
485 $params = $request->get_json_params();
486 $title = sanitize_text_field( $params['title'] );
487 $caption = sanitize_text_field( $params['caption'] );
488 $alt = sanitize_text_field( $params['alt'] );
489 $description = sanitize_text_field( $params['description'] );
490 $url = $params['url'];
491 $filename = sanitize_text_field( $params['filename'] );
492 $image_data = $this->image_download( $url );
493 if ( !$image_data ) {
494 throw new Exception( 'Could not download the image.' );
495 }
496 $upload_dir = wp_upload_dir();
497 if ( empty( $filename ) ) {
498 $filename = basename( $url );
499 }
500 $wp_filetype = wp_check_filetype( $filename );
501 if ( wp_mkdir_p( $upload_dir['path'] ) ) {
502 $file = $upload_dir['path'] . '/' . $filename;
503 }
504 else {
505 $file = $upload_dir['basedir'] . '/' . $filename;
506 }
507
508 // Make sure the file is unique, if not, add a number to the end of the file before the extension
509 $i = 1;
510 $parts = pathinfo( $file );
511 while ( file_exists( $file ) ) {
512 $file = $parts['dirname'] . '/' . $parts['filename'] . '-' . $i . '.' . $parts['extension'];
513 $i++;
514 }
515
516 // Write the file
517 file_put_contents( $file, $image_data );
518 $attachment = [
519 'post_mime_type' => $wp_filetype['type'],
520 'post_title' => $title,
521 'post_content' => $description,
522 'post_excerpt' => $caption,
523 'post_status' => 'inherit'
524 ];
525 // Register the file as a Media Library attachment
526 $attachmentId = wp_insert_attachment( $attachment, $file );
527 require_once( ABSPATH . 'wp-admin/includes/image.php' );
528 $attachment_data = wp_generate_attachment_metadata( $attachmentId, $file );
529 wp_update_attachment_metadata( $attachmentId, $attachment_data );
530 update_post_meta( $attachmentId, '_wp_attachment_image_alt', $alt );
531 return new WP_REST_Response([ 'success' => true, 'attachmentId' => $attachmentId ], 200 );
532 }
533 catch ( Exception $e ) {
534 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
535 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
536 }
537 }
538
539 function rest_openai_files_get() {
540 try {
541 //$params = $request->get_json_params();
542 $openai = new Meow_MWAI_Engines_OpenAI( $this->core );
543 $files = $openai->listFiles();
544 return new WP_REST_Response([ 'success' => true, 'files' => $files ], 200 );
545 }
546 catch ( Exception $e ) {
547 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
548 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
549 }
550 }
551
552 function rest_openai_deleted_finetunes_get() {
553 try {
554 $openai = new Meow_MWAI_Engines_OpenAI( $this->core );
555 $finetunes = $openai->listDeletedFineTunes();
556 return new WP_REST_Response([ 'success' => true, 'finetunes' => $finetunes ], 200 );
557 }
558 catch ( Exception $e ) {
559 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
560 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
561 }
562 }
563
564 function rest_openai_finetunes_get() {
565 try {
566 $openai = new Meow_MWAI_Engines_OpenAI( $this->core );
567 $finetunes = $openai->listFineTunes();
568 return new WP_REST_Response([ 'success' => true, 'finetunes' => $finetunes ], 200 );
569 }
570 catch ( Exception $e ) {
571 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
572 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
573 }
574 }
575
576 function rest_openai_files_upload( $request ) {
577 try {
578 $params = $request->get_json_params();
579 $filename = sanitize_text_field( $params['filename'] );
580 $data = $params['data'];
581 $openai = new Meow_MWAI_Engines_OpenAI( $this->core );
582 $file = $openai->uploadFile( $filename, $data );
583 return new WP_REST_Response([ 'success' => true, 'file' => $file ], 200 );
584 }
585 catch ( Exception $e ) {
586 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
587 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
588 }
589 }
590
591 function rest_openai_files_delete( $request ) {
592 try {
593 $params = $request->get_json_params();
594 $fileId = $params['fileId'];
595 $openai = new Meow_MWAI_Engines_OpenAI( $this->core );
596 $openai->deleteFile( $fileId );
597 return new WP_REST_Response([ 'success' => true ], 200 );
598 }
599 catch ( Exception $e ) {
600 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
601 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
602 }
603 }
604
605 function rest_openai_finetunes_cancel( $request ) {
606 try {
607 $params = $request->get_json_params();
608 $finetuneId = $params['finetuneId'];
609 $openai = new Meow_MWAI_Engines_OpenAI( $this->core );
610 $openai->cancelFineTune( $finetuneId );
611 return new WP_REST_Response([ 'success' => true ], 200 );
612 }
613 catch ( Exception $e ) {
614 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
615 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
616 }
617 }
618
619 function rest_openai_finetunes_delete( $request ) {
620 try {
621 $params = $request->get_json_params();
622 $modelId = $params['modelId'];
623 $openai = new Meow_MWAI_Engines_OpenAI( $this->core );
624 $openai->deleteFineTune( $modelId );
625 return new WP_REST_Response([ 'success' => true ], 200 );
626 }
627 catch ( Exception $e ) {
628 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
629 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
630 }
631 }
632
633 function rest_openai_files_download( $request ) {
634 try {
635 $params = $request->get_json_params();
636 $fileId = $params['fileId'];
637 $openai = new Meow_MWAI_Engines_OpenAI( $this->core );
638 $data = $openai->downloadFile( $fileId );
639 return new WP_REST_Response([ 'success' => true, 'data' => $data ], 200 );
640 }
641 catch ( Exception $e ) {
642 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
643 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
644 }
645 }
646
647 function rest_openai_files_finetune( $request ) {
648 try {
649 $params = $request->get_json_params();
650 $fileId = $params['fileId'];
651 $model = $params['model'];
652 $suffix = $params['suffix'];
653 $hyperparams = [
654 "nEpochs" => $params['nEpochs'],
655 "batchSize" => $params['batchSize']
656 ];
657 $openai = new Meow_MWAI_Engines_OpenAI( $this->core );
658 $finetune = $openai->fineTuneFile( $fileId, $model, $suffix, $hyperparams );
659 return new WP_REST_Response([ 'success' => true, 'finetune' => $finetune ], 200 );
660 }
661 catch ( Exception $e ) {
662 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
663 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
664 }
665 }
666
667 function rest_openai_incidents() {
668 try {
669 $transient = get_transient( 'mwai_openai_incidents' );
670 if ( $transient ) {
671 return new WP_REST_Response([ 'success' => true, 'incidents' => $transient ], 200 );
672 }
673 $openai = new Meow_MWAI_Engines_OpenAI( $this->core );
674 $incidents = $openai->getIncidents();
675 set_transient( 'mwai_openai_incidents', $incidents, 60 * 10 );
676 return new WP_REST_Response([ 'success' => true, 'incidents' => $incidents ], 200 );
677 }
678 catch ( Exception $e ) {
679 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
680 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
681 }
682 }
683
684 function rest_helpers_count_posts( $request ) {
685 try {
686 $params = $request->get_query_params();
687 $postType = $params['postType'];
688 $postStatus = $params['postStatus'];
689 $postStatus = !empty( $params['postStatus'] ) ? explode( ',', $postStatus ) : [ 'publish' ];
690 $count = wp_count_posts( $postType );
691 $count = array_sum( array_intersect_key( (array)$count, array_flip( $postStatus ) ) );
692 return new WP_REST_Response([ 'success' => true, 'count' => $count ], 200 );
693 }
694 catch ( Exception $e ) {
695 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
696 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
697 }
698 }
699
700 function rest_helpers_post_content( $request ) {
701 try {
702 $params = $request->get_query_params();
703 $offset = (int)$params['offset'];
704 $postType = $params['postType'];
705 $postStatus = $params['postStatus'];
706 $postStatus = !empty( $params['postStatus'] ) ? explode( ',', $postStatus ) : [ 'publish' ];
707 $postId = (int)$params['postId'];
708
709 $post = null;
710 if ( !empty( $postId ) ) {
711 $post = get_post( $postId );
712 if ( $post->post_status !== 'publish' && $post->post_status !== 'future'
713 && $post->post_status !== 'draft' && $post->post_status !== 'private' ) {
714 $post = null;
715 }
716 }
717 else {
718 $posts = get_posts( [
719 'posts_per_page' => 1,
720 'post_type' => $postType,
721 'offset' => $offset,
722 'post_status' => $postStatus,
723 ] );
724 $post = count( $posts ) === 0 ? null : $posts[0];
725 }
726 if ( !$post ) {
727 return new WP_REST_Response([ 'success' => false, 'message' => 'Post not found' ], 404 );
728 }
729 $cleanPost = $this->core->getCleanPost( $post );
730 return new WP_REST_Response([ 'success' => true, 'content' => $cleanPost['content'],
731 'checksum' => $cleanPost['checksum'], 'language' => $cleanPost['language'], 'excerpt' => $cleanPost['excerpt'],
732 'postId' => $cleanPost['postId'], 'title' => $cleanPost['title'], 'url' => $cleanPost['url'] ], 200 );
733 }
734 catch ( Exception $e ) {
735 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
736 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
737 }
738 }
739
740 function rest_system_templates_get( $request ) {
741 try {
742 $params = $request->get_query_params();
743 $category = $params['category'];
744 $templates = [];
745 $templates_option = get_option( 'mwai_templates', [] );
746 if ( !is_array( $templates_option ) ) {
747 update_option( 'mwai_templates', [] );
748 }
749 $categories = array_column( $templates_option, 'category' );
750 $index = array_search( $category, $categories );
751 $templates = [];
752 if ( $index !== false ) {
753 $templates = $templates_option[$index]['templates'];
754 }
755 return new WP_REST_Response([ 'success' => true, 'templates' => $templates ], 200 );
756 }
757 catch ( Exception $e ) {
758 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
759 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
760 }
761 }
762
763 function rest_system_templates_save( $request ) {
764 try {
765 $params = $request->get_json_params();
766 $category = $params['category'];
767 $templates = $params['templates'];
768 $templates_option = get_option( 'mwai_templates', [] );
769 $categories = array_column( $templates_option, 'category' );
770 $index = array_search( $category, $categories );
771 if ( $index !== false && $index >= 0 ) {
772 $templates_option[$index]['templates'] = $templates;
773 }
774 else {
775 $group = [ 'category' => $category, 'templates' => $templates ];
776 $templates_option[] = $group;
777 }
778
779 update_option( 'mwai_templates', $templates_option );
780 return new WP_REST_Response([ 'success' => true ], 200 );
781 }
782 catch ( Exception $e ) {
783 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
784 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
785 }
786 }
787
788 function rest_system_logs_list( $request ) {
789 try {
790 $params = $request->get_json_params();
791 $offset = $params['offset'];
792 $limit = $params['limit'];
793 $filters = $params['filters'];
794 $sort = $params['sort'];
795 $logs = apply_filters( 'mwai_stats_logs', [], $offset, $limit, $filters, $sort );
796 return new WP_REST_Response([ 'success' => true, 'total' => $logs['total'], 'logs' => $logs['rows'] ], 200 );
797 }
798 catch ( Exception $e ) {
799 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
800 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
801 }
802 }
803
804 function rest_system_logs_delete( $request ) {
805 try {
806 $params = $request->get_json_params();
807 $logIds = $params['logIds'];
808 $success = apply_filters( 'mwai_stats_logs_delete', true, $logIds );
809 return new WP_REST_Response([ 'success' => $success ], 200 );
810 }
811 catch ( Exception $e ) {
812 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
813 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
814 }
815 }
816
817 function rest_system_logs_meta_get( $request ) {
818 try {
819 $params = $request->get_json_params();
820 $logId = $params['logId'];
821 $metaKeys = $params['metaKeys'];
822 $data = apply_filters( 'mwai_stats_logs_meta', [], $logId, $metaKeys );
823 return new WP_REST_Response([ 'success' => true, 'data' => $data ], 200 );
824 }
825 catch ( Exception $e ) {
826 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
827 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
828 }
829 }
830
831 function rest_ai_moderate( $request ) {
832 try {
833 $params = $request->get_json_params();
834 $text = $params['text'];
835 if ( !$text ) {
836 return new WP_REST_Response([ 'success' => false, 'message' => 'Text not found.' ], 404 );
837 }
838 $openai = new Meow_MWAI_Engines_OpenAI( $this->core );
839 $results = $openai->moderate( $text );
840 return new WP_REST_Response([ 'success' => true, 'results' => $results ], 200 );
841 }
842 catch ( Exception $e ) {
843 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
844 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
845 }
846
847 }
848
849 function rest_ai_transcribe( $request ) {
850 try {
851 $params = $request->get_json_params();
852 $query = new Meow_MWAI_Query_Transcribe();
853 $query->injectParams( $params );
854 $query->setEnv('admin-tools');
855 $reply = $this->core->ai->run( $query );
856 return new WP_REST_Response([ 'success' => true, 'data' => $reply->result ], 200 );
857 }
858 catch ( Exception $e ) {
859 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
860 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
861 }
862 }
863
864 function rest_helpers_post_types() {
865 try {
866 $postTypes = $this->core->getPostTypes();
867 return new WP_REST_Response([ 'success' => true, 'postTypes' => $postTypes ], 200 );
868 }
869 catch ( Exception $e ) {
870 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
871 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
872 }
873 }
874
875 function rest_settings_themes( $request ) {
876 try {
877 $method = $request->get_method();
878 if ( $method === 'GET' ) {
879 $themes = $this->core->getThemes();
880 return new WP_REST_Response([ 'success' => true, 'themes' => $themes ], 200 );
881 }
882 else if ( $method === 'POST' ) {
883 $params = $request->get_json_params();
884 $themes = $params['themes'];
885 $themes = $this->core->updateThemes( $themes );
886 return new WP_REST_Response([ 'success' => true, 'themes' => $themes ], 200 );
887 }
888 }
889 catch ( Exception $e ) {
890 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
891 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
892 }
893 }
894
895 function rest_settings_chatbots( $request ) {
896 try {
897 $method = $request->get_method();
898 if ( $method === 'GET' ) {
899 $chatbots = $this->core->getChatbots();
900 return new WP_REST_Response([ 'success' => true, 'chatbots' => $chatbots ], 200 );
901 }
902 else if ( $method === 'POST' ) {
903 $params = $request->get_json_params();
904 $chatbots = $params['chatbots'];
905 $chatbots = $this->core->updateChatbots( $chatbots );
906 return new WP_REST_Response([ 'success' => true, 'chatbots' => $chatbots ], 200 );
907 }
908 return new WP_REST_Response([ 'success' => false, 'message' => 'Method not allowed' ], 405 );
909 }
910 catch ( Exception $e ) {
911 $message = apply_filters( 'mwai_ai_exception', $e->getMessage() );
912 return new WP_REST_Response([ 'success' => false, 'message' => $message ], 500 );
913 }
914 }
915 }
916